Cloth simulation with NURBS

Another fluxus friday adventure…

; a simple realtime cloth simulation model
(clear)
(texture (load-texture "test2.png"))

(define rez 25) ; resolution of nurbs patch
(define dist 0.1) ; the desired spring length

(define p ; setup the nurbs primitive
    (with-state
        (backfacecull 0) ; we wanna see the back
        (ambient 0.2)
        (rotate (vector -90 0 0))
        (scale (vector 8 4 4))
        (build-nurbs-plane (- rez 1) (- rez 1))))

(with-primitive p (pdata-add "vel" "v"))

(define (spring a b) ; return vector trying to keep the length
    (let ((d (vsub a b))) ; between the two input points constant
        (vmul d (- dist (vmag d)))))

(every-frame
    (with-primitive p
        (pdata-index-map! ; for each control vertex
            (lambda (i v p)
                (let ((x (modulo i rez)) ; get the x and y from
                      (y (quotient i rez))) ; the index
                    (if (> x 0) 
                        ; we want to 'pin' the top row of cvs 
                        (vmul (vadd v 
                                (spring p (pdata-ref "p" (- i 1)))
                                (if (< x (- rez 1)) ; deal with the edges
                                    (spring p (pdata-ref "p" (+ i 1)))
                                    (vector 0 0 0))
                                (if (> y 0)
                                    (spring p (pdata-ref "p" (- i rez)))
                                    (vector 0 0 0))
                                (if (< y (- rez 1))
                                    (spring p (pdata-ref "p" (+ i rez)))
                                    (vector 0 0 0))
                                ; add constant gravity 
                                (vector 0 0 -0.001)) 
                            0.995) v)))
            "vel" "p")
        (pdata-op "+" "p" "vel") ; add velocity to the vertex positions
        (recalc-normals 1))) 

; setup the lights
(light-diffuse 0 (vector 0 0 0))
(define l (make-light 'point 'free))
(light-diffuse l (vector 1 1 1))
(light-position l (vector 10 300 -10))
(light-specular l (vector 1 1 1))
(light-ambient l (vector 0.3 0.3 0.3))

Diffusion-limited aggregation with particles

Trying to reinstate “fluxus friday” where I reserve some time for livecoding or fluxus hacking at the end of the week. First up, a new way of making fuzzy blobs in fluxus – particle aggregation. I like the analogue feel to it – reminds me of the voxels from last year. I also found this for syntax highlighting lisp for blog posts.

; a blurry particle aggregation example
(clear)
(hint-depth-sort)
(texture (load-texture "splat.png"))
(blend-mode 'src-alpha 'one)
(define p (build-particles 500))
(define r 1)

; setup the particle primitive
(with-primitive p
    (pdata-add "a" "f") ; 1 if we have attached to another particle
    (pdata-add "vel" "v") ; velocity array
    (pdata-map! (lambda (a) 0) "a") ; init to zero
    (pdata-set! "a" 0 1)
    (pdata-map! (lambda (c) 0.1) "c") ; init the colour
    (pdata-map!
        (lambda (p)
            (vmul (hsrndvec) r)) ; space out in a hollow sphere
        "p")
    (pdata-map!
        (lambda (vel p)
            (vector 0.02 0 0)) ; init velocities
        "vel" "p")
    (pdata-set! "p" 0 (vector 0 0 0)))

; check particle n against all others and return #t if we
; are close enouth to another to aggregate
(define (collide? n)
    (let ((np (pdata-ref "p" n)))
        (pdata-index-fold
            (lambda (i p a r)
                (if (and (not r) (not (zero? a)) (not (eq? i n)) (< (vdist p np) 0.05))
                    #t r))
            #f "p" "a")))

(every-frame
    (with-primitive p
        (pdata-map!
            (lambda (p vel a)
                (if (zero? a) ; if we're not attached
                    (if (> (vmag p) r) ; and we are outside the sphere
                        (vmul (hsrndvec) r) ; reset position
                        (vadd p vel)) ; move with velocity
                     p))
            "p" "vel" "a")
        (pdata-index-map! ; check all particles and set a if they
            (lambda (i a) ; have attached to any others
                (if (and (zero? a) (collide? i)) 1 a))
            "a")))

Germination X: Draw your own plant spirits


Part of our groworld bazaar at Pixelache 2011 was the “draw your own plant spirits” workshop/gallery installation in the Augusta gallery on Suomenlinna island. This was the first event to use the Germination X game in a public setting, and the idea was to get people to help us design characters to represent the layers, or groups of plant types that permaculture companion planting uses.

This started with a drawing challenge, to draw on paper your idea of what a “spirit” would look like for trees, leafy ground cover plants or shrubs. The drawing was then instantly scanned and automatically put into the game, connected with the FAtiMA AI system and animated. The game with it’s new characters being projected on the wall at all times.

We wanted to ask more questions about how emotions could be expressed by the characters in different ways – along with how the fundamentals of permaculture could be described by the game itself in a social network setting. In the gallery format this proved difficult – as people had more than enough to think about being put on the spot and asked to draw something!

The thing that impressed me most was the range of the styles and ideas resulting from this simple request. Despite being able to see the characters drawn by other people around them on bits of paper, and in the game, each one was quite unique – giving us a lot to think about.

Groworld Bazaar @ Pixelache

After much organisation, shopping for seeds, clay, compost, drawing equipment, aronia berry products, packing, catching ferries, unpacking and then finally tidying up – Pixelache 2011 and FoAM’s groworld bazaar is over!

Suomenlinna island was a great venue for the festival, despite the logistical challenges it brought a good vibe with it’s fortified buildings, village atmosphere and fresh sea air. Due to my commitments I didn’t see as much of the other events as I’d have liked, but I still managed to meet a lot of interesting people. I’ll write a report on the “draw your own plant spirit” germination x event at camp pixelache shortly.

Germination X: Relationships

More documentation for the Germination X game – this diagram attempts to explain the relationships between the plant spirits and the plants, and between each other. Green indicates “love”, red indicates “hate”. Each spirit represents a “layer” in permaculture terminology – a collection of plants, for example the CoverSpirit represents the soil cover species such as clover and dandelion (which is not strictly correct Lina informs me, but we’ll skip that for now).

The basic emotions of “love” and “hate” give the FAtiMA AI system something to react to in order to cause higher level emotions. For example, the fact that the CoverSpirit is not fond of the TreeSpirit (as trees cause shade for it’s plants) means that it experiences “resentment” when the TreeSpirit is happy at an apple tree flowering. The CoverSpirit will in turn express “admiration” for the ShrubSpirit being happy at the planting of a new aronia bush. This can be seen as the most basic form of this kind of “socially aware” artificial intelligence.

Germination X: Secret mechanisms

I’ve made some graphs to document the underlying processes currently used by Germination X in preparation for the Pixelache workshop. These are not considered required for playing the game of course, but more as a description of how things work now, and hopefully a way to prompt suggestions on improvements and possible new directions. I’ve always found workshop participants very good for this once they understand the way things work.

Companion planting relationships

A key idea of this game is to treat plants differently to the monocultures encouraged by game mechanics used by other farming games. We are using a very simple model for doing this – the overall health of each plant is figured out by looking at the other plants in it’s local neighbourhood. The idea in the collection of plants we are starting with is that clover may be beneficial to most other plants as it mulches and creates good soil (green arrows indicate liking, red indicates not). Trees can’t grow too close together to each other, dandelions don’t mind too much what conditions they grow in, but don’t like aronia as the area around them will be too shady. Getting too literal and complex with this kind of simulation is not the point, but even with very simple relationships we aim to create an interesting world to play with, and hopefully bring out some of the wider issues from the groworld project.

Plant growth cycles

Perennial life cycle

Each plant grows according to another simplified model of plant growth, switching between states Lina has drawn for each plant based on the season and the plant’s health. Plants enter a decay process in autumn or at any time when their health is too low. In spring if their health is above a certain threshold they regrow and can go on to flower and fruit.

Perennials are plants that last for many years. They currently grow to an adult stage and then have a yearly cycle. At any time they can start to decay based on unfavourable conditions, if conditions improve (by players planting beneficial plants nearby) they will recover next spring, or if not, decay completely and be removed from the world.

Annual life cycle

Annuals are plants that regrow from seed to seed in a year or less, represented in the game as a plant or patch of small plants that regrows each year in a cycle.

Although in total this looks fairly complex, it’s all implemented in quite a pleasingly short section of clojure.

FarmVille

At it’s height Farmville attracted 60 million players per month. This makes it the most played computer game in history, and not without good reason – I enjoyed playing it too. What continues to fascinate me beyond the appeal of the game itself is the worldview it presents regarding plants (and also domesticated animals) and food production in general. In order to appeal to such a wide range of players there have to be strict restrictions on how they treat issues such as death, disease and slaughter.

FarmVille creators Zynga explain how it works in a single slide

For example, horses are cultivated for the harvesting of their hair, when pigs are “100% ready” you get truffles. There is no death allowed anywhere, everyone is clearly vegetarian, there is never bad weather, crop failure or insect infestation. The game has come under some criticism for these and other issues. What I find interesting is that despite the restrictions on awkward issues, the logical conclusion of the way the game works leads to animals crammed in to the smallest area possible, and the winning strategy for plants is to create a vast monocultures of the most lucrative crop.

This clearly is “just a computer game” albeit one that 60 million people play regularly, but computer games can be used to create and explore worlds at the limits of our imagination – so what does it tell us if this is the way we need to portray the world for people to have fun? How does this happen? It the only way possible?

One aim for the Germination X project is to explore these questions.

Germination X: Seasons and Video

As well as featuring a hi scores table (now making it into a real game!), we have most of Lina’s plants in the game, only the dandelion needs replacing from the older version. With the new artwork the difference between the seasons is much more apparent, for example autumn above and spring below.

I’ve also made a quick video of the game for an appearance on Finnish national TV station YLE: