cleaning up the particle system more

This commit is contained in:
Jeffrey Ventrella 2013-07-24 16:37:13 -07:00
parent 288a218ae2
commit aee29a0ab1
4 changed files with 64 additions and 86 deletions

View file

@ -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;
}
}
}
}

View file

@ -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();
}
}
}
}
}

View file

@ -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

View file

@ -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;