diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7b0694695b..adb88147e9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -73,7 +73,7 @@ using namespace std; static char STAR_FILE[] = "http://s3-us-west-1.amazonaws.com/highfidelity/stars.txt"; static char STAR_CACHE_FILE[] = "cachedStars.txt"; -static const bool TESTING_PARTICLE_SYSTEM = false; +static const bool TESTING_PARTICLE_SYSTEM = true; static const int BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH = 6; // farther dragged clicks are ignored @@ -3510,23 +3510,13 @@ void Application::updateParticleSystem(float deltaTime) { _particleSystem.setShowingEmitter(_coolDemoParticleEmitter, true); glm::vec3 particleEmitterPosition = glm::vec3(5.0f, 1.0f, 5.0f); _particleSystem.setEmitterPosition(_coolDemoParticleEmitter, particleEmitterPosition); - float radius = 0.01f; - glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); glm::vec3 velocity(0.0f, 0.1f, 0.0f); float lifespan = 100000.0f; - - // determine a collision sphere - glm::vec3 collisionSpherePosition = glm::vec3( 5.0f, 0.5f, 5.0f ); - float collisionSphereRadius = 0.5f; - _particleSystem.setCollisionSphere(_coolDemoParticleEmitter, collisionSpherePosition, collisionSphereRadius); - _particleSystem.emitParticlesNow(_coolDemoParticleEmitter, 1500, radius, color, velocity, lifespan); + _particleSystem.emitParticlesNow(_coolDemoParticleEmitter, 1500, velocity, lifespan); } // signal that the particle system has been initialized _particleSystemInitialized = true; - - // apply a preset color palette - _particleSystem.setOrangeBlueColorPalette(); } else { // update the particle system @@ -3547,6 +3537,7 @@ void Application::updateParticleSystem(float deltaTime) { ParticleSystem::ParticleAttributes attributes; attributes.radius = 0.01f; + attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); attributes.gravity = 0.0f + 0.05f * sinf( t * 0.52f ); attributes.airFriction = 2.5 + 2.0f * sinf( t * 0.32f ); attributes.jitter = 0.05f + 0.05f * sinf( t * 0.42f ); @@ -3563,7 +3554,7 @@ void Application::updateParticleSystem(float deltaTime) { attributes.gravity = 0.0f; } - _particleSystem.setParticleAttributes(_coolDemoParticleEmitter, attributes); + _particleSystem.setParticleAttributes(_coolDemoParticleEmitter, attributes); } _particleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); diff --git a/interface/src/Hand.cpp b/interface/src/Hand.cpp index bbfd58c5b1..69d8ddfaac 100755 --- a/interface/src/Hand.cpp +++ b/interface/src/Hand.cpp @@ -216,9 +216,13 @@ void Hand::updateFingerParticles(float deltaTime) { if (!_particleSystemInitialized) { for ( int f = 0; f< NUM_FINGERS_PER_HAND; f ++ ) { + + _particleSystem.setShowingEmitter(f, true ); _fingerParticleEmitter[f] = _particleSystem.addEmitter(); + assert( _fingerParticleEmitter[f] != -1 ); + ParticleSystem::ParticleAttributes attributes; // set attributes for each life stage of the particle: @@ -277,17 +281,17 @@ void Hand::updateFingerParticles(float deltaTime) { } else { fingerDirection = IDENTITY_UP; } + + glm::quat particleEmitterRotation = rotationBetween(palm.getNormal(), fingerDirection); - glm::quat particleEmitterRotation = rotationBetween(IDENTITY_UP, fingerDirection); + //glm::quat particleEmitterRotation = glm::angleAxis(0.0f, fingerDirection); _particleSystem.setEmitterPosition(_fingerParticleEmitter[f], particleEmitterPosition); _particleSystem.setEmitterRotation(_fingerParticleEmitter[f], particleEmitterRotation); - float radius = 0.005f; - const glm::vec4 color(1.0f, 0.6f, 0.0f, 0.5f); const glm::vec3 velocity = fingerDirection * 0.002f; const float lifespan = 1.0f; - _particleSystem.emitParticlesNow(_fingerParticleEmitter[f], 1, radius, color, velocity, lifespan); + _particleSystem.emitParticlesNow(_fingerParticleEmitter[f], 1, velocity, lifespan); } } } diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 66bb847226..9dcdbe5f06 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -21,36 +21,35 @@ ParticleSystem::ParticleSystem() { _numParticles = 0; _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default - for (unsigned int e = 0; e < MAX_EMITTERS; e++) { - _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f); - _emitter[e].rotation = glm::quat(); - _emitter[e].right = IDENTITY_RIGHT; - _emitter[e].up = IDENTITY_UP; - _emitter[e].front = IDENTITY_FRONT; - _emitter[e].visible = false; - _emitter[e].baseParticle.alive = false; - _emitter[e].baseParticle.age = 0.0f; - _emitter[e].baseParticle.lifespan = 0.0f; - _emitter[e].baseParticle.radius = 0.0f; - _emitter[e].baseParticle.emitterIndex = 0; - _emitter[e].baseParticle.position = glm::vec3(0.0f, 0.0f, 0.0f); - _emitter[e].baseParticle.velocity = glm::vec3(0.0f, 0.0f, 0.0f); - + for (unsigned int emitterIndex = 0; emitterIndex < MAX_EMITTERS; emitterIndex++) { + _emitter[emitterIndex].position = glm::vec3(0.0f, 0.0f, 0.0f); + _emitter[emitterIndex].rotation = glm::quat(); + _emitter[emitterIndex].visible = false; + _emitter[emitterIndex].baseParticle.alive = false; + _emitter[emitterIndex].baseParticle.age = 0.0f; + _emitter[emitterIndex].baseParticle.lifespan = 0.0f; + _emitter[emitterIndex].baseParticle.radius = 0.0f; + _emitter[emitterIndex].baseParticle.emitterIndex = 0; + _emitter[emitterIndex].baseParticle.position = glm::vec3(0.0f, 0.0f, 0.0f); + _emitter[emitterIndex].baseParticle.velocity = glm::vec3(0.0f, 0.0f, 0.0f); - for (int s = 0; sradius = DEFAULT_PARTICLE_RADIUS; + a->color = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f); + a->bounce = DEFAULT_PARTICLE_BOUNCE; + a->airFriction = DEFAULT_PARTICLE_AIR_FRICTION; + a->gravity = 0.0f; + a->jitter = 0.0f; + a->emitterAttraction = 0.0f; + a->tornadoForce = 0.0f; + a->neighborAttraction = 0.0f; + a->neighborRepulsion = 0.0f; + a->collisionSphereRadius = 0.0f; + a->collisionSpherePosition = glm::vec3(0.0f, 0.0f, 0.0f); + a->usingCollisionSphere = false; } }; @@ -79,11 +78,6 @@ int ParticleSystem::addEmitter() { void ParticleSystem::simulate(float deltaTime) { - // update emitters - for (unsigned int e = 0; e < _numEmitters; e++) { - updateEmitter(e, deltaTime); - } - // update particles for (unsigned int p = 0; p < _numParticles; p++) { if (_particle[p].alive) { @@ -96,23 +90,14 @@ void ParticleSystem::simulate(float deltaTime) { } } - -void ParticleSystem::updateEmitter(int e, float deltaTime) { - - _emitter[e].front = _emitter[e].rotation * IDENTITY_FRONT; - _emitter[e].right = _emitter[e].rotation * IDENTITY_RIGHT; - _emitter[e].up = _emitter[e].rotation * IDENTITY_UP; -} - - -void ParticleSystem::emitParticlesNow(int e, int num, float radius, glm::vec4 color, glm::vec3 velocity, float lifespan) { +void ParticleSystem::emitParticlesNow(int e, int num, glm::vec3 velocity, float lifespan) { for (unsigned int p = 0; p < num; p++) { - createParticle(e, _emitter[e].position, velocity, radius, color, lifespan); + createParticle(e, velocity, lifespan); } } -void ParticleSystem::createParticle(int e, glm::vec3 position, glm::vec3 velocity, float radius, glm::vec4 color, float lifespan) { +void ParticleSystem::createParticle(int e, glm::vec3 velocity, float lifespan) { for (unsigned int p = 0; p < MAX_PARTICLES; p++) { if (!_particle[p].alive) { @@ -121,12 +106,10 @@ void ParticleSystem::createParticle(int e, glm::vec3 position, glm::vec3 velocit _particle[p].lifespan = lifespan; _particle[p].alive = true; _particle[p].age = 0.0f; - _particle[p].position = position; _particle[p].velocity = velocity; - _particle[p].color = color; - - _particle[p].radius = _emitter[e].particleAttributes[0].radius; - _particle[p].color = _emitter[e].particleAttributes[0].color; + _particle[p].position = _emitter[e].position; + _particle[p].radius = _emitter[e].particleAttributes[0].radius; + _particle[p].color = _emitter[e].particleAttributes[0].color; _numParticles ++; @@ -148,23 +131,6 @@ void ParticleSystem::killParticle(int p) { } -void ParticleSystem::setOrangeBlueColorPalette() { - - for (unsigned int p = 0; p < _numParticles; p++) { - - float radian = ((float)p / (float)_numParticles) * PI_TIMES_TWO; - float wave = sinf(radian); - - float red = 0.5f + 0.5f * wave; - float green = 0.3f + 0.3f * wave; - float blue = 0.2f - 0.2f * wave; - float alpha = 1.0f; - - _particle[p].color = glm::vec4(red, green, blue, alpha); - } -} - - void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleAttributes attributes) { for (int lifeStage = 0; lifeStage < NUM_PARTICLE_LIFE_STAGES; lifeStage ++ ) { @@ -201,13 +167,7 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { int lifeStage = (int)( ageFraction * (NUM_PARTICLE_LIFE_STAGES-1) ); float lifeStageFraction = ageFraction * ( NUM_PARTICLE_LIFE_STAGES - 1 ) - lifeStage; - - /* - if ( p == 0 ) { - printf( "lifespan = %f ageFraction = %f lifeStage = %d lifeStageFraction = %f\n", _particle[p].lifespan, ageFraction, lifeStage, lifeStageFraction ); - } - */ - + _particle[p].radius = _emitter[_particle[p].emitterIndex].particleAttributes[lifeStage ].radius * (1.0f - lifeStageFraction) + _emitter[_particle[p].emitterIndex].particleAttributes[lifeStage+1].radius * lifeStageFraction; @@ -250,7 +210,11 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { } // apply tornado force - glm::vec3 tornadoDirection = glm::cross(vectorToHome, myEmitter.up); + + + glm::vec3 emitterUp = myEmitter.rotation * IDENTITY_UP; + + glm::vec3 tornadoDirection = glm::cross(vectorToHome, emitterUp); _particle[p].velocity += tornadoDirection * myEmitter.particleAttributes[lifeStage].tornadoForce * deltaTime; // apply air friction @@ -294,15 +258,6 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { _particle[p].age += deltaTime; } -void ParticleSystem::setCollisionSphere(int e, glm::vec3 position, float radius) { - - int lifeStage = 0; - - _emitter[e].particleAttributes[lifeStage].usingCollisionSphere = true; - _emitter[e].particleAttributes[lifeStage].collisionSpherePosition = position; - _emitter[e].particleAttributes[lifeStage].collisionSphereRadius = radius; -} - void ParticleSystem::setEmitterBaseParticle(int emitterIndex, bool showing ) { _emitter[emitterIndex].baseParticle.alive = true; @@ -395,10 +350,10 @@ void ParticleSystem::renderParticle(int p) { void ParticleSystem::renderEmitter(int e, float size) { - - glm::vec3 r = _emitter[e].right * size; - glm::vec3 u = _emitter[e].up * size; - glm::vec3 f = _emitter[e].front * size; + + glm::vec3 r = _emitter[e].rotation * IDENTITY_FRONT * size; + glm::vec3 u = _emitter[e].rotation * IDENTITY_RIGHT * size; + glm::vec3 f = _emitter[e].rotation * IDENTITY_UP * size; glLineWidth(2.0f); diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index d6563cc1a5..764800f23e 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -4,7 +4,6 @@ // // Created by Jeffrey on July 10, 2013 // -// #ifndef hifi_ParticleSystem_h #define hifi_ParticleSystem_h @@ -38,57 +37,50 @@ public: ParticleSystem(); - int addEmitter(); // add (create) an emitter and get its unique id - void emitParticlesNow(int emitterIndex, int numParticles, float radius, glm::vec4 color, glm::vec3 velocity, float lifespan); + int addEmitter(); // add (create new) emitter and get its unique id + void emitParticlesNow(int emitterIndex, int numParticles, glm::vec3 velocity, float lifespan); void simulate(float deltaTime); void render(); + + void setUpDirection(glm::vec3 upDirection) {_upDirection = upDirection;} // tell particle system which direction is up void setEmitterBaseParticle(int emitterIndex, bool showing ); void setEmitterBaseParticle(int emitterIndex, bool showing, float radius, glm::vec4 color ); - - void setOrangeBlueColorPalette(); // apply a nice preset color palette to the particles - void setUpDirection(glm::vec3 upDirection) {_upDirection = upDirection;} // tell particle system which direction is up - void setParticleAttributes(int emitterIndex, ParticleAttributes attributes); - void setParticleAttributes(int emitterIndex, int lifeStage, ParticleAttributes attributes); - void setCollisionSphere (int emitterIndex, glm::vec3 position, float radius); // specify a sphere for the particles to collide with - void setEmitterPosition (int emitterIndex, glm::vec3 position) { _emitter[emitterIndex].position = position; } // set position of emitter - void setEmitterRotation (int emitterIndex, glm::quat rotation) { _emitter[emitterIndex].rotation = rotation; } // set rotation of emitter - void setShowingEmitter (int emitterIndex, bool showing ) { _emitter[emitterIndex].visible = showing; } // set its visibiity + void setParticleAttributes (int emitterIndex, ParticleAttributes attributes); + void setParticleAttributes (int emitterIndex, int lifeStage, ParticleAttributes attributes); + void setEmitterPosition (int emitterIndex, glm::vec3 position) { _emitter[emitterIndex].position = position; } // set position of emitter + void setEmitterRotation (int emitterIndex, glm::quat rotation) { _emitter[emitterIndex].rotation = rotation; } // set rotation of emitter + void setShowingEmitter (int emitterIndex, bool showing ) { _emitter[emitterIndex].visible = showing; } // set its visibiity private: struct Particle { - bool alive; // is the particle active? - glm::vec3 position; // position - glm::vec3 velocity; // velocity - glm::vec4 color; // color (rgba) - float age; // age in seconds - float radius; // radius - float lifespan; // how long this particle stays alive (in seconds) - int emitterIndex; // which emitter created this particle? + bool alive; // is the particle active? + glm::vec3 position; // position + glm::vec3 velocity; // velocity + glm::vec4 color; // color (rgba) + float age; // age in seconds + float radius; // radius + float lifespan; // how long this particle stays alive (in seconds) + int emitterIndex; // which emitter created this particle? }; struct Emitter { glm::vec3 position; glm::quat rotation; - glm::vec3 right; // derived from rotation - glm::vec3 up; // derived from rotation - glm::vec3 front; // derived from rotation bool visible; Particle baseParticle; // a non-physical particle at the emitter position ParticleAttributes particleAttributes[NUM_PARTICLE_LIFE_STAGES]; // the attributes of particles emitted from this emitter }; - glm::vec3 _upDirection; - Emitter _emitter[MAX_EMITTERS]; - Particle _particle[MAX_PARTICLES]; - int _numParticles; - int _numEmitters; + glm::vec3 _upDirection; + Emitter _emitter[MAX_EMITTERS]; + Particle _particle[MAX_PARTICLES]; + int _numParticles; + int _numEmitters; // private methods - void updateEmitter(int e, float deltaTime); void updateParticle(int index, float deltaTime); - void createParticle(int e, glm::vec3 position, glm::vec3 velocity, float radius, glm::vec4 color, float lifespan); - //void runSpecialEffectsTest(int e, float deltaTime); // for debugging and artistic exploration + void createParticle(int e, glm::vec3 velocity, float lifespan); void killParticle(int p); void renderEmitter(int emitterIndex, float size); void renderParticle(int p);