The Heliconius Butterfly Wing Pattern Evolver game is finished and ready for it’s debut as part of the Butterfly Evolution Exhibit at the Royal Society Summer Exhibition 2014. Read more about the scientific context on the researcher’s website, and click the image above to play the game.
The source code is here, it’s the first time I’ve used WebGL for a game, and it’s using the browser version of fluxus. It worked out pretty well, even to the extent that the researchers could edit the code themselves to add new explanation screens for the genetics. Like any production code it has niggles, here’s the function to render a butterfly:
(define (render-butterfly s) (with-state ;; set tex based on index (texture (list-ref test-tex (butterfly-texture s))) ;; move to location (translate (butterfly-pos s)) ;; point towards direction (maim (vnormalise (butterfly-dir s)) (vector 0 0 1)) (rotate (vector 0 90 90)) ;; angle correctly (scale (vector 0.5 0.5 0.5)) ;; make smaller (draw-obj 4) ;; draw the body (with-state ;; draw the wings in a new state (rotate (vector 180 0 0)) (translate (vector 0 0 -0.5)) ;; position and angle right ;; calculate the wing angle based on speed (let ((a (- 90 (* (butterfly-flap-amount s) (+ 1 (sin (* (butterfly-speed s) (+ (butterfly-fuzz s) (time))))))))) (with-state (rotate (vector 0 0 a)) (draw-obj 3)) ;; draw left wing (with-state (scale (vector 1 -1 1)) ;; flip (rotate (vector 0 0 a)) (draw-obj 3)))))) ;; draw right wing
There is only immediate mode rendering at the moment, so the transforms are not optimised and little things like draw-obj takes an id of a preloaded chunk of geometry, rather than specifying it by name need to be fixed. However it works well and the thing that was most successful was welding together the Nightjar Game Engine (HTML5 canvas) with fluxus (WebGL) and using them together. This works by having two canvas elements drawn over each other – all the 2D (text, effects and graphs) are drawn using canvas, and the butterflies are drawn in 3D with WebGL. The render loops are run simultaneously with some extra commands to get the canvas pixel coordinates of objects drawn in 3D space.