1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
#X3D V3.2 utf8
PROFILE Interchange
DEF ParticleScript Script {
inputOutput MFVec3f coords []
inputOutput MFColor colors []
initializeOnly MFVec3f speeds []
initializeOnly MFVec3f last_coord_change []
inputOutput MFInt32 line_coordIndex []
inputOutput MFInt32 line_colorIndex []
inputOutput MFVec3f line_coords []
inputOutput MFColor line_colors []
initializeOnly SFTime previousTime -1
initializeOnly SFTime timeDiff 0
inputOnly SFTime time
# number of particles
initializeOnly SFInt32 count 1000
# randomization params
initializeOnly SFFloat speed_horiz_const 1.25
initializeOnly SFFloat speed_horiz_rand 0.5
initializeOnly SFFloat speed_vert_const 12.5
initializeOnly SFFloat speed_vert_rand 5
# helper vars
initializeOnly SFInt32 i 0
initializeOnly SFVec3f v 0 0 0
# This is only used internally to call update_lines function.
# Value passed here doesn't matter.
inputOutput SFBool update_lines FALSE
url "castlescript:
function initialize(timestamp)
{ Initialize starting coords position. }
array_set_count(coords, count);
for (i, 0, count - 1,
array_set(coords, i, vector(
sin(i * 2 * Pi / count) * 2.0,
cos(i * 2 * Pi / count) * 2.0,
0)));
{ Starting speeds. }
array_set_count(speeds, count);
for (i, 0, count - 1,
array_set(speeds, i,
{ Speed slightly outside of the circle and much up. }
vector(
vector_get(array_get(coords, i), 0) * (speed_horiz_const + speed_horiz_rand * random()),
vector_get(array_get(coords, i), 1) * (speed_horiz_const + speed_horiz_rand * random()),
speed_vert_const + random() * speed_vert_rand)));
{ Initialize colors. }
array_set_count(colors, count);
for (i, 0, count - 1,
array_set(colors, i,
{ random blueish color }
vector(random() * 0.2, random() * 0.2, 1 - random() * 0.2)));
{ Initialize last_coord_change. }
array_set_count(last_coord_change, count);
for (i, 0, count - 1,
array_set(last_coord_change, i, vector(0, 0, 0)));
update_lines := TRUE
function time(value, timestamp)
{ calculate timeDiff, to scale animations
(so that it runs with the same speed on every system) }
timeDiff := if (previousTime >= 0, value - previousTime, 0);
{ update previousTime }
previousTime := value;
{ update positions }
for (i, 0, count - 1,
v := array_get(coords, i);
{ increase positions by speed }
v := v + array_get(speeds, i) * timeDiff;
{ fall down by gravity }
vector_set(v, 2, vector_get(v, 2) - timeDiff * 5);
array_set(last_coord_change, i,
array_get(speeds, i) + vector(0, 0, -5));
{ when particle falls down on the ground --- initialize new }
when (vector_get(v, 2) < 0,
v := vector(
sin(i * 2 * Pi / count) * 2.0,
cos(i * 2 * Pi / count) * 2.0,
0);
array_set(speeds, i,
vector(
vector_get(v, 0) * (speed_horiz_const + speed_horiz_rand * random()),
vector_get(v, 1) * (speed_horiz_const + speed_horiz_rand * random()),
speed_vert_const + random() * speed_vert_rand));
array_set(last_coord_change, i, vector(0, 0, 0))
);
array_set(coords, i, v));
{ decrease speeds by time }
for (i, 0, count - 1,
v := array_get(speeds, i);
v := v * power(0.5, timeDiff);
array_set(speeds, i, v));
update_lines := TRUE
{ initialize LineSet properties, based on coords, speeds, colors }
function update_lines(value, timestamp)
array_set_count(line_coords, count * 2);
array_set_count(line_colors, count * 2);
array_set_count(line_coordIndex, count * 3);
array_set_count(line_colorIndex, count * 3);
for (i, 0, count - 1,
v := array_get(coords, i);
array_set(line_coords, 2 * i , v - array_get(last_coord_change, i) / 10);
array_set(line_coords, 2 * i + 1, v + array_get(last_coord_change, i) / 10);
array_set(line_colors, 2 * i , array_get(colors, i));
array_set(line_colors, 2 * i + 1, array_get(colors, i));
array_set(line_colorIndex, 3 * i , 2 * i);
array_set(line_colorIndex, 3 * i + 1, 2 * i + 1);
array_set(line_colorIndex, 3 * i + 2, -1);
array_set(line_coordIndex, 3 * i , 2 * i);
array_set(line_coordIndex, 3 * i + 1, 2 * i + 1);
array_set(line_coordIndex, 3 * i + 2, -1))
"
}
Collision {
enabled FALSE
children Shape {
geometry DEF LnSet IndexedLineSet {
color DEF LnColor Color { }
coord DEF LnCoord Coordinate { }
}
}
}
ROUTE ParticleScript.line_colors TO LnColor.color
ROUTE ParticleScript.line_coords TO LnCoord.point
ROUTE ParticleScript.line_colorIndex TO LnSet.set_colorIndex
ROUTE ParticleScript.line_coordIndex TO LnSet.set_coordIndex
Collision {
enabled FALSE
children Shape {
geometry PointSet {
color DEF PtColor Color { }
coord DEF PtCoord Coordinate { }
}
}
}
ROUTE ParticleScript.colors TO PtColor.color
ROUTE ParticleScript.coords TO PtCoord.point
DEF Time TimeSensor { loop TRUE }
ROUTE Time.time TO ParticleScript.time
Shape {
appearance Appearance { material Material { } }
geometry Box { }
}
# Camera settings "encoded" in the VRML declaration below :
# direction -0.0198693256825208 -4.1451200805120436E-010 -0.0022825174964964
# up -0.1141257956624031 -3.7782339745717763E-007 0.9934662580490112
# gravityUp 0 -4.3711388286737929E-008 1
Transform {
translation 21.568759918212891 5.8969815697196282E-009 4.7044863700866699
rotation 1 0 -0 1.5707963705062866
children Viewpoint {
position 0 0 0 # camera position is expressed by translation
orientation -0.057063028216362 0.9967384338378906 0.0570633709430694 1.5740633010864258
}
}
NavigationInfo {
type "FLY"
}
|