Fluxus

Input 

Quite quickly you are going to want to start using data from outside of fluxus to control your animations. This is really what starts making this stuff interesting, after all.

Sound

The original purpose of fluxus and still perhaps it's best use, was as a sound to light vjing application. In order to do this it needs to take real time values from an incoming sound source. We do this by configuring the sound with:

(start-audio “jack-port-to-read-sound-from” 256 44100)

Running some application to provide sound, or just taking it from the input on your sound card, and then using:

(gh harmonic-number)

To give us floating point values we can plug into parameters to animate them. You can test there is something coming through either with:

(every-frame (begin (display (gh 0)) (newline)))

And see if it prints anything other than 0's or run the bars.scm script in examples, which should display a graphic equaliser. It's also useful to use:

(gain 1)

To control the gain on the incoming signal, which will have a big effect on the scale of the values coming from (gh).

Keyboard

Keyboard control is useful when using fluxus for things like non-livecoding vjing, as it's a nice simple way to control parameters without showing the code on screen. It's also obviously useful for when writing games with fluxus.

(key-pressed key-string)

Returns a #t if the key is currently pressed down, for example:

(every-frame
    (when (key-pressed "x")     
        (colour (rndvec))
        (draw-cube)))

Draws a cube with randomly changing colour when the x key is pressed.

(keys-down)

Returns a list of the current keys pressed, which is handy in some situations. For keys which aren't able to be described by strings, there is also:

(key-special-pressed key-code-number)

For instance

(key-special-pressed 101)

Returns #t when the “up” cursor key is pressed. To find out what the mysterious key codes are, you can simply run this script:

(every-frame (begin (display (keys-special-down)) (newline)))

Which will print out the list of special keys currently pressed. Press the key you want and see what the code is. Note: These key codes may be platform specific.

Mouse

You can find out the mouse coordinates with:

(mouse-x)
(mouse-y)

And whether mouse buttons are pressed with:

(mouse-button button-number)

Which will return #t if the button is down.

Select

While we're on the subject of the mouse, one of the best uses for it is selecting primitives, which you can do with:

(select screen-x screen-y size)

Which will render the bit of the screen around the x y coordinate and return the id of the highest primitive in the z buffer. To give a better example:

; click on the donuts!
(clear)

(define (make-donuts n)
    (when (not (zero? n))
        (with-state
            (translate (vmul (srndvec) 5))
            (scale 0.1)
            (build-torus 1 2 12 12))
        (make-donuts (- n 1))))

(make-donuts 10)

(every-frame
    (when (mouse-button 1)
        (let ((s (select (mouse-x) (mouse-y) 2)))
            (when (not (zero? s))
                (with-primitive s
                    (colour (rndvec)))))))

OSC

OSC (Open Sound Control) is a standard protocol for communication between arty programs over a network. Fluxus has (almost) full support for receiving and sending OSC messages.

To get you started, here is an example of a fluxus script which reads OSC messages from a port and uses the first value of a message to set the position of a cube:

(osc-source "6543")
(every-frame
    (with-state
        (when (osc-msg "/zzz")
             (translate (vector 0 0 (osc 0))))
            (draw-cube)))

And this is a pd patch which can be used to control the cube's position.

#N canvas 618 417 286 266 10;
#X obj 58 161 sendOSC;
#X msg 73 135 connect localhost 6543;
#X msg 58 82 send /zzz $1;
#X floatatom 58 29 5 0 0 0 - - -;
#X obj 58 54 / 100;
#X obj 73 110 loadbang;
#X connect 1 0 0 0;
#X connect 2 0 0 0;
#X connect 3 0 4 0;
#X connect 4 0 2 0;
#X connect 5 0 1 0;

Time

I've decided to include time as a source of input, as you could kind of say it comes from the outside world. It's also a useful way of animating things, and making animation more reliable.

(time)

This returns the time in seconds since the program was started. It returns a float number and is updated once per frame.

(delta)

This command returns the time since the last frame. (delta) is a very important command, as it allows you to make your animation frame rate independent. Consider the following script:

(clear)
(define my-cube (build-cube))
(every-frame
        (with-primitive my-cube
                (rotate (vector 5 0 0))))

This rotates my-cube by one degree each frame. The problem is that it will speed up as the framerate rises, and slow down as it falls. If you run the script on a different computer it will move at a different rate. This used to be a problem when running old computer games - they become unplayable as they run too fast on newer hardware!

The solution is to use (delta):

(clear)
(define my-cube (build-cube))
(every-frame
        (with-primitive my-cube
                (rotate (vector (* 45 (delta)) 0 0))))

The cube will rotate at the same speed everywhere - 45 degrees per second. The normal (time) command is not too useful on it's own - as it returns an ever increasing number, it doesn't mean much for animation. A common way to tame it is pass it through (sin) to get a sine wave:

(clear)
(define my-cube (build-cube))
(every-frame
        (with-primitive my-cube
                (rotate (vector (* 45 (sin (time))) 0 0))))

This is also framerate independent and gives you a value from -1 to 1 to play with. You can also record the time when the script starts to sequence events to happen:

(clear)
(define my-cube (build-cube))
(define start-time (time)) ; record the time now
(every-frame
        ; when the script has been running for 5 seconds...
        (when (> (- (time) start-time) 5)
                (with-primitive my-cube
                        (rotate (vector (* 45 (delta)) 0 0)))))