In case you didn't know, pixelpusher (evan.raskob) is a live video performance artist, or "pixelist" based in London, UK. Click the Info button above for hiring and contact info.
by pixelpusher on Saturday 12 December 2009
[Blog]
reaction diffusion visuals on the GPU in Fluxus
As part of MakeArt 2009’s theme, forking (taking someone’s code and altering it so it becomes a new project built on top of it), I’ve forked Claude Heiland-Allen’s (claudius maximus) excellent rdex-client into an open source fluxus project on googlecode.
What this does is (from Claude’s site):
rdex-client is an installation that explores in an autonomous hyperspace mathematical model, searching for interesting emergent behaviour (life-alike, alife).
The model is a kind of continuous non-linear cellular automaton, based on partial differential equations representing chemistry of two reagents involving reaction and diffusion.
The mathematical equations of the model have four parameters, that need to be set to concrete values when running the simulation. rdex-client explores this 4D parameter space at random.
(the fluxus version doesn’t do the sophisticated analysis stuff yet, like Claude’s does)
IOhannes’s talk was about software as “intelligent” agents, which boiled down to programming using Pd (involving visual boxes you connect by wiring together bungee-like “patch cords”) using visual objects. What I really enjoyed about his talk is depth of his curiosity and his willingness to experiment. For example, making cannibalistic objects, where one ropes another with its patch cord and sucks the life (screen size) out of it. Or boxing, and using that as controller data for a performance. With his agents, though, the idea of making your computer code work with (or against) you is a powerful notion.
Gabor Papp fooled us all into thinking he was livecoding his talk, but it really turned out he recorded movies of his livecoding and edited them together or loaded them into fluxus. Still, bonus points to Gabor for doing his entire presentation from within Fluxus. And of course, he’s been doing some really interesting things, especially with “simple” geometric animations. (Not really so simple, but they look that way)
Wesley is demoing yet another amazing-looking audio-visual programming environment called LuaAV. Seriously, the last thing I need to distract me from doing something productive is another audio-visual programming development tool in a language that I should learn. The system itself shows the experience of the developers; it’s an asynchronous events-based system, which in plain-speak means that you can set up many interesting audio-visual things to happen at different times and they all occur independently, as if you were a big shot investment banker with a bunch of secretaries whom you could trust to carry out all of your wishes once told, and not step on each others’ toes (too much).
For those of you who haven’t seen it, SketchPatch is a playground for Processing sketches, where you can create, edit, share, and copy others’ sketches. All sketches on the site are Creative Commons 3.0 attribution licensed, which means you can copy the code and use it as long as you give credit to the original author(s).
Playing with a circular particle system based on a water simulation, done using Fluxus (http://pawfal.org/fluxus). Energy is tranferred between adjacent toads, so after time they start to bounce back and forth chaotically.
Code:
; a simple script that looks like it could be made into a
; water simulation of some kind
(clear)
(require fluxus-016/shapes)
(hint-ignore-depth)
; dimensions of the circles
(define elems 20)
; angle between each element
(define elem-angle (/ 3.14156 elems))
; simulation constants
(define max-dist 10)
(define max-dist-sq (* max-dist max-dist))
(define min-dist 4)
(define min-dist-sq (* min-dist min-dist))
(define max-vel-mag 0.1)
; stops the simulation going out of control
(define max-vel (vmul (vector (cos elem-angle) (sin elem-angle) 0) max-vel-mag))
(define max-vel-sq (vdist-sq max-vel (vector 0 0 0)))
(define trans 0.008) ; the amount the energy transmitted to
; the neighboring vertex
; feedback velocity per frame
(define feedback 0.1)
; complexity of initial positions (sin peaks, basically)
(define complexity 4)
; make a list of points in a circle
(define circle-points (build-circle-points elems 1))
(define tex (load-texture "/Users/evan/cvs/newflx/fluxus/textures/whitetoady.png"))
(define s (build-particles elems))
(with-primitive s
(pdata-add "vel" "v")
(pdata-add "v0" "v")
(pdata-add "p0" "v")
(pdata-index-map!
(lambda (i p)
(list-ref circle-points i))
"p")
; copy default pos at radius 1
(pdata-copy "p" "p0")
; scale circle radius
(pdata-index-map!
(lambda (i p)
; (vmul p (+ (* (* 0.5 (+ 1 (sin (* 3.4156 (/ i elems)))))
; (- max-dist min-dist)) min-dist)))
(vmul p (* (* 0.5 (+ 1 (sin (* complexity (* 3.4156 (/ i elems)))))) max-dist)))
"p")
; start off the simulation with random point distances
; (pdata-index-map!
; (lambda (i p)
; (vadd p (vmul p (* (* max-dist 0.4) (crndf)) )))
; "p")
(pdata-index-map!
(lambda (i vel p)
(vmul p (/ max-dist 10)))
"vel" "p")
; store initial velocity
(pdata-copy "vel" "v0")
; start off the simulation with random colours
(pdata-map!
(lambda (c)
(rndvec))
"c")
; start off the simulation with random colours
(pdata-map!
(lambda (s)
(vector 2 2 0.6))
"s")
)
(define (simulate n)
(cond [(< n 0) 0]
[else
(let* [(result (pdata-get "vel" n))
(p (pdata-get "p" n))
(p-sq (vdist-sq p (vector 0 0 0)))]
(cond [(> p-sq max-dist-sq)
; (display "max")(newline)
; we are above "sea level" head down
(pdata-set "vel" n (vmul (pdata-ref "vel" n) -0.9))
; (pdata-set "vel" n (vmul (pdata-ref "v0" n) -1))
(pdata-set "p" n (vmul (pdata-ref "p0" n) max-dist))
]
[(< p-sq min-dist-sq)
; (display "mIN")(newline)
; we are below "sea level" head up
; (pdata-set "vel" n (pdata-ref "v0" n))
(pdata-set "vel" n (vmul (pdata-ref "vel" n) -0.9))
(pdata-set "p" n (vmul (pdata-ref "p0" n) min-dist))
]
[else
(let [(pv (* (vdist (pdata-get "vel" (- n 1)) (vector 0 0 0)) trans))
(nv (* (vdist (pdata-get "vel" (+ n 1)) (vector 0 0 0)) trans))]
; mix in the surrounding verts to transmit energy around
(set! result (vadd result
(vmul result pv)))
(set! result (vadd result
(vmul result nv)))
; add the result to the existing velocity
(pdata-set "vel" n (vadd (pdata-get "vel" n) (vmul result feedback)))
;(pdata-set "vel" n (vadd (pdata-get "vel" n) result))
)
]
)
(let* [
(v (pdata-get "vel" n))
(v0 (pdata-get "v0" n))
(vmax (vmul v0 max-vel-mag))
(v-sq (vdist-sq v (vector 0 0 0)))]
; clamp the velocity - this stops the
; simulation going too fast and blowing up
(cond [(> v-sq max-vel-sq)
; divide by mag to get sign, mult by max-vel
(pdata-set "vel" n (vmul (vmul v (/ 1 (vmag v))) max-vel-mag))
]
)
)
)
(simulate (- n 1))
]
)
)
(define (render)
(set! feedback (* 0.4 0.5 (+ 1 (sin (* 0.3 (time))))))
(with-primitive s
(rotate (vector 0 0 2))
(texture tex)
(simulate (pdata-size))
(pdata-op "+" "p" "vel")
; (recalc-normals 1)
)
)
(every-frame (render))