From aee29a0ab1c31269be64c2020011c772adb29b16 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 24 Jul 2013 16:37:13 -0700 Subject: [PATCH] cleaning up the particle system more --- interface/src/Application.cpp | 16 ++++--- interface/src/ParticleSystem.cpp | 74 +++++++++++++++++++------------- interface/src/ParticleSystem.h | 3 +- interface/src/avatar/Hand.cpp | 57 ++++-------------------- 4 files changed, 64 insertions(+), 86 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5c0873c4cf..339bd520e7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3660,13 +3660,11 @@ void Application::updateParticleSystem(float deltaTime) { if (_coolDemoParticleEmitter != -1) { _particleSystem.setShowingEmitter(_coolDemoParticleEmitter, true); glm::vec3 particleEmitterPosition = glm::vec3(5.0f, 1.0f, 5.0f); - _particleSystem.setEmitterPosition(_coolDemoParticleEmitter, particleEmitterPosition); + _particleSystem.setEmitterPosition (_coolDemoParticleEmitter, particleEmitterPosition); _particleSystem.setEmitterParticleLifespan(_coolDemoParticleEmitter, 100000.0f); - _particleSystem.setEmitterThrust(_coolDemoParticleEmitter, 0.0f); - _particleSystem.setEmitterRate(_coolDemoParticleEmitter, 1500); - - _particleSystem.emitNow(_coolDemoParticleEmitter); + _particleSystem.setEmitterThrust (_coolDemoParticleEmitter, 0.0f); + _particleSystem.setEmitterRate (_coolDemoParticleEmitter, 10000.0); // to emit a pile o particles now } // signal that the particle system has been initialized @@ -3674,6 +3672,7 @@ void Application::updateParticleSystem(float deltaTime) { } else { // update the particle system + static bool emitting = true; static float t = 0.0f; t += deltaTime; @@ -3706,6 +3705,13 @@ void Application::updateParticleSystem(float deltaTime) { _particleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); _particleSystem.simulate(deltaTime); + + if (_coolDemoParticleEmitter != -1) { + if (emitting) { + _particleSystem.setEmitterRate(_coolDemoParticleEmitter, 0.0); // stop emitter + emitting = false; + } + } } } diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index b2cea57034..1270760459 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -31,6 +31,7 @@ ParticleSystem::ParticleSystem() { _emitter[emitterIndex].particleResolution = DEFAULT_PARTICLE_SPHERE_RESOLUTION; _emitter[emitterIndex].particleLifespan = DEFAULT_PARTICLE_LIFESPAN; _emitter[emitterIndex].showingBaseParticle = false; + _emitter[emitterIndex].emitReserve = 0.0; _emitter[emitterIndex].thrust = 0.0f; _emitter[emitterIndex].rate = 0.0f; _emitter[emitterIndex].currentParticle = 0; @@ -80,6 +81,24 @@ int ParticleSystem::addEmitter() { void ParticleSystem::simulate(float deltaTime) { + // emit particles + for (int e = 0; e < _numEmitters; e++) { + + assert( e >= 0 ); + assert( e <= MAX_EMITTERS ); + assert( _emitter[e].rate >= 0 ); + + _emitter[e].emitReserve += _emitter[e].rate * deltaTime; + + int numParticlesEmittedThisTime = (int)_emitter[e].emitReserve; + + _emitter[e].emitReserve -= numParticlesEmittedThisTime; + + for (int p = 0; p < numParticlesEmittedThisTime; p++) { + createParticle(e); + } + } + // update particles for (unsigned int p = 0; p < _numParticles; p++) { if (_particle[p].alive) { @@ -92,17 +111,6 @@ void ParticleSystem::simulate(float deltaTime) { } } -void ParticleSystem::emitNow(int e) { - - assert( e >= 0 ); - assert( e <= MAX_EMITTERS ); - assert( _emitter[e].rate >= 0 ); - - for (int p = 0; p < _emitter[e].rate; p++) { - createParticle(e); - } -} - void ParticleSystem::createParticle(int e) { for (unsigned int p = 0; p < MAX_PARTICLES; p++) { @@ -115,11 +123,12 @@ void ParticleSystem::createParticle(int e) { _particle[p].position = _emitter[e].position; _particle[p].radius = _emitter[e].particleAttributes[0].radius; _particle[p].color = _emitter[e].particleAttributes[0].color; + _particle[p].previousParticle = -1; - if (( _particle[_emitter[e].currentParticle].alive) && (_particle[_emitter[e].currentParticle].emitterIndex == e )) { - _particle[p].previousParticle = _emitter[e].currentParticle; - } else { - _particle[p].previousParticle = -1; + if ( _particle[_emitter[e].currentParticle].alive) { + if (_particle[_emitter[e].currentParticle].emitterIndex == e ) { + _particle[p].previousParticle = _emitter[e].currentParticle; + } } _emitter[e].currentParticle = p; @@ -128,7 +137,7 @@ void ParticleSystem::createParticle(int e) { assert(_numParticles <= MAX_PARTICLES); - return; + break; } } } @@ -139,9 +148,15 @@ void ParticleSystem::killParticle(int p) { assert( p < MAX_PARTICLES); assert( _numParticles > 0); - _particle[p].alive = false; + _particle[p].alive = false; + _particle[p].previousParticle = -1; + _particle[p].position = _emitter[_particle[p].emitterIndex].position; + _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); + _particle[p].age = 0.0f; + _particle[p].emitterIndex = -1; + _numParticles --; -} + } void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleAttributes attributes) { @@ -274,12 +289,16 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { void ParticleSystem::killAllParticles() { + for (int e = 0; e < _numEmitters; e++) { + _emitter[e].currentParticle = -1; + _emitter[e].emitReserve = 0.0f; + } + for (unsigned int p = 0; p < _numParticles; p++) { killParticle(p); } } - void ParticleSystem::render() { // render the emitters @@ -340,29 +359,24 @@ void ParticleSystem::renderParticle(int p) { glEnd(); } } else if (_emitter[_particle[p].emitterIndex].particleRenderStyle == PARTICLE_RENDER_STYLE_SPHERE) { + glPushMatrix(); glTranslatef(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); glutSolidSphere(_particle[p].radius, _emitter[_particle[p].emitterIndex].particleResolution, _emitter[_particle[p].emitterIndex].particleResolution); glPopMatrix(); - if (SHOW_VELOCITY_TAILS) { - glColor4f( _particle[p].color.x, _particle[p].color.y, _particle[p].color.z, 0.5f); - glm::vec3 end = _particle[p].position - _particle[p].velocity * 2.0f; - glBegin(GL_LINES); - glVertex3f(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); - glVertex3f(end.x, end.y, end.z); - glEnd(); - } } else if (_emitter[_particle[p].emitterIndex].particleRenderStyle == PARTICLE_RENDER_STYLE_RIBBON) { if (_particle[p].previousParticle != -1) { - if (_particle[_particle[p].previousParticle].alive) { + if ((_particle[p].alive) + && (_particle[_particle[p].previousParticle].alive) + && (_particle[_particle[p].previousParticle].emitterIndex == _particle[p].emitterIndex )) { int pp = _particle[p].previousParticle; glm::vec3 v = _particle[p].position - _particle[pp].position; float distance = glm::length(v); - + if (distance > 0.0f) { v /= distance; @@ -415,7 +429,7 @@ void ParticleSystem::renderParticle(int p) { glVertex3f(ppDown.x, ppDown.y, ppDown.z ); glEnd(); - } + } } } } diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index 34089941bd..5ecb3510d9 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -13,7 +13,6 @@ const int MAX_PARTICLES = 5000; const int MAX_EMITTERS = 100; const int NUM_PARTICLE_LIFE_STAGES = 4; // each equal time-division of the particle's life can have different attributes -const bool SHOW_VELOCITY_TAILS = false; enum ParticleRenderStyle { @@ -46,7 +45,6 @@ public: ParticleSystem(); int addEmitter(); // add (create new) emitter and get its unique id - void emitNow(int emitterIndex); void simulate(float deltaTime); void killAllParticles(); void render(); @@ -83,6 +81,7 @@ private: bool visible; // whether or not a line is shown indicating the emitter (indicating its direction) float particleLifespan; // how long the particle shall live, in seconds int particleResolution; // for sphere-based particles + float emitReserve; // baed on 'rate', this is the number of particles that need to be emitted at a given time step float thrust; // the initial velocity upon emitting along the emitter direction float rate; // currently, how many particles emitted during a simulation time step bool showingBaseParticle; // if true, a copy of particle 0 is shown on the emitter position diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 672d543694..ef343e5608 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -310,47 +310,6 @@ void Hand::updateFingerParticles(float deltaTime) { _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); } } - /* - else if (_testRaveGloveMode == 1) { - ParticleSystem::ParticleAttributes attributes; - - attributes.gravity = 0.001f; - attributes.airFriction = 0.0f; - attributes.jitter = 0.0f; - attributes.emitterAttraction = 0.0f; - attributes.tornadoForce = 0.0f; - attributes.neighborAttraction = 0.0f; - attributes.neighborRepulsion = 0.0f; - attributes.bounce = 0.0f; - attributes.usingCollisionSphere = false; - - attributes.color = glm::vec4( 1.0f, 0.2f, 0.2f, 1.0f); - attributes.radius = 0.003f + 0.002f * sinf(_testRaveGloveClock * 6.2f); - for ( int f = 0; f< NUM_FINGERS; f ++ ) { - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); - } - } - */ - - // update the particles - int fingerIndex = 0; - for (size_t i = 0; i < getNumPalms(); ++i) { - PalmData& palm = getPalms()[i]; - if (palm.isActive()) { - for (size_t f = 0; f < palm.getNumFingers(); ++f) { - FingerData& finger = palm.getFingers()[f]; - if (finger.isActive()) { - if (_fingerParticleEmitter[0] != -1) { - _particleSystem.emitNow(_fingerParticleEmitter[fingerIndex]); - fingerIndex ++; - } - } - } - } - } _particleSystem.simulate(deltaTime); } @@ -373,7 +332,7 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.0f ); _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.0f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 30.0f ); _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 20 ); attributes.radius = 0.02f; @@ -400,7 +359,7 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.0f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 50.0f ); _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 5 ); attributes.radius = 0.001f; @@ -435,7 +394,7 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0 ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 50.0 ); _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 6 ); attributes.radius = 0.005f; @@ -475,7 +434,7 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.6f ); _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.001f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 10.0 ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 5 ); attributes.radius = 0.001f; @@ -511,7 +470,7 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.1 ); _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 3.0 ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 12 ); attributes.radius = 0.0f; @@ -548,7 +507,7 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.2 ); _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 6.0 ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 12 ); attributes.radius = 0.0f; @@ -585,7 +544,7 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0 ); _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 6.0 ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 7 ); attributes.radius = 0.0f; @@ -622,7 +581,7 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0 ); _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0 ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 7 ); attributes.radius = 0.001f;