1794 lines
60 KiB
Scheme
1794 lines
60 KiB
Scheme
;; p l a n t e y e s [ copyright (c) 2009 foam vzw : gpl v3 ]
|
|
|
|
#lang scheme/base
|
|
(require scheme/class
|
|
fluxus-016/fluxus
|
|
fluxus-016/shapes
|
|
"sound.ss"
|
|
"message.ss"
|
|
"list-utils.ss"
|
|
"ornament-views.ss"
|
|
"path-gen.ss")
|
|
|
|
(provide (all-defined-out))
|
|
|
|
; the fluxus code to make things look the way they do
|
|
|
|
(define debug-messages #f) ; prints out all the messages sent to the renderer
|
|
|
|
(define (ornament-colour) (vector 0.7 0.7 0.7))
|
|
(define (pickup-colour) (vector 1 1 1))
|
|
(define (earth-colour) (vector 0 0 0))
|
|
(define (dust-colour) (vmul (vector 0.05 0.05 0.05) (* 2 (rndf))))
|
|
(define (stones-colour) (vector 0.55 0.5 0.45))
|
|
(define (alive-colour) (vmul (vector 1 1 1) (+ 0.5 (* (rndf) 0.5))))
|
|
(define (worm-colour) (vmul (vector 1.0 0.8 0.8) (+ 0.5 (* (rndf) 0.5))))
|
|
(define (marker-colour) (vector 0.3 0.8 0.3))
|
|
(define (sky-colour) (vdiv (vector 170 153 135) 256))
|
|
|
|
(define wire-mode #f)
|
|
(define fog-col (earth-colour))
|
|
(define fog-strength 0.01)
|
|
(define default-grow-speed 0.5)
|
|
(define grow-overshoot 10)
|
|
|
|
(define above-fog-col (vector 0.9 0.9 1))
|
|
(define above-fog-strength 0.01)
|
|
(define ground-change-duration 4)
|
|
|
|
(define min-fin-len 3)
|
|
(define fin-length-var 4)
|
|
(define fin-grow-prob 200)
|
|
(define max-fins-per-twig 5)
|
|
|
|
(define max-twiglets-per-twig 10)
|
|
|
|
|
|
(define (pre-ripple)
|
|
(when (not (pdata-exists? "rip-pref"))
|
|
(pdata-copy "p" "rip-pref")))
|
|
|
|
(define (ripple t speed wave-length)
|
|
(pdata-map!
|
|
(lambda (p pref)
|
|
(vadd pref (vmul (srndvec)
|
|
(* 0.1 (+ 1 (sin (+ (* t speed) (* wave-length
|
|
(vdist (vtransform p
|
|
(minverse (get-transform)))
|
|
(vector 0 0 0))))))))))
|
|
"p" "rip-pref"))
|
|
|
|
(define (fract n)
|
|
(- n (floor n)))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define dust%
|
|
(class object%
|
|
(field
|
|
(rate 1)
|
|
(above-ground #f)
|
|
(next-p 0)
|
|
(root (let ((p (with-state
|
|
(colour 0)
|
|
(hint-depth-sort)
|
|
(texture (load-texture "textures/particle.png"))
|
|
(build-particles 500))))
|
|
(with-primitive p
|
|
(pdata-map!
|
|
(lambda (c)
|
|
(vector 0 0 0 0.01))
|
|
"c")
|
|
(pdata-map!
|
|
(lambda (p)
|
|
(vmul (srndvec) 100))
|
|
"p")
|
|
(pdata-map!
|
|
(lambda (s)
|
|
(let ((s (* 4 (rndf))))
|
|
(vector s s s)))
|
|
"s")) p))
|
|
(emitter (with-state (build-locator)))
|
|
(pos (with-primitive root (vtransform (vector 0 0 0) (get-global-transform)))))
|
|
|
|
(define/public (set-above-ground s)
|
|
(set! above-ground s)
|
|
(with-primitive root
|
|
(colour (if s 1 0))
|
|
(pdata-map!
|
|
(lambda (c)
|
|
(if s (vector 1 1 1 0.01) (vector 0 0 0 0.01)))
|
|
"c")))
|
|
|
|
(define/public (update t d)
|
|
|
|
(let ((emitter-pos (with-primitive emitter
|
|
(identity)
|
|
(translate (vmul pos -1)) ; makes the particles relative to the centre of the plant
|
|
(concat (get-locked-matrix)) ; which makes the depth sorting work better
|
|
(translate (vector 0 0 -10))
|
|
(vtransform (vector 0 0 0) (get-transform)))))
|
|
|
|
(with-primitive root
|
|
(for ((i (in-range 0 rate)))
|
|
(pdata-set! "p" next-p (vadd emitter-pos (vmul (srndvec) 10)))
|
|
(pdata-set! "c" next-p (if above-ground (vector 1 1 1 0.01) (vector 0 0 0 0.01)))
|
|
(pdata-set! "s" next-p (let ((s (* 4 (rndf)))) (vector s s s)))
|
|
(set! next-p (+ next-p 1)))
|
|
(pdata-op "*" "c" 1.01)
|
|
(pdata-op "*" "s" 0.995))))
|
|
|
|
(super-new)))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define insect-view%
|
|
(class object%
|
|
(init-field
|
|
(id 0)
|
|
(from (vector 0 0 0))
|
|
(type 'none))
|
|
|
|
(field
|
|
(to from)
|
|
(from-dir (vector 0 0 0))
|
|
(to-dir (vector 0 0 0))
|
|
(time 0)
|
|
(tick 1)
|
|
(speed 0)
|
|
(idle-sound-time (+ 2 (* (rndf) 10))))
|
|
|
|
(define/public (move pos dur)
|
|
(set! from to)
|
|
(set! from-dir to-dir)
|
|
(set! to pos)
|
|
(set! to-dir (vnormalise (vsub from to)))
|
|
(set! time 0)
|
|
(set! tick dur))
|
|
|
|
(define/public (play-idle-sound pos)
|
|
(cond
|
|
((eq? type 'worm) (play-sound 'worm-idle pos))
|
|
((eq? type 'butterfly) (play-sound 'butterfly-idle pos))
|
|
((eq? type 'spider) (play-sound 'spider-idle pos))))
|
|
|
|
(define/public (update t d)
|
|
(set! time (+ time d)))
|
|
|
|
(define/public (do-tx t d)
|
|
(let* ((t (min (/ time tick) 1))
|
|
(h (hermite-tangent from to (vmul from-dir 2) (vmul to-dir 2) t)))
|
|
(translate (car h))
|
|
(when (< idle-sound-time 0)
|
|
(set! idle-sound-time (+ 2 (* (rndf) 10)))
|
|
(play-idle-sound (car h)))
|
|
(set! speed (vmag (cadr h)))
|
|
(concat (maim (vector 0 1 0) (vnormalise (cadr h)))))
|
|
|
|
(set! time (+ time d))
|
|
(set! idle-sound-time (- idle-sound-time d)))
|
|
|
|
(super-new)))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define (add-blendshape key model)
|
|
(let ((b (load-primitive model))
|
|
(pname (string-append "p" (number->string key))))
|
|
(pdata-add pname "v")
|
|
(pdata-index-map!
|
|
(lambda (i p)
|
|
(with-primitive b (pdata-ref "p" i)))
|
|
pname)
|
|
(destroy b)))
|
|
|
|
(define (set-blendshape key)
|
|
(pdata-copy (string-append "p" (number->string key)) "p"))
|
|
|
|
(define spider-insect-view%
|
|
(class insect-view%
|
|
(inherit-field from to from-dir to-dir time tick speed)
|
|
(inherit do-tx)
|
|
|
|
(field
|
|
(root (let ((p (with-state
|
|
(hint-unlit)
|
|
(colour (vector 0 0 0))
|
|
(load-primitive "meshes/spider-1.obj"))))
|
|
(with-primitive p
|
|
(pdata-copy "p" "p0")
|
|
(add-blendshape 1 "meshes/spider-2.obj")
|
|
(add-blendshape 2 "meshes/spider-3.obj") p)))
|
|
(anim-t 0)
|
|
(anim-d (* 0.2 (rndf)))
|
|
(blendshape 0))
|
|
|
|
(define/override (update t d)
|
|
(with-primitive root
|
|
(set! anim-d (* 0.01 (/ 1 (max 0.0001 speed))))
|
|
(when (> anim-t anim-d)
|
|
(set! anim-t 0)
|
|
(set! blendshape (modulo (+ blendshape 1) 3))
|
|
(set-blendshape blendshape))
|
|
(identity)
|
|
(do-tx t d)
|
|
(rotate (vector 0 0 -90))
|
|
(scale 0.1))
|
|
(set! anim-t (+ anim-t d)))
|
|
|
|
(super-new)))
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define butterfly-insect-view%
|
|
(class insect-view%
|
|
(inherit-field from to from-dir to-dir time tick)
|
|
(inherit do-tx)
|
|
|
|
(field
|
|
(root (let ((p (with-state
|
|
(hint-unlit)
|
|
(colour 0)
|
|
(load-primitive "meshes/butterfly-body.obj"))))
|
|
(with-state
|
|
(colour (rndvec))
|
|
(parent p)
|
|
(hint-depth-sort)
|
|
(hint-unlit)
|
|
(backfacecull 0)
|
|
(texture (load-texture "textures/butterfly.png"))
|
|
(load-primitive "meshes/butterfly.obj")
|
|
(translate (vector 0 0.001 0))
|
|
(load-primitive "meshes/butterfly.obj")) p)))
|
|
|
|
(define/override (update t d)
|
|
(with-primitive root
|
|
(let ((a (* 90 (rndf))))
|
|
(with-primitive (car (get-children))
|
|
(rotate (vector 0 0 a)))
|
|
(with-primitive (cadr (get-children))
|
|
(rotate (vector 0 0 (- a)))))
|
|
(identity)
|
|
(do-tx t d)
|
|
(scale 1))
|
|
(set! time (+ time d)))
|
|
|
|
(super-new)))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define worm-insect-view%
|
|
(class insect-view%
|
|
(inherit-field from to from-dir to-dir time tick)
|
|
|
|
(field
|
|
(hidden #t)
|
|
(from2 from)
|
|
(from-dir2 from-dir)
|
|
(root (let ((p (build-ribbon 20)))
|
|
(with-primitive p
|
|
(translate (vector 0 0 -0.1))
|
|
(hint-depth-sort)
|
|
;(hint-unlit)
|
|
(colour (worm-colour))
|
|
(texture (load-texture "textures/worm.png"))
|
|
(let ((width (+ 0.5 (* 0.5 (rndf)))))
|
|
(pdata-index-map!
|
|
(lambda (i w)
|
|
width #;(+ 0.05 (* (abs (sin (* i 0.5))) 0.1)))
|
|
"w"))
|
|
#;(pdata-map!
|
|
(lambda (c)
|
|
(vector 1 1 1))
|
|
"c"))
|
|
p)))
|
|
|
|
(define/override (move pos dur)
|
|
(set! from2 from)
|
|
(set! from to)
|
|
(set! from-dir2 from-dir)
|
|
(set! from-dir to-dir)
|
|
(set! to pos)
|
|
(set! to-dir (vmul (vsub to from) 5))
|
|
(set! time 0)
|
|
(set! tick dur))
|
|
|
|
(define/override (update t d)
|
|
(let ((nt (/ time tick))) ; normalise time
|
|
(when (< nt 1)
|
|
(with-primitive root
|
|
(pdata-index-map!
|
|
(lambda (i p)
|
|
(let ((st (- nt (* i 0.05))))
|
|
(if (< st 0)
|
|
(hermite from2 from (vmul from-dir2 2) (vmul from-dir 2) (+ st 1))
|
|
(hermite from to (vmul from-dir 2) (vmul to-dir 2) st))))
|
|
"p"))))
|
|
|
|
(set! time (+ time d)))
|
|
|
|
(super-new)))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define (build-squiggle x y)
|
|
(let ((p (build-ribbon 15))
|
|
(x (/ x 10))
|
|
(y (/ y 10)))
|
|
(with-primitive p
|
|
(pdata-add "vel" "v")
|
|
(pdata-map!
|
|
(lambda (vel)
|
|
(vmul (srndvec) 0.1))
|
|
"vel")
|
|
(pdata-index-map!
|
|
(lambda (i p)
|
|
(vector (cos (/ i x)) (sin (/ i y)) (/ i (pdata-size))))
|
|
"p")
|
|
(pdata-index-map!
|
|
(lambda (i p)
|
|
(* 0.5 (sin (* 3.141 (/ i (pdata-size))))))
|
|
"w")
|
|
(pdata-map!
|
|
(lambda (c)
|
|
(vector 1 1 1))
|
|
"c")
|
|
(pdata-copy "p" "pref")
|
|
(recalc-bb))
|
|
p))
|
|
|
|
(define pickup-view%
|
|
(class object%
|
|
(init-field
|
|
(id -1)
|
|
(type 'none)
|
|
(pos (vector 0 0 0))
|
|
(highlit #f))
|
|
|
|
(field
|
|
(rot (vmul (rndvec) 360))
|
|
(root (let ((p (with-state
|
|
(translate pos)
|
|
(rotate rot)
|
|
(colour (pickup-colour))
|
|
(texture (load-texture "textures/spark.png"))
|
|
(shader "shaders/spark.vert.glsl" "shaders/spark.frag.glsl")
|
|
(hint-nozwrite)
|
|
(hint-frustum-cull)
|
|
(blend-mode 'src-alpha 'one)
|
|
(cond
|
|
((eq? type 'nutrient) (colour (vector 1 1 0.5)) (build-squiggle 2 2))
|
|
((eq? type 'leaf) (colour (vector 0.5 1 0.5)) (build-squiggle 2 4))
|
|
((eq? type 'horn) (colour (vector 0.5 1 1)) (build-squiggle 3 4))
|
|
((eq? type 'inflatoe) (colour (vector 1 0.5 0.5)) (build-squiggle 4 5))
|
|
((eq? type 'fork) (colour (vector 0.5 0.5 1)) (build-squiggle 5 2))
|
|
((eq? type 'flower) (colour (vector 1 0.5 0.75)) (build-squiggle 4 3))))))
|
|
(with-primitive p (shader-set! (list "BaseMap" 0))) p))
|
|
(from pos)
|
|
(destination (vector 0 0 0))
|
|
(speed 0.05)
|
|
(t -1)
|
|
(destroy-time -99)
|
|
(dissolve-time -99)
|
|
(delme #f))
|
|
|
|
(define/public (get-type)
|
|
type)
|
|
|
|
(define/public (pick-up point)
|
|
(set! destroy-time point))
|
|
|
|
(define/public (delme?)
|
|
delme)
|
|
|
|
(define/public (highlight)
|
|
(set! highlit #t))
|
|
|
|
(define/public (get-root)
|
|
root)
|
|
|
|
(define/public (move-to s)
|
|
(set! t 0)
|
|
(set! from pos)
|
|
(set! destination s))
|
|
|
|
(define/public (update t d)
|
|
|
|
(with-primitive root
|
|
(rotate (vector (* d (if highlit 50 10)) 0 0)))
|
|
|
|
(when (and highlit (eq? dissolve-time -99))
|
|
(with-primitive root
|
|
(pdata-map!
|
|
(lambda (p pref)
|
|
(vadd pref (vmul (srndvec) 0.1)))
|
|
"p" "pref")))
|
|
|
|
(when (> destroy-time -99)
|
|
(set! destroy-time (- destroy-time (* d default-grow-speed 0.5)))
|
|
(when (< destroy-time 0)
|
|
(set! destroy-time -100)
|
|
(set! dissolve-time 4)))
|
|
|
|
(when (> dissolve-time -99)
|
|
(set! dissolve-time (- dissolve-time d))
|
|
(with-primitive root
|
|
(pdata-op "+" "p" "vel")
|
|
(pdata-op "*" "w" 0.95))
|
|
(when (< dissolve-time 0)
|
|
(destroy root)
|
|
(set! delme #t)))
|
|
|
|
(set! t (+ t speed)))
|
|
|
|
(super-new)))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define twig-view%
|
|
(class object%
|
|
(init-field
|
|
(id 0)
|
|
(pos (vector 0 0 0))
|
|
(type 'none)
|
|
(dir (vector 0 1 0))
|
|
(radius 1)
|
|
(num-points 0))
|
|
|
|
(field
|
|
(index 0)
|
|
(parent-twig-id -1)
|
|
(child-twig-ids '())
|
|
(ornaments '())
|
|
(col (vector 1 1 1))
|
|
(tex "")
|
|
(markers '())
|
|
(shrink-t 0)
|
|
(grow-t -1)
|
|
(marker-destroy-t 0)
|
|
(grow-speed default-grow-speed)
|
|
(delme #f))
|
|
|
|
(define/public (get-id) id)
|
|
(define/public (delme?) delme)
|
|
(define/public (get-dir) dir)
|
|
(define/public (set-dir! s) (set! dir s))
|
|
(define/public (set-col! s) (set! col s))
|
|
(define/public (set-tex! s) (set! tex s))
|
|
(define/public (get-pos) pos)
|
|
(define/public (build sp) 0)
|
|
(define/public (get-num-points) index)
|
|
(define/public (get-grow-t) grow-t)
|
|
(define/public (set-pos! s) (set! pos s))
|
|
(define/public (get-child-twig-ids) child-twig-ids)
|
|
(define/public (get-root) (error "need to overide this"))
|
|
(define/public (destroy-twig) (destroy (get-root)))
|
|
(define/public (set-parent-twig-id s) (set! parent-twig-id s))
|
|
(define/public (get-point point-index) (error "need to overide this"))
|
|
(define/public (get-width point-index) (error "need to overide this"))
|
|
(define/public (set-grow-speed s) (set! grow-speed s))
|
|
|
|
(define/public (add-child-twig-id twig-id)
|
|
(set! child-twig-ids (cons twig-id child-twig-ids)))
|
|
|
|
(define/public (growing?)
|
|
(< grow-t (+ num-points grow-overshoot)))
|
|
|
|
(define/public (start-growing)
|
|
(play-sound 'twig-start-growing
|
|
(with-primitive (get-root) (vtransform (vector 0 0 0) (get-global-transform))))
|
|
(set! grow-t 0)
|
|
(set! markers (cons (build-locator) markers)))
|
|
|
|
(define/pubment (start-shrinking)
|
|
(play-sound 'twig-start-decay
|
|
(with-primitive (get-root) (vtransform (vector 0 0 0) (get-global-transform))))
|
|
(set! shrink-t (if (growing?) grow-t (+ num-points grow-overshoot)))
|
|
(for-each
|
|
(lambda (o)
|
|
(send (cadr o) start-shrinking))
|
|
ornaments)
|
|
(inner (void) start-shrinking))
|
|
|
|
(define/pubment (add-point point width make-marker)
|
|
(when make-marker
|
|
(play-sound 'place-marker (vadd point (with-primitive (get-root)
|
|
(vtransform (vector 0 0 0) (get-global-transform)))))
|
|
(set! markers (append markers (list (let ((p (with-state
|
|
(parent (get-root))
|
|
(translate point)
|
|
(scale 0.001)
|
|
(colour (marker-colour))
|
|
(build-sphere 8 8)))) (with-primitive p (shader-set! (list "Pos" point))) p)))))
|
|
|
|
(inner (void) add-point point width make-marker))
|
|
|
|
(define/pubment (update-markers t d)
|
|
(for-each
|
|
(lambda (marker)
|
|
(with-primitive marker
|
|
(let ((sc (vmag (vtransform-rot (vector 0 1 0) (get-transform)))))
|
|
(when (< sc 0.1)
|
|
(scale (+ 1.0 (* d 1)))))))
|
|
markers))
|
|
|
|
(define/public (add-ornament point-index property)
|
|
(when (< point-index grow-t)
|
|
(play-sound 'twig-new-ornament
|
|
(vadd (get-point point-index)
|
|
(with-primitive (get-root) (vtransform (vector 0 0 0) (get-global-transform)))))
|
|
(with-state
|
|
(parent (get-root))
|
|
(let ((ornament (property->ornament property
|
|
(get-point point-index)
|
|
(get-width point-index)
|
|
(vnormalise (vsub (get-point point-index) (get-point (- point-index 1))))
|
|
col)))
|
|
(set! ornaments (cons (list point-index ornament) ornaments))))))
|
|
|
|
(define/pubment (set-excitations! a b)
|
|
(for-each
|
|
(lambda (ornament)
|
|
(send (cadr ornament) set-excitations! a b))
|
|
ornaments))
|
|
|
|
(define/pubment (update t d)
|
|
(inner (void) update t d)
|
|
|
|
(update-markers t d)
|
|
|
|
(when (> shrink-t 0)
|
|
(set! shrink-t (- shrink-t (* d grow-speed))))
|
|
|
|
(when (< shrink-t 0)
|
|
(set! delme #t))
|
|
|
|
(when (and (not (eq? grow-t -1)) (< grow-t (+ num-points grow-overshoot)))
|
|
(set! grow-t (+ grow-t (* d grow-speed)))
|
|
(when (and (not (null? markers)) (> 0 (- marker-destroy-t grow-t)))
|
|
#;(play-sound 'twig-eat-marker
|
|
(with-primitive (car markers) (vtransform (vector 0 0 0) (get-global-transform))))
|
|
(set! marker-destroy-t (+ 1 marker-destroy-t))
|
|
(destroy (car markers))
|
|
(set! markers (cdr markers))))
|
|
|
|
(when (> grow-t (+ num-points 10))
|
|
(set! grow-t 999)))
|
|
|
|
(super-new)))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define ribbon-twig-view%
|
|
(class twig-view%
|
|
|
|
(inherit-field pos radius num-points index col tex grow-t grow-speed shrink-t)
|
|
(inherit growing?)
|
|
|
|
(field
|
|
(root 0)
|
|
(widths '())
|
|
(points '())
|
|
(global-growth 0)
|
|
(global-growth-time 20)
|
|
(finalised #f))
|
|
|
|
|
|
(define/override (build sp)
|
|
(set! grow-speed (* grow-speed 5))
|
|
(set! root (let ((p (with-state
|
|
(translate pos)
|
|
(hint-frustum-cull)
|
|
(colour col)
|
|
(hint-unlit)
|
|
(shader "shaders/ribbon.vert.glsl" "shaders/ribbon.frag.glsl")
|
|
(texture (load-texture "textures/ribbon-twig.png"))
|
|
(build-ribbon num-points))))
|
|
(with-primitive p
|
|
(shader-set! (list "Base" 0 "Origin" pos))
|
|
(pdata-map!
|
|
(lambda (w)
|
|
0)
|
|
"w")
|
|
(pdata-set! "w" 0 radius))
|
|
p)))
|
|
|
|
|
|
(define/override (get-root)
|
|
root)
|
|
|
|
(define/public (finalised?)
|
|
finalised)
|
|
|
|
#;(define/override (get-point point-index)
|
|
(with-primitive root
|
|
(pdata-ref "p" point-index)))
|
|
|
|
#;(define/override (get-width point-index)
|
|
(with-primitive root
|
|
(pdata-ref "w" point-index)))
|
|
|
|
(define/override (get-point point-index)
|
|
(list-ref points point-index))
|
|
|
|
(define/override (get-width point-index)
|
|
(list-ref widths point-index))
|
|
|
|
(define/augment (add-point point width make-marker)
|
|
#;(with-primitive root
|
|
(pdata-index-map! ; set all the remaining points to the end
|
|
(lambda (i p) ; in order to hide them
|
|
(if (< i index)
|
|
p
|
|
point))
|
|
"p"))
|
|
(set! widths (append widths (list width)))
|
|
(set! points (append points (list point)))
|
|
(set! index (+ index 1)))
|
|
|
|
(define/augment (start-shrinking)
|
|
(set! grow-speed (* grow-speed 3)))
|
|
|
|
(define/augment (update t d)
|
|
(when (and (> grow-t 0) (< grow-t (+ (length points) 10)))
|
|
(with-primitive root
|
|
(identity)
|
|
(translate pos)
|
|
(scale (/ global-growth global-growth-time))
|
|
(pdata-index-map!
|
|
(lambda (i w)
|
|
(* (/ global-growth global-growth-time)
|
|
(cond ((< i (- grow-t 1))
|
|
(list-ref widths i))
|
|
((< i grow-t)
|
|
(* (list-ref widths i) (fract grow-t)))
|
|
(else
|
|
0))))
|
|
"w")
|
|
|
|
(pdata-index-map!
|
|
(lambda (i p)
|
|
(cond ((< i (- grow-t 1))
|
|
(list-ref points i))
|
|
((equal? i (inexact->exact (floor (+ grow-t 1))))
|
|
(vmix
|
|
(list-ref points i)
|
|
(list-ref points (- i 1)) (fract grow-t)))
|
|
(else
|
|
(list-ref points i))))
|
|
"p")
|
|
(recalc-bb)))
|
|
|
|
(when (> shrink-t 0)
|
|
(with-primitive root
|
|
(identity)
|
|
(translate pos)
|
|
(scale (/ shrink-t (+ num-points grow-overshoot)))))
|
|
|
|
(when (and (not (growing?)) (not finalised))
|
|
(with-primitive root
|
|
(recalc-bb)
|
|
(hint-frustum-cull))
|
|
(set! finalised #t))
|
|
|
|
(when (< global-growth global-growth-time)
|
|
(set! global-growth (+ global-growth d))))
|
|
|
|
(super-new)))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
; bunches of ribbon twigs
|
|
(define twiglets%
|
|
(class object%
|
|
(init-field
|
|
(par 0)
|
|
(col (vector 1 1 1))
|
|
(shape-params '(0 0)))
|
|
|
|
(field
|
|
(twigs '()))
|
|
|
|
(define/public (build pos dir width length)
|
|
(set! twigs (list (build-tree pos dir width length))))
|
|
|
|
(define (build-tree pos dir width length)
|
|
(let ((t (make-object ribbon-twig-view% 0 pos 'ribbon
|
|
dir
|
|
(* width (+ 0.5 (rndf))) length)))
|
|
(send t set-grow-speed 0.1)
|
|
(send t set-col! col)
|
|
(with-state
|
|
(parent par)
|
|
(send t build shape-params))
|
|
(let ((path-gen (make-object path-gen% (car shape-params) (cadr shape-params)
|
|
(vector 0 0 0) (send t get-dir)))
|
|
(ppos (vector 0 0 0)))
|
|
(for ((i (in-range 0 length)))
|
|
(let ((width (if (eq? i (- length 1)) 0 (/ width (+ i 1)))))
|
|
(send t add-point (send path-gen get-pos (* 5 width)) width #f))))
|
|
(send t start-growing)
|
|
t))
|
|
|
|
|
|
|
|
(define/public (update t d)
|
|
(for-each
|
|
(lambda (twig)
|
|
(send twig update t d)
|
|
(when (and
|
|
(< (length twigs) 10)
|
|
(> (send twig get-num-points) 5)
|
|
(zero? (random 400)))
|
|
(let ((pi (inexact->exact (floor (send twig get-grow-t)))))
|
|
(when (and (> pi 0) (< pi (send twig get-num-points)))
|
|
(set! twigs (cons
|
|
(build-tree
|
|
(vadd (send twig get-pos) (send twig get-point pi))
|
|
(send twig get-dir)
|
|
(/ (send twig get-width pi) 1.4)
|
|
(/ (send twig get-num-points) 2))
|
|
twigs))))))
|
|
twigs)
|
|
|
|
#;(set! twigs (filter
|
|
(lambda (twig)
|
|
(not (send twig finalised?)))
|
|
twigs)))
|
|
|
|
(define/public (start-shrinking)
|
|
(for-each
|
|
(lambda (twig)
|
|
(send twig start-shrinking))
|
|
twigs))
|
|
|
|
(super-new)))
|
|
|
|
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define fin%
|
|
(class object%
|
|
(init-field
|
|
(fin-size 1)
|
|
(twig-ob #f)
|
|
(col (vector 0 0 0))
|
|
(path-len 0)
|
|
(profile-len 0))
|
|
|
|
(field
|
|
(fin-len (min (- path-len 1) (+ min-fin-len (random fin-length-var))))
|
|
(root (build-polygons (* fin-len 2) 'triangle-strip))
|
|
(pos (random profile-len))
|
|
(start (* (random (- path-len fin-len)) profile-len))
|
|
(grow-t 0)
|
|
(grow-speed (* (rndf) 0.1)))
|
|
|
|
(define/public (build)
|
|
(with-primitive root
|
|
(parent twig-ob)
|
|
(texture (load-texture "textures/fin-roots.png"))
|
|
(hint-unlit)
|
|
(hint-depth-sort)
|
|
(colour col)
|
|
(backfacecull 0)
|
|
(pdata-index-map!
|
|
(lambda (i t)
|
|
(vector (/ (+ (quotient i 2) 1) (/ (pdata-size) 2)) (if (odd? i) 1 0) 0))
|
|
"t")))
|
|
|
|
(define/public (update t d)
|
|
(when (< grow-t 1)
|
|
(with-primitive root
|
|
(pdata-index-map!
|
|
(lambda (i p)
|
|
(let* ((ti (+ start pos (* (quotient i 2) profile-len)))
|
|
(tp (with-primitive twig-ob (pdata-ref "p" ti)))
|
|
(tn (with-primitive twig-ob (pdata-ref "n" ti))))
|
|
(if (even? i)
|
|
tp
|
|
(vadd tp (vmul tn (* grow-t fin-size))))))
|
|
"p"))
|
|
|
|
(set! grow-t (+ grow-t (* d grow-speed)))))
|
|
|
|
(super-new)))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define extruded-twig-view%
|
|
(class twig-view%
|
|
|
|
(inherit growing?)
|
|
(inherit-field index radius num-points pos dir col tex grow-t shrink-t
|
|
ornaments grow-speed delme markers marker-destroy-t)
|
|
|
|
(field
|
|
(profile '())
|
|
(path '())
|
|
(root 0)
|
|
(widths '())
|
|
(fins '())
|
|
(twiglets '())
|
|
(finalised #f)
|
|
(shape-params '(0 0)))
|
|
|
|
(define/override (build sp)
|
|
(set! shape-params sp)
|
|
(set! profile (build-circle-points 7 1))
|
|
(set! path (build-list num-points (lambda (_) (vector 0 0 0))))
|
|
(set! widths (build-list num-points (lambda (_) 1)))
|
|
(set! root (let ((p (with-state
|
|
(backfacecull 1)
|
|
(when wire-mode
|
|
(hint-none)
|
|
(hint-wire))
|
|
(ambient (vmul col 0.5))
|
|
(shader "shaders/tree.vert.glsl" "shaders/tree.frag.glsl")
|
|
(texture (load-texture "textures/root-norm.png"))
|
|
(colour col)
|
|
(build-partial-extrusion profile path 3))))
|
|
(with-primitive p
|
|
(shader-set! (list "NormalMap" 0)))
|
|
|
|
p)))
|
|
|
|
(define/override (get-root)
|
|
root)
|
|
|
|
(define/override (get-point point-index)
|
|
(list-ref path point-index))
|
|
|
|
(define/override (get-width point-index)
|
|
(list-ref widths point-index))
|
|
|
|
(define/augment (start-shrinking)
|
|
(for-each
|
|
(lambda (o)
|
|
(send o start-shrinking))
|
|
twiglets))
|
|
|
|
(define (list-set l c s)
|
|
(cond ((null? l) '())
|
|
((zero? c) (cons s (list-set (cdr l) (- c 1) s)))
|
|
(else (cons (car l) (list-set (cdr l) (- c 1) s)))))
|
|
|
|
(define/augment (add-point point width make-marker)
|
|
(set! path (list-set path index point))
|
|
(set! widths (list-set widths index width))
|
|
(set! index (+ index 1)))
|
|
|
|
(define/augment (update t d)
|
|
|
|
(for-each
|
|
(lambda (ornament)
|
|
(send (cadr ornament) update t d))
|
|
ornaments)
|
|
|
|
|
|
(with-primitive root
|
|
(shader-set! (list "Time" t))
|
|
#;(let ((t (inexact->exact (round (fmod (* 5 t) 3)))))
|
|
(cond
|
|
((eq? t 0) (texture (load-texture "textures/cells-1.png")))
|
|
((eq? t 1) (texture (load-texture "textures/cells-2.png")))
|
|
((eq? t 2) (texture (load-texture "textures/cells-3.png"))))))
|
|
|
|
#;(when (and (zero? (random fin-grow-prob))
|
|
(< (length fins) max-fins-per-twig)
|
|
(not (growing?))
|
|
(> (length path) 1))
|
|
(let ((new-fin (make-object fin% (+ 0.3 (* radius (rndf))) root
|
|
(vmul col (rndf))
|
|
(length path) (length profile))))
|
|
(send new-fin build)
|
|
(set! fins (cons new-fin fins))))
|
|
|
|
#;(for-each
|
|
(lambda (fin)
|
|
(send fin update t d))
|
|
fins)
|
|
|
|
(for-each
|
|
(lambda (twiglet)
|
|
(send twiglet update t d))
|
|
twiglets)
|
|
|
|
(when (and (not (eq? grow-t -1)) (not (eq? grow-t 999)))
|
|
; randomly add twiglets as we are growing
|
|
(when (and (zero? (random 100))
|
|
(< grow-t num-points)
|
|
(> grow-t 3)
|
|
(< (length twiglets) max-twiglets-per-twig))
|
|
(let ((t (make-object twiglets% (get-root) col shape-params))
|
|
(pi (inexact->exact (floor grow-t))))
|
|
(send t build (get-point pi) dir (/ (get-width pi) 2) 20)
|
|
(set! twiglets (cons t twiglets))))
|
|
(with-primitive root
|
|
(partial-extrude grow-t profile path widths (vector 1 0 0) 0.05)))
|
|
|
|
(when (> shrink-t 0)
|
|
(with-primitive root
|
|
(partial-extrude shrink-t profile path widths (vector 1 0 0) 0.05)))
|
|
|
|
(when (and (not (growing?)) (not finalised))
|
|
(with-primitive root
|
|
(recalc-bb)
|
|
(hint-frustum-cull))
|
|
(set! finalised #t))
|
|
|
|
)
|
|
|
|
(define/public (get-end-pos)
|
|
(list-ref path (if (zero? index) 0 (- index 1)))
|
|
#;(with-primitive root (pdata-ref "p" (- (* index (length profile)) 1))))
|
|
|
|
(super-new)))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define plant-view%
|
|
(class object%
|
|
|
|
(init-field
|
|
(id "none")
|
|
(pos (vector 0 0 0))
|
|
(size 0)
|
|
(col (vector 1 1 1))
|
|
(tex "")
|
|
(is-player #f)
|
|
(shape-params '(0 0)))
|
|
|
|
(field
|
|
(twigs '()) ; a assoc list map between ids and twigs stored flat here,
|
|
; for fast access, but prims heirachically in the scenegraph
|
|
(root (with-state
|
|
(translate pos)
|
|
(build-locator)))
|
|
(seed (let ((p (with-state
|
|
(parent root)
|
|
(shader "shaders/seed.vert.glsl" "shaders/seed.frag.glsl")
|
|
(texture (load-texture "textures/cells-1.png"))
|
|
(multitexture 1 (load-texture "textures/cells-2.png"))
|
|
(multitexture 2 (load-texture "textures/cells-3.png"))
|
|
(multitexture 3 (load-texture "textures/root-norm.png"))
|
|
(backfacecull 0)
|
|
(opacity 0.75)
|
|
(colour col)
|
|
(ambient (vmul col 0.5))
|
|
(hint-depth-sort)
|
|
(scale (* 0.06 size))
|
|
(when wire-mode
|
|
(hint-none)
|
|
(hint-wire))
|
|
;(hint-unlit)
|
|
(load-primitive "meshes/seed.obj"))))
|
|
(with-primitive p
|
|
(shader-set! (list "Maps" (list 0 1 2) "NormalMap" 3)))
|
|
p))
|
|
(dust (if is-player (with-state
|
|
(parent root)
|
|
(make-object dust%)) #f))
|
|
(nutrients (if (and #f is-player) (let ((p (with-state
|
|
;(hint-depth-sort)
|
|
(hint-nozwrite)
|
|
(hint-unlit)
|
|
(parent root)
|
|
(blend-mode 'src-alpha 'one)
|
|
(texture (load-texture "textures/smoke.png"))
|
|
(build-particles 100))))
|
|
(with-primitive p
|
|
(pdata-add "twig" "f")
|
|
(pdata-add "point" "f")
|
|
(pdata-add "offset" "v")
|
|
(pdata-add "speed" "f")
|
|
(pdata-map!
|
|
(lambda (point)
|
|
0)
|
|
"point")
|
|
(pdata-map!
|
|
(lambda (point)
|
|
(* 3 (+ 0.1 (rndf))))
|
|
"speed")
|
|
(pdata-map!
|
|
(lambda (offset)
|
|
(vector 0 0 0))
|
|
"offset")
|
|
(pdata-map!
|
|
(lambda (c)
|
|
(vector 1 1 1))
|
|
"c")
|
|
(pdata-map!
|
|
(lambda (p)
|
|
(vmul (vadd (crndvec) (vector 0 -1 0)) 900))
|
|
"p")
|
|
(pdata-map!
|
|
(lambda (s)
|
|
(vmul (vector 1 1 1) (+ 0.1 (rndf))))
|
|
"s"))
|
|
p) #f)))
|
|
|
|
(define/public (is-player?)
|
|
is-player)
|
|
|
|
(define/public (get-id)
|
|
id)
|
|
|
|
(define/public (get-col)
|
|
col)
|
|
|
|
(define/public (get-twig twig-id)
|
|
(let ((l (assq twig-id twigs)))
|
|
(if l
|
|
(cadr (assq twig-id twigs))
|
|
#f)))
|
|
|
|
(define/public (destroy-branch-twig twig-id)
|
|
(when (get-twig twig-id) ; might have destroyed itself already
|
|
(for-each
|
|
(lambda (twig-id)
|
|
(destroy-branch-twig twig-id))
|
|
(send (get-twig twig-id) get-child-twig-ids))
|
|
(send (get-twig twig-id) destroy-twig))
|
|
(set! twigs (assoc-remove twig-id twigs)))
|
|
|
|
(define/public (destroy-plant)
|
|
(destroy root)
|
|
(for-each
|
|
(lambda (twig)
|
|
(destroy-branch-twig (car twig)))
|
|
twigs))
|
|
|
|
(define/public (shrink-twig twig-id)
|
|
(send (get-twig twig-id) start-shrinking)
|
|
(for-each
|
|
(lambda (twig-id)
|
|
(shrink-twig twig-id))
|
|
(send (get-twig twig-id) get-child-twig-ids)))
|
|
|
|
(define/public (add-twig parent-twig-id point-index twig)
|
|
(let ((ptwig (get-twig parent-twig-id)))
|
|
(when ptwig
|
|
(send twig set-pos! (send ptwig get-point point-index)) ; attach to parent twig
|
|
; tell the twigs about this relationship (might turn out to be overkill)
|
|
(send ptwig add-child-twig-id (send twig get-id))
|
|
(send twig set-parent-twig-id parent-twig-id))
|
|
|
|
(send twig set-col! col)
|
|
(send twig set-tex! tex)
|
|
(send twig build shape-params)
|
|
|
|
(with-primitive (send twig get-root)
|
|
(parent root))
|
|
|
|
(set! twigs (cons (list (send twig get-id) twig) twigs))))
|
|
|
|
(define/public (add-twig-point twig-id point width)
|
|
(when (get-twig twig-id)
|
|
(send (get-twig twig-id) add-point point width is-player)))
|
|
|
|
(define/public (start-twig-growing twig-id)
|
|
(when (get-twig twig-id)
|
|
(send (get-twig twig-id) start-growing)))
|
|
|
|
(define/public (grow-seed amount)
|
|
(with-primitive seed (scale amount)))
|
|
|
|
(define/public (add-ornament twig-id point-index property) 0
|
|
(when (get-twig twig-id)
|
|
(send (get-twig twig-id) add-ornament point-index property)))
|
|
|
|
(define/public (hide-twigs s)
|
|
(for-each
|
|
(lambda (twig)
|
|
(with-primitive (send (cadr twig) get-root)
|
|
(hide s)))
|
|
twigs))
|
|
|
|
(define/public (set-excitations! a b)
|
|
(for-each
|
|
(lambda (twig)
|
|
(send (cadr twig) set-excitations! a b))
|
|
twigs))
|
|
|
|
(define/public (nutrient-absorb twig-id twig-point)
|
|
(when nutrients
|
|
(with-primitive nutrients
|
|
(let ((p (random (pdata-size))))
|
|
(pdata-set! "twig" p twig-id)
|
|
(pdata-set! "point" p twig-point)
|
|
(pdata-set! "p" p (send (get-twig twig-id) get-point twig-point))
|
|
(pdata-set! "offset" p (vmul (srndvec) (
|
|
send (get-twig twig-id) get-width twig-point)))))))
|
|
|
|
(define/public (update-nutrients t d)
|
|
(when (and nutrients (not (null? twigs)))
|
|
(with-primitive nutrients
|
|
(pdata-index-map!
|
|
(lambda (i p twig-id point offset speed)
|
|
(let* ((twig-id (inexact->exact twig-id))
|
|
(twig (get-twig twig-id))
|
|
(point (inexact->exact point)))
|
|
(cond
|
|
((or (< point 1) (not twig))
|
|
(let* ((new-twig (choose twigs))
|
|
(num-points (send (cadr new-twig) get-num-points))
|
|
(new-point (if (zero? num-points) 0 (random num-points))))
|
|
(pdata-set! "twig" i (car new-twig))
|
|
(pdata-set! "point" i new-point)
|
|
(pdata-set! "offset" i (vmix offset (vmul (srndvec) (send (cadr new-twig) get-width new-point)) 0.2))
|
|
(send (cadr new-twig) get-point new-point)))
|
|
((< (vdist (vadd (send twig get-point point) offset) p) 0.1)
|
|
(pdata-set! "point" i (- point 1))
|
|
(vadd p (vmul (vnormalise (vsub (vadd (send twig get-point (- point 1)) offset) p)) (* speed d))))
|
|
(else
|
|
(vadd p (vmul (vnormalise (vsub (vadd (send twig get-point point) offset) p)) (* speed d)))))))
|
|
"p" "twig" "point" "offset" "speed"))))
|
|
|
|
(define/public (above-ground)
|
|
(play-sound 'going-above-ground pos)
|
|
(when dust (send dust set-above-ground #t)))
|
|
|
|
(define/public (below-ground)
|
|
(play-sound 'going-below-ground pos)
|
|
(when dust (send dust set-above-ground #f)))
|
|
|
|
(define/public (update t d)
|
|
(when dust (send dust update t d))
|
|
|
|
(with-primitive seed
|
|
(shader-set! (list "Time" t))
|
|
#;(let ((t (inexact->exact (round (fmod (* 5 t) 3)))))
|
|
(cond
|
|
((eq? t 0) (texture (load-texture "textures/cells-1.png")))
|
|
((eq? t 1) (texture (load-texture "textures/cells-2.png")))
|
|
((eq? t 2) (texture (load-texture "textures/cells-3.png"))))))
|
|
|
|
|
|
(update-nutrients t d)
|
|
#;(with-primitive seed
|
|
(scale (+ 1 (* 0.001 (sin (* 2 t))))))
|
|
(for-each
|
|
(lambda (twig)
|
|
(when (send (cadr twig) delme?)
|
|
(destroy-branch-twig (car twig))))
|
|
twigs)
|
|
|
|
(for-each
|
|
(lambda (twig)
|
|
(send (cadr twig) update t d))
|
|
twigs))
|
|
|
|
(super-new)))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define (build-env-box top bottom left right front back lower)
|
|
(let ((p (build-locator)))
|
|
(with-state
|
|
(parent p)
|
|
(hint-unlit)
|
|
|
|
(list
|
|
(let ((t (with-state
|
|
(texture (load-texture top))
|
|
(translate (vector 0 0.5 0))
|
|
(rotate (vector 90 0 0))
|
|
(build-plane))))
|
|
(when lower (with-primitive t
|
|
(pdata-map!
|
|
(lambda (t)
|
|
(vmul t 10))
|
|
"t"))
|
|
) t)
|
|
|
|
(with-state
|
|
(texture (load-texture left))
|
|
(translate (vector 0 0 -0.5))
|
|
(rotate (vector 0 0 0))
|
|
(build-plane))
|
|
|
|
(with-state
|
|
(texture (load-texture back))
|
|
(translate (vector 0.5 0 0))
|
|
(rotate (vector 0 90 0))
|
|
(build-plane))
|
|
|
|
(with-state
|
|
(texture (load-texture right))
|
|
(translate (vector 0 0 0.5))
|
|
(rotate (vector 0 0 0))
|
|
(build-plane))
|
|
|
|
(with-state
|
|
(texture (load-texture front))
|
|
(translate (vector -0.5 0 0))
|
|
(rotate (vector 0 90 0))
|
|
(build-plane))
|
|
|
|
(if lower
|
|
(with-state
|
|
(texture (load-texture bottom))
|
|
(translate (vector 0 -0.5 0))
|
|
(rotate (vector 90 0 0))
|
|
(build-plane)) 0)))))
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define grow-hud%
|
|
(class object%
|
|
|
|
(field
|
|
(cam #f)
|
|
(hud (build-locator))
|
|
(grow-mode-hud (build-locator)
|
|
#;(let ((p (with-state
|
|
(parent hud)
|
|
(translate (vector 0 0 3))
|
|
(scale (vector 1.3 1 1))
|
|
(hint-depth-sort)
|
|
(hint-nozwrite)
|
|
(texture (load-texture "textures/grow-mode-hud.png"))
|
|
(hint-unlit)
|
|
(build-plane))))
|
|
(with-primitive p (hide 1)) p))
|
|
(grow-mode-hud-state #f)
|
|
(grow-mode-hud-t 2)
|
|
(markers (make-marker-list 10))
|
|
(next-marker 0)
|
|
(text-list '())
|
|
(next-text-t -1)
|
|
(new-text #f))
|
|
|
|
(define/public (make-marker-list n)
|
|
(build-list n
|
|
(lambda (_)
|
|
(let ((p (with-state
|
|
(parent hud)
|
|
;(hint-unlit)
|
|
(colour 0.5)
|
|
(build-sphere 8 8))))
|
|
(with-primitive p (hide 1)) p))))
|
|
|
|
(define/public (set-cam s)
|
|
(set! cam s)
|
|
(with-primitive hud
|
|
(parent cam)))
|
|
|
|
(define/public (set-mode-on num-markers)
|
|
(when (> num-markers (length markers))
|
|
(set! markers (append markers (make-marker-list
|
|
(- num-markers (length markers))))))
|
|
|
|
(set! next-marker 0)
|
|
|
|
(for ((i (in-range 0 num-markers)))
|
|
(with-primitive (list-ref markers i)
|
|
(identity)
|
|
(scale 0.1)
|
|
(colour (marker-colour))
|
|
(hide 0)
|
|
(let ((a (* (/ i num-markers) 360 0.0174532925)))
|
|
(translate (vmul (vector (sin a) (cos a) 0) 15)))))
|
|
|
|
(with-primitive grow-mode-hud (hide 0) (opacity 0))
|
|
(set! grow-mode-hud-state #t)
|
|
(set! grow-mode-hud-t 0))
|
|
|
|
(define/public (set-mode-off)
|
|
(with-primitive grow-mode-hud (hide 0) (opacity 0))
|
|
(set! grow-mode-hud-state #f)
|
|
(set! grow-mode-hud-t 0))
|
|
|
|
(define/public (display text time)
|
|
(set! new-text #t)
|
|
(set! text-list (append text-list (list (list time (let ((t (with-state
|
|
(build-type "meshes/pensharp.ttf" text))))
|
|
(let* ((p (type->poly t))
|
|
(shad (build-copy p)))
|
|
(destroy t)
|
|
(with-primitive p
|
|
(hide 1)
|
|
(parent hud)
|
|
(hint-unlit)
|
|
(colour 1)
|
|
(scale 0.04)
|
|
(translate (vector 0 10 5))
|
|
; subtract the centre point to centre the text
|
|
(let ((c (vdiv (pdata-fold vadd (vector 0 0 0) "p") (pdata-size))))
|
|
(translate (vmul c -1))))
|
|
(with-primitive shad
|
|
(parent p)
|
|
(translate (vector 0 0 -0.01))
|
|
(hint-wire)
|
|
(wire-colour (vector 0 0 0))
|
|
(line-width 5))
|
|
p)))))))
|
|
|
|
(define/public (update-text t d)
|
|
|
|
(when (and new-text (eq? next-text-t -1))
|
|
(set! next-text-t (+ t (car (car text-list)))))
|
|
|
|
(set! new-text #f)
|
|
|
|
(when (not (null? text-list))
|
|
(let ((i (car text-list)))
|
|
(with-primitive (cadr i) (hide 0))
|
|
(when (> t next-text-t)
|
|
(destroy (cadr i))
|
|
(set! text-list (cdr text-list))
|
|
(if (null? text-list)
|
|
(set! next-text-t -1)
|
|
(set! next-text-t (+ t (car (car text-list)))))))))
|
|
|
|
(define/public (scrub-marker)
|
|
(with-primitive (list-ref markers next-marker)
|
|
;(hide 1)
|
|
(scale 0.99))
|
|
(set! next-marker (+ next-marker 1)))
|
|
|
|
(define/pubment (update-markers t d)
|
|
(for-each
|
|
(lambda (marker)
|
|
(with-primitive marker
|
|
(let ((sc (vmag (vtransform-rot (vector 0 1 0) (get-transform)))))
|
|
(when (and (< sc 0.1) (> sc 0))
|
|
(scale (- 1.0 (* d 1)))))))
|
|
markers))
|
|
|
|
(define/public (update t d)
|
|
(update-text t d)
|
|
(update-markers t d)
|
|
(when (< grow-mode-hud-t 1)
|
|
(with-primitive grow-mode-hud
|
|
(opacity (if grow-mode-hud-state
|
|
(* grow-mode-hud-t 0.5)
|
|
(* (- 1 (* grow-mode-hud-t )) 0.5)))))
|
|
|
|
(when (and (> grow-mode-hud-t 1) (not grow-mode-hud-state))
|
|
(with-primitive grow-mode-hud (hide 1)))
|
|
|
|
(set! grow-mode-hud-t (+ grow-mode-hud-t d 0.02)))
|
|
|
|
(super-new)))
|
|
|
|
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(define game-view%
|
|
(class object%
|
|
|
|
(field
|
|
(plants '()) ; map of ids -> plants
|
|
(pickups '()) ; map of ids -> pickups
|
|
(insects '()) ; map of ids -> insects
|
|
(camera-dist 1)
|
|
(env-root (with-state (scale 1000) (build-locator)))
|
|
(root-camera-t 0)
|
|
(num-msgs 0)
|
|
(grow-hud (make-object grow-hud%))
|
|
(floor #f)
|
|
|
|
#;(upper-env (with-state
|
|
(parent env-root)
|
|
(hint-depth-sort)
|
|
(colour 2)
|
|
(translate (vector 0 0.28 0))
|
|
(build-env-box "textures/top.png" "textures/bottom-trans.png"
|
|
"textures/left.png" "textures/right.png"
|
|
"textures/front.png" "textures/back.png")))
|
|
#;(lower-env (with-state
|
|
(parent env-root)
|
|
(hint-depth-sort)
|
|
(translate (vector 0 -0.22001 0))
|
|
(build-env-box "textures/bottom-trans.png" "textures/bottom.png"
|
|
"textures/sleft.png" "textures/sright.png"
|
|
"textures/sfront.png" "textures/sback.png")))
|
|
#;(upper-env (with-state
|
|
(parent env-root)
|
|
;(hint-depth-sort)
|
|
(hint-unlit)
|
|
(translate (vector 0 0.28 0))
|
|
(build-env-box "textures/sky-top.png" "textures/floor.png"
|
|
"textures/sky-side.png" "textures/sky-side.png"
|
|
"textures/sky-side.png" "textures/sky-side.png" #f)))
|
|
#;(lower-env (with-state
|
|
(parent env-root)
|
|
;(hint-depth-sort)
|
|
(hint-unlit)
|
|
(colour (earth-colour))
|
|
(translate (vector 0 -0.22001 0))
|
|
(build-env-box "textures/floor.png" "textures/earth-bottom.png"
|
|
"textures/earth-side.png" "textures/earth-side.png"
|
|
"textures/earth-side.png" "textures/earth-side.png" #t)))
|
|
|
|
(stones '())
|
|
(ground-change-t 0)
|
|
(going-up #f))
|
|
|
|
(define/public (setup world-list)
|
|
(let ((l (make-light 'point 'free)))
|
|
(light-diffuse 0 (vector 0 0 0))
|
|
(light-diffuse l (vector 1 1 1))
|
|
(light-position l (vector 0 500 0)))
|
|
(set! stones
|
|
(map
|
|
(lambda (stone)
|
|
(let ((p (with-state
|
|
(hint-frustum-cull)
|
|
(colour 1)
|
|
(ambient 0.5)
|
|
(translate (list-ref stone 2))
|
|
(scale (list-ref stone 3))
|
|
(rotate (list-ref stone 4))
|
|
(cond
|
|
((eq? (list-ref stone 0) 'stone)
|
|
(colour (stones-colour))
|
|
(ambient (vmul (stones-colour) 0.5))
|
|
(shader "shaders/tree.vert.glsl" "shaders/rocks.frag.glsl")
|
|
(texture (load-texture "textures/root-norm.png")))
|
|
((eq? (list-ref stone 0) 'tree)
|
|
(colour (vector 0.45 0.4 0.3))
|
|
(ambient (vmul (vector 0.45 0.4 0.3) 0.5))
|
|
(shader "shaders/tree.vert.glsl" "shaders/rocks.frag.glsl")
|
|
(texture (load-texture "textures/root-norm.png")))
|
|
((eq? (list-ref stone 0) 'bg)
|
|
(hint-unlit)
|
|
(translate (vector 0 12 0))
|
|
(colour 1)
|
|
(texture (load-texture "textures/bg3.png"))))
|
|
|
|
(load-primitive (list-ref stone 1)))))
|
|
(with-primitive p
|
|
#;(when (eq? (list-ref stone 0) 'stone)
|
|
(pdata-map!
|
|
(lambda (t)
|
|
(vmul t 4))
|
|
"t"))
|
|
(apply-transform)
|
|
(recalc-bb)) ; apply the transform to speed up the ray tracing, don't have to tranform the ray into object space
|
|
p))
|
|
(list-ref world-list 2)))
|
|
#;(set! floor (let ((p (with-state
|
|
(hint-none)
|
|
(hint-unlit)
|
|
(hint-wire)
|
|
(colour 0.5)
|
|
;(opacity 0.2)
|
|
(texture (load-texture "textures/top.png"))
|
|
(hint-vertcols)
|
|
(translate (vector 0 0 0))
|
|
(rotate (vector 90 0 0))
|
|
(scale 500)
|
|
(line-width 2)
|
|
(backfacecull 0)
|
|
(build-seg-plane 80 80))))
|
|
(with-primitive p
|
|
(poly-convert-to-indexed)
|
|
(pdata-map!
|
|
(lambda (t)
|
|
(vmul t 10))
|
|
"t")
|
|
(pdata-map!
|
|
(lambda (c)
|
|
(vmul (vector 1 0.8 0.7) (rndf)))
|
|
"c")
|
|
(pdata-map!
|
|
(lambda (p)
|
|
(vadd p (vmul (grndvec) 0.001)))
|
|
"p")) p))
|
|
(with-state ; cap the top of the world
|
|
(translate (vector 0 300 0))
|
|
(rotate (vector 90 0 0))
|
|
(scale 5000)
|
|
(hint-unlit)
|
|
(colour (sky-colour))
|
|
(build-plane))
|
|
(below-ground))
|
|
|
|
(define/public (set-cam s)
|
|
(send grow-hud set-cam s))
|
|
|
|
(define/public (above-ground)
|
|
#;(with-primitive floor
|
|
(colour (vector 0.4 0.6 0.4))
|
|
(texture (load-texture "textures/top.png")))
|
|
(for-each
|
|
(lambda (plant)
|
|
(send (cadr plant) above-ground))
|
|
plants)
|
|
#;(for-each
|
|
(lambda (pickup)
|
|
(with-primitive (send (cadr pickup) get-root) (hide 1)))
|
|
pickups)
|
|
(set! going-up #t)
|
|
(set! ground-change-t ground-change-duration))
|
|
|
|
(define/public (below-ground)
|
|
#;(with-primitive floor
|
|
(texture (load-texture "textures/top.png"))
|
|
(colour (vector 0.4 0.6 0.4)))
|
|
(for-each
|
|
(lambda (plant)
|
|
(send (cadr plant) below-ground))
|
|
plants)
|
|
#;(for-each
|
|
(lambda (pickup)
|
|
(with-primitive (send (cadr pickup) get-root) (hide 0)))
|
|
pickups)
|
|
(set! going-up #f)
|
|
(set! ground-change-t ground-change-duration))
|
|
|
|
(define/public (update-ground-change t d)
|
|
(when (> ground-change-t 0)
|
|
(set! ground-change-t (- ground-change-t d))
|
|
(let* ((t (max 0 (/ ground-change-t ground-change-duration)))
|
|
(anim-t (if going-up t (- 1 t))))
|
|
|
|
(set-fov 53 0.1 (lerp 1000 1000 anim-t))
|
|
(clear-colour fog-col)
|
|
;(clear-colour (vmix fog-col above-fog-col anim-t))
|
|
;(fog (vmix fog-col above-fog-col anim-t) (lerp fog-strength above-fog-strength anim-t) 1 100)
|
|
)
|
|
)
|
|
)
|
|
|
|
(define/public (get-stones)
|
|
stones)
|
|
|
|
(define/public (add-plant plant)
|
|
;(destroy-plant (send plant get-id)) ; just in case
|
|
(set! plants (cons (list (send plant get-id) plant) plants)))
|
|
|
|
(define/public (get-plant plant-id)
|
|
(let ((p (assoc plant-id plants)))
|
|
(if (not p) #f (cadr p))))
|
|
|
|
(define/public (destroy-plant plant-id)
|
|
(let ((p (get-plant plant-id)))
|
|
(when p (send p destroy-plant)
|
|
(set! plants (assoc-remove plant-id plants)))))
|
|
|
|
(define/public (destroy-branch-twig plant-id twig-id)
|
|
(send (get-plant plant-id) destroy-branch-twig twig-id))
|
|
|
|
(define/public (add-twig plant-id parent-twig-id point-index twig)
|
|
(when (get-plant plant-id)
|
|
(send (get-plant plant-id) add-twig parent-twig-id point-index twig)))
|
|
|
|
(define/public (grow-seed plant-id amount)
|
|
(when (get-plant plant-id)
|
|
(send (get-plant plant-id) grow-seed amount)))
|
|
|
|
(define/public (get-pickup pickup-id)
|
|
(let ((p (assq pickup-id pickups)))
|
|
(if p (cadr p) #f)))
|
|
|
|
(define/public (add-pickup pickup-id type pos)
|
|
(set! pickups (cons (list pickup-id (make-object pickup-view% pickup-id type pos)) pickups)))
|
|
|
|
(define/public (add-insect insect-id pos type)
|
|
(cond
|
|
((eq? type 'worm)
|
|
(set! insects (cons (list insect-id
|
|
(make-object worm-insect-view% insect-id pos type)) insects)))
|
|
((eq? type 'spider)
|
|
(set! insects (cons (list insect-id
|
|
(make-object spider-insect-view% insect-id pos type)) insects)))
|
|
((eq? type 'butterfly)
|
|
(set! insects (cons (list insect-id
|
|
(make-object butterfly-insect-view% insect-id pos type)) insects)))))
|
|
|
|
(define/public (get-insect insect-id)
|
|
(cadr (assq insect-id insects)))
|
|
|
|
(define/public (pick-up-pickup pickup-id point)
|
|
(let ((pu (get-pickup pickup-id)))
|
|
(when pu
|
|
(send (get-pickup pickup-id) pick-up point))))
|
|
|
|
(define/public (highlight-pickup plant-id pickup-id)
|
|
(let ((pu (get-pickup pickup-id)))
|
|
(when pu
|
|
(let* ((p (get-pickup pickup-id))
|
|
(type (send p get-type)))
|
|
(send p highlight)
|
|
(when (send (get-plant plant-id) is-player?)
|
|
(display
|
|
(cond
|
|
((eq? type 'nutrient) "found a nutrient")
|
|
((eq? type 'leaf) "found a nutrient from the leaf plant")
|
|
((eq? type 'horn) "found a nutrient from the horn plant")
|
|
((eq? type 'inflatoe) "found an inflatoe growing ability")
|
|
((eq? type 'fork) "found a nutrient from the canopy plant")
|
|
((eq? type 'flower) "found a nutrient from the flower plant")) 4))))))
|
|
|
|
(define/public (add-ornament plant-id twig-id point-index property)
|
|
(when (get-plant plant-id)
|
|
(send (get-plant plant-id) add-ornament twig-id point-index property)))
|
|
|
|
(define/public (shrink-twig plant-id twig-id)
|
|
(when (get-plant plant-id)
|
|
(send (get-plant plant-id) shrink-twig twig-id)))
|
|
|
|
(define/public (set-excitations! a b)
|
|
(for-each
|
|
(lambda (plant)
|
|
(send (cadr plant) set-excitations! a b))
|
|
plants))
|
|
|
|
(define/public (set-grow-mode-on num)
|
|
(send grow-hud set-mode-on num))
|
|
|
|
(define/public (set-grow-mode-off)
|
|
(send grow-hud set-mode-off))
|
|
|
|
(define/public (scrub-marker)
|
|
(send grow-hud scrub-marker))
|
|
|
|
(define/public (display text time)
|
|
(send grow-hud display text time))
|
|
|
|
(define/public (update t d messages)
|
|
|
|
(update-ground-change t d)
|
|
(send grow-hud update t d)
|
|
|
|
(for-each
|
|
(lambda (plant)
|
|
(send (cadr plant) update t d))
|
|
plants)
|
|
|
|
(for-each
|
|
(lambda (pickup)
|
|
(send (cadr pickup) update t d))
|
|
pickups)
|
|
|
|
(for-each
|
|
(lambda (insect)
|
|
(send (cadr insect) update t d))
|
|
insects)
|
|
|
|
(when debug-messages
|
|
(for-each
|
|
(lambda (msg)
|
|
(send msg print))
|
|
messages))
|
|
|
|
;(when (> (length messages) 0) (printf "~a~n" (length messages)))
|
|
|
|
(set! pickups (filter
|
|
(lambda (pickup)
|
|
(not (send (cadr pickup) delme?)))
|
|
pickups))
|
|
|
|
(for-each
|
|
(lambda (msg)
|
|
(cond
|
|
((eq? (send msg get-name) 'player-plant)
|
|
(printf "adding player plant to view ~a~n" (send msg get-data 'plant-id))
|
|
(add-plant (make-object plant-view%
|
|
(send msg get-data 'plant-id)
|
|
(send msg get-data 'pos)
|
|
(send msg get-data 'size)
|
|
(send msg get-data 'col)
|
|
(send msg get-data 'tex)
|
|
#t
|
|
(list (send msg get-data 'curve)
|
|
(send msg get-data 'corner)))))
|
|
|
|
((eq? (send msg get-name) 'new-plant)
|
|
(printf "adding new plant to view ~a~n" (send msg get-data 'plant-id))
|
|
(add-plant (make-object plant-view%
|
|
(send msg get-data 'plant-id)
|
|
(send msg get-data 'pos)
|
|
(send msg get-data 'size)
|
|
(send msg get-data 'col)
|
|
(send msg get-data 'tex)
|
|
#f
|
|
(list (send msg get-data 'curve)
|
|
(send msg get-data 'corner)))))
|
|
|
|
|
|
((eq? (send msg get-name) 'grow-seed)
|
|
(grow-seed (send msg get-data 'plant-id)
|
|
(send msg get-data 'amount)))
|
|
|
|
((eq? (send msg get-name) 'destroy-branch-twig)
|
|
(destroy-branch-twig (send msg get-data 'plant-id) (send msg get-data 'twig-id)))
|
|
|
|
((eq? (send msg get-name) 'new-twig)
|
|
(add-twig (send msg get-data 'plant-id)
|
|
(send msg get-data 'parent-twig-id)
|
|
(send msg get-data 'point-index)
|
|
(cond
|
|
((eq? (send msg get-data 'render-type) 'ribbon)
|
|
(make-object ribbon-twig-view%
|
|
(send msg get-data 'twig-id)
|
|
(vector 0 0 0) ; will be filled in by add-twig
|
|
(send msg get-data 'type)
|
|
(send msg get-data 'dir)
|
|
(send msg get-data 'width)
|
|
(send msg get-data 'num-points)))
|
|
|
|
((eq? (send msg get-data 'render-type) 'extruded)
|
|
(make-object extruded-twig-view%
|
|
(send msg get-data 'twig-id)
|
|
(vector 0 0 0) ; will be filled in by add-twig
|
|
(send msg get-data 'type)
|
|
(send msg get-data 'dir)
|
|
(send msg get-data 'width)
|
|
(send msg get-data 'num-points))))))
|
|
|
|
((eq? (send msg get-name) 'add-twig-point)
|
|
(when (get-plant (send msg get-data 'plant-id))
|
|
(send (get-plant (send msg get-data 'plant-id)) add-twig-point
|
|
(send msg get-data 'twig-id)
|
|
(send msg get-data 'point)
|
|
(send msg get-data 'width))))
|
|
|
|
((eq? (send msg get-name) 'start-growing)
|
|
(when (get-plant (send msg get-data 'plant-id))
|
|
(send (get-plant (send msg get-data 'plant-id)) start-twig-growing
|
|
(send msg get-data 'twig-id))))
|
|
|
|
((eq? (send msg get-name) 'new-pickup)
|
|
(add-pickup
|
|
(send msg get-data 'pickup-id)
|
|
(send msg get-data 'type)
|
|
(send msg get-data 'pos)))
|
|
|
|
((eq? (send msg get-name) 'pick-up-pickup)
|
|
(pick-up-pickup
|
|
(send msg get-data 'pickup-id)
|
|
(send msg get-data 'point)))
|
|
|
|
((eq? (send msg get-name) 'pick-up-highlight)
|
|
(highlight-pickup
|
|
(send msg get-data 'plant-id)
|
|
(send msg get-data 'pickup-id)))
|
|
|
|
((eq? (send msg get-name) 'shrink-twig)
|
|
(shrink-twig
|
|
(send msg get-data 'plant-id)
|
|
(send msg get-data 'twig-id)))
|
|
|
|
((eq? (send msg get-name) 'new-ornament)
|
|
(add-ornament
|
|
(send msg get-data 'plant-id)
|
|
(send msg get-data 'twig-id)
|
|
(send msg get-data 'point-index)
|
|
(send msg get-data 'property)))
|
|
|
|
((eq? (send msg get-name) 'vrob)
|
|
(set! num-msgs (+ num-msgs 1))
|
|
(printf "num light-level msgs: ~a~n" num-msgs)
|
|
(set-excitations!
|
|
(send msg get-data 'light-level)
|
|
(send msg get-data 'soil-moisture))
|
|
#;(for-each
|
|
(lambda (p)
|
|
(with-primitive p
|
|
(colour (send msg get-data 'amount))))
|
|
upper-env))
|
|
|
|
((eq? (send msg get-name) 'new-insect)
|
|
(add-insect
|
|
(send msg get-data 'insect-id)
|
|
(send msg get-data 'pos)
|
|
(send msg get-data 'type)))
|
|
|
|
((eq? (send msg get-name) 'insect-move)
|
|
(send (get-insect (send msg get-data 'insect-id)) move
|
|
(send msg get-data 'pos)
|
|
(send msg get-data 'duration)))
|
|
|
|
))
|
|
messages))
|
|
|
|
|
|
|
|
|
|
(super-new)))
|