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
1313
1414 const float DEFAULT_PARTICLE_BOUNCE = 1.0f;
1515 const float DEFAULT_PARTICLE_AIR_FRICTION = 2.0f;
16−const float DEFAULT_PARTICLE_JITTER = 0.05f;
1716 const float DEFAULT_PARTICLE_GRAVITY = 0.05f;
1817
1918 ParticleSystem::ParticleSystem() {
2019
21− _timer = 0.0f;
22− _numEmitters = 0;
23− _gravity = DEFAULT_PARTICLE_GRAVITY;
24− _bounce = DEFAULT_PARTICLE_BOUNCE;
25− _airFriction = DEFAULT_PARTICLE_AIR_FRICTION;
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−
20+ _timer = 0.0f;
21+ _numEmitters = 0;
22+ _numParticles = 0;
23+ _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default
24+
3725 for (unsigned int e = 0; e < MAX_EMITTERS; e++) {
38− _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f);
39− _emitter[e].rotation = glm::quat();
40− _emitter[e].right = IDENTITY_RIGHT;
41− _emitter[e].up = IDENTITY_UP;
42− _emitter[e].front = IDENTITY_FRONT;
26+ _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f);
27+ _emitter[e].rotation = glm::quat();
28+ _emitter[e].right = IDENTITY_RIGHT;
29+ _emitter[e].up = IDENTITY_UP;
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+
4344 };
4445
4546 for (unsigned int p = 0; p < MAX_PARTICLES; p++) {
@@ -69,9 +70,11 @@ void ParticleSystem::simulate(float deltaTime) { · 23 unmodified lines
6970
7071 // update emitters
7172 for (unsigned int e = 0; e < _numEmitters; e++) {
72− updateEmitter(e, deltaTime);
73+ updateEmitter(e, deltaTime);
7374 }
7475
76+ runSpecialEffectsTest(0, deltaTime);
77+
7578 // update particles
7679 for (unsigned int p = 0; p < _numParticles; p++) {
7780 if (_particle[p].alive) {
@@ -91,22 +94,23 @@ void ParticleSystem::updateEmitter(int e, float deltaTime) { · 13 unmodified lines
9194 void ParticleSystem::emitParticlesNow(int e, int num, float radius, glm::vec4 color, glm::vec3 velocity, float lifespan) {
9295
9396 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);
9598 }
9699 }
97100
98−void ParticleSystem::createParticle(glm::vec3 position, glm::vec3 velocity, float radius, glm::vec4 color, float lifespan) {
101+void ParticleSystem::createParticle(int e, glm::vec3 position, glm::vec3 velocity, float radius, glm::vec4 color, float lifespan) {
99102
100103 for (unsigned int p = 0; p < MAX_PARTICLES; p++) {
101104 if (!_particle[p].alive) {
102105
103− _particle[p].lifespan = lifespan;
104− _particle[p].alive = true;
105− _particle[p].age = 0.0f;
106− _particle[p].position = position;
107− _particle[p].velocity = velocity;
108− _particle[p].radius = radius;
109− _particle[p].color = color;
106+ _particle[p].emitterIndex = e;
107+ _particle[p].lifespan = lifespan;
108+ _particle[p].alive = true;
109+ _particle[p].age = 0.0f;
110+ _particle[p].position = position;
111+ _particle[p].velocity = velocity;
112+ _particle[p].radius = radius;
113+ _particle[p].color = color;
110114
111115 _numParticles ++;
112116
@@ -145,29 +149,20 @@ void ParticleSystem::setOrangeBlueColorPalette() { · 32 unmodified lines
145149 }
146150
147151
148−void ParticleSystem::runSpecialEffectsTest(float deltaTime) {
152+void ParticleSystem::runSpecialEffectsTest(int e, float deltaTime) {
149153
150154 _timer += deltaTime;
151−
152− glm::vec3 tilt = glm::vec3
153− (
154− 30.0f * sinf( _timer * 0.55f ),
155− 0.0f,
156− 30.0f * cosf( _timer * 0.75f )
157− );
158−
159− _emitter[0].rotation = glm::quat(glm::radians(tilt));
160−
161− _gravity = 0.0f + DEFAULT_PARTICLE_GRAVITY * sinf( _timer * 0.52f );
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;
155+
156+ _emitter[e].gravity = 0.0f + DEFAULT_PARTICLE_GRAVITY * sinf( _timer * 0.52f );
157+ _emitter[e].airFriction = (DEFAULT_PARTICLE_AIR_FRICTION + 0.5f) + 2.0f * sinf( _timer * 0.32f );
158+ _emitter[e].jitter = 0.05f + 0.05f * sinf( _timer * 0.42f );
159+ _emitter[e].emitterAttraction = 0.015f + 0.015f * cosf( _timer * 0.6f );
160+ _emitter[e].tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f );
161+ _emitter[e].neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f );
162+ _emitter[e].neighborRepulsion = 0.2f + 0.2f * sinf( _timer * 0.4f );
163+
164+ if (_emitter[e].gravity < 0.0f) {
165+ _emitter[e].gravity = 0.0f;
171166 }
172167 }
173168
@@ -179,40 +174,45 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 5 unmodified lines
179174 if (_particle[p].age > _particle[p].lifespan) {
180175 killParticle(p);
181176 }
177+
178+ Emitter myEmitter = _emitter[_particle[p].emitterIndex];
182179
183180 // apply random jitter
184181 _particle[p].velocity +=
185182 glm::vec3
186183 (
187− -_jitter * ONE_HALF + _jitter * randFloat(),
188− -_jitter * ONE_HALF + _jitter * randFloat(),
189− -_jitter * ONE_HALF + _jitter * randFloat()
184+ -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat(),
185+ -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat(),
186+ -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat()
190187 ) * deltaTime;
191188
192189 // apply attraction to home position
193− glm::vec3 vectorToHome = _emitter[_particle[p].emitterIndex].position - _particle[p].position;
194− _particle[p].velocity += vectorToHome * _emitterAttraction * deltaTime;
190+ glm::vec3 vectorToHome = myEmitter.position - _particle[p].position;
191+ _particle[p].velocity += vectorToHome * myEmitter.emitterAttraction * deltaTime;
195192
196193 // apply neighbor attraction
197194 int neighbor = p + 1;
198195 if (neighbor == _numParticles ) {
199196 neighbor = 0;
200197 }
201− glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position;
202198
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;
204203
205− float distanceToNeighbor = glm::length(vectorToNeighbor);
206− if (distanceToNeighbor > 0.0f) {
207− _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * _neighborRepulsion * deltaTime;
204+ float distanceToNeighbor = glm::length(vectorToNeighbor);
205+ if (distanceToNeighbor > 0.0f) {
206+ _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * myEmitter.neighborRepulsion * deltaTime;
207+ }
208208 }
209209
210210 // apply tornado force
211− glm::vec3 tornadoDirection = glm::cross(vectorToHome, _emitter[_particle[p].emitterIndex].up);
212− _particle[p].velocity += tornadoDirection * _tornadoForce * deltaTime;
211+ glm::vec3 tornadoDirection = glm::cross(vectorToHome, myEmitter.up);
212+ _particle[p].velocity += tornadoDirection * myEmitter.tornadoForce * deltaTime;
213213
214214 // apply air friction
215− float drag = 1.0 - _airFriction * deltaTime;
215+ float drag = 1.0 - myEmitter.airFriction * deltaTime;
216216 if (drag < 0.0f) {
217217 _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
218218 } else {
@@ -220,7 +220,7 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 1 unmodified line
220220 }
221221
222222 // apply gravity
223− _particle[p].velocity -= _upDirection * _gravity * deltaTime;
223+ _particle[p].velocity -= _upDirection * myEmitter.gravity * deltaTime;
224224
225225 // update position by velocity
226226 _particle[p].position += _particle[p].velocity;
@@ -230,36 +230,38 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 3 unmodified lines
230230 _particle[p].position.y = _particle[p].radius;
231231
232232 if (_particle[p].velocity.y < 0.0f) {
233− _particle[p].velocity.y *= -_bounce;
233+ _particle[p].velocity.y *= -myEmitter.bounce;
234234 }
235235 }
236236
237237 // collision with sphere
238− if (_usingCollisionSphere) {
239− glm::vec3 vectorToSphereCenter = _collisionSpherePosition - _particle[p].position;
238+ if (myEmitter.usingCollisionSphere) {
239+ glm::vec3 vectorToSphereCenter = myEmitter.collisionSpherePosition - _particle[p].position;
240240 float distanceToSphereCenter = glm::length(vectorToSphereCenter);
241− float combinedRadius = _collisionSphereRadius + _particle[p].radius;
241+ float combinedRadius = myEmitter.collisionSphereRadius + _particle[p].radius;
242242 if (distanceToSphereCenter < combinedRadius) {
243243
244244 if (distanceToSphereCenter > 0.0f){
245245 glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter;
246− _particle[p].position = _collisionSpherePosition - directionToSphereCenter * combinedRadius;
246+ _particle[p].position = myEmitter.collisionSpherePosition - directionToSphereCenter * combinedRadius;
247247 }
248248 }
249249 }
250250 }
251251
252−void ParticleSystem::setCollisionSphere(glm::vec3 position, float radius) {
253− _usingCollisionSphere = true;
254− _collisionSpherePosition = position;
255− _collisionSphereRadius = radius;
252+void ParticleSystem::setCollisionSphere(int e, glm::vec3 position, float radius) {
253+ _emitter[e].usingCollisionSphere = true;
254+ _emitter[e].collisionSpherePosition = position;
255+ _emitter[e].collisionSphereRadius = radius;
256256 }
257257
258258 void ParticleSystem::render() {
259259
260260 // render the emitters
261261 for (unsigned int e = 0; e < _numEmitters; e++) {
262− renderEmitter(e, 0.2f);
262+ if (_emitter[e].showingEmitter) {
263+ renderEmitter(e, 0.2f);
264+ }
263265 };
264266
265267 // render the particles