This commit is contained in:
Jeffrey Ventrella 2013-07-31 13:07:52 -07:00
parent 89f36a7eb7
commit 0aaeb4550a
3 changed files with 73 additions and 71 deletions

View file

@ -51,7 +51,7 @@ ParticleSystem::ParticleSystem() {
_particle[p].age = 0.0f; _particle[p].age = 0.0f;
_particle[p].radius = 0.0f; _particle[p].radius = 0.0f;
_particle[p].emitterIndex = 0; _particle[p].emitterIndex = 0;
_particle[p].previousParticle = -1; _particle[p].previousParticle = NULL_PARTICLE;
_particle[p].position = glm::vec3(0.0f, 0.0f, 0.0f); _particle[p].position = glm::vec3(0.0f, 0.0f, 0.0f);
_particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
} }
@ -64,7 +64,7 @@ int ParticleSystem::addEmitter() {
return _numEmitters - 1; return _numEmitters - 1;
} }
return -1; return NULL_EMITTER;
} }
@ -75,9 +75,9 @@ void ParticleSystem::simulate(float deltaTime) {
// emit particles // emit particles
for (int e = 0; e < _numEmitters; e++) { for (int e = 0; e < _numEmitters; e++) {
assert( e >= 0 ); assert(e >= 0);
assert( e <= MAX_EMITTERS ); assert(e <= MAX_EMITTERS);
assert( _emitter[e].rate >= 0 ); assert(_emitter[e].rate >= 0);
_emitter[e].emitReserve += _emitter[e].rate * deltaTime; _emitter[e].emitReserve += _emitter[e].rate * deltaTime;
@ -116,10 +116,10 @@ void ParticleSystem::createParticle(int e, float timeFraction) {
_particle[p].position = _emitter[e].previousPosition + timeFraction * (_emitter[e].position - _emitter[e].previousPosition); _particle[p].position = _emitter[e].previousPosition + timeFraction * (_emitter[e].position - _emitter[e].previousPosition);
_particle[p].radius = _emitter[e].particleAttributes[0].radius; _particle[p].radius = _emitter[e].particleAttributes[0].radius;
_particle[p].color = _emitter[e].particleAttributes[0].color; _particle[p].color = _emitter[e].particleAttributes[0].color;
_particle[p].previousParticle = -1; _particle[p].previousParticle = NULL_PARTICLE;
if ( _particle[_emitter[e].currentParticle].alive) { if (_particle[_emitter[e].currentParticle].alive) {
if (_particle[_emitter[e].currentParticle].emitterIndex == e ) { if (_particle[_emitter[e].currentParticle].emitterIndex == e) {
_particle[p].previousParticle = _emitter[e].currentParticle; _particle[p].previousParticle = _emitter[e].currentParticle;
} }
} }
@ -133,15 +133,15 @@ void ParticleSystem::createParticle(int e, float timeFraction) {
void ParticleSystem::killParticle(int p) { void ParticleSystem::killParticle(int p) {
assert( p >= 0); assert(p >= 0);
assert( p < MAX_PARTICLES); assert(p < MAX_PARTICLES);
_particle[p].alive = false; _particle[p].alive = false;
_particle[p].previousParticle = -1; _particle[p].previousParticle = NULL_PARTICLE;
_particle[p].position = _emitter[_particle[p].emitterIndex].position; _particle[p].position = _emitter[_particle[p].emitterIndex].position;
_particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
_particle[p].age = 0.0f; _particle[p].age = 0.0f;
_particle[p].emitterIndex = -1; _particle[p].emitterIndex = NULL_PARTICLE;
} }
@ -153,7 +153,7 @@ void ParticleSystem::setEmitterPosition(int emitterIndex, glm::vec3 position) {
void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleAttributes attributes) { void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleAttributes attributes) {
for (int lifeStage = 0; lifeStage < NUM_PARTICLE_LIFE_STAGES; lifeStage ++ ) { for (int lifeStage = 0; lifeStage < NUM_PARTICLE_LIFE_STAGES; lifeStage ++) {
setParticleAttributes(emitterIndex, (ParticleLifeStage)lifeStage, attributes); setParticleAttributes(emitterIndex, (ParticleLifeStage)lifeStage, attributes);
} }
} }
@ -185,8 +185,8 @@ void ParticleSystem::setParticleAttributesToDefault(ParticleAttributes * a) {
void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleLifeStage lifeStage, ParticleAttributes attributes) { void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleLifeStage lifeStage, ParticleAttributes attributes) {
assert(lifeStage >= 0 ); assert(lifeStage >= 0);
assert(lifeStage < NUM_PARTICLE_LIFE_STAGES ); assert(lifeStage < NUM_PARTICLE_LIFE_STAGES);
ParticleAttributes * a = &_emitter[emitterIndex].particleAttributes[lifeStage]; ParticleAttributes * a = &_emitter[emitterIndex].particleAttributes[lifeStage];
@ -226,8 +226,8 @@ void ParticleSystem::updateParticle(int p, float deltaTime) {
if (_emitter[_particle[p].emitterIndex].particleLifespan > 0.0) { if (_emitter[_particle[p].emitterIndex].particleLifespan > 0.0) {
ageFraction = _particle[p].age / myEmitter.particleLifespan; ageFraction = _particle[p].age / myEmitter.particleLifespan;
lifeStage = (int)( ageFraction * (NUM_PARTICLE_LIFE_STAGES-1) ); lifeStage = (int)(ageFraction * (NUM_PARTICLE_LIFE_STAGES - 1));
lifeStageFraction = ageFraction * ( NUM_PARTICLE_LIFE_STAGES - 1 ) - lifeStage; lifeStageFraction = ageFraction * (NUM_PARTICLE_LIFE_STAGES - 1) - lifeStage;
// adjust radius // adjust radius
_particle[p].radius _particle[p].radius
@ -250,18 +250,18 @@ void ParticleSystem::updateParticle(int p, float deltaTime) {
// apply neighbor attraction // apply neighbor attraction
int neighbor = p + 1; int neighbor = p + 1;
if (neighbor == MAX_PARTICLES ) { if (neighbor == MAX_PARTICLES) {
neighbor = 0; neighbor = 0;
} }
if ( _particle[neighbor].emitterIndex == _particle[p].emitterIndex) { if (_particle[neighbor].emitterIndex == _particle[p].emitterIndex) {
glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position; glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position;
_particle[p].velocity -= vectorToNeighbor * myEmitter.particleAttributes[lifeStage].neighborAttraction * deltaTime; _particle[p].velocity -= vectorToNeighbor * myEmitter.particleAttributes[lifeStage].neighborAttraction * deltaTime;
float distanceToNeighbor = glm::length(vectorToNeighbor); float distanceToNeighbor = glm::length(vectorToNeighbor);
if (distanceToNeighbor > 0.0f) { if (distanceToNeighbor > 0.0f) {
_particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * myEmitter.particleAttributes[lifeStage].neighborRepulsion * deltaTime; _particle[neighbor].velocity += (vectorToNeighbor / (1.0f + distanceToNeighbor * distanceToNeighbor)) * myEmitter.particleAttributes[lifeStage].neighborRepulsion * deltaTime;
} }
} }
@ -320,7 +320,7 @@ void ParticleSystem::updateParticle(int p, float deltaTime) {
float modulation = 0.0f; float modulation = 0.0f;
float radian = _timer * myEmitter.particleAttributes[lifeStage ].modulationRate * PI_TIMES_TWO; float radian = _timer * myEmitter.particleAttributes[lifeStage ].modulationRate * PI_TIMES_TWO;
if (myEmitter.particleAttributes[lifeStage ].modulationStyle == COLOR_MODULATION_STYLE_LIGHNTESS_PULSE) { if (myEmitter.particleAttributes[lifeStage ].modulationStyle == COLOR_MODULATION_STYLE_LIGHNTESS_PULSE) {
if ( sinf(radian) > 0.0f ) { if (sinf(radian) > 0.0f) {
modulation = myEmitter.particleAttributes[lifeStage].modulationAmplitude; modulation = myEmitter.particleAttributes[lifeStage].modulationAmplitude;
} }
} else if (myEmitter.particleAttributes[lifeStage].modulationStyle == COLOR_MODULATION_STYLE_LIGHTNESS_WAVE) { } else if (myEmitter.particleAttributes[lifeStage].modulationStyle == COLOR_MODULATION_STYLE_LIGHTNESS_WAVE) {
@ -347,7 +347,7 @@ void ParticleSystem::updateParticle(int p, float deltaTime) {
void ParticleSystem::killAllParticles() { void ParticleSystem::killAllParticles() {
for (int e = 0; e < _numEmitters; e++) { for (int e = 0; e < _numEmitters; e++) {
_emitter[e].currentParticle = -1; _emitter[e].currentParticle = NULL_PARTICLE;
_emitter[e].emitReserve = 0.0f; _emitter[e].emitReserve = 0.0f;
_emitter[e].previousPosition = _emitter[e].position; _emitter[e].previousPosition = _emitter[e].position;
_emitter[e].rate = 0.0f; _emitter[e].rate = 0.0f;
@ -366,7 +366,7 @@ void ParticleSystem::render() {
for (int e = 0; e < _numEmitters; e++) { for (int e = 0; e < _numEmitters; e++) {
if (_emitter[e].showingBaseParticle) { if (_emitter[e].showingBaseParticle) {
glColor4f(_particle[0].color.r, _particle[0].color.g, _particle[0].color.b, _particle[0].color.a ); glColor4f(_particle[0].color.r, _particle[0].color.g, _particle[0].color.b, _particle[0].color.a);
glPushMatrix(); glPushMatrix();
glTranslatef(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); glTranslatef(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z);
glutSolidSphere(_particle[0].radius, _emitter[e].particleResolution, _emitter[e].particleResolution); glutSolidSphere(_particle[0].radius, _emitter[e].particleResolution, _emitter[e].particleResolution);
@ -390,7 +390,7 @@ void ParticleSystem::render() {
void ParticleSystem::renderParticle(int p) { void ParticleSystem::renderParticle(int p) {
glColor4f(_particle[p].color.r, _particle[p].color.g, _particle[p].color.b, _particle[p].color.a ); glColor4f(_particle[p].color.r, _particle[p].color.g, _particle[p].color.b, _particle[p].color.a);
if (_emitter[_particle[p].emitterIndex].particleRenderStyle == PARTICLE_RENDER_STYLE_BILLBOARD) { if (_emitter[_particle[p].emitterIndex].particleRenderStyle == PARTICLE_RENDER_STYLE_BILLBOARD) {
glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition();
@ -428,66 +428,64 @@ void ParticleSystem::renderParticle(int p) {
} else if (_emitter[_particle[p].emitterIndex].particleRenderStyle == PARTICLE_RENDER_STYLE_RIBBON) { } else if (_emitter[_particle[p].emitterIndex].particleRenderStyle == PARTICLE_RENDER_STYLE_RIBBON) {
if (_particle[p].previousParticle != -1) { if (_particle[p].previousParticle != NULL_PARTICLE) {
if ((_particle[p].alive) if ((_particle[p].alive)
&& (_particle[_particle[p].previousParticle].alive) && (_particle[_particle[p].previousParticle].alive)
&& (_particle[_particle[p].previousParticle].emitterIndex == _particle[p].emitterIndex )) { && (_particle[_particle[p].previousParticle].emitterIndex == _particle[p].emitterIndex)) {
int pp = _particle[p].previousParticle; glm::vec3 vectorFromPreviousParticle = _particle[p].position - _particle[_particle[p].previousParticle].position;
float distance = glm::length(vectorFromPreviousParticle);
glm::vec3 v = _particle[p].position - _particle[pp].position;
float distance = glm::length(v);
if (distance > 0.0f) { if (distance > 0.0f) {
v /= distance; vectorFromPreviousParticle /= distance;
glm::vec3 up = glm::normalize(glm::cross(v, _upDirection)) * _particle[p].radius; glm::vec3 up = glm::normalize(glm::cross(vectorFromPreviousParticle, _upDirection)) * _particle[p].radius;
glm::vec3 right = glm::normalize(glm::cross(up, v )) * _particle[p].radius; glm::vec3 right = glm::normalize(glm::cross(up, vectorFromPreviousParticle )) * _particle[p].radius;
glm::vec3 p0Left = _particle[p ].position - right; glm::vec3 p0Left = _particle[p ].position - right;
glm::vec3 p0Right = _particle[p ].position + right; glm::vec3 p0Right = _particle[p ].position + right;
glm::vec3 p0Down = _particle[p ].position - up; glm::vec3 p0Down = _particle[p ].position - up;
glm::vec3 p0Up = _particle[p ].position + up; glm::vec3 p0Up = _particle[p ].position + up;
glm::vec3 ppLeft = _particle[pp].position - right; glm::vec3 ppLeft = _particle[_particle[p].previousParticle].position - right;
glm::vec3 ppRight = _particle[pp].position + right; glm::vec3 ppRight = _particle[_particle[p].previousParticle].position + right;
glm::vec3 ppDown = _particle[pp].position - up; glm::vec3 ppDown = _particle[_particle[p].previousParticle].position - up;
glm::vec3 ppUp = _particle[pp].position + up; glm::vec3 ppUp = _particle[_particle[p].previousParticle].position + up;
glBegin(GL_TRIANGLES); glBegin(GL_TRIANGLES);
glVertex3f(p0Left.x, p0Left.y, p0Left.z ); glVertex3f(p0Left.x, p0Left.y, p0Left.z );
glVertex3f(p0Right.x, p0Right.y, p0Right.z ); glVertex3f(p0Right.x, p0Right.y, p0Right.z);
glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z );
glVertex3f(p0Right.x, p0Right.y, p0Right.z ); glVertex3f(p0Right.x, p0Right.y, p0Right.z);
glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z );
glVertex3f(ppRight.x, ppRight.y, ppRight.z ); glVertex3f(ppRight.x, ppRight.y, ppRight.z);
glVertex3f(p0Up.x, p0Up.y, p0Up.z ); glVertex3f(p0Up.x, p0Up.y, p0Up.z );
glVertex3f(p0Down.x, p0Down.y, p0Down.z ); glVertex3f(p0Down.x, p0Down.y, p0Down.z );
glVertex3f(ppDown.x, ppDown.y, ppDown.z ); glVertex3f(ppDown.x, ppDown.y, ppDown.z );
glVertex3f(p0Up.x, p0Up.y, p0Up.z ); glVertex3f(p0Up.x, p0Up.y, p0Up.z );
glVertex3f(ppUp.x, ppUp.y, ppUp.z ); glVertex3f(ppUp.x, ppUp.y, ppUp.z );
glVertex3f(ppDown.x, ppDown.y, ppDown.z ); glVertex3f(ppDown.x, ppDown.y, ppDown.z );
glVertex3f(p0Up.x, p0Up.y, p0Left.z ); glVertex3f(p0Up.x, p0Up.y, p0Left.z );
glVertex3f(p0Right.x, p0Right.y, p0Right.z ); glVertex3f(p0Right.x, p0Right.y, p0Right.z);
glVertex3f(p0Down.x, p0Down.y, p0Down.z ); glVertex3f(p0Down.x, p0Down.y, p0Down.z );
glVertex3f(p0Up.x, p0Up.y, p0Left.z ); glVertex3f(p0Up.x, p0Up.y, p0Left.z );
glVertex3f(p0Left.x, p0Left.y, p0Left.z ); glVertex3f(p0Left.x, p0Left.y, p0Left.z );
glVertex3f(p0Down.x, p0Down.y, p0Down.z ); glVertex3f(p0Down.x, p0Down.y, p0Down.z );
glVertex3f(ppUp.x, ppUp.y, ppLeft.z ); glVertex3f(ppUp.x, ppUp.y, ppLeft.z );
glVertex3f(ppRight.x, ppRight.y, ppRight.z ); glVertex3f(ppRight.x, ppRight.y, ppRight.z);
glVertex3f(ppDown.x, ppDown.y, ppDown.z ); glVertex3f(ppDown.x, ppDown.y, ppDown.z );
glVertex3f(ppUp.x, ppUp.y, ppLeft.z ); glVertex3f(ppUp.x, ppUp.y, ppLeft.z );
glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z );
glVertex3f(ppDown.x, ppDown.y, ppDown.z ); glVertex3f(ppDown.x, ppDown.y, ppDown.z );
glEnd(); glEnd();
} }

View file

@ -11,6 +11,8 @@
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
const int MAX_PARTICLES = 5000; const int MAX_PARTICLES = 5000;
const int NULL_EMITTER = -1;
const int NULL_PARTICLE = -1;
const int MAX_EMITTERS = 100; const int MAX_EMITTERS = 100;
enum ParticleRenderStyle enum ParticleRenderStyle

View file

@ -14,7 +14,7 @@
#include "Util.h" #include "Util.h"
#include "renderer/ProgramObject.h" #include "renderer/ProgramObject.h"
const bool SHOW_LEAP_HAND = true; const bool SHOW_LEAP_HAND = false;
using namespace std; using namespace std;
@ -22,18 +22,17 @@ Hand::Hand(Avatar* owningAvatar) :
HandData((AvatarData*)owningAvatar), HandData((AvatarData*)owningAvatar),
_raveGloveClock(0.0f), _raveGloveClock(0.0f),
_raveGloveMode(0), _raveGloveMode(RAVE_GLOVE_EFFECTS_MODE_0),
_raveGloveInitialized(false), _raveGloveInitialized(false),
_isRaveGloveActive(false),
_owningAvatar(owningAvatar), _owningAvatar(owningAvatar),
_renderAlpha(1.0), _renderAlpha(1.0),
_lookingInMirror(false), _lookingInMirror(false),
_isRaveGloveActive(false), _ballColor(0.0, 0.0, 0.4)
_ballColor(0.0, 0.0, 0.4)
{ {
// initialize all finger particle emitters with an invalid id as default // initialize all finger particle emitters with an invalid id as default
for (int f = 0; f< NUM_FINGERS; f ++ ) { for (int f = 0; f< NUM_FINGERS; f ++ ) {
_raveGloveEmitter[f] = -1; _raveGloveEmitter[f] = NULL_EMITTER;
} }
} }
@ -58,7 +57,7 @@ void Hand::simulate(float deltaTime, bool isMine) {
} }
void Hand::calculateGeometry() { void Hand::calculateGeometry() {
glm::vec3 offset(0.0, -0.2, -0.3); // place the hand in front of the face where we can see it glm::vec3 offset(0.2, -0.2, -0.3); // place the hand in front of the face where we can see it
Head& head = _owningAvatar->getHead(); Head& head = _owningAvatar->getHead();
_basePosition = head.getPosition() + head.getOrientation() * offset; _basePosition = head.getPosition() + head.getOrientation() * offset;
@ -256,7 +255,7 @@ void Hand::updateRaveGloveEmitters() {
for (size_t f = 0; f < palm.getNumFingers(); ++f) { for (size_t f = 0; f < palm.getNumFingers(); ++f) {
FingerData& finger = palm.getFingers()[f]; FingerData& finger = palm.getFingers()[f];
if (finger.isActive()) { if (finger.isActive()) {
if (_raveGloveEmitter[0] != -1) { if (_raveGloveEmitter[0] != NULL_EMITTER) {
glm::vec3 fingerDirection = finger.getTipPosition() - finger.getRootPosition(); glm::vec3 fingerDirection = finger.getTipPosition() - finger.getRootPosition();
float fingerLength = glm::length(fingerDirection); float fingerLength = glm::length(fingerDirection);
@ -269,6 +268,7 @@ void Hand::updateRaveGloveEmitters() {
assert(_raveGloveEmitter[fingerIndex] >=0 ); assert(_raveGloveEmitter[fingerIndex] >=0 );
assert(_raveGloveEmitter[fingerIndex] < NUM_FINGERS ); assert(_raveGloveEmitter[fingerIndex] < NUM_FINGERS );
_raveGloveParticleSystem.setEmitterPosition (_raveGloveEmitter[fingerIndex], finger.getTipPosition()); _raveGloveParticleSystem.setEmitterPosition (_raveGloveEmitter[fingerIndex], finger.getTipPosition());
_raveGloveParticleSystem.setEmitterDirection(_raveGloveEmitter[fingerIndex], fingerDirection); _raveGloveParticleSystem.setEmitterDirection(_raveGloveEmitter[fingerIndex], fingerDirection);
fingerIndex ++; fingerIndex ++;
@ -289,7 +289,7 @@ void Hand::updateRaveGloveParticles(float deltaTime) {
// start up the rave glove finger particles... // start up the rave glove finger particles...
for ( int f = 0; f< NUM_FINGERS; f ++ ) { for ( int f = 0; f< NUM_FINGERS; f ++ ) {
_raveGloveEmitter[f] = _raveGloveParticleSystem.addEmitter(); _raveGloveEmitter[f] = _raveGloveParticleSystem.addEmitter();
assert( _raveGloveEmitter[f] != -1 ); assert( _raveGloveEmitter[f] != NULL_EMITTER );
} }
setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_2); setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_2);
@ -299,13 +299,15 @@ void Hand::updateRaveGloveParticles(float deltaTime) {
_raveGloveClock += deltaTime; _raveGloveClock += deltaTime;
// this rave glove effect oscillates though various colors and radii that are meant to show off some effects
if (_raveGloveMode == RAVE_GLOVE_EFFECTS_MODE_0) { if (_raveGloveMode == RAVE_GLOVE_EFFECTS_MODE_0) {
ParticleSystem::ParticleAttributes attributes; ParticleSystem::ParticleAttributes attributes;
float red = 0.5f + 0.5f * sinf(_raveGloveClock * 1.4f); float red = 0.5f + 0.5f * sinf(_raveGloveClock * 1.4f);
float green = 0.5f + 0.5f * cosf(_raveGloveClock * 1.7f); float green = 0.5f + 0.5f * cosf(_raveGloveClock * 1.7f);
float blue = 0.5f + 0.5f * sinf(_raveGloveClock * 2.0f); float blue = 0.5f + 0.5f * sinf(_raveGloveClock * 2.0f);
float alpha = 1.0f;
attributes.color = glm::vec4(red, green, blue, 1.0f); attributes.color = glm::vec4(red, green, blue, alpha);
attributes.radius = 0.01f + 0.005f * sinf(_raveGloveClock * 2.2f); attributes.radius = 0.01f + 0.005f * sinf(_raveGloveClock * 2.2f);
attributes.modulationAmplitude = 0.0f; attributes.modulationAmplitude = 0.0f;