History

more work on particle emitter API

Jeffrey Ventrella committed 13 years ago

Commit 84b6adf1 parent 3bc6b4c4 files · +172 −109Browse files

Showing the changes to interface/src/ParticleSystem.cpp (1 of 4 files). Show all

Unified · Split

interface/src/ParticleSystem.cpp+79−77
@@ -13,33 +13,34 @@ · 12 unmodified lines
13 13
14const float DEFAULT_PARTICLE_BOUNCE = 1.0f;14const float DEFAULT_PARTICLE_BOUNCE = 1.0f;
15const float DEFAULT_PARTICLE_AIR_FRICTION = 2.0f;15const float DEFAULT_PARTICLE_AIR_FRICTION = 2.0f;
16const float DEFAULT_PARTICLE_JITTER = 0.05f;
17const float DEFAULT_PARTICLE_GRAVITY = 0.05f;16const float DEFAULT_PARTICLE_GRAVITY = 0.05f;
18 17
19ParticleSystem::ParticleSystem() {18ParticleSystem::ParticleSystem() {
20 19
21 _timer = 0.0f;20 _timer = 0.0f;
22 _numEmitters = 0;21 _numEmitters = 0;
23 _gravity = DEFAULT_PARTICLE_GRAVITY;22 _numParticles = 0;
24 _bounce = DEFAULT_PARTICLE_BOUNCE;23 _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default
25 _airFriction = DEFAULT_PARTICLE_AIR_FRICTION;24
26 _jitter = DEFAULT_PARTICLE_JITTER;
27 _emitterAttraction = 0.0f;
28 _tornadoForce = 0.0f;
29 _neighborAttraction = 0.0f;
30 _neighborRepulsion = 0.0f;
31 _collisionSphereRadius = 0.0f;
32 _collisionSpherePosition = glm::vec3(0.0f, 0.0f, 0.0f);
33 _numParticles = 0;
34 _usingCollisionSphere = false;
35 _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default
36
37 for (unsigned int e = 0; e < MAX_EMITTERS; e++) {25 for (unsigned int e = 0; e < MAX_EMITTERS; e++) {
38 _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f);26 _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f);
39 _emitter[e].rotation = glm::quat();27 _emitter[e].rotation = glm::quat();
40 _emitter[e].right = IDENTITY_RIGHT;28 _emitter[e].right = IDENTITY_RIGHT;
41 _emitter[e].up = IDENTITY_UP;29 _emitter[e].up = IDENTITY_UP;
42 _emitter[e].front = IDENTITY_FRONT;30 _emitter[e].front = IDENTITY_FRONT;
31 _emitter[e].bounce = DEFAULT_PARTICLE_BOUNCE;
32 _emitter[e].airFriction = DEFAULT_PARTICLE_AIR_FRICTION;
33 _emitter[e].gravity = DEFAULT_PARTICLE_GRAVITY;
34 _emitter[e].jitter = 0.0f;
35 _emitter[e].emitterAttraction = 0.0f;
36 _emitter[e].tornadoForce = 0.0f;
37 _emitter[e].neighborAttraction = 0.0f;
38 _emitter[e].neighborRepulsion = 0.0f;
39 _emitter[e].collisionSphereRadius = 0.0f;
40 _emitter[e].collisionSpherePosition = glm::vec3(0.0f, 0.0f, 0.0f);
41 _emitter[e].usingCollisionSphere = false;
42 _emitter[e].showingEmitter = false;
43
43 }; 44 };
44 45
45 for (unsigned int p = 0; p < MAX_PARTICLES; p++) {46 for (unsigned int p = 0; p < MAX_PARTICLES; p++) {
@@ -69,9 +70,11 @@ void ParticleSystem::simulate(float deltaTime) { · 23 unmodified lines
69 70
70 // update emitters71 // update emitters
71 for (unsigned int e = 0; e < _numEmitters; e++) {72 for (unsigned int e = 0; e < _numEmitters; e++) {
72 updateEmitter(e, deltaTime);73 updateEmitter(e, deltaTime);
73 }74 }
74 75
76 runSpecialEffectsTest(0, deltaTime);
77
75 // update particles78 // update particles
76 for (unsigned int p = 0; p < _numParticles; p++) {79 for (unsigned int p = 0; p < _numParticles; p++) {
77 if (_particle[p].alive) {80 if (_particle[p].alive) {
@@ -91,22 +94,23 @@ void ParticleSystem::updateEmitter(int e, float deltaTime) { · 13 unmodified lines
91void ParticleSystem::emitParticlesNow(int e, int num, float radius, glm::vec4 color, glm::vec3 velocity, float lifespan) {94void ParticleSystem::emitParticlesNow(int e, int num, float radius, glm::vec4 color, glm::vec3 velocity, float lifespan) {
92 95
93 for (unsigned int p = 0; p < num; p++) {96 for (unsigned int p = 0; p < num; p++) {
94 createParticle(_emitter[e].position, velocity, radius, color, lifespan);97 createParticle(e, _emitter[e].position, velocity, radius, color, lifespan);
95 }98 }
96}99}
97 100
98void ParticleSystem::createParticle(glm::vec3 position, glm::vec3 velocity, float radius, glm::vec4 color, float lifespan) {101void ParticleSystem::createParticle(int e, glm::vec3 position, glm::vec3 velocity, float radius, glm::vec4 color, float lifespan) {
99 102
100 for (unsigned int p = 0; p < MAX_PARTICLES; p++) {103 for (unsigned int p = 0; p < MAX_PARTICLES; p++) {
101 if (!_particle[p].alive) {104 if (!_particle[p].alive) {
102 105
103 _particle[p].lifespan = lifespan;106 _particle[p].emitterIndex = e;
104 _particle[p].alive = true;107 _particle[p].lifespan = lifespan;
105 _particle[p].age = 0.0f;108 _particle[p].alive = true;
106 _particle[p].position = position;109 _particle[p].age = 0.0f;
107 _particle[p].velocity = velocity;110 _particle[p].position = position;
108 _particle[p].radius = radius;111 _particle[p].velocity = velocity;
109 _particle[p].color = color;112 _particle[p].radius = radius;
113 _particle[p].color = color;
110 114
111 _numParticles ++; 115 _numParticles ++;
112 116
@@ -145,29 +149,20 @@ void ParticleSystem::setOrangeBlueColorPalette() { · 32 unmodified lines
145}149}
146 150
147 151
148void ParticleSystem::runSpecialEffectsTest(float deltaTime) {152void ParticleSystem::runSpecialEffectsTest(int e, float deltaTime) {
149 153
150 _timer += deltaTime;154 _timer += deltaTime;
151 155
152 glm::vec3 tilt = glm::vec3156 _emitter[e].gravity = 0.0f + DEFAULT_PARTICLE_GRAVITY * sinf( _timer * 0.52f );
153 (157 _emitter[e].airFriction = (DEFAULT_PARTICLE_AIR_FRICTION + 0.5f) + 2.0f * sinf( _timer * 0.32f );
154 30.0f * sinf( _timer * 0.55f ),158 _emitter[e].jitter = 0.05f + 0.05f * sinf( _timer * 0.42f );
155 0.0f,159 _emitter[e].emitterAttraction = 0.015f + 0.015f * cosf( _timer * 0.6f );
156 30.0f * cosf( _timer * 0.75f )160 _emitter[e].tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f );
157 );161 _emitter[e].neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f );
158 162 _emitter[e].neighborRepulsion = 0.2f + 0.2f * sinf( _timer * 0.4f );
159 _emitter[0].rotation = glm::quat(glm::radians(tilt));163
160 164 if (_emitter[e].gravity < 0.0f) {
161 _gravity = 0.0f + DEFAULT_PARTICLE_GRAVITY * sinf( _timer * 0.52f );165 _emitter[e].gravity = 0.0f;
162 _airFriction = (DEFAULT_PARTICLE_AIR_FRICTION + 0.5f) + 2.0f * sinf( _timer * 0.32f );
163 _jitter = DEFAULT_PARTICLE_JITTER + DEFAULT_PARTICLE_JITTER * sinf( _timer * 0.42f );
164 _emitterAttraction = 0.015f + 0.015f * cosf( _timer * 0.6f );
165 _tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f );
166 _neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f );
167 _neighborRepulsion = 0.2f + 0.2f * sinf( _timer * 0.4f );
168
169 if (_gravity < 0.0f) {
170 _gravity = 0.0f;
171 }166 }
172}167}
173 168
@@ -179,40 +174,45 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 5 unmodified lines
179 if (_particle[p].age > _particle[p].lifespan) {174 if (_particle[p].age > _particle[p].lifespan) {
180 killParticle(p);175 killParticle(p);
181 }176 }
177
178 Emitter myEmitter = _emitter[_particle[p].emitterIndex];
182 179
183 // apply random jitter180 // apply random jitter
184 _particle[p].velocity += 181 _particle[p].velocity +=
185 glm::vec3182 glm::vec3
186 (183 (
187 -_jitter * ONE_HALF + _jitter * randFloat(), 184 -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat(),
188 -_jitter * ONE_HALF + _jitter * randFloat(), 185 -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat(),
189 -_jitter * ONE_HALF + _jitter * randFloat()186 -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat()
190 ) * deltaTime;187 ) * deltaTime;
191 188
192 // apply attraction to home position189 // apply attraction to home position
193 glm::vec3 vectorToHome = _emitter[_particle[p].emitterIndex].position - _particle[p].position;190 glm::vec3 vectorToHome = myEmitter.position - _particle[p].position;
194 _particle[p].velocity += vectorToHome * _emitterAttraction * deltaTime;191 _particle[p].velocity += vectorToHome * myEmitter.emitterAttraction * deltaTime;
195 192
196 // apply neighbor attraction193 // apply neighbor attraction
197 int neighbor = p + 1;194 int neighbor = p + 1;
198 if (neighbor == _numParticles ) {195 if (neighbor == _numParticles ) {
199 neighbor = 0;196 neighbor = 0;
200 }197 }
201 glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position;
202 198
203 _particle[p].velocity -= vectorToNeighbor * _neighborAttraction * deltaTime;199 if ( _particle[neighbor].emitterIndex == _particle[p].emitterIndex) {
200 glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position;
201
202 _particle[p].velocity -= vectorToNeighbor * myEmitter.neighborAttraction * deltaTime;
204 203
205 float distanceToNeighbor = glm::length(vectorToNeighbor);204 float distanceToNeighbor = glm::length(vectorToNeighbor);
206 if (distanceToNeighbor > 0.0f) {205 if (distanceToNeighbor > 0.0f) {
207 _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * _neighborRepulsion * deltaTime;206 _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * myEmitter.neighborRepulsion * deltaTime;
207 }
208 }208 }
209 209
210 // apply tornado force210 // apply tornado force
211 glm::vec3 tornadoDirection = glm::cross(vectorToHome, _emitter[_particle[p].emitterIndex].up);211 glm::vec3 tornadoDirection = glm::cross(vectorToHome, myEmitter.up);
212 _particle[p].velocity += tornadoDirection * _tornadoForce * deltaTime;212 _particle[p].velocity += tornadoDirection * myEmitter.tornadoForce * deltaTime;
213 213
214 // apply air friction214 // apply air friction
215 float drag = 1.0 - _airFriction * deltaTime;215 float drag = 1.0 - myEmitter.airFriction * deltaTime;
216 if (drag < 0.0f) {216 if (drag < 0.0f) {
217 _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f);217 _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
218 } else {218 } else {
@@ -220,7 +220,7 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 1 unmodified line
220 }220 }
221 221
222 // apply gravity222 // apply gravity
223 _particle[p].velocity -= _upDirection * _gravity * deltaTime; 223 _particle[p].velocity -= _upDirection * myEmitter.gravity * deltaTime;
224 224
225 // update position by velocity225 // update position by velocity
226 _particle[p].position += _particle[p].velocity;226 _particle[p].position += _particle[p].velocity;
@@ -230,36 +230,38 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 3 unmodified lines
230 _particle[p].position.y = _particle[p].radius;230 _particle[p].position.y = _particle[p].radius;
231 231
232 if (_particle[p].velocity.y < 0.0f) {232 if (_particle[p].velocity.y < 0.0f) {
233 _particle[p].velocity.y *= -_bounce;233 _particle[p].velocity.y *= -myEmitter.bounce;
234 }234 }
235 }235 }
236 236
237 // collision with sphere237 // collision with sphere
238 if (_usingCollisionSphere) {238 if (myEmitter.usingCollisionSphere) {
239 glm::vec3 vectorToSphereCenter = _collisionSpherePosition - _particle[p].position;239 glm::vec3 vectorToSphereCenter = myEmitter.collisionSpherePosition - _particle[p].position;
240 float distanceToSphereCenter = glm::length(vectorToSphereCenter);240 float distanceToSphereCenter = glm::length(vectorToSphereCenter);
241 float combinedRadius = _collisionSphereRadius + _particle[p].radius;241 float combinedRadius = myEmitter.collisionSphereRadius + _particle[p].radius;
242 if (distanceToSphereCenter < combinedRadius) {242 if (distanceToSphereCenter < combinedRadius) {
243 243
244 if (distanceToSphereCenter > 0.0f){244 if (distanceToSphereCenter > 0.0f){
245 glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter;245 glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter;
246 _particle[p].position = _collisionSpherePosition - directionToSphereCenter * combinedRadius; 246 _particle[p].position = myEmitter.collisionSpherePosition - directionToSphereCenter * combinedRadius;
247 }247 }
248 }248 }
249 }249 }
250}250}
251 251
252void ParticleSystem::setCollisionSphere(glm::vec3 position, float radius) {252void ParticleSystem::setCollisionSphere(int e, glm::vec3 position, float radius) {
253 _usingCollisionSphere = true;253 _emitter[e].usingCollisionSphere = true;
254 _collisionSpherePosition = position; 254 _emitter[e].collisionSpherePosition = position;
255 _collisionSphereRadius = radius;255 _emitter[e].collisionSphereRadius = radius;
256}256}
257 257
258void ParticleSystem::render() {258void ParticleSystem::render() {
259 259
260 // render the emitters260 // render the emitters
261 for (unsigned int e = 0; e < _numEmitters; e++) {261 for (unsigned int e = 0; e < _numEmitters; e++) {
262 renderEmitter(e, 0.2f);262 if (_emitter[e].showingEmitter) {
263 renderEmitter(e, 0.2f);
264 }
263 }; 265 };
264 266
265 // render the particles267 // render the particles