Behavioral Animation Example
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(load 'transform.al)
(load 'BooleanPrimitives.al)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define render-rib? #f)
(define *actors* '()) ;; list of live actors
(define (add-actor actor) (set! *actors* (cons actor *actors*)))
(define *num-actors* 10)
(define (randR low high) (+ (* (rand) (- high low)) low))
(define *boundary* 30)
(define *perfect-distance* 15)
(define *max-turn* 4)
(define *speed* .4)
(define (clamp x l h) (cond ((< x l) l) ((> x h) h) (else x)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (shark)
(solid "difference"
(surface "matte")
(color (vec3 .2 .2 .2))
(translate 0 0 -.95)
(scale .1 1 1)
(solid-sphere 2 -2 2)
(translate 0 0 -1.2)
(scale 10 1.2 1)
(solid-sphere 2 -2 2)
))
(define (water)
(separator
(surface "plastic")
(rotate -90 (vec3 1 0 0))
(color (vec3 0 .2 1))
(disk 'radius 100)
))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (actor-create)
(let (
(direction (vec3 0 0 1))
(speed .5)
(position (vec3 0 0 0))
(dead? #f)
(id 0)
)
(define (set-direction! vel) (set! direction vel))
(define (set-speed! vel) (set! speed vel))
(define (set-position! pos) (set! position pos))
(define (set-dead! dead) (set! dead? dead))
(define (set-id! new-id) (set! id new-id))
(define (influence-force other-pos)
(let (
(d (norm (- position other-pos)))
)
(if (< d *perfect-distance*)
(* (normalize (- position other-pos))
(expt (- *perfect-distance* d) 2))
(* (normalize (- other-pos position))
(expt (- d *perfect-distance*) 2))
)))
(define (update)
(let ((a-list *actors*)
(force (vec3 0 0 0))
)
;; compute influence forces from other actors
(while (not (null? a-list))
(begin
(define other (car a-list))
(if (<> (other 'id) id)
(set! force (+ force (influence-force (other 'position))))
)
(set! a-list (cdr a-list))
))
;; compute new direction
(set! force (normalize force))
; determine axis and angle of rotation
; from current direction to force direction
(define axis (cross direction force))
(define angle (degrees (acos (dot direction force))))
(set! angle (clamp angle (- 0 *max-turn*) *max-turn*))
(set! direction (transform-point direction (mat4-rotate angle axis)))
;; compute new position
(set! position (+ position (* direction speed)))
))
(define (draw)
(separator (translate position)
(concat-transform (from-z-xfm direction))
(shark)
))
(lambda (message)
(cond
((eq? message 'set-direction!) set-direction!)
((eq? message 'set-speed!) set-speed!)
((eq? message 'set-position!) set-position!)
((eq? message 'set-dead!) set-dead!)
((eq? message 'set-id!) set-id!)
((eq? message 'direction) direction)
((eq? message 'speed) speed)
((eq? message 'position) position)
((eq? message 'dead?) dead?)
((eq? message 'id) id)
((eq? message 'update) (update))
((eq? message 'draw) (draw))
(else (error "actor: invalid operation" message))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (generate-actors)
(let (
(n *num-actors*)
(actor '())
)
(while (> n 0)
(begin
(set! actor (actor-create))
((actor 'set-direction!)
(normalize (vec3 (randR -1 1) 0 (randR -1 1))))
((actor 'set-speed!) *speed*)
((actor 'set-id!) n)
((actor 'set-position!) (vec3 (randR -15 15)
0
(randR -15 15)))
(add-actor actor)
(set! n (sub1 n))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (update-actors)
(define a-list *actors*)
(while (not (null? a-list))
(begin
((car a-list) 'update)
(set! a-list (cdr a-list)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (draw-actors)
(define a-list *actors*)
(while (not (null? a-list))
(begin
((car a-list) 'draw)
(set! a-list (cdr a-list)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (animate duration)
(begin
(set-time! 0)
(generate-actors)
(while (< time duration)
(begin
(update-actors)
(world
(srand 1)
(tessellate 4 4)
(camera "main" "perspective"
'from (vec3 20 5 20)
'fov 60)
(light "pointlight" 'from (vec3 0 10 10) 'intensity 1000)
(water)
(draw-actors)
)
(if render-rib?
(render
'display-name (string-append "frame." (number->string time))
'format '(160 121 1)
))
(set-time! (add1 time))
))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;(animate 90)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Return to Behavioral Animation
mrl