History

added extra mode and started prototyping "ribbon" effect

Jeffrey Ventrella committed 13 years ago

Commit 062ee651 parent 90bc3e94 files · +341 −204Browse files

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

Unified · Split

interface/src/ParticleSystem.cpp+182−118
@@ -25,19 +25,16 @@ ParticleSystem::ParticleSystem() { · 24 unmodified lines
2525
2626 for (unsigned int emitterIndex = 0; emitterIndex < MAX_EMITTERS; emitterIndex++) {
2727
28− _emitter[emitterIndex].position = glm::vec3(0.0f, 0.0f, 0.0f);
29− _emitter[emitterIndex].direction = glm::vec3(0.0f, 1.0f, 0.0f);
30− _emitter[emitterIndex].visible = false;
31− _emitter[emitterIndex].particleResolution = DEFAULT_PARTICLE_SPHERE_RESOLUTION;
32− _emitter[emitterIndex].particleLifespan = DEFAULT_PARTICLE_LIFESPAN;
33− _emitter[emitterIndex].baseParticle.alive = false;
34− _emitter[emitterIndex].baseParticle.age = 0.0f;
35− _emitter[emitterIndex].thrust = 0.0f;
36− _emitter[emitterIndex].rate = 0.0f;
37− _emitter[emitterIndex].baseParticle.radius = 0.0f;
38− _emitter[emitterIndex].baseParticle.emitterIndex = 0;
39− _emitter[emitterIndex].baseParticle.position = glm::vec3(0.0f, 0.0f, 0.0f);
40− _emitter[emitterIndex].baseParticle.velocity = glm::vec3(0.0f, 0.0f, 0.0f);
28+ _emitter[emitterIndex].position = glm::vec3(0.0f, 0.0f, 0.0f);
29+ _emitter[emitterIndex].direction = glm::vec3(0.0f, 1.0f, 0.0f);
30+ _emitter[emitterIndex].visible = false;
31+ _emitter[emitterIndex].particleResolution = DEFAULT_PARTICLE_SPHERE_RESOLUTION;
32+ _emitter[emitterIndex].particleLifespan = DEFAULT_PARTICLE_LIFESPAN;
33+ _emitter[emitterIndex].showingBaseParticle = false;
34+ _emitter[emitterIndex].thrust = 0.0f;
35+ _emitter[emitterIndex].rate = 0.0f;
36+ _emitter[emitterIndex].currentParticle = 0;
37+ _emitter[emitterIndex].particleRenderStyle = PARTICLE_RENDER_STYLE_SPHERE;
4138
4239 for (int lifeStage = 0; lifeStage<NUM_PARTICLE_LIFE_STAGES; lifeStage++) {
4340
@@ -60,12 +57,13 @@ ParticleSystem::ParticleSystem() { · 16 unmodified lines
6057 };
6158
6259 for (unsigned int p = 0; p < MAX_PARTICLES; p++) {
63− _particle[p].alive = false;
64− _particle[p].age = 0.0f;
65− _particle[p].radius = 0.0f;
66− _particle[p].emitterIndex = 0;
67− _particle[p].position = glm::vec3(0.0f, 0.0f, 0.0f);
68− _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
60+ _particle[p].alive = false;
61+ _particle[p].age = 0.0f;
62+ _particle[p].radius = 0.0f;
63+ _particle[p].emitterIndex = 0;
64+ _particle[p].previousParticle = -1;
65+ _particle[p].position = glm::vec3(0.0f, 0.0f, 0.0f);
66+ _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
6967 }
7068 }
7169
@@ -106,15 +104,23 @@ void ParticleSystem::createParticle(int e, glm::vec3 velocity) { · 34 unmodified lines
106104
107105 for (unsigned int p = 0; p < MAX_PARTICLES; p++) {
108106 if (!_particle[p].alive) {
109−
110− _particle[p].emitterIndex = e;
111− _particle[p].alive = true;
112− _particle[p].age = 0.0f;
113− _particle[p].velocity = _emitter[e].direction * _emitter[e].thrust;
114− _particle[p].position = _emitter[e].position;
115− _particle[p].radius = _emitter[e].particleAttributes[0].radius;
116− _particle[p].color = _emitter[e].particleAttributes[0].color;
117−
107+
108+ _particle[p].emitterIndex = e;
109+ _particle[p].alive = true;
110+ _particle[p].age = 0.0f;
111+ _particle[p].velocity = _emitter[e].direction * _emitter[e].thrust;
112+ _particle[p].position = _emitter[e].position;
113+ _particle[p].radius = _emitter[e].particleAttributes[0].radius;
114+ _particle[p].color = _emitter[e].particleAttributes[0].color;
115+
116+ if (( _particle[_emitter[e].currentParticle].alive) && (_particle[_emitter[e].currentParticle].emitterIndex == e )) {
117+ _particle[p].previousParticle = _emitter[e].currentParticle;
118+ } else {
119+ _particle[p].previousParticle = -1;
120+ }
121+
122+ _emitter[e].currentParticle = p;
123+
118124 _numParticles ++;
119125
120126 assert(_numParticles <= MAX_PARTICLES);
@@ -164,105 +170,104 @@ void ParticleSystem::setParticleAttributes(int emitterIndex, int lifeStage, Part · 43 unmodified lines
164170
165171 void ParticleSystem::updateParticle(int p, float deltaTime) {
166172
167− assert(_particle[p].age <= _emitter[_particle[p].emitterIndex].particleLifespan);
168−
169− float ageFraction = _particle[p].age / _emitter[_particle[p].emitterIndex].particleLifespan;
170−
171− int lifeStage = (int)( ageFraction * (NUM_PARTICLE_LIFE_STAGES-1) );
173+ if (_emitter[_particle[p].emitterIndex].particleLifespan > 0.0) {
174+
175+ Emitter myEmitter = _emitter[_particle[p].emitterIndex];
172176
173− float lifeStageFraction = ageFraction * ( NUM_PARTICLE_LIFE_STAGES - 1 ) - lifeStage;
177+ assert(_particle[p].age <= myEmitter.particleLifespan);
174178
175− _particle[p].radius
176− = _emitter[_particle[p].emitterIndex].particleAttributes[lifeStage ].radius * (1.0f - lifeStageFraction)
177− + _emitter[_particle[p].emitterIndex].particleAttributes[lifeStage+1].radius * lifeStageFraction;
179+ float ageFraction = _particle[p].age / myEmitter.particleLifespan;
180+
181+ int lifeStage = (int)( ageFraction * (NUM_PARTICLE_LIFE_STAGES-1) );
182+
183+ float lifeStageFraction = ageFraction * ( NUM_PARTICLE_LIFE_STAGES - 1 ) - lifeStage;
184+
178185
179− _particle[p].color
180− = _emitter[_particle[p].emitterIndex].particleAttributes[lifeStage ].color * (1.0f - lifeStageFraction)
181− + _emitter[_particle[p].emitterIndex].particleAttributes[lifeStage+1].color * lifeStageFraction;
186+ _particle[p].radius
187+ = myEmitter.particleAttributes[lifeStage ].radius * (1.0f - lifeStageFraction)
188+ + myEmitter.particleAttributes[lifeStage+1].radius * lifeStageFraction;
189+
190+ _particle[p].color
191+ = myEmitter.particleAttributes[lifeStage ].color * (1.0f - lifeStageFraction)
192+ + myEmitter.particleAttributes[lifeStage+1].color * lifeStageFraction;
193+
194+ // apply random jitter
195+ float j = myEmitter.particleAttributes[lifeStage].jitter;
196+ _particle[p].velocity +=
197+ glm::vec3
198+ (
199+ -j * ONE_HALF + j * randFloat(),
200+ -j * ONE_HALF + j * randFloat(),
201+ -j * ONE_HALF + j * randFloat()
202+ ) * deltaTime;
182203
183− Emitter myEmitter = _emitter[_particle[p].emitterIndex];
184−
185− // apply random jitter
186− float j = myEmitter.particleAttributes[lifeStage].jitter;
187− _particle[p].velocity +=
188− glm::vec3
189− (
190− -j * ONE_HALF + j * randFloat(),
191− -j * ONE_HALF + j * randFloat(),
192− -j * ONE_HALF + j * randFloat()
193− ) * deltaTime;
194−
195− // apply attraction to home position
196− glm::vec3 vectorToHome = myEmitter.position - _particle[p].position;
197− _particle[p].velocity += vectorToHome * myEmitter.particleAttributes[lifeStage].emitterAttraction * deltaTime;
198−
199− // apply neighbor attraction
200− int neighbor = p + 1;
201− if (neighbor == _numParticles ) {
202− neighbor = 0;
203− }
204−
205− if ( _particle[neighbor].emitterIndex == _particle[p].emitterIndex) {
206− glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position;
207−
208− _particle[p].velocity -= vectorToNeighbor * myEmitter.particleAttributes[lifeStage].neighborAttraction * deltaTime;
204+ // apply attraction to home position
205+ glm::vec3 vectorToHome = myEmitter.position - _particle[p].position;
206+ _particle[p].velocity += vectorToHome * myEmitter.particleAttributes[lifeStage].emitterAttraction * deltaTime;
207+
208+ // apply neighbor attraction
209+ int neighbor = p + 1;
210+ if (neighbor == _numParticles ) {
211+ neighbor = 0;
212+ }
213+
214+ if ( _particle[neighbor].emitterIndex == _particle[p].emitterIndex) {
215+ glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position;
216+
217+ _particle[p].velocity -= vectorToNeighbor * myEmitter.particleAttributes[lifeStage].neighborAttraction * deltaTime;
209218
210− float distanceToNeighbor = glm::length(vectorToNeighbor);
211− if (distanceToNeighbor > 0.0f) {
212− _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * myEmitter.particleAttributes[lifeStage].neighborRepulsion * deltaTime;
219+ float distanceToNeighbor = glm::length(vectorToNeighbor);
220+ if (distanceToNeighbor > 0.0f) {
221+ _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * myEmitter.particleAttributes[lifeStage].neighborRepulsion * deltaTime;
222+ }
213223 }
214− }
215−
216− // apply tornado force
217− glm::vec3 tornadoDirection = glm::cross(vectorToHome, myEmitter.direction);
218− _particle[p].velocity += tornadoDirection * myEmitter.particleAttributes[lifeStage].tornadoForce * deltaTime;
219−
220− // apply air friction
221− float drag = 1.0 - myEmitter.particleAttributes[lifeStage].airFriction * deltaTime;
222− if (drag < 0.0f) {
223− _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
224− } else {
225− _particle[p].velocity *= drag;
226− }
227−
228− // apply gravity
229− _particle[p].velocity -= _upDirection * myEmitter.particleAttributes[lifeStage].gravity * deltaTime;
224+
225+ // apply tornado force
226+ glm::vec3 tornadoDirection = glm::cross(vectorToHome, myEmitter.direction);
227+ _particle[p].velocity += tornadoDirection * myEmitter.particleAttributes[lifeStage].tornadoForce * deltaTime;
228+
229+ // apply air friction
230+ float drag = 1.0 - myEmitter.particleAttributes[lifeStage].airFriction * deltaTime;
231+ if (drag < 0.0f) {
232+ _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
233+ } else {
234+ _particle[p].velocity *= drag;
235+ }
236+
237+ // apply gravity
238+ _particle[p].velocity -= _upDirection * myEmitter.particleAttributes[lifeStage].gravity * deltaTime;
230239
231− // update position by velocity
232− _particle[p].position += _particle[p].velocity;
233−
234− // collision with ground
235− if (_particle[p].position.y < _particle[p].radius) {
236− _particle[p].position.y = _particle[p].radius;
240+ // update position by velocity
241+ _particle[p].position += _particle[p].velocity;
237242
238− if (_particle[p].velocity.y < 0.0f) {
239− _particle[p].velocity.y *= -myEmitter.particleAttributes[lifeStage].bounce;
243+ // collision with ground
244+ if (_particle[p].position.y < _particle[p].radius) {
245+ _particle[p].position.y = _particle[p].radius;
246+
247+ if (_particle[p].velocity.y < 0.0f) {
248+ _particle[p].velocity.y *= -myEmitter.particleAttributes[lifeStage].bounce;
249+ }
240250 }
241− }
242−
243− // collision with sphere
244− if (myEmitter.particleAttributes[lifeStage].usingCollisionSphere) {
245− glm::vec3 vectorToSphereCenter = myEmitter.particleAttributes[lifeStage].collisionSpherePosition - _particle[p].position;
246− float distanceToSphereCenter = glm::length(vectorToSphereCenter);
247− float combinedRadius = myEmitter.particleAttributes[lifeStage].collisionSphereRadius + _particle[p].radius;
248− if (distanceToSphereCenter < combinedRadius) {
249251
250− if (distanceToSphereCenter > 0.0f){
251− glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter;
252− _particle[p].position = myEmitter.particleAttributes[lifeStage].collisionSpherePosition - directionToSphereCenter * combinedRadius;
252+ // collision with sphere
253+ if (myEmitter.particleAttributes[lifeStage].usingCollisionSphere) {
254+ glm::vec3 vectorToSphereCenter = myEmitter.particleAttributes[lifeStage].collisionSpherePosition - _particle[p].position;
255+ float distanceToSphereCenter = glm::length(vectorToSphereCenter);
256+ float combinedRadius = myEmitter.particleAttributes[lifeStage].collisionSphereRadius + _particle[p].radius;
257+ if (distanceToSphereCenter < combinedRadius) {
258+
259+ if (distanceToSphereCenter > 0.0f){
260+ glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter;
261+ _particle[p].position = myEmitter.particleAttributes[lifeStage].collisionSpherePosition - directionToSphereCenter * combinedRadius;
262+ }
253263 }
254264 }
255− }
265+ }
256266
257267 // do this at the end...
258− _particle[p].age += deltaTime;
268+ _particle[p].age += deltaTime;
259269 }
260270
261−void ParticleSystem::setShowingEmitterBaseParticle(int emitterIndex, bool showing ) {
262−
263− _emitter[emitterIndex].baseParticle.alive = true;
264− _emitter[emitterIndex].baseParticle.emitterIndex = emitterIndex;
265−}
266271
267272 void ParticleSystem::killAllParticles() {
268273
@@ -277,11 +282,11 @@ void ParticleSystem::render() { · 8 unmodified lines
277282 // render the emitters
278283 for (int e = 0; e < _numEmitters; e++) {
279284
280− if (_emitter[e].baseParticle.alive) {
281− glColor4f(_emitter[e].baseParticle.color.r, _emitter[e].baseParticle.color.g, _emitter[e].baseParticle.color.b, _emitter[e].baseParticle.color.a );
285+ if (_emitter[e].showingBaseParticle) {
286+ glColor4f(_particle[0].color.r, _particle[0].color.g, _particle[0].color.b, _particle[0].color.a );
282287 glPushMatrix();
283288 glTranslatef(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z);
284− glutSolidSphere(_emitter[e].baseParticle.radius, _emitter[e].particleResolution, _emitter[e].particleResolution);
289+ glutSolidSphere(_particle[0].radius, _emitter[e].particleResolution, _emitter[e].particleResolution);
285290 glPopMatrix();
286291 }
287292
@@ -289,11 +294,13 @@ void ParticleSystem::render() { · 1 unmodified line
289294 renderEmitter(e, 0.2f);
290295 }
291296 };
292−
297+
293298 // render the particles
294299 for (unsigned int p = 0; p < _numParticles; p++) {
295300 if (_particle[p].alive) {
296− renderParticle(p);
301+ if (_emitter[_particle[p].emitterIndex].particleLifespan > 0.0) {
302+ renderParticle(p);
303+ }
297304 }
298305 }
299306 }
@@ -302,7 +309,7 @@ void ParticleSystem::renderParticle(int p) { · 2 unmodified lines
302309
303310 glColor4f(_particle[p].color.r, _particle[p].color.g, _particle[p].color.b, _particle[p].color.a );
304311
305− if (USE_BILLBOARD_RENDERING) {
312+ if (_emitter[_particle[p].emitterIndex].particleRenderStyle == PARTICLE_RENDER_STYLE_BILLBOARD) {
306313 glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition();
307314 glm::vec3 viewVector = _particle[p].position - cameraPosition;
308315 float distance = glm::length(viewVector);
@@ -329,7 +336,7 @@ void ParticleSystem::renderParticle(int p) { · 20 unmodified lines
329336 glVertex3f(p3.x, p3.y, p3.z);
330337 glEnd();
331338 }
332− } else {
339+ } else if (_emitter[_particle[p].emitterIndex].particleRenderStyle == PARTICLE_RENDER_STYLE_SPHERE) {
333340 glPushMatrix();
334341 glTranslatef(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z);
335342 glutSolidSphere(_particle[p].radius, _emitter[_particle[p].emitterIndex].particleResolution, _emitter[_particle[p].emitterIndex].particleResolution);
@@ -343,9 +350,66 @@ void ParticleSystem::renderParticle(int p) { · 7 unmodified lines
343350 glVertex3f(end.x, end.y, end.z);
344351 glEnd();
345352 }
353+ } else if (_emitter[_particle[p].emitterIndex].particleRenderStyle == PARTICLE_RENDER_STYLE_RIBBON) {
354+
355+ if (_particle[p].previousParticle != -1) {
356+ if (_particle[_particle[p].previousParticle].alive) {
357+
358+ int pp = _particle[p].previousParticle;
359+
360+ glm::vec3 v = _particle[p].position - _particle[pp].position;
361+ float distance = glm::length(v);
362+
363+ if (distance > 0.0f) {
364+
365+ v /= distance;
366+
367+ glm::vec3 up = glm::normalize(glm::cross(v, _upDirection));
368+ glm::vec3 right = glm::normalize(glm::cross(up, v));
369+
370+ right *= _particle[p].radius;
371+ up *= _particle[p].radius;
372+
373+ glm::vec3 p0Left = _particle[p ].position - right;
374+ glm::vec3 p0Right = _particle[p ].position + right;
375+ glm::vec3 p0Down = _particle[p ].position - up;
376+ glm::vec3 p0Up = _particle[p ].position + up;
377+
378+ glm::vec3 ppLeft = _particle[pp].position - right;
379+ glm::vec3 ppRight = _particle[pp].position + right;
380+ glm::vec3 ppDown = _particle[pp].position - up;
381+ glm::vec3 ppUp = _particle[pp].position + up;
382+
383+ glBegin(GL_TRIANGLES);
384+ glVertex3f(p0Left.x, p0Left.y, p0Left.z );
385+ glVertex3f(p0Right.x, p0Right.y, p0Right.z );
386+ glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z );
387+ glEnd();
388+
389+ glBegin(GL_TRIANGLES);
390+ glVertex3f(p0Right.x, p0Right.y, p0Right.z );
391+ glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z );
392+ glVertex3f(ppRight.x, ppRight.y, ppRight.z );
393+ glEnd();
394+
395+ glBegin(GL_TRIANGLES);
396+ glVertex3f(p0Up.x, p0Up.y, p0Up.z );
397+ glVertex3f(p0Down.x, p0Down.y, p0Down.z );
398+ glVertex3f(ppDown.x, ppDown.y, ppDown.z );
399+ glEnd();
400+
401+ glBegin(GL_TRIANGLES);
402+ glVertex3f(p0Up.x, p0Up.y, p0Up.z );
403+ glVertex3f(ppUp.x, ppUp.y, ppUp.z );
404+ glVertex3f(ppDown.x, ppDown.y, ppDown.z );
405+ glEnd();
406+ }
407+ }
408+ }
346409 }
347410 }
348411
412+
349413 void ParticleSystem::renderEmitter(int e, float size) {
350414
351415 glLineWidth(2.0f);