]> gitweb.factorcode.org Git - factor.git/blob - extra/fluids/fluids.factor
specialized-arrays: performed some cleanup.
[factor.git] / extra / fluids / fluids.factor
1 ! Copyright (C) 2010 Erik Charlebois.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays classes.struct destructors game.loop
4 game.worlds gpu gpu.buffers gpu.effects.blur gpu.framebuffers
5 gpu.render gpu.shaders gpu.state gpu.textures gpu.util images
6 images.loader kernel literals locals make math math.rectangles
7 math.vectors namespaces opengl.gl sequences specialized-arrays
8 ui.gadgets.worlds ui.gestures ui.pixel-formats gpu.effects.step
9 images.pgm images.ppm alien.data ;
10 FROM: alien.c-types => float ;
11 SPECIALIZED-ARRAY: float
12 IN: fluids
13
14 STRUCT: particle_t
15     { p float[2] }
16     { v float[2] }
17     { m float    } ;
18 SPECIALIZED-ARRAY: particle_t
19
20 CONSTANT: gravity { 0.0 -0.1 }
21
22 :: verlet-integrate-particle ( particle dt -- particle' )
23     particle [ p>> ] [ v>> ] bi dt v*n v+
24     gravity dt dt * particle m>> 2 * / v*n v+ :> p'
25     p' particle p>> v- dt v/n :> v'
26     p' v' particle m>> particle_t <struct-boa> ; inline
27
28 CONSTANT: initial-particles
29 particle_t-array{
30     S{ particle_t f float-array{ 0.5 0.6 } float-array{ 0 0.1 } 1.0 }
31     S{ particle_t f float-array{ 0.5 0.6 } float-array{ 0.1 0 } 3.0 }
32     
33     S{ particle_t f float-array{ 0.5 0.5 } float-array{ 0.1 0.1 } 2.0 }
34     S{ particle_t f float-array{ 0.5 0.6 } float-array{ -0.1 0 } 1.0 }
35     S{ particle_t f float-array{ 0.6 0.5 } float-array{ 0 -0.1 } 3.0 }
36     S{ particle_t f float-array{ 0.7 0.5 } float-array{ 0.1 0.1 } 1.0 }
37     S{ particle_t f float-array{ 0.1 0.5 } float-array{ -0.1 -0.1 } 5.0 }
38     S{ particle_t f float-array{ 0.2 0.5 } float-array{ 0 0 } 1.0 }
39     S{ particle_t f float-array{ 0.3 0.3 } float-array{ 0 0 } 4.0 }
40     S{ particle_t f float-array{ 0.5 0.15 } float-array{ 0 0 } 1.0 }
41     S{ particle_t f float-array{ 0.5 0.1 } float-array{ 0 0 } 9.0 }
42 }
43
44 : integrate-particles! ( particles dt -- particles )
45     [ verlet-integrate-particle ] curry map! ;
46
47 TUPLE: fluids-world < game-world
48     particles texture ramp { paused boolean initial: f } ;
49
50 : make-texture ( pathname -- texture )
51     load-image
52     [
53         [ component-order>> ]
54         [ component-type>> ] bi
55         T{ texture-parameters
56            { wrap clamp-texcoord-to-edge }
57            { min-filter filter-nearest }
58            { mag-filter filter-nearest }
59            { min-mipmap-filter f } }
60         <texture-2d>
61     ]
62     [
63         0 swap [ allocate-texture-image ] 3keep 2drop
64     ] bi ;
65
66 SYMBOL: fluid
67
68 : integrate ( world -- )
69     particles>> 1/60 integrate-particles! drop ;
70
71 : pause ( -- )
72     fluid get [ not ] change-paused drop ;
73
74 : step ( -- )
75     fluid get paused>> [ fluid get integrate ] when ;
76
77 M: fluids-world begin-game-world
78     dup fluid set
79     init-gpu
80     initial-particles clone >>particles
81     "vocab:fluids/particle2.pgm" make-texture >>texture
82     "vocab:fluids/colors.ppm" make-texture >>ramp
83     drop ;
84
85 M: fluids-world end-game-world
86     drop ;
87
88 M: fluids-world tick-game-world
89     dup paused>> [ drop ] [ integrate ] if ;
90
91 M:: fluids-world draw-world* ( world -- )
92     world particles>> [
93         [ p>> [ first , ] [ second , ] bi ] each
94     ] curry float-array{ } make :> verts
95     
96     [ 
97         verts world texture>> 30.0 world dim>> { 4 4 } v/
98         blended-point-sprite-batch &dispose
99         blend-state new set-gpu-state
100         gaussian-blur &dispose
101         world ramp>> world dim>> step-texture &dispose
102         world dim>> draw-texture
103     ] with-destructors ;
104
105 GAME: fluids {
106     { world-class fluids-world }
107     { title "Fluids Test" }
108     { pixel-format-attributes {
109         windowed double-buffered T{ depth-bits { value 24 } } } }
110     { pref-dim { 1024 768 } }
111     { tick-interval-nanos $[ 60 fps ] }
112 } ;
113
114 fluids-world H{
115     { T{ button-down } [ [
116         hand-loc get float >c-array
117         world get dim>> float >c-array v/ 2 v*n 1 v-n { 1 -1 } v*
118         float-array{ 0 0.2 } 2.0 particle_t <struct-boa> suffix
119     ] change-particles drop ] }
120 } set-gestures