From 87d9aae328bafbc502bb82280c2c02690d1d72ad Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 19 Jul 2013 15:50:40 -0700 Subject: [PATCH 01/88] improvements to particle system --- interface/src/Application.cpp | 8 ++-- interface/src/Hand.cpp | 69 +++++++++++++++++++------------- interface/src/Hand.h | 1 + interface/src/ParticleSystem.cpp | 23 +++++++---- interface/src/ParticleSystem.h | 6 +-- 5 files changed, 66 insertions(+), 41 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8f14e8ed57..199a0a9763 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3510,9 +3510,10 @@ void Application::updateParticleSystem(float deltaTime) { _particleSystem.setShowingEmitter(_coolDemoParticleEmitter, true); glm::vec3 particleEmitterPosition = glm::vec3(5.0f, 1.0f, 5.0f); _particleSystem.setEmitterPosition(_coolDemoParticleEmitter, particleEmitterPosition); - glm::vec3 velocity(0.0f, 0.1f, 0.0f); + int num = 1500; + float thrust = 0.1f; float lifespan = 100000.0f; - _particleSystem.emitParticlesNow(_coolDemoParticleEmitter, 1500, velocity, lifespan); + _particleSystem.emitParticlesNow(_coolDemoParticleEmitter, num, thrust, lifespan); } // signal that the particle system has been initialized @@ -3532,7 +3533,8 @@ void Application::updateParticleSystem(float deltaTime) { 30.0f * cosf( t * 0.75f ) ); - _particleSystem.setEmitterRotation(_coolDemoParticleEmitter, glm::quat(glm::radians(tilt))); + //_particleSystem.setEmitterRotation(_coolDemoParticleEmitter, glm::quat(glm::radians(tilt))); + _particleSystem.setEmitterDirection(_coolDemoParticleEmitter, glm::vec3(0.0f, 1.0f, 0.0f)); ParticleSystem::ParticleAttributes attributes; diff --git a/interface/src/Hand.cpp b/interface/src/Hand.cpp index 69d8ddfaac..3f8b4d6a0f 100755 --- a/interface/src/Hand.cpp +++ b/interface/src/Hand.cpp @@ -14,6 +14,8 @@ #include "Util.h" #include "renderer/ProgramObject.h" +const bool SHOW_LEAP_HAND = true; + using namespace std; Hand::Hand(Avatar* owningAvatar) : @@ -83,6 +85,7 @@ void Hand::render(bool lookingInMirror) { _lookingInMirror = lookingInMirror; calculateGeometry(); + updateFingerParticleEmitters(); // do this right after calculateGeometry if (_isRaveGloveActive) { renderRaveGloveStage(); @@ -95,7 +98,9 @@ void Hand::render(bool lookingInMirror) { glEnable(GL_DEPTH_TEST); glEnable(GL_RESCALE_NORMAL); - renderHandSpheres(); + if ( SHOW_LEAP_HAND ) { + renderHandSpheres(); + } } void Hand::renderRaveGloveStage() { @@ -210,6 +215,38 @@ void Hand::setLeapHands(const std::vector& handPositions, } } +void Hand::updateFingerParticleEmitters() { + + if (_particleSystemInitialized) { + + 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[fingerIndex] != -1) { + + glm::vec3 fingerDirection = finger.getTipPosition() - finger.getRootPosition(); + float fingerLength = glm::length(fingerDirection); + + if (fingerLength > 0.0f) { + fingerDirection /= fingerLength; + } else { + fingerDirection = IDENTITY_UP; + } + + _particleSystem.setEmitterPosition (_fingerParticleEmitter[f], finger.getTipPosition()); + _particleSystem.setEmitterDirection(_fingerParticleEmitter[f], fingerDirection); + } + } + } + } + } + } +} + void Hand::updateFingerParticles(float deltaTime) { @@ -217,7 +254,7 @@ void Hand::updateFingerParticles(float deltaTime) { for ( int f = 0; f< NUM_FINGERS_PER_HAND; f ++ ) { - _particleSystem.setShowingEmitter(f, true ); + //_particleSystem.setShowingEmitter(f, true); _fingerParticleEmitter[f] = _particleSystem.addEmitter(); @@ -258,9 +295,6 @@ void Hand::updateFingerParticles(float deltaTime) { _particleSystemInitialized = true; } else { // update the particles - - static float t = 0.0f; - t += deltaTime; int fingerIndex = 0; for (size_t i = 0; i < getNumPalms(); ++i) { @@ -270,33 +304,14 @@ void Hand::updateFingerParticles(float deltaTime) { FingerData& finger = palm.getFingers()[f]; if (finger.isActive()) { if (_fingerParticleEmitter[fingerIndex] != -1) { - - glm::vec3 particleEmitterPosition = finger.getTipPosition(); - - glm::vec3 fingerDirection = particleEmitterPosition - leapPositionToWorldPosition(finger.getRootPosition()); - float fingerLength = glm::length(fingerDirection); - - if (fingerLength > 0.0f) { - fingerDirection /= fingerLength; - } else { - fingerDirection = IDENTITY_UP; - } - - glm::quat particleEmitterRotation = rotationBetween(palm.getNormal(), fingerDirection); - - //glm::quat particleEmitterRotation = glm::angleAxis(0.0f, fingerDirection); - - _particleSystem.setEmitterPosition(_fingerParticleEmitter[f], particleEmitterPosition); - _particleSystem.setEmitterRotation(_fingerParticleEmitter[f], particleEmitterRotation); - - const glm::vec3 velocity = fingerDirection * 0.002f; + const float thrust = 0.002; const float lifespan = 1.0f; - _particleSystem.emitParticlesNow(_fingerParticleEmitter[f], 1, velocity, lifespan); + _particleSystem.emitParticlesNow(_fingerParticleEmitter[f], 1, thrust, lifespan); } } } } - } + } _particleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); _particleSystem.simulate(deltaTime); diff --git a/interface/src/Hand.h b/interface/src/Hand.h index fb6b863458..2edbefd534 100755 --- a/interface/src/Hand.h +++ b/interface/src/Hand.h @@ -47,6 +47,7 @@ public: void setLeapHands (const std::vector& handPositions, const std::vector& handNormals); void updateFingerParticles(float deltaTime); + void updateFingerParticleEmitters(); void setRaveGloveActive(bool active) { _isRaveGloveActive = active; } diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 9dcdbe5f06..2115dd42b9 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -22,9 +22,9 @@ ParticleSystem::ParticleSystem() { _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default 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].position = glm::vec3(0.0f, 0.0f, 0.0f); + _emitter[emitterIndex].direction = glm::vec3(0.0f, 1.0f, 0.0f); + _emitter[emitterIndex].visible = false; _emitter[emitterIndex].baseParticle.alive = false; _emitter[emitterIndex].baseParticle.age = 0.0f; _emitter[emitterIndex].baseParticle.lifespan = 0.0f; @@ -90,10 +90,10 @@ void ParticleSystem::simulate(float deltaTime) { } } -void ParticleSystem::emitParticlesNow(int e, int num, glm::vec3 velocity, float lifespan) { +void ParticleSystem::emitParticlesNow(int e, int num, float thrust, float lifespan) { for (unsigned int p = 0; p < num; p++) { - createParticle(e, velocity, lifespan); + createParticle(e, _emitter[e].direction * thrust, lifespan); } } @@ -212,9 +212,9 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { // apply tornado force - glm::vec3 emitterUp = myEmitter.rotation * IDENTITY_UP; + //glm::vec3 emitterUp = myEmitter.rotation * IDENTITY_UP; - glm::vec3 tornadoDirection = glm::cross(vectorToHome, emitterUp); + glm::vec3 tornadoDirection = glm::cross(vectorToHome, myEmitter.direction); _particle[p].velocity += tornadoDirection * myEmitter.particleAttributes[lifeStage].tornadoForce * deltaTime; // apply air friction @@ -351,12 +351,19 @@ void ParticleSystem::renderParticle(int p) { void ParticleSystem::renderEmitter(int e, float 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; + */ + glm::vec3 f = _emitter[e].direction; + //glm::vec3 r = glm::vec3(_emitter[e].direction.y, _emitter[e].direction.z, _emitter[e].direction.x); + //glm::vec3 u = glm::vec3(_emitter[e].direction.z, _emitter[e].direction.x, _emitter[e].direction.y); + glLineWidth(2.0f); +/* glColor3f(0.8f, 0.4, 0.4); glBegin(GL_LINES); glVertex3f(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); @@ -368,7 +375,7 @@ void ParticleSystem::renderEmitter(int e, float size) { glVertex3f(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); glVertex3f(_emitter[e].position.x + u.x, _emitter[e].position.y + u.y, _emitter[e].position.z + u.z); glEnd(); - +*/ glColor3f(0.4f, 0.4, 0.8); glBegin(GL_LINES); glVertex3f(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index 764800f23e..03ed9cbe90 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -38,7 +38,7 @@ public: ParticleSystem(); int addEmitter(); // add (create new) emitter and get its unique id - void emitParticlesNow(int emitterIndex, int numParticles, glm::vec3 velocity, float lifespan); + void emitParticlesNow(int emitterIndex, int numParticles, float thrust, float lifespan); void simulate(float deltaTime); void render(); @@ -48,7 +48,7 @@ public: 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 setEmitterDirection (int emitterIndex, glm::vec3 direction) { _emitter[emitterIndex].direction = direction; } // set directional axis (normal) void setShowingEmitter (int emitterIndex, bool showing ) { _emitter[emitterIndex].visible = showing; } // set its visibiity private: @@ -66,7 +66,7 @@ private: struct Emitter { glm::vec3 position; - glm::quat rotation; + glm::vec3 direction; 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 From 7f3750f1f0039f9331a090aae57d9cb21e9c444c Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 19 Jul 2013 16:08:19 -0700 Subject: [PATCH 02/88] clean up --- interface/src/Application.cpp | 8 -------- interface/src/Hand.cpp | 2 -- interface/src/ParticleSystem.cpp | 4 ---- 3 files changed, 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 50218fc94b..9b8fb2be93 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3556,14 +3556,6 @@ void Application::updateParticleSystem(float deltaTime) { if (_coolDemoParticleEmitter != -1) { - glm::vec3 tilt = glm::vec3 - ( - 30.0f * sinf( t * 0.55f ), - 0.0f, - 30.0f * cosf( t * 0.75f ) - ); - - //_particleSystem.setEmitterRotation(_coolDemoParticleEmitter, glm::quat(glm::radians(tilt))); _particleSystem.setEmitterDirection(_coolDemoParticleEmitter, glm::vec3(0.0f, 1.0f, 0.0f)); ParticleSystem::ParticleAttributes attributes; diff --git a/interface/src/Hand.cpp b/interface/src/Hand.cpp index 3f8b4d6a0f..b896ffcd0e 100755 --- a/interface/src/Hand.cpp +++ b/interface/src/Hand.cpp @@ -254,8 +254,6 @@ void Hand::updateFingerParticles(float deltaTime) { for ( int f = 0; f< NUM_FINGERS_PER_HAND; f ++ ) { - //_particleSystem.setShowingEmitter(f, true); - _fingerParticleEmitter[f] = _particleSystem.addEmitter(); assert( _fingerParticleEmitter[f] != -1 ); diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 2115dd42b9..efc57c2e18 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -210,10 +210,6 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { } // apply tornado force - - - //glm::vec3 emitterUp = myEmitter.rotation * IDENTITY_UP; - glm::vec3 tornadoDirection = glm::cross(vectorToHome, myEmitter.direction); _particle[p].velocity += tornadoDirection * myEmitter.particleAttributes[lifeStage].tornadoForce * deltaTime; From ed2780062b72cb496c341ec5834ec13c07acf727 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 19 Jul 2013 16:23:02 -0700 Subject: [PATCH 03/88] clean up --- interface/src/ParticleSystem.cpp | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index efc57c2e18..c1f14fad63 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -22,6 +22,7 @@ ParticleSystem::ParticleSystem() { _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default for (unsigned int emitterIndex = 0; emitterIndex < MAX_EMITTERS; emitterIndex++) { + _emitter[emitterIndex].position = glm::vec3(0.0f, 0.0f, 0.0f); _emitter[emitterIndex].direction = glm::vec3(0.0f, 1.0f, 0.0f); _emitter[emitterIndex].visible = false; @@ -346,36 +347,12 @@ void ParticleSystem::renderParticle(int p) { void ParticleSystem::renderEmitter(int e, float 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; - */ - glm::vec3 f = _emitter[e].direction; - //glm::vec3 r = glm::vec3(_emitter[e].direction.y, _emitter[e].direction.z, _emitter[e].direction.x); - //glm::vec3 u = glm::vec3(_emitter[e].direction.z, _emitter[e].direction.x, _emitter[e].direction.y); - glLineWidth(2.0f); - -/* - glColor3f(0.8f, 0.4, 0.4); - glBegin(GL_LINES); - glVertex3f(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); - glVertex3f(_emitter[e].position.x + r.x, _emitter[e].position.y + r.y, _emitter[e].position.z + r.z); - glEnd(); - - glColor3f(0.4f, 0.8, 0.4); - glBegin(GL_LINES); - glVertex3f(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); - glVertex3f(_emitter[e].position.x + u.x, _emitter[e].position.y + u.y, _emitter[e].position.z + u.z); - glEnd(); -*/ glColor3f(0.4f, 0.4, 0.8); glBegin(GL_LINES); glVertex3f(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); - glVertex3f(_emitter[e].position.x + f.x, _emitter[e].position.y + f.y, _emitter[e].position.z + f.z); + glVertex3f(_emitter[e].position.x + _emitter[e].direction.x, _emitter[e].position.y + _emitter[e].direction.y, _emitter[e].position.z + _emitter[e].direction.z); glEnd(); } From 05039b4e3ebe11be196baf6c29344bc9528dc25c Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 19 Jul 2013 18:02:48 -0700 Subject: [PATCH 04/88] adding rave glove modes and changing API of particle system to accommodate --- interface/src/Application.cpp | 6 +- interface/src/ParticleSystem.cpp | 20 ++-- interface/src/ParticleSystem.h | 28 +++-- interface/src/avatar/Hand.cpp | 200 +++++++++++++++++++++++++------ interface/src/avatar/Hand.h | 18 +-- 5 files changed, 205 insertions(+), 67 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0490c93246..160fb4b946 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3587,10 +3587,12 @@ void Application::updateParticleSystem(float deltaTime) { _particleSystem.setShowingEmitter(_coolDemoParticleEmitter, true); glm::vec3 particleEmitterPosition = glm::vec3(5.0f, 1.0f, 5.0f); _particleSystem.setEmitterPosition(_coolDemoParticleEmitter, particleEmitterPosition); + + _particleSystem.setEmitterParticleLifespan(_coolDemoParticleEmitter, 100000.0f); + int num = 1500; float thrust = 0.1f; - float lifespan = 100000.0f; - _particleSystem.emitParticlesNow(_coolDemoParticleEmitter, num, thrust, lifespan); + _particleSystem.emitParticlesNow(_coolDemoParticleEmitter, num, thrust); } // signal that the particle system has been initialized diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index c1f14fad63..ad992cbf42 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -14,6 +14,7 @@ const float DEFAULT_PARTICLE_RADIUS = 0.01f; const float DEFAULT_PARTICLE_BOUNCE = 1.0f; const float DEFAULT_PARTICLE_AIR_FRICTION = 2.0f; +const float DEFAULT_PARTICLE_LIFESPAN = 1.0f; ParticleSystem::ParticleSystem() { @@ -26,6 +27,7 @@ ParticleSystem::ParticleSystem() { _emitter[emitterIndex].position = glm::vec3(0.0f, 0.0f, 0.0f); _emitter[emitterIndex].direction = glm::vec3(0.0f, 1.0f, 0.0f); _emitter[emitterIndex].visible = false; + _emitter[emitterIndex].particleLifespan = DEFAULT_PARTICLE_LIFESPAN; _emitter[emitterIndex].baseParticle.alive = false; _emitter[emitterIndex].baseParticle.age = 0.0f; _emitter[emitterIndex].baseParticle.lifespan = 0.0f; @@ -91,23 +93,23 @@ void ParticleSystem::simulate(float deltaTime) { } } -void ParticleSystem::emitParticlesNow(int e, int num, float thrust, float lifespan) { +void ParticleSystem::emitParticlesNow(int e, int num, float thrust) { for (unsigned int p = 0; p < num; p++) { - createParticle(e, _emitter[e].direction * thrust, lifespan); + createParticle(e, _emitter[e].direction * thrust); } } -void ParticleSystem::createParticle(int e, glm::vec3 velocity, float lifespan) { +void ParticleSystem::createParticle(int e, glm::vec3 velocity) { for (unsigned int p = 0; p < MAX_PARTICLES; p++) { if (!_particle[p].alive) { _particle[p].emitterIndex = e; - _particle[p].lifespan = lifespan; _particle[p].alive = true; _particle[p].age = 0.0f; _particle[p].velocity = velocity; + _particle[p].lifespan = _emitter[e].particleLifespan; _particle[p].position = _emitter[e].position; _particle[p].radius = _emitter[e].particleAttributes[0].radius; _particle[p].color = _emitter[e].particleAttributes[0].color; @@ -261,15 +263,15 @@ void ParticleSystem::setEmitterBaseParticle(int emitterIndex, bool showing ) { _emitter[emitterIndex].baseParticle.emitterIndex = emitterIndex; } -void ParticleSystem::setEmitterBaseParticle(int emitterIndex, bool showing, float radius, glm::vec4 color ) { +void ParticleSystem::killAllParticles() { - _emitter[emitterIndex].baseParticle.alive = true; - _emitter[emitterIndex].baseParticle.emitterIndex = emitterIndex; - _emitter[emitterIndex].baseParticle.radius = radius; - _emitter[emitterIndex].baseParticle.color = color; + for (unsigned int p = 0; p < _numParticles; p++) { + killParticle(p); + } } + void ParticleSystem::render() { // render the emitters diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index 03ed9cbe90..c58c698b8e 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -11,10 +11,10 @@ #include const int MAX_PARTICLES = 5000; -const int MAX_EMITTERS = 20; +const int MAX_EMITTERS = 20; const int NUM_PARTICLE_LIFE_STAGES = 4; const bool USE_BILLBOARD_RENDERING = false; -const bool SHOW_VELOCITY_TAILS = false; +const bool SHOW_VELOCITY_TAILS = false; class ParticleSystem { public: @@ -38,18 +38,21 @@ public: ParticleSystem(); int addEmitter(); // add (create new) emitter and get its unique id - void emitParticlesNow(int emitterIndex, int numParticles, float thrust, float lifespan); + void emitParticlesNow(int emitterIndex, int numParticles, float thrust); void simulate(float deltaTime); + void killAllParticles(); 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 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 setEmitterDirection (int emitterIndex, glm::vec3 direction) { _emitter[emitterIndex].direction = direction; } // set directional axis (normal) - void setShowingEmitter (int emitterIndex, bool showing ) { _emitter[emitterIndex].visible = showing; } // set its visibiity + void setEmitterBaseParticle (int emitterIndex, bool showing ); + void setParticleAttributes (int emitterIndex, ParticleAttributes attributes); // set attributes for whole life of particles + void setParticleAttributes (int emitterIndex, int lifeStage, ParticleAttributes attributes); // set attributes for this life stage of particles + void setEmitterBaseParticleColor (int emitterIndex, glm::vec4 color ) {_emitter[emitterIndex].baseParticle.color = color; } + void setEmitterBaseParticleRadius(int emitterIndex, float radius ) {_emitter[emitterIndex].baseParticle.radius = radius; } + void setEmitterPosition (int emitterIndex, glm::vec3 position ) {_emitter[emitterIndex].position = position; } + void setEmitterDirection (int emitterIndex, glm::vec3 direction) {_emitter[emitterIndex].direction = direction; } + void setShowingEmitter (int emitterIndex, bool showing ) {_emitter[emitterIndex].visible = showing; } + void setEmitterParticleLifespan (int emitterIndex, float lifespan ) {_emitter[emitterIndex].particleLifespan = lifespan; } private: @@ -68,6 +71,7 @@ private: glm::vec3 position; glm::vec3 direction; bool visible; + float particleLifespan; Particle baseParticle; // a non-physical particle at the emitter position ParticleAttributes particleAttributes[NUM_PARTICLE_LIFE_STAGES]; // the attributes of particles emitted from this emitter }; @@ -80,7 +84,7 @@ private: // private methods void updateParticle(int index, float deltaTime); - void createParticle(int e, glm::vec3 velocity, float lifespan); + void createParticle(int e, glm::vec3 velocity); void killParticle(int p); void renderEmitter(int emitterIndex, float size); void renderParticle(int p); diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index b896ffcd0e..929e4848f9 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -20,12 +20,17 @@ using namespace std; Hand::Hand(Avatar* owningAvatar) : HandData((AvatarData*)owningAvatar), + + _testRaveGloveClock(0.0f), + _testRaveGloveMode(0), + _particleSystemInitialized(false), _owningAvatar(owningAvatar), _renderAlpha(1.0), _lookingInMirror(false), - _ballColor(0.0, 0.0, 0.4), - _particleSystemInitialized(false) -{ + _isRaveGloveActive(false), + _ballColor(0.0, 0.0, 0.4) + + { // initialize all finger particle emitters with an invalid id as default for (int f = 0; f< NUM_FINGERS_PER_HAND; f ++ ) { _fingerParticleEmitter[f] = -1; @@ -251,16 +256,65 @@ void Hand::updateFingerParticleEmitters() { void Hand::updateFingerParticles(float deltaTime) { if (!_particleSystemInitialized) { - + for ( int f = 0; f< NUM_FINGERS_PER_HAND; f ++ ) { - _fingerParticleEmitter[f] = _particleSystem.addEmitter(); - assert( _fingerParticleEmitter[f] != -1 ); - - ParticleSystem::ParticleAttributes attributes; + } + + setRaveGloveMode(_testRaveGloveMode); + _particleSystemInitialized = true; + } else { + // update the particles + + _testRaveGloveClock += deltaTime; + + if (_testRaveGloveClock > 4) { + _testRaveGloveClock = 0.0f; + _testRaveGloveMode ++; + if (_testRaveGloveMode > 4) { + _testRaveGloveMode = 0; + } + setRaveGloveMode(_testRaveGloveMode); + } + + 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[fingerIndex] != -1) { + const float thrust = 0.002; + _particleSystem.emitParticlesNow(_fingerParticleEmitter[f], 10, thrust); + } + } + } + } + } + + _particleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); + _particleSystem.simulate(deltaTime); + } +} + + +void Hand::setRaveGloveMode(int mode) { + + _particleSystem.killAllParticles(); + + for ( int f = 0; f< NUM_FINGERS_PER_HAND; f ++ ) { + + ParticleSystem::ParticleAttributes attributes; + + //----------------------------------------- + // Fire! + //----------------------------------------- + if (mode == 0) { + + _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 1.0f); - // set attributes for each life stage of the particle: attributes.radius = 0.0f; attributes.color = glm::vec4( 1.0f, 1.0f, 0.5f, 0.5f); attributes.gravity = 0.0f; @@ -282,39 +336,113 @@ void Hand::updateFingerParticles(float deltaTime) { attributes.radius = 0.01f; attributes.gravity = 0.0f; - attributes.color = glm::vec4( 0.0f, 0.0f, 0.0f, 0.2f); + attributes.color = glm::vec4( 0.4f, 0.4f, 0.4f, 0.2f); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); attributes.radius = 0.02f; - attributes.color = glm::vec4( 0.0f, 0.0f, 0.0f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + attributes.color = glm::vec4( 0.4f, 0.6f, 0.9f, 0.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + + + + //----------------------------------------- + // water + //----------------------------------------- + } else if (mode == 1) { + + _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 1.0f); + + attributes.radius = 0.001f; + attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.5f); + attributes.gravity = -0.005f; + attributes.airFriction = 0.0f; + attributes.jitter = 0.002f; + attributes.emitterAttraction = 0.0f; + attributes.tornadoForce = 0.0f; + attributes.neighborAttraction = 0.0f; + attributes.neighborRepulsion = 0.0f; + attributes.bounce = 1.0f; + attributes.usingCollisionSphere = false; + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + + attributes.gravity = 0.005f; + attributes.jitter = 0.0f; + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + + attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.2f); + attributes.radius = 0.002f; + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + + attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + + //----------------------------------------- + // flashy + //----------------------------------------- + } else if (mode == 2) { + + _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 0.05f); + + attributes.radius = 0.0f; + attributes.color = glm::vec4( 1.0f, 0.0f, 0.0f, 1.0f); + attributes.gravity = 0.0f; + attributes.airFriction = 0.0f; + attributes.jitter = 0.1f; + attributes.emitterAttraction = 0.0f; + attributes.tornadoForce = 0.0f; + attributes.neighborAttraction = 0.0f; + attributes.neighborRepulsion = 0.0f; + attributes.bounce = 1.0f; + attributes.usingCollisionSphere = false; + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + + attributes.radius = 0.01f; + attributes.color = glm::vec4( 1.0f, 1.0f, 0.0f, 1.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + + attributes.radius = 0.01f; + attributes.color = glm::vec4( 0.0f, 0.0f, 1.0f, 1.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + + attributes.radius = 0.0f; + attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + + //----------------------------------------- + // something + //----------------------------------------- + } else if (mode == 3) { + + _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 0.05f); + + attributes.radius = 0.0f; + attributes.color = glm::vec4( 1.0f, 0.0f, 0.0f, 1.0f); + attributes.gravity = 0.0f; + 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 = 1.0f; + attributes.usingCollisionSphere = false; + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + + attributes.radius = 0.01f; + attributes.color = glm::vec4( 1.0f, 1.0f, 0.0f, 1.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + + attributes.radius = 0.01f; + attributes.color = glm::vec4( 0.0f, 0.0f, 1.0f, 1.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + + attributes.radius = 0.0f; + attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); } - - _particleSystemInitialized = true; - } else { - // 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[fingerIndex] != -1) { - const float thrust = 0.002; - const float lifespan = 1.0f; - _particleSystem.emitParticlesNow(_fingerParticleEmitter[f], 1, thrust, lifespan); - } - } - } - } - } - - _particleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); - _particleSystem.simulate(deltaTime); } } + diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index 2edbefd534..69f3a6e3de 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -61,19 +61,21 @@ private: Hand& operator= (const Hand&); ParticleSystem _particleSystem; - - Avatar* _owningAvatar; - float _renderAlpha; - bool _lookingInMirror; - bool _isRaveGloveActive; - glm::vec3 _ballColor; + float _testRaveGloveClock; + int _testRaveGloveMode; + bool _particleSystemInitialized; + int _fingerParticleEmitter[NUM_FINGERS_PER_HAND]; + Avatar* _owningAvatar; + float _renderAlpha; + bool _lookingInMirror; + bool _isRaveGloveActive; + glm::vec3 _ballColor; std::vector _leapBalls; - bool _particleSystemInitialized; - int _fingerParticleEmitter[NUM_FINGERS_PER_HAND]; // private methods void renderRaveGloveStage(); + void setRaveGloveMode(int mode); void renderHandSpheres(); void calculateGeometry(); }; From ad0ca748bbf8eabf6b4439867e32aee60036567e Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Sat, 20 Jul 2013 09:48:55 -0700 Subject: [PATCH 05/88] added extra mode and improved particle system --- interface/src/Application.cpp | 6 ++-- interface/src/ParticleSystem.cpp | 26 ++++++--------- interface/src/ParticleSystem.h | 25 +++++++------- interface/src/avatar/Hand.cpp | 56 ++++++++++++++++++++------------ 4 files changed, 63 insertions(+), 50 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 160fb4b946..d71d26b785 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3589,10 +3589,10 @@ void Application::updateParticleSystem(float deltaTime) { _particleSystem.setEmitterPosition(_coolDemoParticleEmitter, particleEmitterPosition); _particleSystem.setEmitterParticleLifespan(_coolDemoParticleEmitter, 100000.0f); + _particleSystem.setEmitterThrust(_coolDemoParticleEmitter, 0.0f); + _particleSystem.setEmitterRate(_coolDemoParticleEmitter, 1500); - int num = 1500; - float thrust = 0.1f; - _particleSystem.emitParticlesNow(_coolDemoParticleEmitter, num, thrust); + _particleSystem.emitNow(_coolDemoParticleEmitter); } // signal that the particle system has been initialized diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index ad992cbf42..2d23eae1d8 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -30,7 +30,8 @@ ParticleSystem::ParticleSystem() { _emitter[emitterIndex].particleLifespan = DEFAULT_PARTICLE_LIFESPAN; _emitter[emitterIndex].baseParticle.alive = false; _emitter[emitterIndex].baseParticle.age = 0.0f; - _emitter[emitterIndex].baseParticle.lifespan = 0.0f; + _emitter[emitterIndex].thrust = 0.0f; + _emitter[emitterIndex].rate = 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); @@ -59,7 +60,6 @@ ParticleSystem::ParticleSystem() { for (unsigned int p = 0; p < MAX_PARTICLES; p++) { _particle[p].alive = false; _particle[p].age = 0.0f; - _particle[p].lifespan = 0.0f; _particle[p].radius = 0.0f; _particle[p].emitterIndex = 0; _particle[p].position = glm::vec3(0.0f, 0.0f, 0.0f); @@ -84,7 +84,7 @@ void ParticleSystem::simulate(float deltaTime) { // update particles for (unsigned int p = 0; p < _numParticles; p++) { if (_particle[p].alive) { - if (_particle[p].age > _particle[p].lifespan) { + if (_particle[p].age > _emitter[_particle[p].emitterIndex].particleLifespan) { killParticle(p); } else { updateParticle(p, deltaTime); @@ -93,10 +93,10 @@ void ParticleSystem::simulate(float deltaTime) { } } -void ParticleSystem::emitParticlesNow(int e, int num, float thrust) { +void ParticleSystem::emitNow(int e) { - for (unsigned int p = 0; p < num; p++) { - createParticle(e, _emitter[e].direction * thrust); + for (unsigned int p = 0; p < _emitter[e].rate; p++) { + createParticle(e, _emitter[e].direction); } } @@ -108,8 +108,7 @@ void ParticleSystem::createParticle(int e, glm::vec3 velocity) { _particle[p].emitterIndex = e; _particle[p].alive = true; _particle[p].age = 0.0f; - _particle[p].velocity = velocity; - _particle[p].lifespan = _emitter[e].particleLifespan; + _particle[p].velocity = _emitter[e].direction * _emitter[e].thrust; _particle[p].position = _emitter[e].position; _particle[p].radius = _emitter[e].particleAttributes[0].radius; _particle[p].color = _emitter[e].particleAttributes[0].color; @@ -163,9 +162,9 @@ void ParticleSystem::setParticleAttributes(int emitterIndex, int lifeStage, Part void ParticleSystem::updateParticle(int p, float deltaTime) { - assert(_particle[p].age <= _particle[p].lifespan); + assert(_particle[p].age <= _emitter[_particle[p].emitterIndex].particleLifespan); - float ageFraction = _particle[p].age / _particle[p].lifespan; + float ageFraction = _particle[p].age / _emitter[_particle[p].emitterIndex].particleLifespan; int lifeStage = (int)( ageFraction * (NUM_PARTICLE_LIFE_STAGES-1) ); @@ -257,7 +256,7 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { _particle[p].age += deltaTime; } -void ParticleSystem::setEmitterBaseParticle(int emitterIndex, bool showing ) { +void ParticleSystem::setShowingEmitterBaseParticle(int emitterIndex, bool showing ) { _emitter[emitterIndex].baseParticle.alive = true; _emitter[emitterIndex].baseParticle.emitterIndex = emitterIndex; @@ -271,7 +270,6 @@ void ParticleSystem::killAllParticles() { } - void ParticleSystem::render() { // render the emitters @@ -346,8 +344,6 @@ void ParticleSystem::renderParticle(int p) { } } - - void ParticleSystem::renderEmitter(int e, float size) { glLineWidth(2.0f); @@ -362,5 +358,3 @@ void ParticleSystem::renderEmitter(int e, float size) { - - diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index c58c698b8e..c5ffd95aa4 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -38,21 +38,23 @@ public: ParticleSystem(); int addEmitter(); // add (create new) emitter and get its unique id - void emitParticlesNow(int emitterIndex, int numParticles, float thrust); + void emitNow(int emitterIndex); void simulate(float deltaTime); void killAllParticles(); void render(); void setUpDirection(glm::vec3 upDirection) {_upDirection = upDirection;} // tell particle system which direction is up - void setEmitterBaseParticle (int emitterIndex, bool showing ); - void setParticleAttributes (int emitterIndex, ParticleAttributes attributes); // set attributes for whole life of particles - void setParticleAttributes (int emitterIndex, int lifeStage, ParticleAttributes attributes); // set attributes for this life stage of particles - void setEmitterBaseParticleColor (int emitterIndex, glm::vec4 color ) {_emitter[emitterIndex].baseParticle.color = color; } - void setEmitterBaseParticleRadius(int emitterIndex, float radius ) {_emitter[emitterIndex].baseParticle.radius = radius; } - void setEmitterPosition (int emitterIndex, glm::vec3 position ) {_emitter[emitterIndex].position = position; } - void setEmitterDirection (int emitterIndex, glm::vec3 direction) {_emitter[emitterIndex].direction = direction; } - void setShowingEmitter (int emitterIndex, bool showing ) {_emitter[emitterIndex].visible = showing; } - void setEmitterParticleLifespan (int emitterIndex, float lifespan ) {_emitter[emitterIndex].particleLifespan = lifespan; } + void setShowingEmitterBaseParticle(int emitterIndex, bool showing ); + void setParticleAttributes (int emitterIndex, ParticleAttributes attributes); // set attributes for whole life of particles + void setParticleAttributes (int emitterIndex, int lifeStage, ParticleAttributes attributes); // set attributes for this life stage of particles + void setEmitterBaseParticleColor (int emitterIndex, glm::vec4 color ) {_emitter[emitterIndex].baseParticle.color = color; } + void setEmitterBaseParticleRadius (int emitterIndex, float radius ) {_emitter[emitterIndex].baseParticle.radius = radius; } + void setEmitterPosition (int emitterIndex, glm::vec3 position ) {_emitter[emitterIndex].position = position; } + void setEmitterDirection (int emitterIndex, glm::vec3 direction) {_emitter[emitterIndex].direction = direction; } + void setShowingEmitter (int emitterIndex, bool showing ) {_emitter[emitterIndex].visible = showing; } + void setEmitterParticleLifespan (int emitterIndex, float lifespan ) {_emitter[emitterIndex].particleLifespan = lifespan; } + void setEmitterThrust (int emitterIndex, float thrust ) {_emitter[emitterIndex].thrust = thrust; } + void setEmitterRate (int emitterIndex, float rate ) {_emitter[emitterIndex].rate = rate; } private: @@ -63,7 +65,6 @@ private: 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? }; @@ -72,6 +73,8 @@ private: glm::vec3 direction; bool visible; float particleLifespan; + float thrust; + float rate; Particle baseParticle; // a non-physical particle at the emitter position ParticleAttributes particleAttributes[NUM_PARTICLE_LIFE_STAGES]; // the attributes of particles emitted from this emitter }; diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 929e4848f9..32d5482c30 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -220,6 +220,7 @@ void Hand::setLeapHands(const std::vector& handPositions, } } +// call this right after the geometry of the leap hands are set void Hand::updateFingerParticleEmitters() { if (_particleSystemInitialized) { @@ -253,22 +254,25 @@ void Hand::updateFingerParticleEmitters() { } + +// call this from within the simulate method void Hand::updateFingerParticles(float deltaTime) { if (!_particleSystemInitialized) { + // start up the rave glove finger particles... for ( int f = 0; f< NUM_FINGERS_PER_HAND; f ++ ) { _fingerParticleEmitter[f] = _particleSystem.addEmitter(); assert( _fingerParticleEmitter[f] != -1 ); } setRaveGloveMode(_testRaveGloveMode); + _particleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); _particleSystemInitialized = true; - } else { - // update the particles - + } else { _testRaveGloveClock += deltaTime; + // cycle through the rave glove test modes... if (_testRaveGloveClock > 4) { _testRaveGloveClock = 0.0f; _testRaveGloveMode ++; @@ -278,6 +282,23 @@ void Hand::updateFingerParticles(float deltaTime) { setRaveGloveMode(_testRaveGloveMode); } + if (_testRaveGloveMode == 3) { + ParticleSystem::ParticleAttributes attributes; + float red = 0.5f + 0.5f * sinf(_testRaveGloveClock * 1.4f); + float green = 0.5f + 0.5f * cosf(_testRaveGloveClock * 1.7f); + float blue = 0.5f + 0.5f * sinf(_testRaveGloveClock * 2.0f); + + attributes.color = glm::vec4(red, green, blue, 1.0f); + attributes.radius = 0.02f; + for ( int f = 0; f< NUM_FINGERS_PER_HAND; 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]; @@ -286,20 +307,17 @@ void Hand::updateFingerParticles(float deltaTime) { FingerData& finger = palm.getFingers()[f]; if (finger.isActive()) { if (_fingerParticleEmitter[fingerIndex] != -1) { - const float thrust = 0.002; - _particleSystem.emitParticlesNow(_fingerParticleEmitter[f], 10, thrust); + _particleSystem.emitNow(_fingerParticleEmitter[f]); } } } } } - - _particleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); + _particleSystem.simulate(deltaTime); } } - void Hand::setRaveGloveMode(int mode) { _particleSystem.killAllParticles(); @@ -314,6 +332,8 @@ void Hand::setRaveGloveMode(int mode) { if (mode == 0) { _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 1.0f); + _particleSystem.setEmitterThrust(_fingerParticleEmitter[f], 0.002f); + _particleSystem.setEmitterRate(_fingerParticleEmitter[f], 1.0); attributes.radius = 0.0f; attributes.color = glm::vec4( 1.0f, 1.0f, 0.5f, 0.5f); @@ -351,6 +371,8 @@ void Hand::setRaveGloveMode(int mode) { } else if (mode == 1) { _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 1.0f); + _particleSystem.setEmitterThrust(_fingerParticleEmitter[f], 0.002f); + _particleSystem.setEmitterRate(_fingerParticleEmitter[f], 10.0); attributes.radius = 0.001f; attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.5f); @@ -382,6 +404,8 @@ void Hand::setRaveGloveMode(int mode) { } else if (mode == 2) { _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 0.05f); + _particleSystem.setEmitterThrust(_fingerParticleEmitter[f], 0.002f); + _particleSystem.setEmitterRate(_fingerParticleEmitter[f], 1.0); attributes.radius = 0.0f; attributes.color = glm::vec4( 1.0f, 0.0f, 0.0f, 1.0f); @@ -409,13 +433,14 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); //----------------------------------------- - // something + // color cycle //----------------------------------------- } else if (mode == 3) { _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 0.05f); + _particleSystem.setEmitterThrust(_fingerParticleEmitter[f], 0.002f); - attributes.radius = 0.0f; + attributes.radius = 0.02f; attributes.color = glm::vec4( 1.0f, 0.0f, 0.0f, 1.0f); attributes.gravity = 0.0f; attributes.airFriction = 0.0f; @@ -424,20 +449,11 @@ void Hand::setRaveGloveMode(int mode) { attributes.tornadoForce = 0.0f; attributes.neighborAttraction = 0.0f; attributes.neighborRepulsion = 0.0f; - attributes.bounce = 1.0f; + attributes.bounce = 0.0f; attributes.usingCollisionSphere = false; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); - - attributes.radius = 0.01f; - attributes.color = glm::vec4( 1.0f, 1.0f, 0.0f, 1.0f); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); - - attributes.radius = 0.01f; - attributes.color = glm::vec4( 0.0f, 0.0f, 1.0f, 1.0f); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); - - attributes.radius = 0.0f; - attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); } } From 76952a9d13508441c6064d6401384e5e40556eff Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 21 Jul 2013 16:24:23 -0700 Subject: [PATCH 06/88] testing --- libraries/shared/src/PacketHeaders.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index 041303f2b5..00c19e657a 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -34,6 +34,8 @@ const PACKET_TYPE PACKET_TYPE_ENVIRONMENT_DATA = 'e'; const PACKET_TYPE PACKET_TYPE_DOMAIN_LIST_REQUEST = 'L'; const PACKET_TYPE PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY = 'C'; +// this is a test... + typedef char PACKET_VERSION; PACKET_VERSION versionForPacketType(PACKET_TYPE type); From 13e6f2e6fa9a5a10266806a1fef7300c74cd71a7 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 22 Jul 2013 10:31:23 -0700 Subject: [PATCH 07/88] added sphere resolution to emitter attributes --- interface/src/ParticleSystem.cpp | 14 ++++--- interface/src/ParticleSystem.h | 67 +++++++++++++++++--------------- interface/src/avatar/Hand.cpp | 27 +++++++------ 3 files changed, 59 insertions(+), 49 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 2d23eae1d8..40c493dcbd 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -11,10 +11,11 @@ #include "ParticleSystem.h" #include "Application.h" -const float DEFAULT_PARTICLE_RADIUS = 0.01f; -const float DEFAULT_PARTICLE_BOUNCE = 1.0f; -const float DEFAULT_PARTICLE_AIR_FRICTION = 2.0f; -const float DEFAULT_PARTICLE_LIFESPAN = 1.0f; +const float DEFAULT_PARTICLE_RADIUS = 0.01f; +const float DEFAULT_PARTICLE_BOUNCE = 1.0f; +const float DEFAULT_PARTICLE_AIR_FRICTION = 2.0f; +const float DEFAULT_PARTICLE_LIFESPAN = 1.0f; +const int DEFAULT_PARTICLE_SPHERE_RESOLUTION = 6; ParticleSystem::ParticleSystem() { @@ -27,6 +28,7 @@ ParticleSystem::ParticleSystem() { _emitter[emitterIndex].position = glm::vec3(0.0f, 0.0f, 0.0f); _emitter[emitterIndex].direction = glm::vec3(0.0f, 1.0f, 0.0f); _emitter[emitterIndex].visible = false; + _emitter[emitterIndex].particleResolution = DEFAULT_PARTICLE_SPHERE_RESOLUTION; _emitter[emitterIndex].particleLifespan = DEFAULT_PARTICLE_LIFESPAN; _emitter[emitterIndex].baseParticle.alive = false; _emitter[emitterIndex].baseParticle.age = 0.0f; @@ -279,7 +281,7 @@ void ParticleSystem::render() { glColor4f(_emitter[e].baseParticle.color.r, _emitter[e].baseParticle.color.g, _emitter[e].baseParticle.color.b, _emitter[e].baseParticle.color.a ); glPushMatrix(); glTranslatef(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); - glutSolidSphere(_emitter[e].baseParticle.radius, 6, 6); + glutSolidSphere(_emitter[e].baseParticle.radius, _emitter[e].particleResolution, _emitter[e].particleResolution); glPopMatrix(); } @@ -330,7 +332,7 @@ void ParticleSystem::renderParticle(int p) { } else { glPushMatrix(); glTranslatef(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); - glutSolidSphere(_particle[p].radius, 6, 6); + glutSolidSphere(_particle[p].radius, _emitter[_particle[p].emitterIndex].particleResolution, _emitter[_particle[p].emitterIndex].particleResolution); glPopMatrix(); if (SHOW_VELOCITY_TAILS) { diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index c5ffd95aa4..680e345d77 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -10,31 +10,32 @@ #include -const int MAX_PARTICLES = 5000; -const int MAX_EMITTERS = 20; +const int MAX_PARTICLES = 5000; +const int MAX_EMITTERS = 20; const int NUM_PARTICLE_LIFE_STAGES = 4; -const bool USE_BILLBOARD_RENDERING = false; -const bool SHOW_VELOCITY_TAILS = false; +const bool USE_BILLBOARD_RENDERING = false; +const bool SHOW_VELOCITY_TAILS = false; class ParticleSystem { public: struct ParticleAttributes { - float radius; - glm::vec4 color; - float bounce; - float gravity; - float airFriction; - float jitter; - float emitterAttraction; - float tornadoForce; - float neighborAttraction; - float neighborRepulsion; - bool usingCollisionSphere; - glm::vec3 collisionSpherePosition; - float collisionSphereRadius; + float radius; // radius of the particle + glm::vec4 color; // color (rgba) of the particle + float bounce; // how much reflection when the particle collides with floor/ground + float gravity; // force opposite of up direction + float airFriction; // continual dampening of velocity + float jitter; // random forces on velocity + float emitterAttraction; // an attraction to the emitter position + float tornadoForce; // force perpendicular to direction axis + float neighborAttraction; // causes particle to be pulled towards next particle in list + float neighborRepulsion; // causes particle to be repelled by previous particle in list + bool usingCollisionSphere; // set to true to allow collision with a sphere + glm::vec3 collisionSpherePosition; // position of the collision sphere + float collisionSphereRadius; // radius of the collision sphere }; + // public methods... ParticleSystem(); int addEmitter(); // add (create new) emitter and get its unique id @@ -47,14 +48,15 @@ public: void setShowingEmitterBaseParticle(int emitterIndex, bool showing ); void setParticleAttributes (int emitterIndex, ParticleAttributes attributes); // set attributes for whole life of particles void setParticleAttributes (int emitterIndex, int lifeStage, ParticleAttributes attributes); // set attributes for this life stage of particles - void setEmitterBaseParticleColor (int emitterIndex, glm::vec4 color ) {_emitter[emitterIndex].baseParticle.color = color; } - void setEmitterBaseParticleRadius (int emitterIndex, float radius ) {_emitter[emitterIndex].baseParticle.radius = radius; } - void setEmitterPosition (int emitterIndex, glm::vec3 position ) {_emitter[emitterIndex].position = position; } - void setEmitterDirection (int emitterIndex, glm::vec3 direction) {_emitter[emitterIndex].direction = direction; } - void setShowingEmitter (int emitterIndex, bool showing ) {_emitter[emitterIndex].visible = showing; } - void setEmitterParticleLifespan (int emitterIndex, float lifespan ) {_emitter[emitterIndex].particleLifespan = lifespan; } - void setEmitterThrust (int emitterIndex, float thrust ) {_emitter[emitterIndex].thrust = thrust; } - void setEmitterRate (int emitterIndex, float rate ) {_emitter[emitterIndex].rate = rate; } + void setEmitterBaseParticleColor (int emitterIndex, glm::vec4 color ) {_emitter[emitterIndex].baseParticle.color = color; } + void setEmitterBaseParticleRadius (int emitterIndex, float radius ) {_emitter[emitterIndex].baseParticle.radius = radius; } + void setEmitterPosition (int emitterIndex, glm::vec3 position ) {_emitter[emitterIndex].position = position; } + void setEmitterParticleResolution (int emitterIndex, int resolution) {_emitter[emitterIndex].particleResolution = resolution; } + void setEmitterDirection (int emitterIndex, glm::vec3 direction ) {_emitter[emitterIndex].direction = direction; } + void setShowingEmitter (int emitterIndex, bool showing ) {_emitter[emitterIndex].visible = showing; } + void setEmitterParticleLifespan (int emitterIndex, float lifespan ) {_emitter[emitterIndex].particleLifespan = lifespan; } + void setEmitterThrust (int emitterIndex, float thrust ) {_emitter[emitterIndex].thrust = thrust; } + void setEmitterRate (int emitterIndex, float rate ) {_emitter[emitterIndex].rate = rate; } private: @@ -69,13 +71,14 @@ private: }; struct Emitter { - glm::vec3 position; - glm::vec3 direction; - bool visible; - float particleLifespan; - float thrust; - float rate; - Particle baseParticle; // a non-physical particle at the emitter position + glm::vec3 position; // teh position of the emitter in world coordinates + glm::vec3 direction; // a normalized vector used as an axis for particle emission and other effects + 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 thrust; // the initial velocity upon emitting along the emitter direction + float rate; // currently, how many particles emitted during a simulation time step + Particle baseParticle; // a non-physical particle at the emitter position ParticleAttributes particleAttributes[NUM_PARTICLE_LIFE_STAGES]; // the attributes of particles emitted from this emitter }; diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 32d5482c30..56191c3eeb 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -331,9 +331,10 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- if (mode == 0) { - _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 1.0f); - _particleSystem.setEmitterThrust(_fingerParticleEmitter[f], 0.002f); - _particleSystem.setEmitterRate(_fingerParticleEmitter[f], 1.0); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0 ); + _particleSystem.setEmitterParticleResolution(_fingerParticleEmitter[f], 6 ); attributes.radius = 0.0f; attributes.color = glm::vec4( 1.0f, 1.0f, 0.5f, 0.5f); @@ -370,9 +371,10 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- } else if (mode == 1) { - _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 1.0f); - _particleSystem.setEmitterThrust(_fingerParticleEmitter[f], 0.002f); - _particleSystem.setEmitterRate(_fingerParticleEmitter[f], 10.0); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 10.0 ); + _particleSystem.setEmitterParticleResolution(_fingerParticleEmitter[f], 5 ); attributes.radius = 0.001f; attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.5f); @@ -403,9 +405,10 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- } else if (mode == 2) { - _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 0.05f); - _particleSystem.setEmitterThrust(_fingerParticleEmitter[f], 0.002f); - _particleSystem.setEmitterRate(_fingerParticleEmitter[f], 1.0); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.05f ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0 ); + _particleSystem.setEmitterParticleResolution(_fingerParticleEmitter[f], 12 ); attributes.radius = 0.0f; attributes.color = glm::vec4( 1.0f, 0.0f, 0.0f, 1.0f); @@ -437,8 +440,10 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- } else if (mode == 3) { - _particleSystem.setEmitterParticleLifespan(_fingerParticleEmitter[f], 0.05f); - _particleSystem.setEmitterThrust(_fingerParticleEmitter[f], 0.002f); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.05f ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0f ); + _particleSystem.setEmitterParticleResolution(_fingerParticleEmitter[f], 20 ); attributes.radius = 0.02f; attributes.color = glm::vec4( 1.0f, 0.0f, 0.0f, 1.0f); From 5f0d52ce89a0f337e67b6df18de8a6d4be6be50c Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 22 Jul 2013 10:35:02 -0700 Subject: [PATCH 08/88] uh, whatever --- interface/src/avatar/Hand.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 56191c3eeb..3ac8f3d6ea 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -440,9 +440,9 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- } else if (mode == 3) { - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.05f ); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.05f); _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0f ); _particleSystem.setEmitterParticleResolution(_fingerParticleEmitter[f], 20 ); attributes.radius = 0.02f; From c301b799c5bb215d1195e5d8cd90b8bae7bf3a94 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Jul 2013 13:54:47 -0700 Subject: [PATCH 09/88] first cut at selecting audio sources --- audio-mixer/src/PositionalAudioRingBuffer.cpp | 49 +++++++++++- audio-mixer/src/PositionalAudioRingBuffer.h | 10 +++ interface/src/Application.cpp | 12 ++- interface/src/Audio.cpp | 76 ++++++++++++++++++- interface/src/Audio.h | 13 ++++ libraries/audio/src/AudioRingBuffer.h | 8 ++ libraries/shared/src/PacketHeaders.cpp | 6 ++ libraries/shared/src/PacketHeaders.h | 2 - 8 files changed, 171 insertions(+), 5 deletions(-) diff --git a/audio-mixer/src/PositionalAudioRingBuffer.cpp b/audio-mixer/src/PositionalAudioRingBuffer.cpp index 60ec9a425e..936b71fb79 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.cpp +++ b/audio-mixer/src/PositionalAudioRingBuffer.cpp @@ -16,19 +16,66 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer() : AudioRingBuffer(false), _position(0.0f, 0.0f, 0.0f), _orientation(0.0f, 0.0f, 0.0f, 0.0f), - _willBeAddedToMix(false) + _willBeAddedToMix(false), + _sourceID(-1), + _listenMode(AudioRingBuffer::NORMAL), + _listenRadius(0.0f), + _listenSourceCount(0), + _listenSources(NULL) { } +PositionalAudioRingBuffer::~PositionalAudioRingBuffer() { + if (_listenSources) { + delete[] _listenSources; + } +} + int PositionalAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char* currentBuffer = sourceBuffer + numBytesForPacketHeader(sourceBuffer); + currentBuffer += parseSourceData(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); + currentBuffer += parseListenModeData(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); currentBuffer += parsePositionalData(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); currentBuffer += parseAudioSamples(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); return currentBuffer - sourceBuffer; } +int PositionalAudioRingBuffer::parseSourceData(unsigned char* sourceBuffer, int numBytes) { + unsigned char* currentBuffer = sourceBuffer; + + memcpy(&_sourceID, currentBuffer, sizeof(_sourceID)); + currentBuffer += sizeof(_sourceID); + + return currentBuffer - sourceBuffer; +} + +int PositionalAudioRingBuffer::parseListenModeData(unsigned char* sourceBuffer, int numBytes) { + unsigned char* currentBuffer = sourceBuffer; + + memcpy(&_listenMode, currentBuffer, sizeof(_listenMode)); + currentBuffer += sizeof(_listenMode); + + if (_listenMode == AudioRingBuffer::OMNI_DIRECTIONAL_POINT) { + memcpy(&_listenRadius, currentBuffer, sizeof(_listenRadius)); + currentBuffer += sizeof(_listenRadius); + } else if (_listenMode == AudioRingBuffer::SELECTED_SOURCES) { + memcpy(&_listenSourceCount, currentBuffer, sizeof(_listenSourceCount)); + currentBuffer += sizeof(_listenSourceCount); + + if (_listenSources) { + delete[] _listenSources; + } + _listenSources = new int[_listenSourceCount]; + memcpy(_listenSources, currentBuffer, sizeof(int) * _listenSourceCount); + currentBuffer += sizeof(int) * _listenSourceCount; + + } + + return currentBuffer - sourceBuffer; +} + int PositionalAudioRingBuffer::parsePositionalData(unsigned char* sourceBuffer, int numBytes) { unsigned char* currentBuffer = sourceBuffer; diff --git a/audio-mixer/src/PositionalAudioRingBuffer.h b/audio-mixer/src/PositionalAudioRingBuffer.h index 41e775e74a..9fd6921617 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.h +++ b/audio-mixer/src/PositionalAudioRingBuffer.h @@ -16,9 +16,12 @@ class PositionalAudioRingBuffer : public AudioRingBuffer { public: PositionalAudioRingBuffer(); + ~PositionalAudioRingBuffer(); int parseData(unsigned char* sourceBuffer, int numBytes); int parsePositionalData(unsigned char* sourceBuffer, int numBytes); + int parseSourceData(unsigned char* sourceBuffer, int numBytes); + int parseListenModeData(unsigned char* sourceBuffer, int numBytes); bool shouldBeAddedToMix(int numJitterBufferSamples); @@ -36,6 +39,13 @@ protected: glm::vec3 _position; glm::quat _orientation; bool _willBeAddedToMix; + + int _sourceID; + int _listenMode; + float _listenRadius; + int _listenSourceCount; + int* _listenSources; + }; #endif /* defined(__hifi__PositionalAudioRingBuffer__) */ diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9571b44839..d13d69ffb9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3447,9 +3447,19 @@ void* Application::networkReceive(void* args) { case PACKET_TYPE_AVATAR_FACE_VIDEO: processAvatarFaceVideoMessage(app->_incomingPacket, bytesReceived); break; - default: + default: { NodeList::getInstance()->processNodeData(&senderAddress, app->_incomingPacket, bytesReceived); + + // Check to see if we have our ownerID + uint16_t ownerID = NodeList::getInstance()->getOwnerID(); + + if (ownerID != app->_audio.getSourceID()) { + app->_audio.setSourceID(ownerID); + } + + break; + } } } } else if (!app->_enableNetworkThread) { diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 41090584f3..6bc2528bf0 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -120,6 +120,27 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o unsigned char* currentPacketPtr = dataPacket + populateTypeAndVersion(dataPacket, packetType); + // pack Source Data + memcpy(currentPacketPtr, &_sourceID, sizeof(_sourceID)); + currentPacketPtr += (sizeof(_sourceID)); + + // pack Listen Mode Data + memcpy(currentPacketPtr, &_listenMode, sizeof(_listenMode)); + currentPacketPtr += (sizeof(_listenMode)); + + if (_listenMode == AudioRingBuffer::OMNI_DIRECTIONAL_POINT) { + memcpy(currentPacketPtr, &_listenRadius, sizeof(_listenRadius)); + currentPacketPtr += (sizeof(_listenRadius)); + } else if (_listenMode == AudioRingBuffer::SELECTED_SOURCES) { + memcpy(currentPacketPtr, &_listenSourceCount, sizeof(_listenSourceCount)); + currentPacketPtr += (sizeof(_listenSourceCount)); + + if (_listenSources) { + memcpy(currentPacketPtr, &_listenSources, sizeof(int) * _listenSourceCount); + currentPacketPtr += (sizeof(int) * _listenSourceCount); + } + } + // memcpy the three float positions memcpy(currentPacketPtr, &headPosition, sizeof(headPosition)); currentPacketPtr += (sizeof(headPosition)); @@ -309,6 +330,49 @@ void Audio::reset() { _ringBuffer.reset(); } +void Audio::addListenSource(int sourceID) { + + // If we don't yet have a list of listen sources, make one + if (!_listenSources) { + _listenSources = new int[AudioRingBuffer::DEFAULT_LISTEN_LIST_SIZE]; + } + + // First check to see if the source is already in our list + for (int i = 0; i < _listenSourceCount; i++) { + if (_listenSources[i] == sourceID) { + return; // already in list + } + } + + // we know it's not in the list, check to see if we have room to add our source + if (_listenSourceCount + 1 < _listenSourcesArraySize) { + int* newList = new int[_listenSourcesArraySize + AudioRingBuffer::DEFAULT_LISTEN_LIST_SIZE]; + memmove(newList, _listenSources, _listenSourcesArraySize); + delete[] _listenSources; + _listenSources = newList; + _listenSourcesArraySize += AudioRingBuffer::DEFAULT_LISTEN_LIST_SIZE; + } + _listenSources[_listenSourceCount] = sourceID; + _listenSourceCount++; +} + +void Audio::removeListenSource(int sourceID) { + // If we don't yet have a list of listen sources, make one + if (_listenSources) { + // First check to see if the source is already in our list + for (int i = 0; i < _listenSourceCount; i++) { + if (_listenSources[i] == sourceID) { + + // found it, so, move the items forward in list + memmove(&_listenSources[i], &_listenSources[i+1], _listenSourceCount - i); + _listenSourceCount--; + return; + } + } + } +} + + Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) : _stream(NULL), _ringBuffer(true), @@ -338,7 +402,13 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) : _collisionSoundNoise(0.0f), _collisionSoundDuration(0.0f), _proceduralEffectSample(0), - _heartbeatMagnitude(0.0f) + _heartbeatMagnitude(0.0f), + _sourceID(UNKNOWN_NODE_ID), + _listenMode(AudioRingBuffer::NORMAL), + _listenRadius(0.0f), + _listenSourceCount(0), + _listenSourcesArraySize(0), + _listenSources(NULL) { outputPortAudioError(Pa_Initialize()); @@ -407,6 +477,10 @@ Audio::~Audio() { outputPortAudioError(Pa_Terminate()); } delete[] _echoSamplesLeft; + + if (_listenSources) { + delete[] _listenSources; + } } void Audio::addReceivedAudioToBuffer(unsigned char* receivedData, int receivedBytes) { diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 37db447381..ca665c66f0 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -54,6 +54,12 @@ public: // The results of the analysis are written to the log. bool eventuallyAnalyzePing(); + int getSourceID() const { return _sourceID; }; + void setSourceID(int sourceID) { _sourceID = sourceID; }; + void setListenMode(int mode) { _listenMode = mode; }; + void setListenRadius(float radius) { _listenRadius = radius; }; + void addListenSource(int sourceID); + void removeListenSource(int sourceID); private: PaStream* _stream; @@ -90,6 +96,13 @@ private: float _collisionSoundDuration; int _proceduralEffectSample; float _heartbeatMagnitude; + + int _sourceID; + int _listenMode; + float _listenRadius; + int _listenSourceCount; + int _listenSourcesArraySize; + int* _listenSources; // Audio callback in class context. inline void performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* outputRight); diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index dea4a13fec..be87558010 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -27,6 +27,14 @@ const short RING_BUFFER_LENGTH_SAMPLES = RING_BUFFER_LENGTH_FRAMES * BUFFER_LENG class AudioRingBuffer : public NodeData { public: + + static int const DEFAULT_LISTEN_LIST_SIZE = 100; + enum { + NORMAL, + OMNI_DIRECTIONAL_POINT, + SELECTED_SOURCES + }; + AudioRingBuffer(bool isStereo); ~AudioRingBuffer(); diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 821a2d0247..292c4bbc0a 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -14,6 +14,12 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) { switch (type) { + + case PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO: + case PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO: + return 1; + break; + case PACKET_TYPE_HEAD_DATA: return 2; break; diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index c62abb85e9..9652ac14e7 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -35,8 +35,6 @@ const PACKET_TYPE PACKET_TYPE_ENVIRONMENT_DATA = 'e'; const PACKET_TYPE PACKET_TYPE_DOMAIN_LIST_REQUEST = 'L'; const PACKET_TYPE PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY = 'C'; -// this is a test... - typedef char PACKET_VERSION; PACKET_VERSION versionForPacketType(PACKET_TYPE type); From fdebe166bab0d264b25a42e82cc4e4e84dd0d576 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 22 Jul 2013 14:07:51 -0700 Subject: [PATCH 10/88] fixed it so both leap hands produce particles --- interface/src/avatar/Hand.cpp | 23 ++++++++++++----------- interface/src/avatar/Hand.h | 7 +++---- libraries/avatars/src/HandData.h | 3 +++ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 925e93f321..782eb9306a 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -32,7 +32,7 @@ Hand::Hand(Avatar* owningAvatar) : { // initialize all finger particle emitters with an invalid id as default - for (int f = 0; f< NUM_FINGERS_PER_HAND; f ++ ) { + for (int f = 0; f< NUM_FINGERS; f ++ ) { _fingerParticleEmitter[f] = -1; } } @@ -232,7 +232,7 @@ void Hand::setLeapHands(const std::vector& handPositions, void Hand::updateFingerParticleEmitters() { if (_particleSystemInitialized) { - + int fingerIndex = 0; for (size_t i = 0; i < getNumPalms(); ++i) { PalmData& palm = getPalms()[i]; @@ -240,7 +240,7 @@ void Hand::updateFingerParticleEmitters() { for (size_t f = 0; f < palm.getNumFingers(); ++f) { FingerData& finger = palm.getFingers()[f]; if (finger.isActive()) { - if (_fingerParticleEmitter[fingerIndex] != -1) { + if (_fingerParticleEmitter[0] != -1) { glm::vec3 fingerDirection = finger.getTipPosition() - finger.getRootPosition(); float fingerLength = glm::length(fingerDirection); @@ -251,8 +251,9 @@ void Hand::updateFingerParticleEmitters() { fingerDirection = IDENTITY_UP; } - _particleSystem.setEmitterPosition (_fingerParticleEmitter[f], finger.getTipPosition()); - _particleSystem.setEmitterDirection(_fingerParticleEmitter[f], fingerDirection); + _particleSystem.setEmitterPosition (_fingerParticleEmitter[fingerIndex], finger.getTipPosition()); + _particleSystem.setEmitterDirection(_fingerParticleEmitter[fingerIndex], fingerDirection); + fingerIndex ++; } } } @@ -262,14 +263,13 @@ void Hand::updateFingerParticleEmitters() { } - // call this from within the simulate method void Hand::updateFingerParticles(float deltaTime) { if (!_particleSystemInitialized) { // start up the rave glove finger particles... - for ( int f = 0; f< NUM_FINGERS_PER_HAND; f ++ ) { + for ( int f = 0; f< NUM_FINGERS; f ++ ) { _fingerParticleEmitter[f] = _particleSystem.addEmitter(); assert( _fingerParticleEmitter[f] != -1 ); } @@ -298,7 +298,7 @@ void Hand::updateFingerParticles(float deltaTime) { attributes.color = glm::vec4(red, green, blue, 1.0f); attributes.radius = 0.02f; - for ( int f = 0; f< NUM_FINGERS_PER_HAND; f ++ ) { + 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); @@ -314,8 +314,9 @@ void Hand::updateFingerParticles(float deltaTime) { for (size_t f = 0; f < palm.getNumFingers(); ++f) { FingerData& finger = palm.getFingers()[f]; if (finger.isActive()) { - if (_fingerParticleEmitter[fingerIndex] != -1) { - _particleSystem.emitNow(_fingerParticleEmitter[f]); + if (_fingerParticleEmitter[0] != -1) { + _particleSystem.emitNow(_fingerParticleEmitter[fingerIndex]); + fingerIndex ++; } } } @@ -330,7 +331,7 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.killAllParticles(); - for ( int f = 0; f< NUM_FINGERS_PER_HAND; f ++ ) { + for ( int f = 0; f< NUM_FINGERS; f ++ ) { ParticleSystem::ParticleAttributes attributes; diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index a575cbc06b..8152a4b271 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -60,18 +60,17 @@ private: float _testRaveGloveClock; int _testRaveGloveMode; bool _particleSystemInitialized; - int _fingerParticleEmitter[NUM_FINGERS_PER_HAND]; + int _fingerParticleEmitter[NUM_FINGERS]; Avatar* _owningAvatar; float _renderAlpha; bool _lookingInMirror; bool _isRaveGloveActive; glm::vec3 _ballColor; - std::vector _leapBalls; - + std::vector _leapBalls; // private methods void setLeapHands(const std::vector& handPositions, - const std::vector& handNormals); + const std::vector& handNormals); void renderRaveGloveStage(); void setRaveGloveMode(int mode); diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index d2b5cae90d..1a7a99f2db 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -19,7 +19,10 @@ class AvatarData; class FingerData; class PalmData; +const int NUM_HANDS = 2; const int NUM_FINGERS_PER_HAND = 5; +const int NUM_FINGERS = NUM_HANDS * NUM_FINGERS_PER_HAND; + const int LEAPID_INVALID = -1; class HandData { From 90bc3e9a378a72fb0a5088a920768aa2fbb3e730 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 22 Jul 2013 14:08:41 -0700 Subject: [PATCH 11/88] um, ok whatever --- interface/src/LeapManager.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 interface/src/LeapManager.cpp diff --git a/interface/src/LeapManager.cpp b/interface/src/LeapManager.cpp old mode 100755 new mode 100644 From 0f1ac2b2267b86e033220f26c61865813b440fa2 Mon Sep 17 00:00:00 2001 From: Mark Peng Date: Mon, 22 Jul 2013 16:46:06 -0700 Subject: [PATCH 12/88] Fix eyePosition so that lookatVectors point directly to eyes, even when looking at someone from above. --- interface/src/Application.cpp | 9 ++++++--- interface/src/avatar/Head.cpp | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9571b44839..0aee4a726c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1953,10 +1953,13 @@ bool Application::isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3& m void Application::renderLookatIndicator(glm::vec3 pointOfInterest, Camera& whichCamera) { const float DISTANCE_FROM_HEAD_SPHERE = 0.1f; + const float INDICATOR_RADIUS = 0.1f; const float YELLOW[] = { 1.0f, 1.0f, 0.0f }; + const int NUM_SEGMENTS = 30; glm::vec3 haloOrigin(pointOfInterest.x, pointOfInterest.y + DISTANCE_FROM_HEAD_SPHERE, pointOfInterest.z); glColor3f(YELLOW[0], YELLOW[1], YELLOW[2]); - renderCircle(haloOrigin, 0.1f, glm::vec3(0.0f, 1.0f, 0.0f), 30); + glm::vec3 normalToFloor(0.0f, 1.0f, 0.0f); + renderCircle(haloOrigin, INDICATOR_RADIUS, normalToFloor, NUM_SEGMENTS); } void Application::update(float deltaTime) { @@ -2003,7 +2006,7 @@ void Application::update(float deltaTime) { glm::vec3 front = orientation * IDENTITY_FRONT; glm::vec3 up = orientation * IDENTITY_UP; glm::vec3 towardVoxel = getMouseVoxelWorldCoordinates(_mouseVoxelDragging) - - _myAvatar.getCameraPosition(); // is this an error? getCameraPosition dne + - _myAvatar.getCameraPosition(); towardVoxel = front * glm::length(towardVoxel); glm::vec3 lateralToVoxel = glm::cross(up, glm::normalize(towardVoxel)) * glm::length(towardVoxel); _voxelThrust = glm::vec3(0, 0, 0); @@ -2276,7 +2279,7 @@ void Application::updateAvatar(float deltaTime) { // actually need to calculate the view frustum planes to send these details // to the server. loadViewFrustum(_myCamera, _viewFrustum); - _myAvatar.setCameraPosition(_viewFrustum.getPosition()); // setCameraPosition() dne + _myAvatar.setCameraPosition(_viewFrustum.getPosition()); _myAvatar.setCameraOrientation(_viewFrustum.getOrientation()); _myAvatar.setCameraFov(_viewFrustum.getFieldOfView()); _myAvatar.setCameraAspectRatio(_viewFrustum.getAspectRatio()); diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index b8393e26ab..76cf13a44d 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -272,7 +272,7 @@ void Head::calculateGeometry() { + up * _scale * BODY_BALL_RADIUS_HEAD_BASE * EYE_UP_OFFSET + front * _scale * BODY_BALL_RADIUS_HEAD_BASE * EYE_FRONT_OFFSET; - _eyeLevelPosition = _position + up * _scale * BODY_BALL_RADIUS_HEAD_BASE * EYE_UP_OFFSET; + _eyeLevelPosition = _rightEyePosition - right * _scale * BODY_BALL_RADIUS_HEAD_BASE * EYE_RIGHT_OFFSET; //calculate the eyebrow positions _leftEyeBrowPosition = _leftEyePosition; From 4e641eed2fd804a53111ef8216c42fc36dee8ab5 Mon Sep 17 00:00:00 2001 From: Mark Peng Date: Mon, 22 Jul 2013 17:11:11 -0700 Subject: [PATCH 13/88] LookatIndicator now scales with the avatar's scale. --- interface/src/Application.cpp | 6 ++++-- interface/src/Application.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0aee4a726c..c0fe2b360b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -200,6 +200,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _mouseVoxelScale(1.0f / 1024.0f), _justEditedVoxel(false), _isLookingAtOtherAvatar(false), + _lookatIndicatorScale(1.0f), _paintOn(false), _dominantColor(0), _perfStatsOn(false), @@ -1942,6 +1943,7 @@ bool Application::isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3& m glm::vec3 headPosition = avatar->getHead().getPosition(); if (rayIntersectsSphere(mouseRayOrigin, mouseRayDirection, headPosition, HEAD_SPHERE_RADIUS)) { eyePosition = avatar->getHead().getEyeLevelPosition(); + _lookatIndicatorScale = avatar->getScale(); _lookatOtherPosition = headPosition; return true; } @@ -1952,8 +1954,8 @@ bool Application::isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3& m void Application::renderLookatIndicator(glm::vec3 pointOfInterest, Camera& whichCamera) { - const float DISTANCE_FROM_HEAD_SPHERE = 0.1f; - const float INDICATOR_RADIUS = 0.1f; + const float DISTANCE_FROM_HEAD_SPHERE = 0.1f * _lookatIndicatorScale; + const float INDICATOR_RADIUS = 0.1f * _lookatIndicatorScale; const float YELLOW[] = { 1.0f, 1.0f, 0.0f }; const int NUM_SEGMENTS = 30; glm::vec3 haloOrigin(pointOfInterest.x, pointOfInterest.y + DISTANCE_FROM_HEAD_SPHERE, pointOfInterest.z); diff --git a/interface/src/Application.h b/interface/src/Application.h index d29328c0b5..85c8334b3a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -373,6 +373,7 @@ private: bool _isLookingAtOtherAvatar; glm::vec3 _lookatOtherPosition; + float _lookatIndicatorScale; bool _paintOn; // Whether to paint voxels as you fly around unsigned char _dominantColor; // The dominant color of the voxel we're painting From c969570e8c8fb64c2f86ed6e4c3bfe105c64b979 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Jul 2013 23:05:42 -0700 Subject: [PATCH 14/88] working on selected audio --- audio-mixer/src/PositionalAudioRingBuffer.cpp | 32 +- audio-mixer/src/PositionalAudioRingBuffer.h | 4 + audio-mixer/src/main.cpp | 281 +++++++++--------- interface/src/Application.cpp | 36 +++ interface/src/Application.h | 4 + interface/src/Audio.cpp | 16 +- interface/src/Audio.h | 1 + interface/src/avatar/Avatar.h | 4 + 8 files changed, 233 insertions(+), 145 deletions(-) diff --git a/audio-mixer/src/PositionalAudioRingBuffer.cpp b/audio-mixer/src/PositionalAudioRingBuffer.cpp index 936b71fb79..26961c76e8 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.cpp +++ b/audio-mixer/src/PositionalAudioRingBuffer.cpp @@ -32,6 +32,32 @@ PositionalAudioRingBuffer::~PositionalAudioRingBuffer() { } } +bool PositionalAudioRingBuffer::isListeningToSource(PositionalAudioRingBuffer* other) { + switch (_listenMode) { + default: + case AudioRingBuffer::NORMAL: + return true; + break; + + case AudioRingBuffer::OMNI_DIRECTIONAL_POINT: { + float distance = glm::distance(_position, other->_position); + return distance <= _listenRadius; + break; + } + case AudioRingBuffer::SELECTED_SOURCES: + if (_listenSources) { + for (int i = 0; i < _listenSourceCount; i++) { + if (other->_sourceID == _listenSources[i]) { + return true; + } + } + } + return false; + break; + } +} + + int PositionalAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char* currentBuffer = sourceBuffer + numBytesForPacketHeader(sourceBuffer); currentBuffer += parseSourceData(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); @@ -56,21 +82,19 @@ int PositionalAudioRingBuffer::parseListenModeData(unsigned char* sourceBuffer, memcpy(&_listenMode, currentBuffer, sizeof(_listenMode)); currentBuffer += sizeof(_listenMode); - + if (_listenMode == AudioRingBuffer::OMNI_DIRECTIONAL_POINT) { memcpy(&_listenRadius, currentBuffer, sizeof(_listenRadius)); currentBuffer += sizeof(_listenRadius); } else if (_listenMode == AudioRingBuffer::SELECTED_SOURCES) { memcpy(&_listenSourceCount, currentBuffer, sizeof(_listenSourceCount)); currentBuffer += sizeof(_listenSourceCount); - if (_listenSources) { delete[] _listenSources; } _listenSources = new int[_listenSourceCount]; memcpy(_listenSources, currentBuffer, sizeof(int) * _listenSourceCount); currentBuffer += sizeof(int) * _listenSourceCount; - } return currentBuffer - sourceBuffer; @@ -81,7 +105,7 @@ int PositionalAudioRingBuffer::parsePositionalData(unsigned char* sourceBuffer, memcpy(&_position, currentBuffer, sizeof(_position)); currentBuffer += sizeof(_position); - + memcpy(&_orientation, currentBuffer, sizeof(_orientation)); currentBuffer += sizeof(_orientation); diff --git a/audio-mixer/src/PositionalAudioRingBuffer.h b/audio-mixer/src/PositionalAudioRingBuffer.h index 9fd6921617..eb6f0414e7 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.h +++ b/audio-mixer/src/PositionalAudioRingBuffer.h @@ -30,6 +30,10 @@ public: const glm::vec3& getPosition() const { return _position; } const glm::quat& getOrientation() const { return _orientation; } + + bool isListeningToSource(PositionalAudioRingBuffer* other); + int getSourceID() const { return _sourceID; } + int getListeningMode() const { return _listenMode; } protected: // disallow copying of PositionalAudioRingBuffer objects diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 239eb7a32d..2f17113ba4 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -159,168 +159,174 @@ int main(int argc, const char* argv[]) { // zero out the client mix for this node memset(clientSamples, 0, sizeof(clientSamples)); + // loop through all other nodes that have sufficient audio to mix for (NodeList::iterator otherNode = nodeList->begin(); otherNode != nodeList->end(); otherNode++) { + if (((PositionalAudioRingBuffer*) otherNode->getLinkedData())->willBeAddedToMix() && (otherNode != node || (otherNode == node && nodeRingBuffer->shouldLoopbackForNode()))) { PositionalAudioRingBuffer* otherNodeBuffer = (PositionalAudioRingBuffer*) otherNode->getLinkedData(); + + // based on our listen mode we will do this mixing... + if (nodeRingBuffer->isListeningToSource(otherNodeBuffer)) { + float bearingRelativeAngleToSource = 0.0f; + float attenuationCoefficient = 1.0f; + int numSamplesDelay = 0; + float weakChannelAmplitudeRatio = 1.0f; - float bearingRelativeAngleToSource = 0.0f; - float attenuationCoefficient = 1.0f; - int numSamplesDelay = 0; - float weakChannelAmplitudeRatio = 1.0f; + stk::TwoPole* otherNodeTwoPole = NULL; - stk::TwoPole* otherNodeTwoPole = NULL; - - if (otherNode != node) { + // only do axis/distance attenuation when in normal mode + if (otherNode != node && nodeRingBuffer->getListeningMode() == AudioRingBuffer::NORMAL) { - glm::vec3 listenerPosition = nodeRingBuffer->getPosition(); - glm::vec3 relativePosition = otherNodeBuffer->getPosition() - nodeRingBuffer->getPosition(); - glm::quat inverseOrientation = glm::inverse(nodeRingBuffer->getOrientation()); + glm::vec3 listenerPosition = nodeRingBuffer->getPosition(); + glm::vec3 relativePosition = otherNodeBuffer->getPosition() - nodeRingBuffer->getPosition(); + glm::quat inverseOrientation = glm::inverse(nodeRingBuffer->getOrientation()); - float distanceSquareToSource = glm::dot(relativePosition, relativePosition); - float radius = 0.0f; + float distanceSquareToSource = glm::dot(relativePosition, relativePosition); + float radius = 0.0f; - if (otherNode->getType() == NODE_TYPE_AUDIO_INJECTOR) { - InjectedAudioRingBuffer* injectedBuffer = (InjectedAudioRingBuffer*) otherNodeBuffer; - radius = injectedBuffer->getRadius(); - attenuationCoefficient *= injectedBuffer->getAttenuationRatio(); - } + if (otherNode->getType() == NODE_TYPE_AUDIO_INJECTOR) { + InjectedAudioRingBuffer* injectedBuffer = (InjectedAudioRingBuffer*) otherNodeBuffer; + radius = injectedBuffer->getRadius(); + attenuationCoefficient *= injectedBuffer->getAttenuationRatio(); + } - if (radius == 0 || (distanceSquareToSource > radius * radius)) { - // this is either not a spherical source, or the listener is outside the sphere + if (radius == 0 || (distanceSquareToSource > radius * radius)) { + // this is either not a spherical source, or the listener is outside the sphere - if (radius > 0) { - // this is a spherical source - the distance used for the coefficient - // needs to be the closest point on the boundary to the source + if (radius > 0) { + // this is a spherical source - the distance used for the coefficient + // needs to be the closest point on the boundary to the source - // ovveride the distance to the node with the distance to the point on the - // boundary of the sphere - distanceSquareToSource -= (radius * radius); + // ovveride the distance to the node with the distance to the point on the + // boundary of the sphere + distanceSquareToSource -= (radius * radius); - } else { - // calculate the angle delivery for off-axis attenuation - glm::vec3 rotatedListenerPosition = glm::inverse(otherNodeBuffer->getOrientation()) - * relativePosition; + } else { + // calculate the angle delivery for off-axis attenuation + glm::vec3 rotatedListenerPosition = glm::inverse(otherNodeBuffer->getOrientation()) + * relativePosition; - float angleOfDelivery = glm::angle(glm::vec3(0.0f, 0.0f, -1.0f), - glm::normalize(rotatedListenerPosition)); + float angleOfDelivery = glm::angle(glm::vec3(0.0f, 0.0f, -1.0f), + glm::normalize(rotatedListenerPosition)); - const float MAX_OFF_AXIS_ATTENUATION = 0.2f; - const float OFF_AXIS_ATTENUATION_FORMULA_STEP = (1 - MAX_OFF_AXIS_ATTENUATION) / 2.0f; + const float MAX_OFF_AXIS_ATTENUATION = 0.2f; + const float OFF_AXIS_ATTENUATION_FORMULA_STEP = (1 - MAX_OFF_AXIS_ATTENUATION) / 2.0f; - float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + - (OFF_AXIS_ATTENUATION_FORMULA_STEP * (angleOfDelivery / 90.0f)); + float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + + (OFF_AXIS_ATTENUATION_FORMULA_STEP * (angleOfDelivery / 90.0f)); - // multiply the current attenuation coefficient by the calculated off axis coefficient - attenuationCoefficient *= offAxisCoefficient; + // multiply the current attenuation coefficient by the calculated off axis coefficient + attenuationCoefficient *= offAxisCoefficient; + } + + glm::vec3 rotatedSourcePosition = inverseOrientation * relativePosition; + + const float DISTANCE_SCALE = 2.5f; + const float GEOMETRIC_AMPLITUDE_SCALAR = 0.3f; + const float DISTANCE_LOG_BASE = 2.5f; + const float DISTANCE_SCALE_LOG = logf(DISTANCE_SCALE) / logf(DISTANCE_LOG_BASE); + + // calculate the distance coefficient using the distance to this node + float distanceCoefficient = powf(GEOMETRIC_AMPLITUDE_SCALAR, + DISTANCE_SCALE_LOG + + (0.5f * logf(distanceSquareToSource) / logf(DISTANCE_LOG_BASE)) - 1); + distanceCoefficient = std::min(1.0f, distanceCoefficient); + + // multiply the current attenuation coefficient by the distance coefficient + attenuationCoefficient *= distanceCoefficient; + + // project the rotated source position vector onto the XZ plane + rotatedSourcePosition.y = 0.0f; + + // produce an oriented angle about the y-axis + bearingRelativeAngleToSource = glm::orientedAngle(glm::vec3(0.0f, 0.0f, -1.0f), + glm::normalize(rotatedSourcePosition), + glm::vec3(0.0f, 1.0f, 0.0f)); + + const float PHASE_AMPLITUDE_RATIO_AT_90 = 0.5; + + // figure out the number of samples of delay and the ratio of the amplitude + // in the weak channel for audio spatialization + float sinRatio = fabsf(sinf(glm::radians(bearingRelativeAngleToSource))); + numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; + weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); + + // grab the TwoPole object for this source, add it if it doesn't exist + TwoPoleNodeMap& nodeTwoPoles = nodeRingBuffer->getTwoPoles(); + TwoPoleNodeMap::iterator twoPoleIterator = nodeTwoPoles.find(otherNode->getNodeID()); + + if (twoPoleIterator == nodeTwoPoles.end()) { + // setup the freeVerb effect for this source for this client + otherNodeTwoPole = nodeTwoPoles[otherNode->getNodeID()] = new stk::TwoPole; + } else { + otherNodeTwoPole = twoPoleIterator->second; + } + + // calculate the reasonance for this TwoPole based on angle to source + float TWO_POLE_CUT_OFF_FREQUENCY = 800.0f; + float TWO_POLE_MAX_FILTER_STRENGTH = 0.4f; + + otherNodeTwoPole->setResonance(TWO_POLE_CUT_OFF_FREQUENCY, + TWO_POLE_MAX_FILTER_STRENGTH + * fabsf(bearingRelativeAngleToSource) / 180.0f, + true); } + } + + int16_t* sourceBuffer = otherNodeBuffer->getNextOutput(); + + int16_t* goodChannel = (bearingRelativeAngleToSource > 0.0f) + ? clientSamples + : clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; + int16_t* delayedChannel = (bearingRelativeAngleToSource > 0.0f) + ? clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL + : clientSamples; + + int16_t* delaySamplePointer = otherNodeBuffer->getNextOutput() == otherNodeBuffer->getBuffer() + ? otherNodeBuffer->getBuffer() + RING_BUFFER_LENGTH_SAMPLES - numSamplesDelay + : otherNodeBuffer->getNextOutput() - numSamplesDelay; + + for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { + // load up the stkFrameBuffer with this source's samples + stkFrameBuffer[s] = (stk::StkFloat) sourceBuffer[s]; + } + + // perform the TwoPole effect on the stkFrameBuffer + if (otherNodeTwoPole) { + otherNodeTwoPole->tick(stkFrameBuffer); + } + + for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { + if (s < numSamplesDelay) { + // pull the earlier sample for the delayed channel + int earlierSample = delaySamplePointer[s] * attenuationCoefficient * weakChannelAmplitudeRatio; - glm::vec3 rotatedSourcePosition = inverseOrientation * relativePosition; - - const float DISTANCE_SCALE = 2.5f; - const float GEOMETRIC_AMPLITUDE_SCALAR = 0.3f; - const float DISTANCE_LOG_BASE = 2.5f; - const float DISTANCE_SCALE_LOG = logf(DISTANCE_SCALE) / logf(DISTANCE_LOG_BASE); - - // calculate the distance coefficient using the distance to this node - float distanceCoefficient = powf(GEOMETRIC_AMPLITUDE_SCALAR, - DISTANCE_SCALE_LOG + - (0.5f * logf(distanceSquareToSource) / logf(DISTANCE_LOG_BASE)) - 1); - distanceCoefficient = std::min(1.0f, distanceCoefficient); - - // multiply the current attenuation coefficient by the distance coefficient - attenuationCoefficient *= distanceCoefficient; - - // project the rotated source position vector onto the XZ plane - rotatedSourcePosition.y = 0.0f; - - // produce an oriented angle about the y-axis - bearingRelativeAngleToSource = glm::orientedAngle(glm::vec3(0.0f, 0.0f, -1.0f), - glm::normalize(rotatedSourcePosition), - glm::vec3(0.0f, 1.0f, 0.0f)); - - const float PHASE_AMPLITUDE_RATIO_AT_90 = 0.5; - - // figure out the number of samples of delay and the ratio of the amplitude - // in the weak channel for audio spatialization - float sinRatio = fabsf(sinf(glm::radians(bearingRelativeAngleToSource))); - numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; - weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); - - // grab the TwoPole object for this source, add it if it doesn't exist - TwoPoleNodeMap& nodeTwoPoles = nodeRingBuffer->getTwoPoles(); - TwoPoleNodeMap::iterator twoPoleIterator = nodeTwoPoles.find(otherNode->getNodeID()); - - if (twoPoleIterator == nodeTwoPoles.end()) { - // setup the freeVerb effect for this source for this client - otherNodeTwoPole = nodeTwoPoles[otherNode->getNodeID()] = new stk::TwoPole; - } else { - otherNodeTwoPole = twoPoleIterator->second; + delayedChannel[s] = glm::clamp(delayedChannel[s] + earlierSample, + MIN_SAMPLE_VALUE, + MAX_SAMPLE_VALUE); } - - // calculate the reasonance for this TwoPole based on angle to source - float TWO_POLE_CUT_OFF_FREQUENCY = 800.0f; - float TWO_POLE_MAX_FILTER_STRENGTH = 0.4f; - - otherNodeTwoPole->setResonance(TWO_POLE_CUT_OFF_FREQUENCY, - TWO_POLE_MAX_FILTER_STRENGTH - * fabsf(bearingRelativeAngleToSource) / 180.0f, - true); - } - } - - int16_t* sourceBuffer = otherNodeBuffer->getNextOutput(); - - int16_t* goodChannel = (bearingRelativeAngleToSource > 0.0f) - ? clientSamples - : clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; - int16_t* delayedChannel = (bearingRelativeAngleToSource > 0.0f) - ? clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL - : clientSamples; - - int16_t* delaySamplePointer = otherNodeBuffer->getNextOutput() == otherNodeBuffer->getBuffer() - ? otherNodeBuffer->getBuffer() + RING_BUFFER_LENGTH_SAMPLES - numSamplesDelay - : otherNodeBuffer->getNextOutput() - numSamplesDelay; - - for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { - // load up the stkFrameBuffer with this source's samples - stkFrameBuffer[s] = (stk::StkFloat) sourceBuffer[s]; - } - - // perform the TwoPole effect on the stkFrameBuffer - if (otherNodeTwoPole) { - otherNodeTwoPole->tick(stkFrameBuffer); - } - - for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { - if (s < numSamplesDelay) { - // pull the earlier sample for the delayed channel - int earlierSample = delaySamplePointer[s] * attenuationCoefficient * weakChannelAmplitudeRatio; - - delayedChannel[s] = glm::clamp(delayedChannel[s] + earlierSample, - MIN_SAMPLE_VALUE, - MAX_SAMPLE_VALUE); - } - int16_t currentSample = stkFrameBuffer[s] * attenuationCoefficient; + int16_t currentSample = stkFrameBuffer[s] * attenuationCoefficient; - goodChannel[s] = glm::clamp(goodChannel[s] + currentSample, - MIN_SAMPLE_VALUE, - MAX_SAMPLE_VALUE); + goodChannel[s] = glm::clamp(goodChannel[s] + currentSample, + MIN_SAMPLE_VALUE, + MAX_SAMPLE_VALUE); - if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - int sumSample = delayedChannel[s + numSamplesDelay] - + (currentSample * weakChannelAmplitudeRatio); - delayedChannel[s + numSamplesDelay] = glm::clamp(sumSample, - MIN_SAMPLE_VALUE, - MAX_SAMPLE_VALUE); - } + if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { + int sumSample = delayedChannel[s + numSamplesDelay] + + (currentSample * weakChannelAmplitudeRatio); + delayedChannel[s + numSamplesDelay] = glm::clamp(sumSample, + MIN_SAMPLE_VALUE, + MAX_SAMPLE_VALUE); + } - if (s >= BUFFER_LENGTH_SAMPLES_PER_CHANNEL - PHASE_DELAY_AT_90) { - // this could be a delayed sample on the next pass - // so store the affected back in the ARB - otherNodeBuffer->getNextOutput()[s] = (int16_t) stkFrameBuffer[s]; + if (s >= BUFFER_LENGTH_SAMPLES_PER_CHANNEL - PHASE_DELAY_AT_90) { + // this could be a delayed sample on the next pass + // so store the affected back in the ARB + otherNodeBuffer->getNextOutput()[s] = (int16_t) stkFrameBuffer[s]; + } } } } @@ -340,7 +346,6 @@ int main(int argc, const char* argv[]) { if (nodeBuffer->getNextOutput() >= nodeBuffer->getBuffer() + RING_BUFFER_LENGTH_SAMPLES) { nodeBuffer->setNextOutput(nodeBuffer->getBuffer()); } - nodeBuffer->setWillBeAddedToMix(false); } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d13d69ffb9..c1aa032542 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1835,6 +1835,11 @@ void Application::initMenu() { (_simulateLeapHand = debugMenu->addAction("Simulate Leap Hand"))->setCheckable(true); (_testRaveGlove = debugMenu->addAction("Test RaveGlove"))->setCheckable(true); + QMenu* audioDebugMenu = debugMenu->addMenu("Audio Debugging Tools"); + audioDebugMenu->addAction("Listen Mode Normal", this, SLOT(setListenModeNormal()), Qt::CTRL | Qt::Key_1); + audioDebugMenu->addAction("Listen Mode Point/Radius", this, SLOT(setListenModePoint()), Qt::CTRL | Qt::Key_2); + audioDebugMenu->addAction("Listen Mode Single Source", this, SLOT(setListenModeSingleSource()), Qt::CTRL | Qt::Key_3); + QMenu* settingsMenu = menuBar->addMenu("Settings"); (_settingsAutosave = settingsMenu->addAction("Autosave"))->setCheckable(true); _settingsAutosave->setChecked(true); @@ -1846,6 +1851,37 @@ void Application::initMenu() { _networkAccessManager = new QNetworkAccessManager(this); } +void Application::setListenModeNormal() { + _audio.setListenMode(AudioRingBuffer::NORMAL); +} + +void Application::setListenModePoint() { + _audio.setListenMode(AudioRingBuffer::OMNI_DIRECTIONAL_POINT); + _audio.setListenRadius(1.0); +} + +void Application::setListenModeSingleSource() { + _audio.setListenMode(AudioRingBuffer::SELECTED_SOURCES); + _audio.clearListenSources(); + + NodeList* nodeList = NodeList::getInstance(); + for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { + if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) { + Avatar* avatar = (Avatar *) node->getLinkedData(); + glm::vec3 headPosition = avatar->getHead().getPosition(); + glm::vec3 mouseRayOrigin = _myAvatar.getMouseRayOrigin(); + glm::vec3 mouseRayDirection = _myAvatar.getMouseRayDirection(); + const float HEAD_SPHERE_RADIUS = 0.07; + + if (rayIntersectsSphere(mouseRayOrigin, mouseRayDirection, headPosition, HEAD_SPHERE_RADIUS)) { + int sourceID = avatar->getOwningNode()->getNodeID(); + _audio.addListenSource(sourceID); + } + } + } +} + + void Application::updateFrustumRenderModeAction() { switch (_frustumDrawingMode) { default: diff --git a/interface/src/Application.h b/interface/src/Application.h index d29328c0b5..d462e88b98 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -170,6 +170,10 @@ private slots: void copyVoxels(); void pasteVoxels(); void runTests(); + void setListenModeNormal(); + void setListenModePoint(); + void setListenModeSingleSource(); + void renderCoverageMap(); void renderCoverageMapsRecursively(CoverageMap* map); diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 6bc2528bf0..9119d3984f 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -112,7 +112,7 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o // we need the amount of bytes in the buffer + 1 for type // + 12 for 3 floats for position + float for bearing + 1 attenuation byte - unsigned char dataPacket[BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes]; + unsigned char dataPacket[MAX_PACKET_SIZE]; PACKET_TYPE packetType = (Application::getInstance()->shouldEchoAudio()) ? PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO @@ -123,21 +123,25 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o // pack Source Data memcpy(currentPacketPtr, &_sourceID, sizeof(_sourceID)); currentPacketPtr += (sizeof(_sourceID)); + leadingBytes += (sizeof(_sourceID)); // pack Listen Mode Data memcpy(currentPacketPtr, &_listenMode, sizeof(_listenMode)); currentPacketPtr += (sizeof(_listenMode)); + leadingBytes += (sizeof(_listenMode)); if (_listenMode == AudioRingBuffer::OMNI_DIRECTIONAL_POINT) { memcpy(currentPacketPtr, &_listenRadius, sizeof(_listenRadius)); currentPacketPtr += (sizeof(_listenRadius)); + leadingBytes += (sizeof(_listenRadius)); } else if (_listenMode == AudioRingBuffer::SELECTED_SOURCES) { memcpy(currentPacketPtr, &_listenSourceCount, sizeof(_listenSourceCount)); currentPacketPtr += (sizeof(_listenSourceCount)); - + leadingBytes += (sizeof(_listenSourceCount)); if (_listenSources) { - memcpy(currentPacketPtr, &_listenSources, sizeof(int) * _listenSourceCount); + memcpy(currentPacketPtr, _listenSources, sizeof(int) * _listenSourceCount); currentPacketPtr += (sizeof(int) * _listenSourceCount); + leadingBytes += (sizeof(int) * _listenSourceCount); } } @@ -356,6 +360,12 @@ void Audio::addListenSource(int sourceID) { _listenSourceCount++; } +void Audio::clearListenSources() { + delete[] _listenSources; + _listenSources = NULL; + _listenSourceCount = 0; +} + void Audio::removeListenSource(int sourceID) { // If we don't yet have a list of listen sources, make one if (_listenSources) { diff --git a/interface/src/Audio.h b/interface/src/Audio.h index ca665c66f0..facc6a1caf 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -60,6 +60,7 @@ public: void setListenRadius(float radius) { _listenRadius = radius; }; void addListenSource(int sourceID); void removeListenSource(int sourceID); + void clearListenSources(); private: PaStream* _stream; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 75e0ab2f9b..ec0d5a2ce5 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -164,6 +164,10 @@ public: glm::quat getOrientation () const; glm::quat getWorldAlignedOrientation() const; + const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; } + const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; } + + glm::vec3 getGravity () const { return _gravity; } glm::vec3 getUprightHeadPosition() const; From 229d16b9c749a1e0671bb8ca3c79dfdfa51c289e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Jul 2013 23:06:08 -0700 Subject: [PATCH 15/88] added local mode to injector --- injector/src/main.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/injector/src/main.cpp b/injector/src/main.cpp index e2c1effc15..0c3ea2bfe6 100644 --- a/injector/src/main.cpp +++ b/injector/src/main.cpp @@ -40,11 +40,13 @@ bool hasInjectedAudioOnce = false; float sleepIntervalMin = 1.00; float sleepIntervalMax = 2.00; char *sourceAudioFile = NULL; -const char *allowedParameters = ":sc::a::f::t::r:"; +const char *allowedParameters = ":sc::a::f::t::r:l"; float floatArguments[4] = {0.0f, 0.0f, 0.0f, 0.0f}; unsigned char volume = DEFAULT_INJECTOR_VOLUME; float triggerDistance = 0.0f; float radius = 0.0f; +bool wantLocalDomain = false; + void usage(void) { std::cout << "High Fidelity - Interface audio injector" << std::endl; @@ -54,6 +56,7 @@ void usage(void) { std::cout << " -f FILENAME Name of audio source file. Required - RAW format, 22050hz 16bit signed mono" << std::endl; std::cout << " -t FLOAT Trigger distance for injection. If not specified will loop constantly" << std::endl; std::cout << " -r FLOAT Radius for spherical source. If not specified injected audio is point source" << std::endl; + std::cout << " -l Local domain mode." << std::endl; } bool processParameters(int parameterCount, char* parameterData[]) { @@ -96,6 +99,9 @@ bool processParameters(int parameterCount, char* parameterData[]) { ::radius = atof(optarg); std::cout << "[DEBUG] Injector radius: " << optarg << std::endl; break; + case 'l': + ::wantLocalDomain = true; + break; default: usage(); return false; @@ -111,6 +117,7 @@ void createAvatarDataForNode(Node* node) { } int main(int argc, char* argv[]) { + // new seed for random audio sleep times srand(time(0)); @@ -126,6 +133,11 @@ int main(int argc, char* argv[]) { // create an NodeList instance to handle communication with other nodes NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AUDIO_INJECTOR, AUDIO_UDP_SEND_PORT); + if (::wantLocalDomain) { + printf("Local Domain MODE!\n"); + nodeList->setDomainIPToLocalhost(); + } + // start the node list thread that will kill off nodes when they stop talking nodeList->startSilentNodeRemovalThread(); From 062ee657ca48fdfd310a6030e53e7aa6f57ce657 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 23 Jul 2013 14:41:52 -0700 Subject: [PATCH 16/88] added extra mode and started prototyping "ribbon" effect --- interface/src/ParticleSystem.cpp | 306 +++++++++++++++++++------------ interface/src/ParticleSystem.h | 69 ++++--- interface/src/avatar/Hand.cpp | 173 +++++++++++------ interface/src/avatar/Hand.h | 3 + 4 files changed, 344 insertions(+), 207 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 40c493dcbd..c40d692166 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -25,19 +25,16 @@ ParticleSystem::ParticleSystem() { for (unsigned int emitterIndex = 0; emitterIndex < MAX_EMITTERS; emitterIndex++) { - _emitter[emitterIndex].position = glm::vec3(0.0f, 0.0f, 0.0f); - _emitter[emitterIndex].direction = glm::vec3(0.0f, 1.0f, 0.0f); - _emitter[emitterIndex].visible = false; - _emitter[emitterIndex].particleResolution = DEFAULT_PARTICLE_SPHERE_RESOLUTION; - _emitter[emitterIndex].particleLifespan = DEFAULT_PARTICLE_LIFESPAN; - _emitter[emitterIndex].baseParticle.alive = false; - _emitter[emitterIndex].baseParticle.age = 0.0f; - _emitter[emitterIndex].thrust = 0.0f; - _emitter[emitterIndex].rate = 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); + _emitter[emitterIndex].position = glm::vec3(0.0f, 0.0f, 0.0f); + _emitter[emitterIndex].direction = glm::vec3(0.0f, 1.0f, 0.0f); + _emitter[emitterIndex].visible = false; + _emitter[emitterIndex].particleResolution = DEFAULT_PARTICLE_SPHERE_RESOLUTION; + _emitter[emitterIndex].particleLifespan = DEFAULT_PARTICLE_LIFESPAN; + _emitter[emitterIndex].showingBaseParticle = false; + _emitter[emitterIndex].thrust = 0.0f; + _emitter[emitterIndex].rate = 0.0f; + _emitter[emitterIndex].currentParticle = 0; + _emitter[emitterIndex].particleRenderStyle = PARTICLE_RENDER_STYLE_SPHERE; for (int lifeStage = 0; lifeStage 0.0) { + + Emitter myEmitter = _emitter[_particle[p].emitterIndex]; + + assert(_particle[p].age <= myEmitter.particleLifespan); - int lifeStage = (int)( ageFraction * (NUM_PARTICLE_LIFE_STAGES-1) ); + float ageFraction = _particle[p].age / myEmitter.particleLifespan; + + int lifeStage = (int)( ageFraction * (NUM_PARTICLE_LIFE_STAGES-1) ); - float lifeStageFraction = ageFraction * ( NUM_PARTICLE_LIFE_STAGES - 1 ) - lifeStage; + float lifeStageFraction = ageFraction * ( NUM_PARTICLE_LIFE_STAGES - 1 ) - lifeStage; + + + _particle[p].radius + = myEmitter.particleAttributes[lifeStage ].radius * (1.0f - lifeStageFraction) + + myEmitter.particleAttributes[lifeStage+1].radius * lifeStageFraction; + + _particle[p].color + = myEmitter.particleAttributes[lifeStage ].color * (1.0f - lifeStageFraction) + + myEmitter.particleAttributes[lifeStage+1].color * lifeStageFraction; + + // apply random jitter + float j = myEmitter.particleAttributes[lifeStage].jitter; + _particle[p].velocity += + glm::vec3 + ( + -j * ONE_HALF + j * randFloat(), + -j * ONE_HALF + j * randFloat(), + -j * ONE_HALF + j * randFloat() + ) * deltaTime; - _particle[p].radius - = _emitter[_particle[p].emitterIndex].particleAttributes[lifeStage ].radius * (1.0f - lifeStageFraction) - + _emitter[_particle[p].emitterIndex].particleAttributes[lifeStage+1].radius * lifeStageFraction; - - _particle[p].color - = _emitter[_particle[p].emitterIndex].particleAttributes[lifeStage ].color * (1.0f - lifeStageFraction) - + _emitter[_particle[p].emitterIndex].particleAttributes[lifeStage+1].color * lifeStageFraction; + // apply attraction to home position + glm::vec3 vectorToHome = myEmitter.position - _particle[p].position; + _particle[p].velocity += vectorToHome * myEmitter.particleAttributes[lifeStage].emitterAttraction * deltaTime; - Emitter myEmitter = _emitter[_particle[p].emitterIndex]; - - // apply random jitter - float j = myEmitter.particleAttributes[lifeStage].jitter; - _particle[p].velocity += - glm::vec3 - ( - -j * ONE_HALF + j * randFloat(), - -j * ONE_HALF + j * randFloat(), - -j * ONE_HALF + j * randFloat() - ) * deltaTime; - - // apply attraction to home position - glm::vec3 vectorToHome = myEmitter.position - _particle[p].position; - _particle[p].velocity += vectorToHome * myEmitter.particleAttributes[lifeStage].emitterAttraction * deltaTime; - - // apply neighbor attraction - int neighbor = p + 1; - if (neighbor == _numParticles ) { - neighbor = 0; - } - - if ( _particle[neighbor].emitterIndex == _particle[p].emitterIndex) { - glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position; - - _particle[p].velocity -= vectorToNeighbor * myEmitter.particleAttributes[lifeStage].neighborAttraction * deltaTime; - - float distanceToNeighbor = glm::length(vectorToNeighbor); - if (distanceToNeighbor > 0.0f) { - _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * myEmitter.particleAttributes[lifeStage].neighborRepulsion * deltaTime; + // apply neighbor attraction + int neighbor = p + 1; + if (neighbor == _numParticles ) { + neighbor = 0; } - } - - // apply tornado force - glm::vec3 tornadoDirection = glm::cross(vectorToHome, myEmitter.direction); - _particle[p].velocity += tornadoDirection * myEmitter.particleAttributes[lifeStage].tornadoForce * deltaTime; - - // apply air friction - float drag = 1.0 - myEmitter.particleAttributes[lifeStage].airFriction * deltaTime; - if (drag < 0.0f) { - _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); - } else { - _particle[p].velocity *= drag; - } - - // apply gravity - _particle[p].velocity -= _upDirection * myEmitter.particleAttributes[lifeStage].gravity * deltaTime; - - // update position by velocity - _particle[p].position += _particle[p].velocity; - - // collision with ground - if (_particle[p].position.y < _particle[p].radius) { - _particle[p].position.y = _particle[p].radius; - if (_particle[p].velocity.y < 0.0f) { - _particle[p].velocity.y *= -myEmitter.particleAttributes[lifeStage].bounce; - } - } - - // collision with sphere - if (myEmitter.particleAttributes[lifeStage].usingCollisionSphere) { - glm::vec3 vectorToSphereCenter = myEmitter.particleAttributes[lifeStage].collisionSpherePosition - _particle[p].position; - float distanceToSphereCenter = glm::length(vectorToSphereCenter); - float combinedRadius = myEmitter.particleAttributes[lifeStage].collisionSphereRadius + _particle[p].radius; - if (distanceToSphereCenter < combinedRadius) { + if ( _particle[neighbor].emitterIndex == _particle[p].emitterIndex) { + glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position; - if (distanceToSphereCenter > 0.0f){ - glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter; - _particle[p].position = myEmitter.particleAttributes[lifeStage].collisionSpherePosition - directionToSphereCenter * combinedRadius; + _particle[p].velocity -= vectorToNeighbor * myEmitter.particleAttributes[lifeStage].neighborAttraction * deltaTime; + + float distanceToNeighbor = glm::length(vectorToNeighbor); + if (distanceToNeighbor > 0.0f) { + _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * myEmitter.particleAttributes[lifeStage].neighborRepulsion * deltaTime; } } - } + + // apply tornado force + glm::vec3 tornadoDirection = glm::cross(vectorToHome, myEmitter.direction); + _particle[p].velocity += tornadoDirection * myEmitter.particleAttributes[lifeStage].tornadoForce * deltaTime; + + // apply air friction + float drag = 1.0 - myEmitter.particleAttributes[lifeStage].airFriction * deltaTime; + if (drag < 0.0f) { + _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); + } else { + _particle[p].velocity *= drag; + } + + // apply gravity + _particle[p].velocity -= _upDirection * myEmitter.particleAttributes[lifeStage].gravity * deltaTime; + + // update position by velocity + _particle[p].position += _particle[p].velocity; + + // collision with ground + if (_particle[p].position.y < _particle[p].radius) { + _particle[p].position.y = _particle[p].radius; + + if (_particle[p].velocity.y < 0.0f) { + _particle[p].velocity.y *= -myEmitter.particleAttributes[lifeStage].bounce; + } + } + + // collision with sphere + if (myEmitter.particleAttributes[lifeStage].usingCollisionSphere) { + glm::vec3 vectorToSphereCenter = myEmitter.particleAttributes[lifeStage].collisionSpherePosition - _particle[p].position; + float distanceToSphereCenter = glm::length(vectorToSphereCenter); + float combinedRadius = myEmitter.particleAttributes[lifeStage].collisionSphereRadius + _particle[p].radius; + if (distanceToSphereCenter < combinedRadius) { + + if (distanceToSphereCenter > 0.0f){ + glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter; + _particle[p].position = myEmitter.particleAttributes[lifeStage].collisionSpherePosition - directionToSphereCenter * combinedRadius; + } + } + } + } // do this at the end... - _particle[p].age += deltaTime; + _particle[p].age += deltaTime; } -void ParticleSystem::setShowingEmitterBaseParticle(int emitterIndex, bool showing ) { - - _emitter[emitterIndex].baseParticle.alive = true; - _emitter[emitterIndex].baseParticle.emitterIndex = emitterIndex; -} void ParticleSystem::killAllParticles() { @@ -277,11 +282,11 @@ void ParticleSystem::render() { // render the emitters for (int e = 0; e < _numEmitters; e++) { - if (_emitter[e].baseParticle.alive) { - glColor4f(_emitter[e].baseParticle.color.r, _emitter[e].baseParticle.color.g, _emitter[e].baseParticle.color.b, _emitter[e].baseParticle.color.a ); + if (_emitter[e].showingBaseParticle) { + glColor4f(_particle[0].color.r, _particle[0].color.g, _particle[0].color.b, _particle[0].color.a ); glPushMatrix(); glTranslatef(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); - glutSolidSphere(_emitter[e].baseParticle.radius, _emitter[e].particleResolution, _emitter[e].particleResolution); + glutSolidSphere(_particle[0].radius, _emitter[e].particleResolution, _emitter[e].particleResolution); glPopMatrix(); } @@ -289,11 +294,13 @@ void ParticleSystem::render() { renderEmitter(e, 0.2f); } }; - + // render the particles for (unsigned int p = 0; p < _numParticles; p++) { if (_particle[p].alive) { - renderParticle(p); + if (_emitter[_particle[p].emitterIndex].particleLifespan > 0.0) { + renderParticle(p); + } } } } @@ -302,7 +309,7 @@ void ParticleSystem::renderParticle(int p) { glColor4f(_particle[p].color.r, _particle[p].color.g, _particle[p].color.b, _particle[p].color.a ); - if (USE_BILLBOARD_RENDERING) { + if (_emitter[_particle[p].emitterIndex].particleRenderStyle == PARTICLE_RENDER_STYLE_BILLBOARD) { glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); glm::vec3 viewVector = _particle[p].position - cameraPosition; float distance = glm::length(viewVector); @@ -329,7 +336,7 @@ void ParticleSystem::renderParticle(int p) { glVertex3f(p3.x, p3.y, p3.z); glEnd(); } - } else { + } 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); @@ -343,9 +350,66 @@ void ParticleSystem::renderParticle(int p) { 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) { + + 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; + + glm::vec3 up = glm::normalize(glm::cross(v, _upDirection)); + glm::vec3 right = glm::normalize(glm::cross(up, v)); + + right *= _particle[p].radius; + up *= _particle[p].radius; + + glm::vec3 p0Left = _particle[p ].position - right; + glm::vec3 p0Right = _particle[p ].position + right; + glm::vec3 p0Down = _particle[p ].position - up; + glm::vec3 p0Up = _particle[p ].position + up; + + glm::vec3 ppLeft = _particle[pp].position - right; + glm::vec3 ppRight = _particle[pp].position + right; + glm::vec3 ppDown = _particle[pp].position - up; + glm::vec3 ppUp = _particle[pp].position + up; + + glBegin(GL_TRIANGLES); + glVertex3f(p0Left.x, p0Left.y, p0Left.z ); + glVertex3f(p0Right.x, p0Right.y, p0Right.z ); + glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); + glEnd(); + + glBegin(GL_TRIANGLES); + glVertex3f(p0Right.x, p0Right.y, p0Right.z ); + glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); + glVertex3f(ppRight.x, ppRight.y, ppRight.z ); + glEnd(); + + glBegin(GL_TRIANGLES); + glVertex3f(p0Up.x, p0Up.y, p0Up.z ); + glVertex3f(p0Down.x, p0Down.y, p0Down.z ); + glVertex3f(ppDown.x, ppDown.y, ppDown.z ); + glEnd(); + + glBegin(GL_TRIANGLES); + glVertex3f(p0Up.x, p0Up.y, p0Up.z ); + glVertex3f(ppUp.x, ppUp.y, ppUp.z ); + glVertex3f(ppDown.x, ppDown.y, ppDown.z ); + glEnd(); + } + } + } } } + void ParticleSystem::renderEmitter(int e, float size) { glLineWidth(2.0f); diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index 680e345d77..9ba8d8ed35 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -11,11 +11,18 @@ #include const int MAX_PARTICLES = 5000; -const int MAX_EMITTERS = 20; -const int NUM_PARTICLE_LIFE_STAGES = 4; -const bool USE_BILLBOARD_RENDERING = false; +const int MAX_EMITTERS = 1000; +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 +{ + PARTICLE_RENDER_STYLE_SPHERE = 0, + PARTICLE_RENDER_STYLE_BILLBOARD, + PARTICLE_RENDER_STYLE_RIBBON, + NUM_PARTICLE_RENDER_STYLES +}; + class ParticleSystem { public: @@ -45,42 +52,44 @@ public: void render(); void setUpDirection(glm::vec3 upDirection) {_upDirection = upDirection;} // tell particle system which direction is up - void setShowingEmitterBaseParticle(int emitterIndex, bool showing ); void setParticleAttributes (int emitterIndex, ParticleAttributes attributes); // set attributes for whole life of particles void setParticleAttributes (int emitterIndex, int lifeStage, ParticleAttributes attributes); // set attributes for this life stage of particles - void setEmitterBaseParticleColor (int emitterIndex, glm::vec4 color ) {_emitter[emitterIndex].baseParticle.color = color; } - void setEmitterBaseParticleRadius (int emitterIndex, float radius ) {_emitter[emitterIndex].baseParticle.radius = radius; } - void setEmitterPosition (int emitterIndex, glm::vec3 position ) {_emitter[emitterIndex].position = position; } - void setEmitterParticleResolution (int emitterIndex, int resolution) {_emitter[emitterIndex].particleResolution = resolution; } - void setEmitterDirection (int emitterIndex, glm::vec3 direction ) {_emitter[emitterIndex].direction = direction; } - void setShowingEmitter (int emitterIndex, bool showing ) {_emitter[emitterIndex].visible = showing; } - void setEmitterParticleLifespan (int emitterIndex, float lifespan ) {_emitter[emitterIndex].particleLifespan = lifespan; } - void setEmitterThrust (int emitterIndex, float thrust ) {_emitter[emitterIndex].thrust = thrust; } - void setEmitterRate (int emitterIndex, float rate ) {_emitter[emitterIndex].rate = rate; } - + void setEmitterPosition (int emitterIndex, glm::vec3 position ) {_emitter[emitterIndex].position = position; } + void setEmitterParticleResolution (int emitterIndex, int resolution ) {_emitter[emitterIndex].particleResolution = resolution; } + void setEmitterDirection (int emitterIndex, glm::vec3 direction ) {_emitter[emitterIndex].direction = direction; } + void setShowingEmitter (int emitterIndex, bool showing ) {_emitter[emitterIndex].visible = showing; } + void setEmitterParticleLifespan (int emitterIndex, float lifespan ) {_emitter[emitterIndex].particleLifespan = lifespan; } + void setParticleRenderStyle (int emitterIndex, ParticleRenderStyle renderStyle ) {_emitter[emitterIndex].particleRenderStyle = renderStyle; } + void setEmitterThrust (int emitterIndex, float thrust ) {_emitter[emitterIndex].thrust = thrust; } + void setEmitterRate (int emitterIndex, float rate ) {_emitter[emitterIndex].rate = rate; } + void setShowingEmitterBaseParticle(int emitterIndex, bool showing ) {_emitter[emitterIndex].showingBaseParticle = showing; } + 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 - 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 + int emitterIndex; // which emitter created this particle? + int previousParticle; // the last particle that this particle's emitter emitted; }; struct Emitter { - glm::vec3 position; // teh position of the emitter in world coordinates - glm::vec3 direction; // a normalized vector used as an axis for particle emission and other effects - 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 thrust; // the initial velocity upon emitting along the emitter direction - float rate; // currently, how many particles emitted during a simulation time step - Particle baseParticle; // a non-physical particle at the emitter position + glm::vec3 position; // the position of the emitter in world coordinates + glm::vec3 direction; // a normalized vector used as an axis for particle emission and other effects + 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 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 + int currentParticle; // the index of the most recently-emitted particle ParticleAttributes particleAttributes[NUM_PARTICLE_LIFE_STAGES]; // the attributes of particles emitted from this emitter - }; + ParticleRenderStyle particleRenderStyle; + }; glm::vec3 _upDirection; Emitter _emitter[MAX_EMITTERS]; diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 782eb9306a..8a4f04ad78 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -14,7 +14,9 @@ #include "Util.h" #include "renderer/ProgramObject.h" -const bool SHOW_LEAP_HAND = true; +const bool SHOW_LEAP_HAND = false; +const int NUM_TEST_RAVE_GLOVE_MODES = 5; +const float TEST_RAVE_GLOVE_MODE_DURATION = 7.0f; using namespace std; @@ -34,6 +36,10 @@ Hand::Hand(Avatar* owningAvatar) : // initialize all finger particle emitters with an invalid id as default for (int f = 0; f< NUM_FINGERS; f ++ ) { _fingerParticleEmitter[f] = -1; + + //for (int t = 0; t < MAX_TRAIL_PARTICLES; t ++ ) { + // _fingerTrailParticleEmitter[f][t] = -1; + //} } } @@ -281,23 +287,44 @@ void Hand::updateFingerParticles(float deltaTime) { _testRaveGloveClock += deltaTime; // cycle through the rave glove test modes... - if (_testRaveGloveClock > 4) { + if (_testRaveGloveClock > TEST_RAVE_GLOVE_MODE_DURATION) { _testRaveGloveClock = 0.0f; _testRaveGloveMode ++; - if (_testRaveGloveMode > 4) { + if (_testRaveGloveMode > NUM_TEST_RAVE_GLOVE_MODES) { _testRaveGloveMode = 0; } setRaveGloveMode(_testRaveGloveMode); } - if (_testRaveGloveMode == 3) { + if (_testRaveGloveMode == 0) { ParticleSystem::ParticleAttributes attributes; float red = 0.5f + 0.5f * sinf(_testRaveGloveClock * 1.4f); float green = 0.5f + 0.5f * cosf(_testRaveGloveClock * 1.7f); float blue = 0.5f + 0.5f * sinf(_testRaveGloveClock * 2.0f); attributes.color = glm::vec4(red, green, blue, 1.0f); - attributes.radius = 0.02f; + attributes.radius = 0.01f + 0.005f * sinf(_testRaveGloveClock * 2.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); + } + } 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); @@ -332,20 +359,78 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.killAllParticles(); for ( int f = 0; f< NUM_FINGERS; f ++ ) { - + ParticleSystem::ParticleAttributes attributes; //----------------------------------------- - // Fire! + // throbbing color cycle //----------------------------------------- if (mode == 0) { + + _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.0f ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.0f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0f ); + _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 20 ); - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0 ); - _particleSystem.setEmitterParticleResolution(_fingerParticleEmitter[f], 6 ); + attributes.radius = 0.02f; + attributes.color = glm::vec4( 0.0f, 0.0f, 0.0f, 0.0f); + attributes.gravity = 0.0f; + 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; + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); - attributes.radius = 0.0f; + //----------------------------------------- + // trails + //----------------------------------------- + } else if (mode == 1) { + _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); + _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.0f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0f ); + _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 5 ); + + attributes.radius = 0.001f; + attributes.color = glm::vec4( 1.0f, 0.2f, 0.2f, 1.0f); + 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; + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + } + + //----------------------------------------- + // Fire! + //----------------------------------------- + if (mode == 2) { + + _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0 ); + _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 6 ); + + attributes.radius = 0.005f; attributes.color = glm::vec4( 1.0f, 1.0f, 0.5f, 0.5f); attributes.gravity = 0.0f; attributes.airFriction = 0.0f; @@ -373,21 +458,21 @@ void Hand::setRaveGloveMode(int mode) { attributes.color = glm::vec4( 0.4f, 0.6f, 0.9f, 0.0f); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); - - //----------------------------------------- // water //----------------------------------------- - } else if (mode == 1) { + } else if (mode == 3) { - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 10.0 ); - _particleSystem.setEmitterParticleResolution(_fingerParticleEmitter[f], 5 ); + _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 10.0 ); + _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 5 ); attributes.radius = 0.001f; attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.5f); - attributes.gravity = -0.005f; + attributes.gravity = -0.01f; attributes.airFriction = 0.0f; attributes.jitter = 0.002f; attributes.emitterAttraction = 0.0f; @@ -398,7 +483,7 @@ void Hand::setRaveGloveMode(int mode) { attributes.usingCollisionSphere = false; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); - attributes.gravity = 0.005f; + attributes.gravity = 0.01f; attributes.jitter = 0.0f; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); @@ -412,18 +497,20 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // flashy //----------------------------------------- - } else if (mode == 2) { + } else if (mode == 4) { - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.05f ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0 ); - _particleSystem.setEmitterParticleResolution(_fingerParticleEmitter[f], 12 ); + _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.1 ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 3.0 ); + _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 12 ); attributes.radius = 0.0f; - attributes.color = glm::vec4( 1.0f, 0.0f, 0.0f, 1.0f); + attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); attributes.gravity = 0.0f; attributes.airFriction = 0.0f; - attributes.jitter = 0.1f; + attributes.jitter = 0.05f; attributes.emitterAttraction = 0.0f; attributes.tornadoForce = 0.0f; attributes.neighborAttraction = 0.0f; @@ -437,37 +524,11 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); attributes.radius = 0.01f; - attributes.color = glm::vec4( 0.0f, 0.0f, 1.0f, 1.0f); + attributes.color = glm::vec4( 1.0f, 0.0f, 1.0f, 1.0f); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); attributes.radius = 0.0f; - attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); - - //----------------------------------------- - // color cycle - //----------------------------------------- - } else if (mode == 3) { - - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.05f); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0f ); - _particleSystem.setEmitterParticleResolution(_fingerParticleEmitter[f], 20 ); - - attributes.radius = 0.02f; - attributes.color = glm::vec4( 1.0f, 0.0f, 0.0f, 1.0f); - attributes.gravity = 0.0f; - 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; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + attributes.color = glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); } } diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index 8152a4b271..d0782138da 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -19,6 +19,8 @@ #include #include +//const int MAX_TRAIL_PARTICLES = 20; + class Avatar; class ProgramObject; @@ -61,6 +63,7 @@ private: int _testRaveGloveMode; bool _particleSystemInitialized; int _fingerParticleEmitter[NUM_FINGERS]; + //int _fingerTrailParticleEmitter[NUM_FINGERS][MAX_TRAIL_PARTICLES]; Avatar* _owningAvatar; float _renderAlpha; bool _lookingInMirror; From a12ebc63c3bdbe627768b5611065f8bcab5da569 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 23 Jul 2013 18:26:10 -0700 Subject: [PATCH 17/88] made listen mode a typedef --- audio-mixer/src/PositionalAudioRingBuffer.h | 12 ++++++------ libraries/audio/src/AudioRingBuffer.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/audio-mixer/src/PositionalAudioRingBuffer.h b/audio-mixer/src/PositionalAudioRingBuffer.h index eb6f0414e7..58a080872d 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.h +++ b/audio-mixer/src/PositionalAudioRingBuffer.h @@ -33,7 +33,7 @@ public: bool isListeningToSource(PositionalAudioRingBuffer* other); int getSourceID() const { return _sourceID; } - int getListeningMode() const { return _listenMode; } + ListenMode getListeningMode() const { return _listenMode; } protected: // disallow copying of PositionalAudioRingBuffer objects @@ -44,11 +44,11 @@ protected: glm::quat _orientation; bool _willBeAddedToMix; - int _sourceID; - int _listenMode; - float _listenRadius; - int _listenSourceCount; - int* _listenSources; + int _sourceID; + ListenMode _listenMode; + float _listenRadius; + int _listenSourceCount; + int* _listenSources; }; diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index be87558010..4c5374f032 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -29,11 +29,11 @@ class AudioRingBuffer : public NodeData { public: static int const DEFAULT_LISTEN_LIST_SIZE = 100; - enum { + typedef enum { NORMAL, OMNI_DIRECTIONAL_POINT, SELECTED_SOURCES - }; + } ListenMode; AudioRingBuffer(bool isStereo); ~AudioRingBuffer(); From 13ba913fabe58595dcc1114613f724ac2c4d513b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 23 Jul 2013 18:28:30 -0700 Subject: [PATCH 18/88] made listen mode a typedef --- interface/src/Audio.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/interface/src/Audio.h b/interface/src/Audio.h index facc6a1caf..9552d6e2ec 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -56,7 +56,7 @@ public: int getSourceID() const { return _sourceID; }; void setSourceID(int sourceID) { _sourceID = sourceID; }; - void setListenMode(int mode) { _listenMode = mode; }; + void setListenMode(AudioRingBuffer::ListenMode mode) { _listenMode = mode; }; void setListenRadius(float radius) { _listenRadius = radius; }; void addListenSource(int sourceID); void removeListenSource(int sourceID); @@ -98,12 +98,12 @@ private: int _proceduralEffectSample; float _heartbeatMagnitude; - int _sourceID; - int _listenMode; - float _listenRadius; - int _listenSourceCount; - int _listenSourcesArraySize; - int* _listenSources; + int _sourceID; + AudioRingBuffer::ListenMode _listenMode; + float _listenRadius; + int _listenSourceCount; + int _listenSourcesArraySize; + int* _listenSources; // Audio callback in class context. inline void performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* outputRight); From 927b0b6708e131e6985d04c7a6a5ac8a18526659 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 23 Jul 2013 18:31:57 -0700 Subject: [PATCH 19/88] style fixes --- audio-mixer/src/PositionalAudioRingBuffer.cpp | 8 ++++---- injector/src/main.cpp | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/audio-mixer/src/PositionalAudioRingBuffer.cpp b/audio-mixer/src/PositionalAudioRingBuffer.cpp index 26961c76e8..55622566a5 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.cpp +++ b/audio-mixer/src/PositionalAudioRingBuffer.cpp @@ -37,13 +37,13 @@ bool PositionalAudioRingBuffer::isListeningToSource(PositionalAudioRingBuffer* o default: case AudioRingBuffer::NORMAL: return true; - break; + break; case AudioRingBuffer::OMNI_DIRECTIONAL_POINT: { float distance = glm::distance(_position, other->_position); return distance <= _listenRadius; - break; - } + break; + } case AudioRingBuffer::SELECTED_SOURCES: if (_listenSources) { for (int i = 0; i < _listenSourceCount; i++) { @@ -53,7 +53,7 @@ bool PositionalAudioRingBuffer::isListeningToSource(PositionalAudioRingBuffer* o } } return false; - break; + break; } } diff --git a/injector/src/main.cpp b/injector/src/main.cpp index 0c3ea2bfe6..9caad19e60 100644 --- a/injector/src/main.cpp +++ b/injector/src/main.cpp @@ -45,7 +45,7 @@ float floatArguments[4] = {0.0f, 0.0f, 0.0f, 0.0f}; unsigned char volume = DEFAULT_INJECTOR_VOLUME; float triggerDistance = 0.0f; float radius = 0.0f; -bool wantLocalDomain = false; +bool wantsLocalDomain = false; void usage(void) { @@ -100,7 +100,7 @@ bool processParameters(int parameterCount, char* parameterData[]) { std::cout << "[DEBUG] Injector radius: " << optarg << std::endl; break; case 'l': - ::wantLocalDomain = true; + ::wantsLocalDomain = true; break; default: usage(); @@ -133,7 +133,7 @@ int main(int argc, char* argv[]) { // create an NodeList instance to handle communication with other nodes NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AUDIO_INJECTOR, AUDIO_UDP_SEND_PORT); - if (::wantLocalDomain) { + if (::wantsLocalDomain) { printf("Local Domain MODE!\n"); nodeList->setDomainIPToLocalhost(); } From 686bd6c5d103d9eea0963a8b4fb3de7069b8998e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 23 Jul 2013 19:06:47 -0700 Subject: [PATCH 20/88] removed _sourceID, using getNodeID() feature of Node class --- audio-mixer/src/PositionalAudioRingBuffer.cpp | 21 ++++++------------- audio-mixer/src/PositionalAudioRingBuffer.h | 5 +---- audio-mixer/src/main.cpp | 17 +++++++-------- 3 files changed, 14 insertions(+), 29 deletions(-) diff --git a/audio-mixer/src/PositionalAudioRingBuffer.cpp b/audio-mixer/src/PositionalAudioRingBuffer.cpp index 55622566a5..4dc409628f 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.cpp +++ b/audio-mixer/src/PositionalAudioRingBuffer.cpp @@ -8,6 +8,7 @@ #include +#include #include #include "PositionalAudioRingBuffer.h" @@ -17,7 +18,6 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer() : _position(0.0f, 0.0f, 0.0f), _orientation(0.0f, 0.0f, 0.0f, 0.0f), _willBeAddedToMix(false), - _sourceID(-1), _listenMode(AudioRingBuffer::NORMAL), _listenRadius(0.0f), _listenSourceCount(0), @@ -32,7 +32,7 @@ PositionalAudioRingBuffer::~PositionalAudioRingBuffer() { } } -bool PositionalAudioRingBuffer::isListeningToSource(PositionalAudioRingBuffer* other) { +bool PositionalAudioRingBuffer::isListeningToNode(Node& other) const { switch (_listenMode) { default: case AudioRingBuffer::NORMAL: @@ -40,14 +40,15 @@ bool PositionalAudioRingBuffer::isListeningToSource(PositionalAudioRingBuffer* o break; case AudioRingBuffer::OMNI_DIRECTIONAL_POINT: { - float distance = glm::distance(_position, other->_position); + PositionalAudioRingBuffer* otherNodeBuffer = (PositionalAudioRingBuffer*) other.getLinkedData(); + float distance = glm::distance(_position, otherNodeBuffer->_position); return distance <= _listenRadius; break; } case AudioRingBuffer::SELECTED_SOURCES: if (_listenSources) { for (int i = 0; i < _listenSourceCount; i++) { - if (other->_sourceID == _listenSources[i]) { + if (other.getNodeID() == _listenSources[i]) { return true; } } @@ -60,7 +61,7 @@ bool PositionalAudioRingBuffer::isListeningToSource(PositionalAudioRingBuffer* o int PositionalAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char* currentBuffer = sourceBuffer + numBytesForPacketHeader(sourceBuffer); - currentBuffer += parseSourceData(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); + currentBuffer += sizeof(int); // the source ID currentBuffer += parseListenModeData(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); currentBuffer += parsePositionalData(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); currentBuffer += parseAudioSamples(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); @@ -68,15 +69,6 @@ int PositionalAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numByt return currentBuffer - sourceBuffer; } -int PositionalAudioRingBuffer::parseSourceData(unsigned char* sourceBuffer, int numBytes) { - unsigned char* currentBuffer = sourceBuffer; - - memcpy(&_sourceID, currentBuffer, sizeof(_sourceID)); - currentBuffer += sizeof(_sourceID); - - return currentBuffer - sourceBuffer; -} - int PositionalAudioRingBuffer::parseListenModeData(unsigned char* sourceBuffer, int numBytes) { unsigned char* currentBuffer = sourceBuffer; @@ -134,6 +126,5 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix(int numJitterBufferSamples) { return true; } } - return false; } diff --git a/audio-mixer/src/PositionalAudioRingBuffer.h b/audio-mixer/src/PositionalAudioRingBuffer.h index 58a080872d..44d8a2b4f8 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.h +++ b/audio-mixer/src/PositionalAudioRingBuffer.h @@ -20,7 +20,6 @@ public: int parseData(unsigned char* sourceBuffer, int numBytes); int parsePositionalData(unsigned char* sourceBuffer, int numBytes); - int parseSourceData(unsigned char* sourceBuffer, int numBytes); int parseListenModeData(unsigned char* sourceBuffer, int numBytes); bool shouldBeAddedToMix(int numJitterBufferSamples); @@ -31,8 +30,7 @@ public: const glm::vec3& getPosition() const { return _position; } const glm::quat& getOrientation() const { return _orientation; } - bool isListeningToSource(PositionalAudioRingBuffer* other); - int getSourceID() const { return _sourceID; } + bool isListeningToNode(Node& other) const; ListenMode getListeningMode() const { return _listenMode; } protected: @@ -44,7 +42,6 @@ protected: glm::quat _orientation; bool _willBeAddedToMix; - int _sourceID; ListenMode _listenMode; float _listenRadius; int _listenSourceCount; diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 2f17113ba4..6cfa106e5b 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -141,7 +141,6 @@ int main(int argc, const char* argv[]) { for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { PositionalAudioRingBuffer* positionalRingBuffer = (PositionalAudioRingBuffer*) node->getLinkedData(); - if (positionalRingBuffer && positionalRingBuffer->shouldBeAddedToMix(JITTER_BUFFER_SAMPLES)) { // this is a ring buffer that is ready to go // set its flag so we know to push its buffer when all is said and done @@ -161,14 +160,11 @@ int main(int argc, const char* argv[]) { // loop through all other nodes that have sufficient audio to mix for (NodeList::iterator otherNode = nodeList->begin(); otherNode != nodeList->end(); otherNode++) { - if (((PositionalAudioRingBuffer*) otherNode->getLinkedData())->willBeAddedToMix() && (otherNode != node || (otherNode == node && nodeRingBuffer->shouldLoopbackForNode()))) { - PositionalAudioRingBuffer* otherNodeBuffer = (PositionalAudioRingBuffer*) otherNode->getLinkedData(); - // based on our listen mode we will do this mixing... - if (nodeRingBuffer->isListeningToSource(otherNodeBuffer)) { + if (nodeRingBuffer->isListeningToNode(*otherNode)) { float bearingRelativeAngleToSource = 0.0f; float attenuationCoefficient = 1.0f; int numSamplesDelay = 0; @@ -355,14 +351,15 @@ int main(int argc, const char* argv[]) { packetVersionMatch(packetData)) { if (packetData[0] == PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO || packetData[0] == PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO) { + + unsigned char* currentBuffer = packetData + numBytesForPacketHeader(packetData); + int sourceID; + memcpy(&sourceID, currentBuffer, sizeof(sourceID)); + Node* avatarNode = nodeList->addOrUpdateNode(nodeAddress, nodeAddress, NODE_TYPE_AGENT, - nodeList->getLastNodeID()); - - if (avatarNode->getNodeID() == nodeList->getLastNodeID()) { - nodeList->increaseNodeID(); - } + sourceID); nodeList->updateNodeWithData(nodeAddress, packetData, receivedBytes); From a162643e1e5af883426c586c47c74567c5abda77 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 23 Jul 2013 19:21:43 -0700 Subject: [PATCH 21/88] more removing of SourceID from classes --- audio-mixer/src/PositionalAudioRingBuffer.cpp | 3 ++- audio-mixer/src/main.cpp | 2 +- interface/src/Application.cpp | 12 +----------- interface/src/Audio.cpp | 8 ++++---- interface/src/Audio.h | 3 --- 5 files changed, 8 insertions(+), 20 deletions(-) diff --git a/audio-mixer/src/PositionalAudioRingBuffer.cpp b/audio-mixer/src/PositionalAudioRingBuffer.cpp index 4dc409628f..f0a3d41be5 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.cpp +++ b/audio-mixer/src/PositionalAudioRingBuffer.cpp @@ -61,7 +61,7 @@ bool PositionalAudioRingBuffer::isListeningToNode(Node& other) const { int PositionalAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char* currentBuffer = sourceBuffer + numBytesForPacketHeader(sourceBuffer); - currentBuffer += sizeof(int); // the source ID + currentBuffer += sizeof(uint16_t); // the source ID currentBuffer += parseListenModeData(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); currentBuffer += parsePositionalData(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); currentBuffer += parseAudioSamples(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); @@ -126,5 +126,6 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix(int numJitterBufferSamples) { return true; } } + printf("packet mismatch...\n"); return false; } diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 6cfa106e5b..9fc088a8bf 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -353,7 +353,7 @@ int main(int argc, const char* argv[]) { packetData[0] == PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO) { unsigned char* currentBuffer = packetData + numBytesForPacketHeader(packetData); - int sourceID; + uint16_t sourceID; memcpy(&sourceID, currentBuffer, sizeof(sourceID)); Node* avatarNode = nodeList->addOrUpdateNode(nodeAddress, diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c1aa032542..14156b7aee 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3483,19 +3483,9 @@ void* Application::networkReceive(void* args) { case PACKET_TYPE_AVATAR_FACE_VIDEO: processAvatarFaceVideoMessage(app->_incomingPacket, bytesReceived); break; - default: { + default: NodeList::getInstance()->processNodeData(&senderAddress, app->_incomingPacket, bytesReceived); - - // Check to see if we have our ownerID - uint16_t ownerID = NodeList::getInstance()->getOwnerID(); - - if (ownerID != app->_audio.getSourceID()) { - app->_audio.setSourceID(ownerID); - } - - break; - } } } } else if (!app->_enableNetworkThread) { diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 9119d3984f..96c5db4d8c 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -121,9 +121,10 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o unsigned char* currentPacketPtr = dataPacket + populateTypeAndVersion(dataPacket, packetType); // pack Source Data - memcpy(currentPacketPtr, &_sourceID, sizeof(_sourceID)); - currentPacketPtr += (sizeof(_sourceID)); - leadingBytes += (sizeof(_sourceID)); + uint16_t ownerID = NodeList::getInstance()->getOwnerID(); + memcpy(currentPacketPtr, &ownerID, sizeof(ownerID)); + currentPacketPtr += (sizeof(ownerID)); + leadingBytes += (sizeof(ownerID)); // pack Listen Mode Data memcpy(currentPacketPtr, &_listenMode, sizeof(_listenMode)); @@ -413,7 +414,6 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) : _collisionSoundDuration(0.0f), _proceduralEffectSample(0), _heartbeatMagnitude(0.0f), - _sourceID(UNKNOWN_NODE_ID), _listenMode(AudioRingBuffer::NORMAL), _listenRadius(0.0f), _listenSourceCount(0), diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 9552d6e2ec..3886f9d6fc 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -54,8 +54,6 @@ public: // The results of the analysis are written to the log. bool eventuallyAnalyzePing(); - int getSourceID() const { return _sourceID; }; - void setSourceID(int sourceID) { _sourceID = sourceID; }; void setListenMode(AudioRingBuffer::ListenMode mode) { _listenMode = mode; }; void setListenRadius(float radius) { _listenRadius = radius; }; void addListenSource(int sourceID); @@ -98,7 +96,6 @@ private: int _proceduralEffectSample; float _heartbeatMagnitude; - int _sourceID; AudioRingBuffer::ListenMode _listenMode; float _listenRadius; int _listenSourceCount; From 9507cd8955d372199f4cdcd07cdaf6dba81df293 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 23 Jul 2013 19:54:29 -0700 Subject: [PATCH 22/88] switched to vector --- audio-mixer/src/PositionalAudioRingBuffer.cpp | 30 ++++----- audio-mixer/src/PositionalAudioRingBuffer.h | 9 ++- interface/src/Audio.cpp | 67 +++++-------------- interface/src/Audio.h | 5 +- 4 files changed, 33 insertions(+), 78 deletions(-) diff --git a/audio-mixer/src/PositionalAudioRingBuffer.cpp b/audio-mixer/src/PositionalAudioRingBuffer.cpp index f0a3d41be5..9980b48a3e 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.cpp +++ b/audio-mixer/src/PositionalAudioRingBuffer.cpp @@ -19,17 +19,12 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer() : _orientation(0.0f, 0.0f, 0.0f, 0.0f), _willBeAddedToMix(false), _listenMode(AudioRingBuffer::NORMAL), - _listenRadius(0.0f), - _listenSourceCount(0), - _listenSources(NULL) + _listenRadius(0.0f) { } PositionalAudioRingBuffer::~PositionalAudioRingBuffer() { - if (_listenSources) { - delete[] _listenSources; - } } bool PositionalAudioRingBuffer::isListeningToNode(Node& other) const { @@ -46,11 +41,9 @@ bool PositionalAudioRingBuffer::isListeningToNode(Node& other) const { break; } case AudioRingBuffer::SELECTED_SOURCES: - if (_listenSources) { - for (int i = 0; i < _listenSourceCount; i++) { - if (other.getNodeID() == _listenSources[i]) { - return true; - } + for (int i = 0; i < _listenSources.size(); i++) { + if (other.getNodeID() == _listenSources[i]) { + return true; } } return false; @@ -79,14 +72,15 @@ int PositionalAudioRingBuffer::parseListenModeData(unsigned char* sourceBuffer, memcpy(&_listenRadius, currentBuffer, sizeof(_listenRadius)); currentBuffer += sizeof(_listenRadius); } else if (_listenMode == AudioRingBuffer::SELECTED_SOURCES) { - memcpy(&_listenSourceCount, currentBuffer, sizeof(_listenSourceCount)); - currentBuffer += sizeof(_listenSourceCount); - if (_listenSources) { - delete[] _listenSources; + int listenSourcesCount; + memcpy(&listenSourcesCount, currentBuffer, sizeof(listenSourcesCount)); + currentBuffer += sizeof(listenSourcesCount); + for (int i = 0; i < listenSourcesCount; i++) { + int sourceID; + memcpy(&sourceID, currentBuffer, sizeof(sourceID)); + currentBuffer += sizeof(sourceID); + _listenSources.push_back(sourceID); } - _listenSources = new int[_listenSourceCount]; - memcpy(_listenSources, currentBuffer, sizeof(int) * _listenSourceCount); - currentBuffer += sizeof(int) * _listenSourceCount; } return currentBuffer - sourceBuffer; diff --git a/audio-mixer/src/PositionalAudioRingBuffer.h b/audio-mixer/src/PositionalAudioRingBuffer.h index 44d8a2b4f8..6c7ee9ce3f 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.h +++ b/audio-mixer/src/PositionalAudioRingBuffer.h @@ -9,6 +9,7 @@ #ifndef __hifi__PositionalAudioRingBuffer__ #define __hifi__PositionalAudioRingBuffer__ +#include #include #include @@ -42,11 +43,9 @@ protected: glm::quat _orientation; bool _willBeAddedToMix; - ListenMode _listenMode; - float _listenRadius; - int _listenSourceCount; - int* _listenSources; - + ListenMode _listenMode; + float _listenRadius; + std::vector _listenSources; }; #endif /* defined(__hifi__PositionalAudioRingBuffer__) */ diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 96c5db4d8c..a9aa61a34e 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -136,13 +136,14 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o currentPacketPtr += (sizeof(_listenRadius)); leadingBytes += (sizeof(_listenRadius)); } else if (_listenMode == AudioRingBuffer::SELECTED_SOURCES) { - memcpy(currentPacketPtr, &_listenSourceCount, sizeof(_listenSourceCount)); - currentPacketPtr += (sizeof(_listenSourceCount)); - leadingBytes += (sizeof(_listenSourceCount)); - if (_listenSources) { - memcpy(currentPacketPtr, _listenSources, sizeof(int) * _listenSourceCount); - currentPacketPtr += (sizeof(int) * _listenSourceCount); - leadingBytes += (sizeof(int) * _listenSourceCount); + int listenSourceCount = _listenSources.size(); + memcpy(currentPacketPtr, &listenSourceCount, sizeof(listenSourceCount)); + currentPacketPtr += (sizeof(listenSourceCount)); + leadingBytes += (sizeof(listenSourceCount)); + for (int i = 0; i < listenSourceCount; i++) { + memcpy(currentPacketPtr, &_listenSources[i], sizeof(_listenSources[i])); + currentPacketPtr += sizeof(_listenSources[i]); + leadingBytes += sizeof(_listenSources[i]); } } @@ -336,49 +337,18 @@ void Audio::reset() { } void Audio::addListenSource(int sourceID) { - - // If we don't yet have a list of listen sources, make one - if (!_listenSources) { - _listenSources = new int[AudioRingBuffer::DEFAULT_LISTEN_LIST_SIZE]; - } - - // First check to see if the source is already in our list - for (int i = 0; i < _listenSourceCount; i++) { - if (_listenSources[i] == sourceID) { - return; // already in list - } - } - - // we know it's not in the list, check to see if we have room to add our source - if (_listenSourceCount + 1 < _listenSourcesArraySize) { - int* newList = new int[_listenSourcesArraySize + AudioRingBuffer::DEFAULT_LISTEN_LIST_SIZE]; - memmove(newList, _listenSources, _listenSourcesArraySize); - delete[] _listenSources; - _listenSources = newList; - _listenSourcesArraySize += AudioRingBuffer::DEFAULT_LISTEN_LIST_SIZE; - } - _listenSources[_listenSourceCount] = sourceID; - _listenSourceCount++; + _listenSources.push_back(sourceID); } void Audio::clearListenSources() { - delete[] _listenSources; - _listenSources = NULL; - _listenSourceCount = 0; + _listenSources.clear(); } void Audio::removeListenSource(int sourceID) { - // If we don't yet have a list of listen sources, make one - if (_listenSources) { - // First check to see if the source is already in our list - for (int i = 0; i < _listenSourceCount; i++) { - if (_listenSources[i] == sourceID) { - - // found it, so, move the items forward in list - memmove(&_listenSources[i], &_listenSources[i+1], _listenSourceCount - i); - _listenSourceCount--; - return; - } + for (int i = 0; i < _listenSources.size(); i++) { + if (_listenSources[i] == sourceID) { + _listenSources.erase(_listenSources.begin() + i); + return; } } } @@ -415,10 +385,7 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) : _proceduralEffectSample(0), _heartbeatMagnitude(0.0f), _listenMode(AudioRingBuffer::NORMAL), - _listenRadius(0.0f), - _listenSourceCount(0), - _listenSourcesArraySize(0), - _listenSources(NULL) + _listenRadius(0.0f) { outputPortAudioError(Pa_Initialize()); @@ -487,10 +454,6 @@ Audio::~Audio() { outputPortAudioError(Pa_Terminate()); } delete[] _echoSamplesLeft; - - if (_listenSources) { - delete[] _listenSources; - } } void Audio::addReceivedAudioToBuffer(unsigned char* receivedData, int receivedBytes) { diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 3886f9d6fc..2eb4e7ef70 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -9,6 +9,7 @@ #ifndef __interface__Audio__ #define __interface__Audio__ +#include #include #include #include @@ -98,9 +99,7 @@ private: AudioRingBuffer::ListenMode _listenMode; float _listenRadius; - int _listenSourceCount; - int _listenSourcesArraySize; - int* _listenSources; + std::vector _listenSources; // Audio callback in class context. inline void performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* outputRight); From eb8c5653500df4df5a9cd50e09a006e965cd6c94 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 23 Jul 2013 20:08:57 -0700 Subject: [PATCH 23/88] dry up code --- interface/src/Application.cpp | 33 +++++++++++++++++---------------- interface/src/Application.h | 4 +++- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 14156b7aee..9784a8a7e6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1864,20 +1864,13 @@ void Application::setListenModeSingleSource() { _audio.setListenMode(AudioRingBuffer::SELECTED_SOURCES); _audio.clearListenSources(); - NodeList* nodeList = NodeList::getInstance(); - for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { - if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) { - Avatar* avatar = (Avatar *) node->getLinkedData(); - glm::vec3 headPosition = avatar->getHead().getPosition(); - glm::vec3 mouseRayOrigin = _myAvatar.getMouseRayOrigin(); - glm::vec3 mouseRayDirection = _myAvatar.getMouseRayDirection(); - const float HEAD_SPHERE_RADIUS = 0.07; + glm::vec3 mouseRayOrigin = _myAvatar.getMouseRayOrigin(); + glm::vec3 mouseRayDirection = _myAvatar.getMouseRayDirection(); + glm::vec3 eyePositionIgnored; + uint16_t nodeID; - if (rayIntersectsSphere(mouseRayOrigin, mouseRayDirection, headPosition, HEAD_SPHERE_RADIUS)) { - int sourceID = avatar->getOwningNode()->getNodeID(); - _audio.addListenSource(sourceID); - } - } + if (isLookingAtOtherAvatar(mouseRayOrigin, mouseRayDirection, eyePositionIgnored, nodeID)) { + _audio.addListenSource(nodeID); } } @@ -1970,7 +1963,10 @@ const float MAX_AVATAR_EDIT_VELOCITY = 1.0f; const float MAX_VOXEL_EDIT_DISTANCE = 20.0f; const float HEAD_SPHERE_RADIUS = 0.07; -bool Application::isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection, glm::vec3& eyePosition) { + +bool Application::isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection, + glm::vec3& eyePosition, uint16_t& nodeID) { + NodeList* nodeList = NodeList::getInstance(); for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) { @@ -1979,6 +1975,7 @@ bool Application::isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3& m if (rayIntersectsSphere(mouseRayOrigin, mouseRayDirection, headPosition, HEAD_SPHERE_RADIUS)) { eyePosition = avatar->getHead().getEyeLevelPosition(); _lookatOtherPosition = headPosition; + nodeID = avatar->getOwningNode()->getNodeID(); return true; } } @@ -2022,7 +2019,9 @@ void Application::update(float deltaTime) { // Set where I am looking based on my mouse ray (so that other people can see) glm::vec3 eyePosition; - if (_isLookingAtOtherAvatar = isLookingAtOtherAvatar(mouseRayOrigin, mouseRayDirection, eyePosition)) { + uint16_t ignored; + _isLookingAtOtherAvatar = isLookingAtOtherAvatar(mouseRayOrigin, mouseRayDirection, eyePosition, ignored); + if (_isLookingAtOtherAvatar) { // If the mouse is over another avatar's head... glm::vec3 myLookAtFromMouse(eyePosition); _myAvatar.getHead().setLookAtPosition(myLookAtFromMouse); @@ -2284,7 +2283,9 @@ void Application::updateAvatar(float deltaTime) { _viewFrustum.computePickRay(MIDPOINT_OF_SCREEN, MIDPOINT_OF_SCREEN, screenCenterRayOrigin, screenCenterRayDirection); glm::vec3 eyePosition; - if (_isLookingAtOtherAvatar = isLookingAtOtherAvatar(screenCenterRayOrigin, screenCenterRayDirection, eyePosition)) { + uint16_t ignored; + _isLookingAtOtherAvatar = isLookingAtOtherAvatar(screenCenterRayOrigin, screenCenterRayDirection, eyePosition, ignored); + if (_isLookingAtOtherAvatar) { glm::vec3 myLookAtFromMouse(eyePosition); _myAvatar.getHead().setLookAtPosition(myLookAtFromMouse); } diff --git a/interface/src/Application.h b/interface/src/Application.h index d462e88b98..da8cf96189 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -203,7 +203,9 @@ private: void init(); void update(float deltaTime); - bool isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection, glm::vec3& eyePosition); + bool isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection, + glm::vec3& eyePosition, uint16_t& nodeID); + void renderLookatIndicator(glm::vec3 pointOfInterest, Camera& whichCamera); void updateAvatar(float deltaTime); void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum); From 903a24806150d789881dd3f4512b87ebc49f16d6 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 23 Jul 2013 20:46:09 -0700 Subject: [PATCH 24/88] cleaned up some code and added asserts to help track down a crash --- interface/src/ParticleSystem.cpp | 19 ++++++++------ interface/src/ParticleSystem.h | 4 +-- interface/src/avatar/Hand.cpp | 43 +++++++++++++++++++++++++++++--- interface/src/avatar/Hand.h | 3 --- 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index c40d692166..c61bc41764 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -69,13 +69,12 @@ ParticleSystem::ParticleSystem() { int ParticleSystem::addEmitter() { - _numEmitters ++; - - if (_numEmitters > MAX_EMITTERS) { - return -1; + if (_numEmitters < MAX_EMITTERS) { + _numEmitters ++; + return _numEmitters - 1; } - return _numEmitters - 1; + return -1; } @@ -95,12 +94,16 @@ void ParticleSystem::simulate(float deltaTime) { void ParticleSystem::emitNow(int e) { - for (unsigned int p = 0; p < _emitter[e].rate; p++) { - createParticle(e, _emitter[e].direction); + 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, glm::vec3 velocity) { +void ParticleSystem::createParticle(int e) { for (unsigned int p = 0; p < MAX_PARTICLES; p++) { if (!_particle[p].alive) { diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index 9ba8d8ed35..34089941bd 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -11,7 +11,7 @@ #include const int MAX_PARTICLES = 5000; -const int MAX_EMITTERS = 1000; +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; @@ -99,7 +99,7 @@ private: // private methods void updateParticle(int index, float deltaTime); - void createParticle(int e, glm::vec3 velocity); + void createParticle(int e); void killParticle(int p); void renderEmitter(int emitterIndex, float size); void renderParticle(int p); diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 8a4f04ad78..96993b2bc9 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -15,7 +15,7 @@ #include "renderer/ProgramObject.h" const bool SHOW_LEAP_HAND = false; -const int NUM_TEST_RAVE_GLOVE_MODES = 5; +const int NUM_TEST_RAVE_GLOVE_MODES = 6; const float TEST_RAVE_GLOVE_MODE_DURATION = 7.0f; using namespace std; @@ -342,14 +342,14 @@ void Hand::updateFingerParticles(float deltaTime) { FingerData& finger = palm.getFingers()[f]; if (finger.isActive()) { if (_fingerParticleEmitter[0] != -1) { - _particleSystem.emitNow(_fingerParticleEmitter[fingerIndex]); + _particleSystem.emitNow(_fingerParticleEmitter[fingerIndex]); fingerIndex ++; } } } } } - + _particleSystem.simulate(deltaTime); } } @@ -530,6 +530,43 @@ void Hand::setRaveGloveMode(int mode) { attributes.radius = 0.0f; attributes.color = glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + + //----------------------------------------- + // flashy trails + //----------------------------------------- + } else if (mode == 5) { + + _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); + _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.2 ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 6.0 ); + _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 12 ); + + attributes.radius = 0.0f; + attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); + attributes.gravity = 0.0f; + attributes.airFriction = 0.0f; + attributes.jitter = 0.01f; + attributes.emitterAttraction = 0.0f; + attributes.tornadoForce = 0.0f; + attributes.neighborAttraction = 0.0f; + attributes.neighborRepulsion = 0.0f; + attributes.bounce = 1.0f; + attributes.usingCollisionSphere = false; + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + + attributes.radius = 0.01f; + attributes.color = glm::vec4( 1.0f, 1.0f, 0.0f, 1.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + + attributes.radius = 0.01f; + attributes.color = glm::vec4( 1.0f, 0.0f, .0f, 1.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + + attributes.radius = 0.0f; + attributes.color = glm::vec4( 0.0f, 0.0f, 1.0f, 0.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); } } } diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index d0782138da..8152a4b271 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -19,8 +19,6 @@ #include #include -//const int MAX_TRAIL_PARTICLES = 20; - class Avatar; class ProgramObject; @@ -63,7 +61,6 @@ private: int _testRaveGloveMode; bool _particleSystemInitialized; int _fingerParticleEmitter[NUM_FINGERS]; - //int _fingerTrailParticleEmitter[NUM_FINGERS][MAX_TRAIL_PARTICLES]; Avatar* _owningAvatar; float _renderAlpha; bool _lookingInMirror; From 7177b71bc77f29b635787d2e1048ecf36c5f6e5e Mon Sep 17 00:00:00 2001 From: Mark Peng Date: Wed, 24 Jul 2013 00:19:25 -0700 Subject: [PATCH 25/88] Replace var in renderLookatIndicator with const IDENTITY_UP --- interface/src/Application.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c0fe2b360b..c5f12822fe 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1960,8 +1960,7 @@ void Application::renderLookatIndicator(glm::vec3 pointOfInterest, Camera& which const int NUM_SEGMENTS = 30; glm::vec3 haloOrigin(pointOfInterest.x, pointOfInterest.y + DISTANCE_FROM_HEAD_SPHERE, pointOfInterest.z); glColor3f(YELLOW[0], YELLOW[1], YELLOW[2]); - glm::vec3 normalToFloor(0.0f, 1.0f, 0.0f); - renderCircle(haloOrigin, INDICATOR_RADIUS, normalToFloor, NUM_SEGMENTS); + renderCircle(haloOrigin, INDICATOR_RADIUS, IDENTITY_UP, NUM_SEGMENTS); } void Application::update(float deltaTime) { From b2b67d2b3dac6f20dbd079606520874677220559 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 24 Jul 2013 01:18:54 -0700 Subject: [PATCH 26/88] split multiple avatars into multiple packets if needed --- avatar-mixer/src/main.cpp | 62 ++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index f8bc36f6e6..b2e28fe484 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -36,7 +36,7 @@ const int AVATAR_LISTEN_PORT = 55444; -unsigned char *addNodeToBroadcastPacket(unsigned char *currentPosition, Node *nodeToAdd) { +unsigned char* addNodeToBroadcastPacket(unsigned char *currentPosition, Node *nodeToAdd) { currentPosition += packNodeId(currentPosition, nodeToAdd->getNodeID()); AvatarData *nodeData = (AvatarData *)nodeToAdd->getLinkedData(); @@ -51,6 +51,47 @@ void attachAvatarDataToNode(Node* newNode) { } } +unsigned char broadcastPacketBuffer[MAX_PACKET_SIZE]; +unsigned char avatarDataBuffer[MAX_PACKET_SIZE]; +void broadcastAvatarData(NodeList* nodeList, sockaddr* nodeAddress) { + unsigned char* broadcastPacket = (unsigned char*)&::broadcastPacketBuffer[0]; + int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_BULK_AVATAR_DATA); + unsigned char* currentBufferPosition = NULL; + currentBufferPosition = broadcastPacket + numHeaderBytes; + int packetLength = currentBufferPosition - broadcastPacket; + int packetsSent = 0; + + // send back a packet with other active node data to this node + for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { + if (node->getLinkedData() && !socketMatch(nodeAddress, node->getActiveSocket())) { + unsigned char* avatarDataEndpoint = addNodeToBroadcastPacket((unsigned char*)&avatarDataBuffer[0], &*node); + int avatarDataLength = avatarDataEndpoint - (unsigned char*)&avatarDataBuffer; + + if (avatarDataLength + packetLength <= MAX_PACKET_SIZE) { + memcpy(currentBufferPosition, &avatarDataBuffer[0], avatarDataLength); + packetLength += avatarDataLength; + currentBufferPosition += avatarDataLength; + } else { + packetsSent++; + //printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength); + nodeList->getNodeSocket()->send(nodeAddress, broadcastPacket, currentBufferPosition - broadcastPacket); + + // reset the packet + currentBufferPosition = broadcastPacket + numHeaderBytes; + packetLength = currentBufferPosition - broadcastPacket; + + // copy the avatar that didn't fit into the next packet + memcpy(currentBufferPosition, &avatarDataBuffer[0], avatarDataLength); + packetLength += avatarDataLength; + currentBufferPosition += avatarDataLength; + } + } + } + packetsSent++; + //printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength); + nodeList->getNodeSocket()->send(nodeAddress, broadcastPacket, currentBufferPosition - broadcastPacket); +} + int main(int argc, const char* argv[]) { NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT); @@ -67,14 +108,11 @@ int main(int argc, const char* argv[]) { nodeList->startSilentNodeRemovalThread(); - sockaddr *nodeAddress = new sockaddr; - unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE]; + sockaddr* nodeAddress = new sockaddr; ssize_t receivedBytes = 0; - unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; - int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_BULK_AVATAR_DATA); + unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE]; - unsigned char* currentBufferPosition = NULL; uint16_t nodeID = 0; Node* avatarNode = NULL; @@ -104,17 +142,7 @@ int main(int argc, const char* argv[]) { // parse positional data from an node nodeList->updateNodeWithData(avatarNode, packetData, receivedBytes); case PACKET_TYPE_INJECT_AUDIO: - currentBufferPosition = broadcastPacket + numHeaderBytes; - - // send back a packet with other active node data to this node - for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { - if (node->getLinkedData() && !socketMatch(nodeAddress, node->getActiveSocket())) { - currentBufferPosition = addNodeToBroadcastPacket(currentBufferPosition, &*node); - } - } - - nodeList->getNodeSocket()->send(nodeAddress, broadcastPacket, currentBufferPosition - broadcastPacket); - + broadcastAvatarData(nodeList, nodeAddress); break; case PACKET_TYPE_AVATAR_VOXEL_URL: case PACKET_TYPE_AVATAR_FACE_VIDEO: From bacb4f96e37e68492c82c027888ff28521001166 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 24 Jul 2013 09:59:51 -0700 Subject: [PATCH 27/88] added notes --- avatar-mixer/src/main.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index b2e28fe484..8383c992b2 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -51,6 +51,13 @@ void attachAvatarDataToNode(Node* newNode) { } } +// NOTE: some additional optimizations to consider. +// 1) use the view frustum to cull those avatars that are out of view. Since avatar data doesn't need to be present +// if the avatar is not in view or in the keyhole. +// 2) after culling for view frustum, sort order the avatars by distance, send the closest ones first. +// 3) if we need to rate limit the amount of data we send, we can use a distance weighted "semi-random" function to +// determine which avatars are included in the packet stream +// 4) we should optimize the avatar data format to be more compact (100 bytes is pretty wasteful). unsigned char broadcastPacketBuffer[MAX_PACKET_SIZE]; unsigned char avatarDataBuffer[MAX_PACKET_SIZE]; void broadcastAvatarData(NodeList* nodeList, sockaddr* nodeAddress) { From 2f28f3ea4b85971c94915b191448d6815e5dc867 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 24 Jul 2013 12:41:01 -0700 Subject: [PATCH 28/88] made some extra checks for bogus data coming in, and added more particle effects to rave glove hand --- interface/src/ParticleSystem.cpp | 59 ++++++++++------- interface/src/avatar/Hand.cpp | 110 +++++++++++++++++++++++++++---- 2 files changed, 130 insertions(+), 39 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index c61bc41764..b2cea57034 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -367,12 +367,9 @@ void ParticleSystem::renderParticle(int p) { v /= distance; - glm::vec3 up = glm::normalize(glm::cross(v, _upDirection)); - glm::vec3 right = glm::normalize(glm::cross(up, v)); - - right *= _particle[p].radius; - up *= _particle[p].radius; - + glm::vec3 up = glm::normalize(glm::cross(v, _upDirection)) * _particle[p].radius; + glm::vec3 right = glm::normalize(glm::cross(up, v )) * _particle[p].radius; + glm::vec3 p0Left = _particle[p ].position - right; glm::vec3 p0Right = _particle[p ].position + right; glm::vec3 p0Down = _particle[p ].position - up; @@ -383,28 +380,40 @@ void ParticleSystem::renderParticle(int p) { glm::vec3 ppDown = _particle[pp].position - up; glm::vec3 ppUp = _particle[pp].position + up; - glBegin(GL_TRIANGLES); - glVertex3f(p0Left.x, p0Left.y, p0Left.z ); - glVertex3f(p0Right.x, p0Right.y, p0Right.z ); - glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); - glEnd(); + glBegin(GL_TRIANGLES); + + glVertex3f(p0Left.x, p0Left.y, p0Left.z ); + glVertex3f(p0Right.x, p0Right.y, p0Right.z ); + glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); - glBegin(GL_TRIANGLES); - glVertex3f(p0Right.x, p0Right.y, p0Right.z ); - glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); - glVertex3f(ppRight.x, ppRight.y, ppRight.z ); - glEnd(); + glVertex3f(p0Right.x, p0Right.y, p0Right.z ); + glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); + glVertex3f(ppRight.x, ppRight.y, ppRight.z ); - glBegin(GL_TRIANGLES); - glVertex3f(p0Up.x, p0Up.y, p0Up.z ); - glVertex3f(p0Down.x, p0Down.y, p0Down.z ); - glVertex3f(ppDown.x, ppDown.y, ppDown.z ); - glEnd(); + glVertex3f(p0Up.x, p0Up.y, p0Up.z ); + glVertex3f(p0Down.x, p0Down.y, p0Down.z ); + glVertex3f(ppDown.x, ppDown.y, ppDown.z ); - glBegin(GL_TRIANGLES); - glVertex3f(p0Up.x, p0Up.y, p0Up.z ); - glVertex3f(ppUp.x, ppUp.y, ppUp.z ); - glVertex3f(ppDown.x, ppDown.y, ppDown.z ); + glVertex3f(p0Up.x, p0Up.y, p0Up.z ); + glVertex3f(ppUp.x, ppUp.y, ppUp.z ); + glVertex3f(ppDown.x, ppDown.y, ppDown.z ); + + glVertex3f(p0Up.x, p0Up.y, p0Left.z ); + glVertex3f(p0Right.x, p0Right.y, p0Right.z ); + glVertex3f(p0Down.x, p0Down.y, p0Down.z ); + + glVertex3f(p0Up.x, p0Up.y, p0Left.z ); + glVertex3f(p0Left.x, p0Left.y, p0Left.z ); + glVertex3f(p0Down.x, p0Down.y, p0Down.z ); + + glVertex3f(ppUp.x, ppUp.y, ppLeft.z ); + glVertex3f(ppRight.x, ppRight.y, ppRight.z ); + glVertex3f(ppDown.x, ppDown.y, ppDown.z ); + + glVertex3f(ppUp.x, ppUp.y, ppLeft.z ); + glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); + glVertex3f(ppDown.x, ppDown.y, ppDown.z ); + glEnd(); } } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 96993b2bc9..672d543694 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -15,7 +15,7 @@ #include "renderer/ProgramObject.h" const bool SHOW_LEAP_HAND = false; -const int NUM_TEST_RAVE_GLOVE_MODES = 6; +const int NUM_TEST_RAVE_GLOVE_MODES = 8; const float TEST_RAVE_GLOVE_MODE_DURATION = 7.0f; using namespace std; @@ -36,10 +36,6 @@ Hand::Hand(Avatar* owningAvatar) : // initialize all finger particle emitters with an invalid id as default for (int f = 0; f< NUM_FINGERS; f ++ ) { _fingerParticleEmitter[f] = -1; - - //for (int t = 0; t < MAX_TRAIL_PARTICLES; t ++ ) { - // _fingerTrailParticleEmitter[f][t] = -1; - //} } } @@ -48,8 +44,9 @@ void Hand::init() { if (_owningAvatar && _owningAvatar->isMyAvatar()) { _ballColor = glm::vec3(0.0, 0.4, 0.0); } - else + else { _ballColor = glm::vec3(0.0, 0.0, 0.4); + } } void Hand::reset() { @@ -96,12 +93,12 @@ void Hand::render(bool lookingInMirror) { _lookingInMirror = lookingInMirror; calculateGeometry(); - updateFingerParticleEmitters(); // do this right after calculateGeometry if (_isRaveGloveActive) { renderRaveGloveStage(); if (_particleSystemInitialized) { + updateFingerParticleEmitters(); // do this after calculateGeometry _particleSystem.render(); } } @@ -290,9 +287,11 @@ void Hand::updateFingerParticles(float deltaTime) { if (_testRaveGloveClock > TEST_RAVE_GLOVE_MODE_DURATION) { _testRaveGloveClock = 0.0f; _testRaveGloveMode ++; + if (_testRaveGloveMode > NUM_TEST_RAVE_GLOVE_MODES) { _testRaveGloveMode = 0; } + setRaveGloveMode(_testRaveGloveMode); } @@ -310,7 +309,9 @@ void Hand::updateFingerParticles(float deltaTime) { _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); } - } else if (_testRaveGloveMode == 1) { + } + /* + else if (_testRaveGloveMode == 1) { ParticleSystem::ParticleAttributes attributes; attributes.gravity = 0.001f; @@ -332,6 +333,7 @@ void Hand::updateFingerParticles(float deltaTime) { _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); } } + */ // update the particles int fingerIndex = 0; @@ -366,10 +368,10 @@ void Hand::setRaveGloveMode(int mode) { // throbbing color cycle //----------------------------------------- if (mode == 0) { - _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.0f ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.0f ); _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0f ); _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 20 ); @@ -402,8 +404,8 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 5 ); attributes.radius = 0.001f; - attributes.color = glm::vec4( 1.0f, 0.2f, 0.2f, 1.0f); - attributes.gravity = 0.001f; + attributes.color = glm::vec4( 1.0f, 0.5f, 0.2f, 1.0f); + attributes.gravity = 0.005f; attributes.airFriction = 0.0f; attributes.jitter = 0.0f; attributes.emitterAttraction = 0.0f; @@ -413,8 +415,14 @@ void Hand::setRaveGloveMode(int mode) { attributes.bounce = 0.0f; attributes.usingCollisionSphere = false; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + + attributes.radius = 0.002f; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + + attributes.color = glm::vec4( 1.0f, 0.2f, 0.2f, 0.5f); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + + attributes.color = glm::vec4( 1.0f, 0.2f, 0.2f, 0.0f); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); } @@ -465,8 +473,8 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.6f ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.001f ); _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 10.0 ); _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 5 ); @@ -532,7 +540,7 @@ void Hand::setRaveGloveMode(int mode) { _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); //----------------------------------------- - // flashy trails + // Bozo sparkler //----------------------------------------- } else if (mode == 5) { @@ -567,6 +575,80 @@ void Hand::setRaveGloveMode(int mode) { attributes.radius = 0.0f; attributes.color = glm::vec4( 0.0f, 0.0f, 1.0f, 0.0f); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + + //----------------------------------------- + // long sparkler + //----------------------------------------- + } else if (mode == 6) { + + _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); + _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0 ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 6.0 ); + _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 7 ); + + attributes.radius = 0.0f; + attributes.color = glm::vec4( 0.0f, 0.0f, 0.4f, 0.0f); + attributes.gravity = 0.0f; + attributes.airFriction = 0.0f; + attributes.jitter = 0.0001f; + attributes.emitterAttraction = 0.0f; + attributes.tornadoForce = 0.0f; + attributes.neighborAttraction = 0.0f; + attributes.neighborRepulsion = 0.0f; + attributes.bounce = 1.0f; + attributes.usingCollisionSphere = false; + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + + attributes.radius = 0.005f; + attributes.color = glm::vec4( 0.0f, 0.5f, 0.5f, 0.8f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + + attributes.radius = 0.007f; + attributes.color = glm::vec4( 0.5f, 0.0f, 0.5f, 0.5f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + + attributes.radius = 0.02f; + attributes.color = glm::vec4( 0.0f, 0.0f, 1.0f, 0.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + + //----------------------------------------- + // bubble snake + //----------------------------------------- + } else if (mode == 7) { + + _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); + _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0 ); + _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 1.0 ); + _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 7 ); + + attributes.radius = 0.001f; + attributes.color = glm::vec4( 0.5f, 1.0f, 0.5f, 1.0f); + attributes.gravity = 0.0f; + attributes.airFriction = 0.01f; + attributes.jitter = 0.0f; + attributes.emitterAttraction = 0.0f; + attributes.tornadoForce = 1.1f; + attributes.neighborAttraction = 1.1f; + attributes.neighborRepulsion = 1.1f; + attributes.bounce = 0.0f; + attributes.usingCollisionSphere = false; + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + + attributes.radius = 0.002f; + attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + + attributes.radius = 0.003f; + attributes.color = glm::vec4( 0.3f, 0.3f, 0.3f, 0.5f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + + attributes.radius = 0.004f; + attributes.color = glm::vec4( 0.3f, 0.3f, 0.3f, 0.0f); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); } } } From aee29a0ab1c31269be64c2020011c772adb29b16 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 24 Jul 2013 16:37:13 -0700 Subject: [PATCH 29/88] 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; From 5e2dcfee53b5e039427ba5a42e4db3c731199a3d Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 24 Jul 2013 16:52:37 -0700 Subject: [PATCH 30/88] cleaned up some magic numbers --- interface/src/Application.cpp | 8 ++-- interface/src/ParticleSystem.cpp | 4 +- interface/src/ParticleSystem.h | 20 +++++++-- interface/src/avatar/Hand.cpp | 76 ++++++++++++++++---------------- 4 files changed, 61 insertions(+), 47 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 339bd520e7..b12e452b60 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3650,10 +3650,12 @@ void Application::exportSettings() { } - void Application::updateParticleSystem(float deltaTime) { if (!_particleSystemInitialized) { + + const int LIFESPAN_IN_SECONDS = 100000.0f; + const float EMIT_RATE_IN_SECONDS = 10000.0; // create a stable test emitter and spit out a bunch of particles _coolDemoParticleEmitter = _particleSystem.addEmitter(); @@ -3662,9 +3664,9 @@ void Application::updateParticleSystem(float deltaTime) { glm::vec3 particleEmitterPosition = glm::vec3(5.0f, 1.0f, 5.0f); _particleSystem.setEmitterPosition (_coolDemoParticleEmitter, particleEmitterPosition); - _particleSystem.setEmitterParticleLifespan(_coolDemoParticleEmitter, 100000.0f); + _particleSystem.setEmitterParticleLifespan(_coolDemoParticleEmitter, LIFESPAN_IN_SECONDS); _particleSystem.setEmitterThrust (_coolDemoParticleEmitter, 0.0f); - _particleSystem.setEmitterRate (_coolDemoParticleEmitter, 10000.0); // to emit a pile o particles now + _particleSystem.setEmitterRate (_coolDemoParticleEmitter, EMIT_RATE_IN_SECONDS); // to emit a pile o particles now } // signal that the particle system has been initialized diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 1270760459..707fce967a 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -162,11 +162,11 @@ void ParticleSystem::killParticle(int p) { void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleAttributes attributes) { for (int lifeStage = 0; lifeStage < NUM_PARTICLE_LIFE_STAGES; lifeStage ++ ) { - setParticleAttributes(emitterIndex, lifeStage, attributes); + setParticleAttributes(emitterIndex, (ParticleLifeStage)lifeStage, attributes); } } -void ParticleSystem::setParticleAttributes(int emitterIndex, int lifeStage, ParticleAttributes attributes) { +void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleLifeStage lifeStage, ParticleAttributes attributes) { ParticleAttributes * a = &_emitter[emitterIndex].particleAttributes[lifeStage]; diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index 5ecb3510d9..10911a4832 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -10,9 +10,8 @@ #include -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 int MAX_PARTICLES = 5000; +const int MAX_EMITTERS = 100; enum ParticleRenderStyle { @@ -22,6 +21,19 @@ enum ParticleRenderStyle NUM_PARTICLE_RENDER_STYLES }; + +enum ParticleLifeStage +{ + PARTICLE_LIFESTAGE_0 = 0, + PARTICLE_LIFESTAGE_1, + PARTICLE_LIFESTAGE_2, + PARTICLE_LIFESTAGE_3, + NUM_PARTICLE_LIFE_STAGES +}; + + + + class ParticleSystem { public: @@ -51,7 +63,7 @@ public: void setUpDirection(glm::vec3 upDirection) {_upDirection = upDirection;} // tell particle system which direction is up void setParticleAttributes (int emitterIndex, ParticleAttributes attributes); // set attributes for whole life of particles - void setParticleAttributes (int emitterIndex, int lifeStage, ParticleAttributes attributes); // set attributes for this life stage of particles + void setParticleAttributes (int emitterIndex, ParticleLifeStage lifeStage, ParticleAttributes attributes); // set attributes for this life stage void setEmitterPosition (int emitterIndex, glm::vec3 position ) {_emitter[emitterIndex].position = position; } void setEmitterParticleResolution (int emitterIndex, int resolution ) {_emitter[emitterIndex].particleResolution = resolution; } void setEmitterDirection (int emitterIndex, glm::vec3 direction ) {_emitter[emitterIndex].direction = direction; } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index ef343e5608..4374e16043 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -304,10 +304,10 @@ void Hand::updateFingerParticles(float deltaTime) { attributes.color = glm::vec4(red, green, blue, 1.0f); attributes.radius = 0.01f + 0.005f * sinf(_testRaveGloveClock * 2.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); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); } } @@ -346,10 +346,10 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 0.0f; attributes.usingCollisionSphere = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // trails @@ -373,16 +373,16 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 0.0f; attributes.usingCollisionSphere = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.002f; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.color = glm::vec4( 1.0f, 0.2f, 0.2f, 0.5f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.color = glm::vec4( 1.0f, 0.2f, 0.2f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); } //----------------------------------------- @@ -408,22 +408,22 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 1.0f; attributes.usingCollisionSphere = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.01f; attributes.jitter = 0.0f; attributes.gravity = -0.005f; attributes.color = glm::vec4( 1.0f, 0.2f, 0.0f, 0.4f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.radius = 0.01f; attributes.gravity = 0.0f; attributes.color = glm::vec4( 0.4f, 0.4f, 0.4f, 0.2f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.radius = 0.02f; attributes.color = glm::vec4( 0.4f, 0.6f, 0.9f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // water @@ -431,10 +431,10 @@ void Hand::setRaveGloveMode(int mode) { } else if (mode == 3) { _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); - _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); + _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.6f ); _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.001f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); + _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 5 ); attributes.radius = 0.001f; @@ -448,18 +448,18 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 1.0f; attributes.usingCollisionSphere = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.gravity = 0.01f; attributes.jitter = 0.0f; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.2f); attributes.radius = 0.002f; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // flashy @@ -484,19 +484,19 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 1.0f; attributes.usingCollisionSphere = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.01f; attributes.color = glm::vec4( 1.0f, 1.0f, 0.0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.radius = 0.01f; attributes.color = glm::vec4( 1.0f, 0.0f, 1.0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.radius = 0.0f; attributes.color = glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // Bozo sparkler @@ -521,19 +521,19 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 1.0f; attributes.usingCollisionSphere = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.01f; attributes.color = glm::vec4( 1.0f, 1.0f, 0.0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.radius = 0.01f; attributes.color = glm::vec4( 1.0f, 0.0f, .0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.radius = 0.0f; attributes.color = glm::vec4( 0.0f, 0.0f, 1.0f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // long sparkler @@ -558,19 +558,19 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 1.0f; attributes.usingCollisionSphere = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.005f; attributes.color = glm::vec4( 0.0f, 0.5f, 0.5f, 0.8f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.radius = 0.007f; attributes.color = glm::vec4( 0.5f, 0.0f, 0.5f, 0.5f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.radius = 0.02f; attributes.color = glm::vec4( 0.0f, 0.0f, 1.0f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // bubble snake @@ -595,19 +595,19 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 1.1f; attributes.bounce = 0.0f; attributes.usingCollisionSphere = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 0, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.002f; attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 1, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.radius = 0.003f; attributes.color = glm::vec4( 0.3f, 0.3f, 0.3f, 0.5f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 2, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.radius = 0.004f; attributes.color = glm::vec4( 0.3f, 0.3f, 0.3f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], 3, attributes); + _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); } } } From 1d5bf20b80344aa88e3af5aaa9fb359d1dddba7b Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 24 Jul 2013 17:03:35 -0700 Subject: [PATCH 31/88] clean up --- interface/src/ParticleSystem.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 707fce967a..350f2a6b65 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -24,18 +24,20 @@ ParticleSystem::ParticleSystem() { _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default for (unsigned int emitterIndex = 0; emitterIndex < MAX_EMITTERS; emitterIndex++) { - - _emitter[emitterIndex].position = glm::vec3(0.0f, 0.0f, 0.0f); - _emitter[emitterIndex].direction = glm::vec3(0.0f, 1.0f, 0.0f); - _emitter[emitterIndex].visible = false; - _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; - _emitter[emitterIndex].particleRenderStyle = PARTICLE_RENDER_STYLE_SPHERE; + + Emitter e = _emitter[emitterIndex]; + + e.position = glm::vec3(0.0f, 0.0f, 0.0f); + e.direction = glm::vec3(0.0f, 1.0f, 0.0f); + e.visible = false; + e.particleResolution = DEFAULT_PARTICLE_SPHERE_RESOLUTION; + e.particleLifespan = DEFAULT_PARTICLE_LIFESPAN; + e.showingBaseParticle = false; + e.emitReserve = 0.0; + e.thrust = 0.0f; + e.rate = 0.0f; + e.currentParticle = 0; + e.particleRenderStyle = PARTICLE_RENDER_STYLE_SPHERE; for (int lifeStage = 0; lifeStage Date: Thu, 25 Jul 2013 12:29:17 -0700 Subject: [PATCH 32/88] CR feedback --- avatar-mixer/src/main.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index 8383c992b2..0677ffbc7e 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -58,13 +58,12 @@ void attachAvatarDataToNode(Node* newNode) { // 3) if we need to rate limit the amount of data we send, we can use a distance weighted "semi-random" function to // determine which avatars are included in the packet stream // 4) we should optimize the avatar data format to be more compact (100 bytes is pretty wasteful). -unsigned char broadcastPacketBuffer[MAX_PACKET_SIZE]; -unsigned char avatarDataBuffer[MAX_PACKET_SIZE]; void broadcastAvatarData(NodeList* nodeList, sockaddr* nodeAddress) { - unsigned char* broadcastPacket = (unsigned char*)&::broadcastPacketBuffer[0]; + static unsigned char broadcastPacketBuffer[MAX_PACKET_SIZE]; + static unsigned char avatarDataBuffer[MAX_PACKET_SIZE]; + unsigned char* broadcastPacket = (unsigned char*)&broadcastPacketBuffer[0]; int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_BULK_AVATAR_DATA); - unsigned char* currentBufferPosition = NULL; - currentBufferPosition = broadcastPacket + numHeaderBytes; + unsigned char* currentBufferPosition = broadcastPacket + numHeaderBytes; int packetLength = currentBufferPosition - broadcastPacket; int packetsSent = 0; From 919f2a4a939df264e11a4ef82ed7827c759683b6 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 25 Jul 2013 12:56:00 -0700 Subject: [PATCH 33/88] fix voxel-server crash --- libraries/voxels/src/VoxelTree.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index b26a70f34b..fe67a50dee 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1071,6 +1071,9 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, EncodeBitstreamParams& params, int& currentEncodeLevel) const { + // you can't call this without a valid node + assert(node); + // How many bytes have we written so far at this level; int bytesAtThisLevel = 0; @@ -1228,6 +1231,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp } // track stats + // must check childNode here, because it could be we got here with no childNode if (params.stats && childNode) { params.stats->traversed(childNode); } @@ -1243,7 +1247,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp bool childIsInView = (childNode && (!params.viewFrustum || childNode->isInView(*params.viewFrustum))); if (!childIsInView) { - if (params.stats) { + // must check childNode here, because it could be we got here because there was no childNode + if (params.stats && childNode) { params.stats->skippedOutOfView(childNode); } } else { @@ -1253,6 +1258,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp boundaryDistanceForRenderLevel(childNode->getLevel() + params.boundaryLevelAdjust); if (!(distance < boundaryDistance)) { + // don't need to check childNode here, because we can't get here with no childNode if (params.stats) { params.stats->skippedDistance(childNode); } @@ -1306,9 +1312,11 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp // track some stats if (params.stats) { + // don't need to check childNode here, because we can't get here with no childNode if (!shouldRender && childNode->isLeaf()) { params.stats->skippedDistance(childNode); } + // don't need to check childNode here, because we can't get here with no childNode if (childIsOccluded) { params.stats->skippedOccluded(childNode); } @@ -1339,6 +1347,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp inViewWithColorCount++; } else { // otherwise just track stats of the items we discarded + // don't need to check childNode here, because we can't get here with no childNode if (params.stats) { if (childWasInView) { params.stats->skippedWasInView(childNode); @@ -1368,6 +1377,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp writeToThisLevelBuffer += BYTES_PER_COLOR; // move the pointer for color bytesAtThisLevel += BYTES_PER_COLOR; // keep track of byte count for color + // don't need to check childNode here, because we can't get here with no childNode if (params.stats) { params.stats->colorSent(childNode); } @@ -1407,6 +1417,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp } else { bag.insert(node); + // don't need to check node here, because we can't get here with no node if (params.stats) { params.stats->didntFit(node); } From 79648ce656a43f4ad3735d83e4d589dd463946bf Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 25 Jul 2013 15:22:23 -0700 Subject: [PATCH 34/88] fix bug with dragonfly leaving trailing bits --- libraries/voxels/src/VoxelTree.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index fe67a50dee..7bf3c66888 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1485,11 +1485,13 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp if (params.includeColor && !params.includeExistsBits && childTreeBytesOut == 2) { childTreeBytesOut = 0; // this is the degenerate case of a tree with no colors and no child trees } - // If we've asked for existBits, this is also true, except that the tree will output 3 bytes - // NOTE: does this introduce a problem with detecting deletion?? - if (params.includeColor && params.includeExistsBits && childTreeBytesOut == 3) { - childTreeBytesOut = 0; // this is the degenerate case of a tree with no colors and no child trees - } + // We used to try to collapse trees that didn't contain any data, but this does appear to create a problem + // in detecting node deletion. So, I've commented this out but left it in here as a warning to anyone else + // about not attempting to add this optimization back in, without solving the node deletion case. + // We need to send these bitMasks in case the exists in tree bitmask is indicating the deletion of a tree + //if (params.includeColor && params.includeExistsBits && childTreeBytesOut == 3) { + // childTreeBytesOut = 0; // this is the degenerate case of a tree with no colors and no child trees + //} bytesAtThisLevel += childTreeBytesOut; availableBytes -= childTreeBytesOut; From 0c95dc4adf2538897a75517686a8d7b72545f95d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 26 Jul 2013 11:12:48 -0700 Subject: [PATCH 35/88] Fixed voxel trails from animations - removed stageForDeletion behavior of VoxelNode - replaced with VoxelNodeDeletionHook strategy - VoxelSystem now cleans up previously used VBO index slots via hook --- interface/src/VoxelSystem.cpp | 66 +++++++++++++++------------ interface/src/VoxelSystem.h | 7 +++ libraries/voxels/src/VoxelNode.cpp | 23 +++------- libraries/voxels/src/VoxelNode.h | 7 +-- libraries/voxels/src/VoxelNodeBag.cpp | 1 - libraries/voxels/src/VoxelTree.cpp | 20 +++----- libraries/voxels/src/VoxelTree.h | 7 +-- 7 files changed, 59 insertions(+), 72 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index f219e38dc6..0ea6d2d351 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -58,6 +58,32 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) : _tree = new VoxelTree(); pthread_mutex_init(&_bufferWriteLock, NULL); pthread_mutex_init(&_treeLock, NULL); + + _hookID = VoxelNode::addDeleteHook(voxelNodeDeleteHook, (void*)this); +} + +void VoxelSystem::voxelNodeDeleteHook(VoxelNode* node, void* extraData) { + VoxelSystem* theSystem = (VoxelSystem*)extraData; + + if (node->isKnownBufferIndex()) { + theSystem->freeBufferIndex(node->getBufferIndex()); + } +} + +void VoxelSystem::freeBufferIndex(glBufferIndex index) { + _freeIdexes.push_back(index); +} + +void VoxelSystem::clearFreeBufferIndexes() { + for (int i = 0; i < _freeIdexes.size(); i++) { + glBufferIndex nodeIndex = _freeIdexes[i]; + glm::vec3 startVertex(FLT_MAX, FLT_MAX, FLT_MAX); + float voxelScale = 0; + _writeVoxelDirtyArray[nodeIndex] = true; + nodeColor color = { 0, 0, 0, 0}; + updateNodeInArrays(nodeIndex, startVertex, voxelScale, color); + } + _freeIdexes.clear(); } VoxelSystem::~VoxelSystem() { @@ -70,6 +96,8 @@ VoxelSystem::~VoxelSystem() { delete _tree; pthread_mutex_destroy(&_bufferWriteLock); pthread_mutex_destroy(&_treeLock); + + VoxelNode::removeDeleteHook(_hookID); } void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { @@ -173,6 +201,9 @@ void VoxelSystem::setupNewVoxelsForDrawing() { PerformanceWarning warn(_renderWarningsOn, "setupNewVoxelsForDrawing()"); // would like to include _voxelsInArrays, _voxelsUpdated uint64_t start = usecTimestampNow(); uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000; + + // clear up the VBOs for any nodes that have been recently deleted. + clearFreeBufferIndexes(); bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging if (!iAmDebugging && sinceLastTime <= std::max((float) _setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) { @@ -182,7 +213,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { uint64_t sinceLastViewCulling = (start - _lastViewCulling) / 1000; // If the view frustum is no longer changing, but has changed, since last time, then remove nodes that are out of view if ((sinceLastViewCulling >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) - && !isViewChanging() && hasViewChanged()) { + && !isViewChanging()) { _lastViewCulling = start; // When we call removeOutOfView() voxels, we don't actually remove the voxels from the VBOs, but we do remove @@ -239,6 +270,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { } void VoxelSystem::cleanupRemovedVoxels() { + //printf("cleanupRemovedVoxels...\n"); PerformanceWarning warn(_renderWarningsOn, "cleanupRemovedVoxels()"); if (!_removedVoxels.isEmpty()) { while (!_removedVoxels.isEmpty()) { @@ -323,7 +355,7 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) { bool shouldRender = false; // assume we don't need to render it // if it's colored, we might need to render it! shouldRender = node->calculateShouldRender(Application::getInstance()->getViewFrustum()); - node->setShouldRender(shouldRender && !node->isStagedForDeletion()); + node->setShouldRender(shouldRender); // let children figure out their renderness if (!node->isLeaf()) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { @@ -339,13 +371,6 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) { } node->clearDirtyBit(); // clear the dirty bit, do this before we potentially delete things. - // If the node has been asked to be deleted, but we've gotten to here, after updateNodeInArraysXXX() - // then it means our VBOs are "clean" and our vertices have been removed or not added. So we can now - // safely remove the node from the tree and actually delete it. - if (node->isStagedForDeletion()) { - _tree->deleteVoxelCodeFromTree(node->getOctalCode()); - } - return voxelsUpdated; } @@ -1111,7 +1136,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { void VoxelSystem::deleteVoxelAt(float x, float y, float z, float s) { pthread_mutex_lock(&_treeLock); - _tree->deleteVoxelAt(x, y, z, s, true); + _tree->deleteVoxelAt(x, y, z, s); // redraw! setupNewVoxelsForDrawing(); // do we even need to do this? Or will the next network receive kick in? @@ -1167,7 +1192,6 @@ struct FalseColorizeOccludedArgs { long nonLeaves; long nonLeavesOutOfView; long nonLeavesOccluded; - long stagedForDeletion; }; struct FalseColorizeSubTreeOperationArgs { @@ -1189,12 +1213,6 @@ bool VoxelSystem::falseColorizeOccludedOperation(VoxelNode* node, void* extraDat FalseColorizeOccludedArgs* args = (FalseColorizeOccludedArgs*) extraData; args->totalVoxels++; - // if this node is staged for deletion, then just return - if (node->isStagedForDeletion()) { - args->stagedForDeletion++; - return true; - } - // If we are a parent, let's see if we're completely occluded. if (!node->isLeaf()) { args->nonLeaves++; @@ -1275,7 +1293,6 @@ void VoxelSystem::falseColorizeOccluded() { args.outOfView = 0; args.subtreeVoxelsSkipped = 0; args.nonLeaves = 0; - args.stagedForDeletion = 0; args.nonLeavesOutOfView = 0; args.nonLeavesOccluded = 0; args.tree = _tree; @@ -1288,11 +1305,10 @@ void VoxelSystem::falseColorizeOccluded() { _tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedOperation, position, (void*)&args); - qDebug("falseColorizeOccluded()\n position=(%f,%f)\n total=%ld\n colored=%ld\n occluded=%ld\n notOccluded=%ld\n outOfView=%ld\n subtreeVoxelsSkipped=%ld\n stagedForDeletion=%ld\n nonLeaves=%ld\n nonLeavesOutOfView=%ld\n nonLeavesOccluded=%ld\n pointInside_calls=%ld\n occludes_calls=%ld\n intersects_calls=%ld\n", + qDebug("falseColorizeOccluded()\n position=(%f,%f)\n total=%ld\n colored=%ld\n occluded=%ld\n notOccluded=%ld\n outOfView=%ld\n subtreeVoxelsSkipped=%ld\n nonLeaves=%ld\n nonLeavesOutOfView=%ld\n nonLeavesOccluded=%ld\n pointInside_calls=%ld\n occludes_calls=%ld\n intersects_calls=%ld\n", position.x, position.y, args.totalVoxels, args.coloredVoxels, args.occludedVoxels, args.notOccludedVoxels, args.outOfView, args.subtreeVoxelsSkipped, - args.stagedForDeletion, args.nonLeaves, args.nonLeavesOutOfView, args.nonLeavesOccluded, VoxelProjectedPolygon::pointInside_calls, VoxelProjectedPolygon::occludes_calls, @@ -1310,12 +1326,6 @@ bool VoxelSystem::falseColorizeOccludedV2Operation(VoxelNode* node, void* extraD FalseColorizeOccludedArgs* args = (FalseColorizeOccludedArgs*) extraData; args->totalVoxels++; - // if this node is staged for deletion, then just return - if (node->isStagedForDeletion()) { - args->stagedForDeletion++; - return true; - } - // If we are a parent, let's see if we're completely occluded. if (!node->isLeaf()) { args->nonLeaves++; @@ -1404,7 +1414,6 @@ void VoxelSystem::falseColorizeOccludedV2() { args.outOfView = 0; args.subtreeVoxelsSkipped = 0; args.nonLeaves = 0; - args.stagedForDeletion = 0; args.nonLeavesOutOfView = 0; args.nonLeavesOccluded = 0; args.tree = _tree; @@ -1413,11 +1422,10 @@ void VoxelSystem::falseColorizeOccludedV2() { _tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedV2Operation, position, (void*)&args); - qDebug("falseColorizeOccludedV2()\n position=(%f,%f)\n total=%ld\n colored=%ld\n occluded=%ld\n notOccluded=%ld\n outOfView=%ld\n subtreeVoxelsSkipped=%ld\n stagedForDeletion=%ld\n nonLeaves=%ld\n nonLeavesOutOfView=%ld\n nonLeavesOccluded=%ld\n pointInside_calls=%ld\n occludes_calls=%ld\n intersects_calls=%ld\n", + qDebug("falseColorizeOccludedV2()\n position=(%f,%f)\n total=%ld\n colored=%ld\n occluded=%ld\n notOccluded=%ld\n outOfView=%ld\n subtreeVoxelsSkipped=%ld\n nonLeaves=%ld\n nonLeavesOutOfView=%ld\n nonLeavesOccluded=%ld\n pointInside_calls=%ld\n occludes_calls=%ld\n intersects_calls=%ld\n", position.x, position.y, args.totalVoxels, args.coloredVoxels, args.occludedVoxels, args.notOccludedVoxels, args.outOfView, args.subtreeVoxelsSkipped, - args.stagedForDeletion, args.nonLeaves, args.nonLeavesOutOfView, args.nonLeavesOccluded, VoxelProjectedPolygon::pointInside_calls, VoxelProjectedPolygon::occludes_calls, diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 411ae2f81f..cb12eee029 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -187,6 +187,13 @@ private: static ProgramObject* _perlinModulateProgram; static GLuint _permutationNormalTextureID; + + int _hookID; + std::vector _freeIdexes; + + static void voxelNodeDeleteHook(VoxelNode* node, void* extraData); + void freeBufferIndex(glBufferIndex index); + void clearFreeBufferIndexes(); }; #endif diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 34eb2b2261..4a0f017326 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -50,7 +50,6 @@ void VoxelNode::init(unsigned char * octalCode) { _glBufferIndex = GLBUFFER_INDEX_UNKNOWN; _isDirty = true; _shouldRender = false; - _isStagedForDeletion = false; markWithChangedTime(); calculateAABox(); } @@ -159,28 +158,18 @@ VoxelNode* VoxelNode::addChildAtIndex(int childIndex) { } // handles staging or deletion of all deep children -void VoxelNode::safeDeepDeleteChildAtIndex(int childIndex, bool& stagedForDeletion) { +void VoxelNode::safeDeepDeleteChildAtIndex(int childIndex) { VoxelNode* childToDelete = getChildAtIndex(childIndex); if (childToDelete) { // If the child is not a leaf, then call ourselves recursively on all the children if (!childToDelete->isLeaf()) { // delete all it's children for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { - childToDelete->safeDeepDeleteChildAtIndex(i, stagedForDeletion); + childToDelete->safeDeepDeleteChildAtIndex(i); } } - // if this node has a BufferIndex then we need to stage it for deletion - // instead of actually deleting it from the tree - if (childToDelete->isKnownBufferIndex()) { - stagedForDeletion = true; - } - if (stagedForDeletion) { - childToDelete->stageForDeletion(); - _isDirty = true; - } else { - deleteChildAtIndex(childIndex); - _isDirty = true; - } + deleteChildAtIndex(childIndex); + _isDirty = true; markWithChangedTime(); } } @@ -190,7 +179,7 @@ void VoxelNode::setColorFromAverageOfChildren() { int colorArray[4] = {0,0,0,0}; float density = 0.0f; for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { - if (_children[i] && !_children[i]->isStagedForDeletion() && _children[i]->isColored()) { + if (_children[i] && _children[i]->isColored()) { for (int j = 0; j < 3; j++) { colorArray[j] += _children[i]->getTrueColor()[j]; // color averaging should always be based on true colors } @@ -279,7 +268,7 @@ bool VoxelNode::collapseIdenticalLeaves() { int red,green,blue; for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { // if no child, child isn't a leaf, or child doesn't have a color - if (!_children[i] || _children[i]->isStagedForDeletion() || !_children[i]->isLeaf() || !_children[i]->isColored()) { + if (!_children[i] || !_children[i]->isLeaf() || !_children[i]->isColored()) { allChildrenMatch=false; //qDebug("SADNESS child missing or not colored! i=%d\n",i); break; diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index c84ce3c7d6..1efab362de 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -38,7 +38,7 @@ public: void deleteChildAtIndex(int childIndex); VoxelNode* removeChildAtIndex(int childIndex); VoxelNode* addChildAtIndex(int childIndex); - void safeDeepDeleteChildAtIndex(int childIndex, bool& stagedForDeletion); // handles staging or deletion of all descendents + void safeDeepDeleteChildAtIndex(int childIndex); // handles deletion of all descendents void setColorFromAverageOfChildren(); void setRandomColor(int minimumBrightness); @@ -82,10 +82,6 @@ public: void setShouldRender(bool shouldRender); bool getShouldRender() const { return _shouldRender; } - // Used by VoxelSystem to mark a node as to be deleted on next render pass - void stageForDeletion() { _isStagedForDeletion = true; _isDirty = true; }; - bool isStagedForDeletion() const { return _isStagedForDeletion; } - #ifndef NO_FALSE_COLOR // !NO_FALSE_COLOR means, does have false color void setFalseColor(colorPart red, colorPart green, colorPart blue); void setFalseColored(bool isFalseColored); @@ -127,7 +123,6 @@ private: bool _isDirty; uint64_t _lastChanged; bool _shouldRender; - bool _isStagedForDeletion; AABox _box; unsigned char* _octalCode; VoxelNode* _children[8]; diff --git a/libraries/voxels/src/VoxelNodeBag.cpp b/libraries/voxels/src/VoxelNodeBag.cpp index 4f355116e4..bc515c9e5a 100644 --- a/libraries/voxels/src/VoxelNodeBag.cpp +++ b/libraries/voxels/src/VoxelNodeBag.cpp @@ -125,7 +125,6 @@ void VoxelNodeBag::remove(VoxelNode* node) { _elementsInUse--; } } - void VoxelNodeBag::voxelNodeDeleteHook(VoxelNode* node, void* extraData) { VoxelNodeBag* theBag = (VoxelNodeBag*)extraData; theBag->remove(node); // note: remove can safely handle nodes that aren't in it, so we don't need to check contains() diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 7bf3c66888..87def2cc23 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -311,8 +311,7 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, // now also check the childrenInTreeMask, if the mask is missing the bit, then it means we need to delete this child // subtree/node, because it shouldn't actually exist in the tree. if (!oneAtBit(childrenInTreeMask, i) && destinationNode->getChildAtIndex(i)) { - bool stagedForDeletion = false; // assume staging is not needed - destinationNode->safeDeepDeleteChildAtIndex(i, stagedForDeletion); + destinationNode->safeDeepDeleteChildAtIndex(i); _isDirty = true; // by definition! } } @@ -366,15 +365,14 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int this->voxelsBytesReadStats.updateAverage(bufferSizeBytes); } -void VoxelTree::deleteVoxelAt(float x, float y, float z, float s, bool stage) { +void VoxelTree::deleteVoxelAt(float x, float y, float z, float s) { unsigned char* octalCode = pointToVoxel(x,y,z,s,0,0,0); - deleteVoxelCodeFromTree(octalCode, stage); + deleteVoxelCodeFromTree(octalCode); delete[] octalCode; // cleanup memory } class DeleteVoxelCodeFromTreeArgs { public: - bool stage; bool collapseEmptyTrees; unsigned char* codeBuffer; int lengthOfCode; @@ -384,11 +382,10 @@ public: // Note: uses the codeColorBuffer format, but the color's are ignored, because // this only finds and deletes the node from the tree. -void VoxelTree::deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool stage, bool collapseEmptyTrees) { +void VoxelTree::deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool collapseEmptyTrees) { // recurse the tree while decoding the codeBuffer, once you find the node in question, recurse // back and implement color reaveraging, and marking of lastChanged DeleteVoxelCodeFromTreeArgs args; - args.stage = stage; args.collapseEmptyTrees = collapseEmptyTrees; args.codeBuffer = codeBuffer; args.lengthOfCode = numberOfThreeBitSectionsInCode(codeBuffer); @@ -408,7 +405,6 @@ void VoxelTree::deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraDat // matches, then we've reached our target node. if (lengthOfNodeCode == args->lengthOfCode) { // we've reached our target, depending on how we're called we may be able to operate on it - // if we're in "stage" mode, then we can could have the node staged, otherwise we can't really delete // it here, we need to recurse up, and delete it there. So we handle these cases the same to keep // the logic consistent. args->deleteLastChild = true; @@ -468,11 +464,7 @@ void VoxelTree::deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraDat // If the lower level determined it needs to be deleted, then we should delete now. if (args->deleteLastChild) { - if (args->stage) { - childNode->stageForDeletion(); - } else { - node->deleteChildAtIndex(childIndex); // note: this will track dirtiness and lastChanged for this node - } + node->deleteChildAtIndex(childIndex); // note: this will track dirtiness and lastChanged for this node // track our tree dirtiness _isDirty = true; @@ -602,7 +594,7 @@ void VoxelTree::processRemoveVoxelBitstream(unsigned char * bitstream, int buffe int codeLength = numberOfThreeBitSectionsInCode(voxelCode); int voxelDataSize = bytesRequiredForCodeLength(codeLength) + SIZE_OF_COLOR_DATA; - deleteVoxelCodeFromTree(voxelCode, ACTUALLY_DELETE, COLLAPSE_EMPTY_TREE); + deleteVoxelCodeFromTree(voxelCode, COLLAPSE_EMPTY_TREE); voxelCode+=voxelDataSize; atByte+=voxelDataSize; diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 199942605e..5cda791531 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -27,8 +27,6 @@ typedef enum {GRADIENT, RANDOM, NATURAL} creationMode; #define NO_COLOR false #define WANT_COLOR true #define IGNORE_VIEW_FRUSTUM NULL -#define JUST_STAGE_DELETION true -#define ACTUALLY_DELETE false #define COLLAPSE_EMPTY_TREE true #define DONT_COLLAPSE false #define NO_OCCLUSION_CULLING false @@ -113,12 +111,11 @@ public: bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS, VoxelNode* destinationNode = NULL); void readCodeColorBufferToTree(unsigned char* codeColorBuffer, bool destructive = false); - void deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool stage = ACTUALLY_DELETE, - bool collapseEmptyTrees = DONT_COLLAPSE); + void deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool collapseEmptyTrees = DONT_COLLAPSE); void printTreeForDebugging(VoxelNode* startNode); void reaverageVoxelColors(VoxelNode* startNode); - void deleteVoxelAt(float x, float y, float z, float s, bool stage = false); + void deleteVoxelAt(float x, float y, float z, float s); VoxelNode* getVoxelAt(float x, float y, float z, float s) const; void createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue, bool destructive = false); From 4cca7e25724c2293b797a0819ceefb32e9c9851e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 26 Jul 2013 11:44:19 -0700 Subject: [PATCH 36/88] Fixed issue with freeing up abandoned VBO slots when not moving with animation --- interface/src/VoxelSystem.cpp | 16 ++++++++++++++-- interface/src/VoxelSystem.h | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 0ea6d2d351..8282b3d8e0 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -60,6 +60,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) : pthread_mutex_init(&_treeLock, NULL); _hookID = VoxelNode::addDeleteHook(voxelNodeDeleteHook, (void*)this); + _abandonedVBOSlots = 0; } void VoxelSystem::voxelNodeDeleteHook(VoxelNode* node, void* extraData) { @@ -82,6 +83,7 @@ void VoxelSystem::clearFreeBufferIndexes() { _writeVoxelDirtyArray[nodeIndex] = true; nodeColor color = { 0, 0, 0, 0}; updateNodeInArrays(nodeIndex, startVertex, voxelScale, color); + _abandonedVBOSlots++; } _freeIdexes.clear(); } @@ -243,6 +245,10 @@ void VoxelSystem::setupNewVoxelsForDrawing() { } _voxelsUpdated = newTreeToArrays(_tree->rootNode); _tree->clearDirtyBit(); // after we pull the trees into the array, we can consider the tree clean + + if (_writeRenderFullVBO) { + _abandonedVBOSlots = 0; // reset the count of our abandoned slots + } // since we called treeToArrays, we can assume that our VBO is in sync, and so partial updates to the VBOs are // ok again, until/unless we call removeOutOfView() @@ -270,14 +276,20 @@ void VoxelSystem::setupNewVoxelsForDrawing() { } void VoxelSystem::cleanupRemovedVoxels() { - //printf("cleanupRemovedVoxels...\n"); PerformanceWarning warn(_renderWarningsOn, "cleanupRemovedVoxels()"); + // This handles cleanup of voxels that were culled as part of our regular out of view culling operation if (!_removedVoxels.isEmpty()) { while (!_removedVoxels.isEmpty()) { delete _removedVoxels.extract(); } _writeRenderFullVBO = true; // if we remove voxels, we must update our full VBOs } + // we also might have VBO slots that have been abandoned, if too many of our VBO slots + // are abandonded we want to rerender our full VBOs + const float TOO_MANY_ABANDONED_RATIO = 0.25f; + if (!_writeRenderFullVBO && (_abandonedVBOSlots > (_voxelsInWriteArrays * TOO_MANY_ABANDONED_RATIO))) { + _writeRenderFullVBO = true; + } } void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() { @@ -418,6 +430,7 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { // and our scale as infinitely small startVertex[0] = startVertex[1] = startVertex[2] = FLT_MAX; voxelScale = 0; + _abandonedVBOSlots++; } // If this node has not yet been written to the array, then add it to the end of the array. @@ -470,7 +483,6 @@ void VoxelSystem::init() { _voxelsDirty = false; _voxelsInWriteArrays = 0; _voxelsInReadArrays = 0; - _unusedArraySpace = 0; // we will track individual dirty sections with these arrays of bools _writeVoxelDirtyArray = new bool[_maxVoxels]; diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index cb12eee029..4a6d30c78b 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -155,7 +155,7 @@ private: unsigned long _voxelsUpdated; unsigned long _voxelsInReadArrays; unsigned long _voxelsInWriteArrays; - unsigned long _unusedArraySpace; + unsigned long _abandonedVBOSlots; bool _writeRenderFullVBO; bool _readRenderFullVBO; From 9890cf72ce71e2caf367fe23531fb7c35ab6a592 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 26 Jul 2013 12:37:37 -0700 Subject: [PATCH 37/88] added keyboard mode switching for rave glove effects --- interface/src/Application.cpp | 42 +++++++++++++++++++---- interface/src/ParticleSystem.cpp | 35 +++++++++---------- interface/src/avatar/Avatar.cpp | 2 +- interface/src/avatar/Hand.cpp | 54 ++++++++++++++++-------------- interface/src/avatar/Hand.h | 24 ++++++++++++- libraries/avatars/src/AvatarData.h | 12 +++++++ 6 files changed, 118 insertions(+), 51 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b12e452b60..eb3c72786e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -551,6 +551,7 @@ void Application::sendVoxelServerAddScene() { } void Application::keyPressEvent(QKeyEvent* event) { + if (activeWindow() == _window) { if (_chatEntryOn) { if (_chatEntry.keyPressEvent(event)) { @@ -566,6 +567,11 @@ void Application::keyPressEvent(QKeyEvent* event) { } return; } + + //this is for switching between modes for the leap rave glove test + if (_simulateLeapHand->isChecked() || _testRaveGlove->isChecked()) { + _myAvatar.getHand().setRaveGloveEffectsMode((QKeyEvent*)event); + } bool shifted = event->modifiers().testFlag(Qt::ShiftModifier); switch (event->key()) { @@ -765,7 +771,7 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_6: case Qt::Key_7: case Qt::Key_8: - _swatch.handleEvent(event->key(), _eyedropperMode->isChecked()); + _swatch.handleEvent(event->key(), _eyedropperMode->isChecked()); break; default: event->ignore(); @@ -776,6 +782,7 @@ void Application::keyPressEvent(QKeyEvent* event) { void Application::keyReleaseEvent(QKeyEvent* event) { if (activeWindow() == _window) { + if (_chatEntryOn) { _myAvatar.setKeyState(NO_KEY_DOWN); return; @@ -2652,9 +2659,17 @@ void Application::displaySide(Camera& whichCamera) { float sphereRadius = 0.25f; glColor3f(1,0,0); glPushMatrix(); - glutSolidSphere(sphereRadius, 15, 15); + glutSolidSphere(sphereRadius, 15, 15); glPopMatrix(); +/* +glPushMatrix(); +glColor3f(1, 0, 1); +glTranslatef(0.0f, 0.0f, 5.0f); +_particleSystem.render(); +glPopMatrix(); +*/ + //draw a grid ground plane.... if (_renderGroundPlaneOn->isChecked()) { renderGroundPlaneGrid(EDGE_SIZE_GROUND_PLANE, _audio.getCollisionSoundMagnitude()); @@ -2715,13 +2730,25 @@ void Application::displaySide(Camera& whichCamera) { renderLookatIndicator(_lookatOtherPosition, whichCamera); } } - + if (TESTING_PARTICLE_SYSTEM) { if (_particleSystemInitialized) { - _particleSystem.render(); + + + +/* +glPushMatrix(); +glColor3f(1, 0, 1); +glTranslatef(0.0f, 0.0f, 5.0f); +_particleSystem.render(); +glPopMatrix(); +*/ + +_particleSystem.render(); } } - + + // Render the world box if (!_lookingInMirror->isChecked() && _renderStatsOn->isChecked()) { render_world_box(); } @@ -3658,8 +3685,9 @@ void Application::updateParticleSystem(float deltaTime) { const float EMIT_RATE_IN_SECONDS = 10000.0; // create a stable test emitter and spit out a bunch of particles _coolDemoParticleEmitter = _particleSystem.addEmitter(); - + if (_coolDemoParticleEmitter != -1) { + _particleSystem.setShowingEmitter(_coolDemoParticleEmitter, true); glm::vec3 particleEmitterPosition = glm::vec3(5.0f, 1.0f, 5.0f); @@ -3673,7 +3701,7 @@ void Application::updateParticleSystem(float deltaTime) { _particleSystemInitialized = true; } else { // update the particle system - + static bool emitting = true; static float t = 0.0f; t += deltaTime; diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 350f2a6b65..286d7786a4 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -25,19 +25,19 @@ ParticleSystem::ParticleSystem() { for (unsigned int emitterIndex = 0; emitterIndex < MAX_EMITTERS; emitterIndex++) { - Emitter e = _emitter[emitterIndex]; + Emitter * e = &_emitter[emitterIndex]; - e.position = glm::vec3(0.0f, 0.0f, 0.0f); - e.direction = glm::vec3(0.0f, 1.0f, 0.0f); - e.visible = false; - e.particleResolution = DEFAULT_PARTICLE_SPHERE_RESOLUTION; - e.particleLifespan = DEFAULT_PARTICLE_LIFESPAN; - e.showingBaseParticle = false; - e.emitReserve = 0.0; - e.thrust = 0.0f; - e.rate = 0.0f; - e.currentParticle = 0; - e.particleRenderStyle = PARTICLE_RENDER_STYLE_SPHERE; + e->position = glm::vec3(0.0f, 0.0f, 0.0f); + e->direction = glm::vec3(0.0f, 1.0f, 0.0f); + e->visible = false; + e->particleResolution = DEFAULT_PARTICLE_SPHERE_RESOLUTION; + e->particleLifespan = DEFAULT_PARTICLE_LIFESPAN; + e->showingBaseParticle = false; + e->emitReserve = 0.0; + e->thrust = 0.0f; + e->rate = 0.0f; + e->currentParticle = 0; + e->particleRenderStyle = PARTICLE_RENDER_STYLE_SPHERE; for (int lifeStage = 0; lifeStage _emitter[_particle[p].emitterIndex].particleLifespan) { killParticle(p); } else { @@ -319,12 +320,12 @@ void ParticleSystem::render() { } }; - // render the particles + // render the particles for (unsigned int p = 0; p < _numParticles; p++) { if (_particle[p].alive) { if (_emitter[_particle[p].emitterIndex].particleLifespan > 0.0) { renderParticle(p); - } + } } } } @@ -363,8 +364,8 @@ void ParticleSystem::renderParticle(int p) { } 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); + 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(); } else if (_emitter[_particle[p].emitterIndex].particleRenderStyle == PARTICLE_RENDER_STYLE_RIBBON) { diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index c2a2d5aadd..8406db78b7 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -447,7 +447,7 @@ void Avatar::updateThrust(float deltaTime, Transmitter * transmitter) { } void Avatar::simulate(float deltaTime, Transmitter* transmitter) { - + glm::quat orientation = getOrientation(); glm::vec3 front = orientation * IDENTITY_FRONT; glm::vec3 right = orientation * IDENTITY_RIGHT; diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 4374e16043..d5a5cc4fbf 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -14,9 +14,7 @@ #include "Util.h" #include "renderer/ProgramObject.h" -const bool SHOW_LEAP_HAND = false; -const int NUM_TEST_RAVE_GLOVE_MODES = 8; -const float TEST_RAVE_GLOVE_MODE_DURATION = 7.0f; +const bool SHOW_LEAP_HAND = false; using namespace std; @@ -52,6 +50,7 @@ void Hand::init() { void Hand::reset() { } + void Hand::simulate(float deltaTime, bool isMine) { if (_isRaveGloveActive) { updateFingerParticles(deltaTime); @@ -86,6 +85,20 @@ void Hand::calculateGeometry() { } } +void Hand::setRaveGloveEffectsMode(QKeyEvent* event) { + switch (event->key()) { + case Qt::Key_0: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_0); break; + case Qt::Key_1: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_1); break; + case Qt::Key_2: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_2); break; + case Qt::Key_3: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_3); break; + case Qt::Key_4: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_4); break; + case Qt::Key_5: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_5); break; + case Qt::Key_6: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_6); break; + case Qt::Key_7: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_7); break; + case Qt::Key_8: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_8); break; + case Qt::Key_9: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_9); break; + }; +} void Hand::render(bool lookingInMirror) { @@ -277,25 +290,14 @@ void Hand::updateFingerParticles(float deltaTime) { assert( _fingerParticleEmitter[f] != -1 ); } - setRaveGloveMode(_testRaveGloveMode); + setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_2); _particleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); _particleSystemInitialized = true; } else { + _testRaveGloveClock += deltaTime; - // cycle through the rave glove test modes... - if (_testRaveGloveClock > TEST_RAVE_GLOVE_MODE_DURATION) { - _testRaveGloveClock = 0.0f; - _testRaveGloveMode ++; - - if (_testRaveGloveMode > NUM_TEST_RAVE_GLOVE_MODES) { - _testRaveGloveMode = 0; - } - - setRaveGloveMode(_testRaveGloveMode); - } - - if (_testRaveGloveMode == 0) { + if (_testRaveGloveMode == RAVE_GLOVE_EFFECTS_MODE_0) { ParticleSystem::ParticleAttributes attributes; float red = 0.5f + 0.5f * sinf(_testRaveGloveClock * 1.4f); float green = 0.5f + 0.5f * cosf(_testRaveGloveClock * 1.7f); @@ -317,6 +319,8 @@ void Hand::updateFingerParticles(float deltaTime) { void Hand::setRaveGloveMode(int mode) { + _testRaveGloveMode = mode; + _particleSystem.killAllParticles(); for ( int f = 0; f< NUM_FINGERS; f ++ ) { @@ -326,7 +330,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // throbbing color cycle //----------------------------------------- - if (mode == 0) { + if (mode == RAVE_GLOVE_EFFECTS_MODE_0) { _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.0f ); @@ -354,7 +358,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // trails //----------------------------------------- - } else if (mode == 1) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_1) { _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); @@ -388,7 +392,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // Fire! //----------------------------------------- - if (mode == 2) { + if (mode == RAVE_GLOVE_EFFECTS_MODE_2) { _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); @@ -428,7 +432,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // water //----------------------------------------- - } else if (mode == 3) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_3) { _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); @@ -464,7 +468,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // flashy //----------------------------------------- - } else if (mode == 4) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_4) { _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); @@ -501,7 +505,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // Bozo sparkler //----------------------------------------- - } else if (mode == 5) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_5) { _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); @@ -538,7 +542,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // long sparkler //----------------------------------------- - } else if (mode == 6) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_6) { _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); @@ -575,7 +579,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // bubble snake //----------------------------------------- - } else if (mode == 7) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_7) { _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index 8152a4b271..de3e4f420d 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -8,6 +8,12 @@ #ifndef hifi_Hand_h #define hifi_Hand_h +#include +#include +#include +#include +#include + #include #include #include @@ -22,6 +28,22 @@ class Avatar; class ProgramObject; +enum RaveGloveEffectsMode +{ + RAVE_GLOVE_EFFECTS_MODE_NULL = -1, + RAVE_GLOVE_EFFECTS_MODE_0, + RAVE_GLOVE_EFFECTS_MODE_1, + RAVE_GLOVE_EFFECTS_MODE_2, + RAVE_GLOVE_EFFECTS_MODE_3, + RAVE_GLOVE_EFFECTS_MODE_4, + RAVE_GLOVE_EFFECTS_MODE_5, + RAVE_GLOVE_EFFECTS_MODE_6, + RAVE_GLOVE_EFFECTS_MODE_7, + RAVE_GLOVE_EFFECTS_MODE_8, + RAVE_GLOVE_EFFECTS_MODE_9, + NUM_RAVE_GLOVE_EFFECTS_MODES +}; + class Hand : public HandData { public: Hand(Avatar* owningAvatar); @@ -45,7 +67,7 @@ public: void updateFingerParticles(float deltaTime); void updateFingerParticleEmitters(); void setRaveGloveActive(bool active) { _isRaveGloveActive = active; } - + void setRaveGloveEffectsMode(QKeyEvent* event); // getters const glm::vec3& getLeapBallPosition (int ball) const { return _leapBalls[ball].position;} diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 209d822426..368cf7733a 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -32,6 +32,18 @@ const float MAX_AUDIO_LOUDNESS = 1000.0; // close enough for mouth animation enum KeyState { NO_KEY_DOWN = 0, + /* + ONE_KEY_DOWN, + TOW_KEY_DOWN, + THREE_KEY_DOWN, + FOUR_KEY_DOWN, + FIVE_KEY_DOWN, + SIX_KEY_DOWN, + SEVEN_KEY_DOWN, + EIGHT_KEY_DOWN, + NINE_KEY_DOWN, + ZERO_KEY_DOWN, + */ INSERT_KEY_DOWN, DELETE_KEY_DOWN }; From ad00747c2939f6910cf8f5d23037f32d9a8fb329 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 26 Jul 2013 12:44:17 -0700 Subject: [PATCH 38/88] cleanup --- interface/src/Application.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index eb3c72786e..7ffc432760 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -551,7 +551,6 @@ void Application::sendVoxelServerAddScene() { } void Application::keyPressEvent(QKeyEvent* event) { - if (activeWindow() == _window) { if (_chatEntryOn) { if (_chatEntry.keyPressEvent(event)) { @@ -782,7 +781,6 @@ void Application::keyPressEvent(QKeyEvent* event) { void Application::keyReleaseEvent(QKeyEvent* event) { if (activeWindow() == _window) { - if (_chatEntryOn) { _myAvatar.setKeyState(NO_KEY_DOWN); return; From 8cecd6773183cd6c2a31e78a26c26820c4bd3e92 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 26 Jul 2013 12:46:27 -0700 Subject: [PATCH 39/88] cleanup --- interface/src/Application.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7ffc432760..4c596f6e9c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -770,7 +770,7 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_6: case Qt::Key_7: case Qt::Key_8: - _swatch.handleEvent(event->key(), _eyedropperMode->isChecked()); + _swatch.handleEvent(event->key(), _eyedropperMode->isChecked()); break; default: event->ignore(); @@ -2657,17 +2657,9 @@ void Application::displaySide(Camera& whichCamera) { float sphereRadius = 0.25f; glColor3f(1,0,0); glPushMatrix(); - glutSolidSphere(sphereRadius, 15, 15); + glutSolidSphere(sphereRadius, 15, 15); glPopMatrix(); -/* -glPushMatrix(); -glColor3f(1, 0, 1); -glTranslatef(0.0f, 0.0f, 5.0f); -_particleSystem.render(); -glPopMatrix(); -*/ - //draw a grid ground plane.... if (_renderGroundPlaneOn->isChecked()) { renderGroundPlaneGrid(EDGE_SIZE_GROUND_PLANE, _audio.getCollisionSoundMagnitude()); From cecb908dc19bb8ec24bb0c92aad294701d158690 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 26 Jul 2013 12:53:40 -0700 Subject: [PATCH 40/88] cleanup --- libraries/avatars/src/AvatarData.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 368cf7733a..209d822426 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -32,18 +32,6 @@ const float MAX_AUDIO_LOUDNESS = 1000.0; // close enough for mouth animation enum KeyState { NO_KEY_DOWN = 0, - /* - ONE_KEY_DOWN, - TOW_KEY_DOWN, - THREE_KEY_DOWN, - FOUR_KEY_DOWN, - FIVE_KEY_DOWN, - SIX_KEY_DOWN, - SEVEN_KEY_DOWN, - EIGHT_KEY_DOWN, - NINE_KEY_DOWN, - ZERO_KEY_DOWN, - */ INSERT_KEY_DOWN, DELETE_KEY_DOWN }; From 05e0bf3e8425e89f9b03d03792ca504066158611 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 26 Jul 2013 15:21:10 -0700 Subject: [PATCH 41/88] added collision plane --- interface/src/Application.cpp | 3 +++ interface/src/ParticleSystem.cpp | 23 ++++++++++++++++------- interface/src/ParticleSystem.h | 3 +++ interface/src/avatar/Hand.cpp | 8 ++++++++ 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4c596f6e9c..4ab5b28f15 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3715,6 +3715,9 @@ void Application::updateParticleSystem(float deltaTime) { attributes.usingCollisionSphere = true; attributes.collisionSpherePosition = glm::vec3( 5.0f, 0.5f, 5.0f ); attributes.collisionSphereRadius = 0.5f; + attributes.usingCollisionPlane = true; + attributes.collisionPlanePosition = glm::vec3( 5.0f, 0.0f, 5.0f ); + attributes.collisionPlaneNormal = glm::vec3( 0.0f, 1.0f, 0.0f ); if (attributes.gravity < 0.0f) { attributes.gravity = 0.0f; diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 286d7786a4..9ff175cc2b 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -56,6 +56,9 @@ ParticleSystem::ParticleSystem() { a->collisionSphereRadius = 0.0f; a->collisionSpherePosition = glm::vec3(0.0f, 0.0f, 0.0f); a->usingCollisionSphere = false; + a->collisionPlaneNormal = _upDirection; + a->collisionPlanePosition = glm::vec3(0.0f, 0.0f, 0.0f); + a->usingCollisionPlane = false; } }; @@ -186,6 +189,9 @@ void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleLifeStage l a->usingCollisionSphere = attributes.usingCollisionSphere; a->collisionSpherePosition = attributes.collisionSpherePosition; a->collisionSphereRadius = attributes.collisionSphereRadius; + a->usingCollisionPlane = attributes.usingCollisionPlane; + a->collisionPlanePosition = attributes.collisionPlanePosition; + a->collisionPlaneNormal = attributes.collisionPlaneNormal; } @@ -260,13 +266,16 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { // update position by velocity _particle[p].position += _particle[p].velocity; - - // collision with ground - if (_particle[p].position.y < _particle[p].radius) { - _particle[p].position.y = _particle[p].radius; - - if (_particle[p].velocity.y < 0.0f) { - _particle[p].velocity.y *= -myEmitter.particleAttributes[lifeStage].bounce; + + // collision with the plane surface + if (myEmitter.particleAttributes[lifeStage].usingCollisionPlane) { + glm::vec3 vectorFromParticleToPlanePosition = _particle[p].position - myEmitter.particleAttributes[lifeStage].collisionPlanePosition; + glm::vec3 normal = myEmitter.particleAttributes[lifeStage].collisionPlaneNormal; + float dot = glm::dot(vectorFromParticleToPlanePosition, normal); + if (dot < _particle[p].radius) { + _particle[p].position += normal * (_particle[p].radius - dot); + float planeNormalComponentOfVelocity = glm::dot(_particle[p].velocity, normal); + _particle[p].velocity -= normal * planeNormalComponentOfVelocity * (1.0f + myEmitter.particleAttributes[lifeStage].bounce); } } diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index 10911a4832..7f2534c598 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -51,6 +51,9 @@ public: bool usingCollisionSphere; // set to true to allow collision with a sphere glm::vec3 collisionSpherePosition; // position of the collision sphere float collisionSphereRadius; // radius of the collision sphere + bool usingCollisionPlane; // set to true to allow collision with a plane + glm::vec3 collisionPlanePosition; // reference position of the collision plane + glm::vec3 collisionPlaneNormal; // the surface normal of the collision plane }; // public methods... diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index d5a5cc4fbf..6f5c4159b0 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -350,6 +350,7 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 0.0f; attributes.usingCollisionSphere = false; + attributes.usingCollisionPlane = false; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); @@ -377,6 +378,7 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 0.0f; attributes.usingCollisionSphere = false; + attributes.usingCollisionPlane = false; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.002f; @@ -412,6 +414,7 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 1.0f; attributes.usingCollisionSphere = false; + attributes.usingCollisionPlane = false; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.01f; @@ -452,6 +455,7 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 1.0f; attributes.usingCollisionSphere = false; + attributes.usingCollisionPlane = false; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.gravity = 0.01f; @@ -488,6 +492,7 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 1.0f; attributes.usingCollisionSphere = false; + attributes.usingCollisionPlane = false; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.01f; @@ -525,6 +530,7 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 1.0f; attributes.usingCollisionSphere = false; + attributes.usingCollisionPlane = false; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.01f; @@ -562,6 +568,7 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 0.0f; attributes.bounce = 1.0f; attributes.usingCollisionSphere = false; + attributes.usingCollisionPlane = false; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.005f; @@ -599,6 +606,7 @@ void Hand::setRaveGloveMode(int mode) { attributes.neighborRepulsion = 1.1f; attributes.bounce = 0.0f; attributes.usingCollisionSphere = false; + attributes.usingCollisionPlane = false; _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.002f; From 937574a6b5a35c69f02934df236af137f33f7f73 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 26 Jul 2013 15:25:13 -0700 Subject: [PATCH 42/88] cleanup --- interface/src/Application.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4ab5b28f15..6ed785cb57 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2723,28 +2723,15 @@ void Application::displaySide(Camera& whichCamera) { if (TESTING_PARTICLE_SYSTEM) { if (_particleSystemInitialized) { - - - -/* -glPushMatrix(); -glColor3f(1, 0, 1); -glTranslatef(0.0f, 0.0f, 5.0f); -_particleSystem.render(); -glPopMatrix(); -*/ - -_particleSystem.render(); + _particleSystem.render(); } } - // Render the world box if (!_lookingInMirror->isChecked() && _renderStatsOn->isChecked()) { render_world_box(); } // brad's frustum for debugging if (_frustumOn->isChecked()) renderViewFrustum(_viewFrustum); - } void Application::displayOverlay() { From 65278609f2ceae5388c5fd8e531e6d632c33cf9f Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 26 Jul 2013 15:40:06 -0700 Subject: [PATCH 43/88] cleanup --- interface/src/ParticleSystem.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 9ff175cc2b..6469cdbbf0 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -16,6 +16,7 @@ const float DEFAULT_PARTICLE_BOUNCE = 1.0f; const float DEFAULT_PARTICLE_AIR_FRICTION = 2.0f; const float DEFAULT_PARTICLE_LIFESPAN = 1.0f; const int DEFAULT_PARTICLE_SPHERE_RESOLUTION = 6; +const float DEFAULT_EMITTER_RENDER_LENGTH = 0.2f; ParticleSystem::ParticleSystem() { @@ -325,7 +326,7 @@ void ParticleSystem::render() { } if (_emitter[e].visible) { - renderEmitter(e, 0.2f); + renderEmitter(e, DEFAULT_EMITTER_RENDER_LENGTH); } }; @@ -447,14 +448,14 @@ void ParticleSystem::renderParticle(int p) { } } - void ParticleSystem::renderEmitter(int e, float size) { - glLineWidth(2.0f); + glm::vec3 v = _emitter[e].direction * size; + glColor3f(0.4f, 0.4, 0.8); glBegin(GL_LINES); glVertex3f(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); - glVertex3f(_emitter[e].position.x + _emitter[e].direction.x, _emitter[e].position.y + _emitter[e].direction.y, _emitter[e].position.z + _emitter[e].direction.z); + glVertex3f(_emitter[e].position.x + v.x, _emitter[e].position.y + v.y, _emitter[e].position.z + v.z); glEnd(); } From a5a9784e6bbcfbadf6b405232c2d816cb1b8338a Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 26 Jul 2013 15:44:32 -0700 Subject: [PATCH 44/88] cleanup --- interface/src/avatar/Hand.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index de3e4f420d..4b5afdfe5b 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -8,12 +8,7 @@ #ifndef hifi_Hand_h #define hifi_Hand_h -#include #include -#include -#include -#include - #include #include #include From dd2655825a88aaa122c75ff696c1ffdca83aefc6 Mon Sep 17 00:00:00 2001 From: Mark Peng Date: Fri, 26 Jul 2013 16:08:17 -0700 Subject: [PATCH 45/88] Fix first person camera positioning to correspond to eyelevel. This makes sure the lookatVectors don't seem to point upwards when looking at you. --- interface/src/Application.cpp | 2 +- interface/src/avatar/Avatar.cpp | 6 +++++- interface/src/avatar/Avatar.h | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c56a58ce90..8135e656ed 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -407,7 +407,7 @@ void Application::paintGL() { } else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { _myCamera.setTightness(0.0f); // In first person, camera follows head exactly without delay - _myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition()); + _myCamera.setTargetPosition(_myAvatar.getUprightEyeLevelPosition()); _myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation()); } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index c2a2d5aadd..1d6d0ff57c 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -370,7 +370,11 @@ glm::vec3 Avatar::getUprightHeadPosition() const { return _position + getWorldAlignedOrientation() * glm::vec3(0.0f, _pelvisToHeadLength, 0.0f); } - +glm::vec3 Avatar::getUprightEyeLevelPosition() const { + const float EYE_UP_OFFSET = 0.36f; + glm::vec3 up = getWorldAlignedOrientation() * IDENTITY_UP; + return _position + up * _scale * BODY_BALL_RADIUS_HEAD_BASE * EYE_UP_OFFSET + glm::vec3(0.0f, _pelvisToHeadLength, 0.0f);; +} void Avatar::updateThrust(float deltaTime, Transmitter * transmitter) { // diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index ec0d5a2ce5..fc1d7e204d 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -171,6 +171,7 @@ public: glm::vec3 getGravity () const { return _gravity; } glm::vec3 getUprightHeadPosition() const; + glm::vec3 getUprightEyeLevelPosition() const; AvatarVoxelSystem* getVoxels() { return &_voxels; } From f83ee1e0b5a7556707b02217ff27b471c0d18f53 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 29 Jul 2013 09:48:28 -0700 Subject: [PATCH 46/88] cleanup --- interface/src/avatar/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 8406db78b7..dabd5cbfee 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -447,7 +447,7 @@ void Avatar::updateThrust(float deltaTime, Transmitter * transmitter) { } void Avatar::simulate(float deltaTime, Transmitter* transmitter) { - + glm::quat orientation = getOrientation(); glm::vec3 front = orientation * IDENTITY_FRONT; glm::vec3 right = orientation * IDENTITY_RIGHT; From 5812747ef8d7bf55091777fa8eebb274f67e95a2 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 29 Jul 2013 10:06:03 -0700 Subject: [PATCH 47/88] Double the bitrate to see if we can reduce the blockiness. --- interface/src/Webcam.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/Webcam.cpp b/interface/src/Webcam.cpp index e37ca6c70e..814081301b 100644 --- a/interface/src/Webcam.cpp +++ b/interface/src/Webcam.cpp @@ -500,8 +500,9 @@ void FrameGrabber::grabFrame() { // initialize encoder context vpx_codec_enc_cfg_t codecConfig; vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &codecConfig, 0); - codecConfig.rc_target_bitrate = ENCODED_FACE_WIDTH * combinedFaceHeight * codecConfig.rc_target_bitrate / - codecConfig.g_w / codecConfig.g_h; + const int QUALITY_MULTIPLIER = 2; + codecConfig.rc_target_bitrate = QUALITY_MULTIPLIER * ENCODED_FACE_WIDTH * combinedFaceHeight * + codecConfig.rc_target_bitrate / codecConfig.g_w / codecConfig.g_h; codecConfig.g_w = ENCODED_FACE_WIDTH; codecConfig.g_h = combinedFaceHeight; vpx_codec_enc_init(&_codec, vpx_codec_vp8_cx(), &codecConfig, 0); From 20360ad3e906aaf1e8bcf9092f351f0ade04913e Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 29 Jul 2013 10:41:45 -0700 Subject: [PATCH 48/88] Make particle system update/render toggleable, fix GCC compile warnings. --- interface/src/Application.cpp | 14 +++++++------- interface/src/Application.h | 1 + libraries/shared/src/PerfStat.cpp | 2 +- libraries/voxels/src/VoxelSceneStats.cpp | 12 ++++++------ 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c56a58ce90..825b9801d7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -75,8 +75,6 @@ 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 = true; - static const int BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH = 6; // farther dragged clicks are ignored const glm::vec3 START_LOCATION(4.f, 0.f, 5.f); // Where one's own node begins in the world @@ -1497,11 +1495,11 @@ bool Application::sendVoxelsOperation(VoxelNode* node, void* extraData) { int usecToSleep = CLIENT_TO_SERVER_VOXEL_SEND_INTERVAL_USECS - elapsed; if (usecToSleep > 0) { qDebug("sendVoxelsOperation: packet: %d bytes:%lld elapsed %lld usecs, sleeping for %d usecs!\n", - args->packetsSent, args->bytesSent, elapsed, usecToSleep); + args->packetsSent, (long long int)args->bytesSent, (long long int)elapsed, usecToSleep); usleep(usecToSleep); } else { qDebug("sendVoxelsOperation: packet: %d bytes:%lld elapsed %lld usecs, no need to sleep!\n", - args->packetsSent, args->bytesSent, elapsed); + args->packetsSent, (long long int)args->bytesSent, (long long int)elapsed); } args->lastSendTime = now; } @@ -1686,7 +1684,7 @@ void Application::pasteVoxels() { controlledBroadcastToNodes(args.messageBuffer, args.bufferInUse, & NODE_TYPE_VOXEL_SERVER, 1); qDebug("sending packet: %d\n", ++args.packetsSent); args.bytesSent += args.bufferInUse; - qDebug("total bytes sent: %lld\n", args.bytesSent); + qDebug("total bytes sent: %lld\n", (long long int)args.bytesSent); } if (calculatedOctCode) { @@ -1751,6 +1749,8 @@ void Application::initMenu() { _renderLookatOn->setChecked(false); (_renderLookatIndicatorOn = renderMenu->addAction("Lookat Indicator"))->setCheckable(true); _renderLookatIndicatorOn->setChecked(true); + (_renderParticleSystemOn = renderMenu->addAction("Particle System"))->setCheckable(true); + _renderParticleSystemOn->setChecked(true); (_manualFirstPerson = renderMenu->addAction( "First Person", this, SLOT(setRenderFirstPerson(bool)), Qt::Key_P))->setCheckable(true); (_manualThirdPerson = renderMenu->addAction( @@ -2260,7 +2260,7 @@ void Application::update(float deltaTime) { _audio.eventuallyAnalyzePing(); #endif - if (TESTING_PARTICLE_SYSTEM) { + if (_renderParticleSystemOn->isChecked()) { updateParticleSystem(deltaTime); } } @@ -2716,7 +2716,7 @@ void Application::displaySide(Camera& whichCamera) { } } - if (TESTING_PARTICLE_SYSTEM) { + if (_renderParticleSystemOn->isChecked()) { if (_particleSystemInitialized) { _particleSystem.render(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index bee9bb8b20..80ebd34250 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -267,6 +267,7 @@ private: QAction* _renderFrameTimerOn; // Whether to show onscreen text overlay with stats QAction* _renderLookatOn; // Whether to show lookat vectors from avatar eyes if looking at something QAction* _renderLookatIndicatorOn; + QAction* _renderParticleSystemOn; QAction* _manualFirstPerson; // Whether to force first-person mode QAction* _manualThirdPerson; // Whether to force third-person mode QAction* _logOn; // Whether to show on-screen log diff --git a/libraries/shared/src/PerfStat.cpp b/libraries/shared/src/PerfStat.cpp index 86985eb038..70bcaba009 100644 --- a/libraries/shared/src/PerfStat.cpp +++ b/libraries/shared/src/PerfStat.cpp @@ -59,7 +59,7 @@ PerfStat::~PerfStat() { } if (wantDebugOut) { - qDebug("PerfStats: %s elapsed:%f average:%lf count:%ld total:%lf ut:%d us:%d ue:%d t:%ld s:%ld e:%ld\n", + qDebug("PerfStats: %s elapsed:%f average:%lf count:%ld total:%lf ut:%ld us:%ld ue:%ld t:%ld s:%ld e:%ld\n", this->group.c_str(),elapsed,average,count,totalTime, (end.tv_usec-start.tv_usec),start.tv_usec,end.tv_usec, (end.tv_sec-start.tv_sec),start.tv_sec,end.tv_sec diff --git a/libraries/voxels/src/VoxelSceneStats.cpp b/libraries/voxels/src/VoxelSceneStats.cpp index b226886a25..9dd696eaa6 100644 --- a/libraries/voxels/src/VoxelSceneStats.cpp +++ b/libraries/voxels/src/VoxelSceneStats.cpp @@ -378,10 +378,10 @@ int VoxelSceneStats::unpackFromMessage(unsigned char* sourceBuffer, int availabl void VoxelSceneStats::printDebugDetails() { qDebug("\n------------------------------\n"); qDebug("VoxelSceneStats:\n"); - qDebug(" start : %llu \n", _start); - qDebug(" end : %llu \n", _end); - qDebug(" elapsed : %llu \n", _elapsed); - qDebug(" encoding : %llu \n", _totalEncodeTime); + qDebug(" start : %llu \n", (long long unsigned int)_start); + qDebug(" end : %llu \n", (long long unsigned int)_end); + qDebug(" elapsed : %llu \n", (long long unsigned int)_elapsed); + qDebug(" encoding : %llu \n", (long long unsigned int)_totalEncodeTime); qDebug("\n"); qDebug(" full scene: %s\n", debug::valueOf(_isFullScene)); qDebug(" moving: %s\n", debug::valueOf(_isMoving)); @@ -457,12 +457,12 @@ char* VoxelSceneStats::getItemValue(int item) { calcAverageFPS = (float)USECS_PER_SECOND / (float)elapsedAverage; sprintf(_itemValueBuffer, "%llu usecs (%d fps) Average: %.0f usecs (%d fps)", - _elapsed, calcFPS, elapsedAverage, calcAverageFPS); + (long long unsigned int)_elapsed, calcFPS, elapsedAverage, calcAverageFPS); break; } case ITEM_ENCODE: calcFPS = (float)USECS_PER_SECOND / (float)_totalEncodeTime; - sprintf(_itemValueBuffer, "%llu usecs (%d fps)", _totalEncodeTime, calcFPS); + sprintf(_itemValueBuffer, "%llu usecs (%d fps)", (long long unsigned int)_totalEncodeTime, calcFPS); break; case ITEM_PACKETS: { float elapsedSecs = ((float)_elapsed / (float)USECS_PER_SECOND); From d01f694d4914848e54e9fda8ef793c68af74dcae Mon Sep 17 00:00:00 2001 From: Mark Peng Date: Mon, 29 Jul 2013 11:52:29 -0700 Subject: [PATCH 49/88] Remove extra semicolon in avatar.cpp --- interface/src/avatar/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 1d6d0ff57c..0bf2c94b10 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -373,7 +373,7 @@ glm::vec3 Avatar::getUprightHeadPosition() const { glm::vec3 Avatar::getUprightEyeLevelPosition() const { const float EYE_UP_OFFSET = 0.36f; glm::vec3 up = getWorldAlignedOrientation() * IDENTITY_UP; - return _position + up * _scale * BODY_BALL_RADIUS_HEAD_BASE * EYE_UP_OFFSET + glm::vec3(0.0f, _pelvisToHeadLength, 0.0f);; + return _position + up * _scale * BODY_BALL_RADIUS_HEAD_BASE * EYE_UP_OFFSET + glm::vec3(0.0f, _pelvisToHeadLength, 0.0f); } void Avatar::updateThrust(float deltaTime, Transmitter * transmitter) { From bfd7f3a6c9738e087afa554415a05f653569cf80 Mon Sep 17 00:00:00 2001 From: Mark Peng Date: Mon, 29 Jul 2013 12:25:01 -0700 Subject: [PATCH 50/88] Remove rendering of your own avatar's lookatVectors. This fixes the behavior where if you are moving and jumping, you will occasionally see your own lookatVectors on your screen. --- interface/src/Application.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c8be70b0e4..f331ee9407 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2709,7 +2709,6 @@ void Application::displaySide(Camera& whichCamera) { _myAvatar.getHead().setLookAtPosition(_myCamera.getPosition()); } _myAvatar.render(_lookingInMirror->isChecked(), _renderAvatarBalls->isChecked()); - _myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked()); if (_renderLookatIndicatorOn->isChecked() && _isLookingAtOtherAvatar) { renderLookatIndicator(_lookatOtherPosition, whichCamera); From d6428a81459f1875e0385f6ffc80a4749b08b095 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 29 Jul 2013 13:03:42 -0700 Subject: [PATCH 51/88] removed unneeded cast --- interface/src/VoxelSystem.cpp | 2 +- libraries/voxels/src/VoxelNodeBag.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 8282b3d8e0..c1da906c3e 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -59,7 +59,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) : pthread_mutex_init(&_bufferWriteLock, NULL); pthread_mutex_init(&_treeLock, NULL); - _hookID = VoxelNode::addDeleteHook(voxelNodeDeleteHook, (void*)this); + _hookID = VoxelNode::addDeleteHook(voxelNodeDeleteHook, this); _abandonedVBOSlots = 0; } diff --git a/libraries/voxels/src/VoxelNodeBag.cpp b/libraries/voxels/src/VoxelNodeBag.cpp index bc515c9e5a..713f4de1dd 100644 --- a/libraries/voxels/src/VoxelNodeBag.cpp +++ b/libraries/voxels/src/VoxelNodeBag.cpp @@ -13,7 +13,7 @@ VoxelNodeBag::VoxelNodeBag() : _bagElements(NULL), _elementsInUse(0), _sizeOfElementsArray(0) { - _hookID = VoxelNode::addDeleteHook(voxelNodeDeleteHook, (void*)this); + _hookID = VoxelNode::addDeleteHook(voxelNodeDeleteHook, this); }; VoxelNodeBag::~VoxelNodeBag() { From 97aaa738c357a712f40b54578a84bb4653fd4a0a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 29 Jul 2013 13:07:12 -0700 Subject: [PATCH 52/88] fixed typo --- interface/src/VoxelSystem.cpp | 8 ++++---- interface/src/VoxelSystem.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index c1da906c3e..740defd110 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -72,12 +72,12 @@ void VoxelSystem::voxelNodeDeleteHook(VoxelNode* node, void* extraData) { } void VoxelSystem::freeBufferIndex(glBufferIndex index) { - _freeIdexes.push_back(index); + _freeIndexes.push_back(index); } void VoxelSystem::clearFreeBufferIndexes() { - for (int i = 0; i < _freeIdexes.size(); i++) { - glBufferIndex nodeIndex = _freeIdexes[i]; + for (int i = 0; i < _freeIndexes.size(); i++) { + glBufferIndex nodeIndex = _freeIndexes[i]; glm::vec3 startVertex(FLT_MAX, FLT_MAX, FLT_MAX); float voxelScale = 0; _writeVoxelDirtyArray[nodeIndex] = true; @@ -85,7 +85,7 @@ void VoxelSystem::clearFreeBufferIndexes() { updateNodeInArrays(nodeIndex, startVertex, voxelScale, color); _abandonedVBOSlots++; } - _freeIdexes.clear(); + _freeIndexes.clear(); } VoxelSystem::~VoxelSystem() { diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 4a6d30c78b..1e47cda52a 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -189,7 +189,7 @@ private: static GLuint _permutationNormalTextureID; int _hookID; - std::vector _freeIdexes; + std::vector _freeIndexes; static void voxelNodeDeleteHook(VoxelNode* node, void* extraData); void freeBufferIndex(glBufferIndex index); From 03a75ab295a35010c553d3be4d711d79cfa3fa1a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 29 Jul 2013 13:08:05 -0700 Subject: [PATCH 53/88] fixed spacing --- interface/src/VoxelSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 740defd110..af3f7ce5c2 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -81,7 +81,7 @@ void VoxelSystem::clearFreeBufferIndexes() { glm::vec3 startVertex(FLT_MAX, FLT_MAX, FLT_MAX); float voxelScale = 0; _writeVoxelDirtyArray[nodeIndex] = true; - nodeColor color = { 0, 0, 0, 0}; + nodeColor color = {0, 0, 0, 0}; updateNodeInArrays(nodeIndex, startVertex, voxelScale, color); _abandonedVBOSlots++; } From e20f163e0a6015dad18251d263c38a436994dea0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 29 Jul 2013 13:34:58 -0700 Subject: [PATCH 54/88] changed some defines to consts --- libraries/voxels/src/VoxelTree.h | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 5cda791531..88394bd825 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -22,21 +22,23 @@ typedef bool (*RecurseVoxelTreeOperation)(VoxelNode* node, void* extraData); typedef enum {GRADIENT, RANDOM, NATURAL} creationMode; -#define NO_EXISTS_BITS false -#define WANT_EXISTS_BITS true -#define NO_COLOR false -#define WANT_COLOR true -#define IGNORE_VIEW_FRUSTUM NULL -#define COLLAPSE_EMPTY_TREE true -#define DONT_COLLAPSE false -#define NO_OCCLUSION_CULLING false -#define WANT_OCCLUSION_CULLING true -#define IGNORE_COVERAGE_MAP NULL -#define DONT_CHOP 0 -#define NO_BOUNDARY_ADJUST 0 -#define LOW_RES_MOVING_ADJUST 1 -#define IGNORE_LAST_SENT 0 +const bool NO_EXISTS_BITS = false; +const bool WANT_EXISTS_BITS = true; +const bool NO_COLOR = false; +const bool WANT_COLOR = true; +const bool COLLAPSE_EMPTY_TREE = true; +const bool DONT_COLLAPSE = false; +const bool NO_OCCLUSION_CULLING = false; +const bool WANT_OCCLUSION_CULLING = true; + +const int DONT_CHOP = 0; +const int NO_BOUNDARY_ADJUST = 0; +const int LOW_RES_MOVING_ADJUST = 1; +const uint64_t IGNORE_LAST_SENT = 0; + #define IGNORE_SCENE_STATS NULL +#define IGNORE_VIEW_FRUSTUM NULL +#define IGNORE_COVERAGE_MAP NULL class EncodeBitstreamParams { public: From 9662b956c7027f8aa4a606fc3636c71bdd54413a Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 29 Jul 2013 16:00:55 -0600 Subject: [PATCH 55/88] Fixing cmake path on seed's groovy --- jenkins/jobs.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jenkins/jobs.groovy b/jenkins/jobs.groovy index 114e4389ed..5acf313a9a 100644 --- a/jenkins/jobs.groovy +++ b/jenkins/jobs.groovy @@ -90,7 +90,7 @@ static Closure cmakeBuild(srcDir, instCommand) { installCommand instCommand preloadScript '' cmakeArgs '' - projectCmakePath '/usr/bin/cmake' + projectCmakePath '/usr/local/bin/cmake' cleanBuild 'false' cleanInstallDir 'false' builderImpl '' @@ -138,4 +138,4 @@ parameterizedJob.with { (project / publishers / 'hudson.plugins.postbuildtask.PostbuildTask' / tasks / 'hudson.plugins.postbuildtask.TaskProperties' / script).setValue(curlCommand) } -} \ No newline at end of file +} From 37ff8ae030778d18da47e40c84e53d4ef0a37c11 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 29 Jul 2013 15:07:05 -0700 Subject: [PATCH 56/88] added color modulation --- interface/src/ParticleSystem.cpp | 97 +++++-- interface/src/ParticleSystem.h | 14 + interface/src/avatar/Hand.cpp | 439 ++++++++++++++++--------------- interface/src/avatar/Hand.h | 17 +- 4 files changed, 329 insertions(+), 238 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 6469cdbbf0..3add73c3b1 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -20,6 +20,7 @@ const float DEFAULT_EMITTER_RENDER_LENGTH = 0.2f; ParticleSystem::ParticleSystem() { + _timer = 0.0f; _numEmitters = 0; _numParticles = 0; _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default @@ -44,6 +45,9 @@ ParticleSystem::ParticleSystem() { ParticleAttributes * a = &_emitter[emitterIndex].particleAttributes[lifeStage]; + setParticleAttributesToDefault(a); + + /* a->radius = DEFAULT_PARTICLE_RADIUS; a->color = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f); a->bounce = DEFAULT_PARTICLE_BOUNCE; @@ -60,6 +64,9 @@ ParticleSystem::ParticleSystem() { a->collisionPlaneNormal = _upDirection; a->collisionPlanePosition = glm::vec3(0.0f, 0.0f, 0.0f); a->usingCollisionPlane = false; + a->modulationAmplitude = 0.0f; + a->modulationStyle = COLOR_MODULATION_STYLE_NULL; + */ } }; @@ -87,6 +94,8 @@ int ParticleSystem::addEmitter() { void ParticleSystem::simulate(float deltaTime) { + _timer += deltaTime; + // emit particles for (int e = 0; e < _numEmitters; e++) { @@ -173,6 +182,31 @@ void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleAttributes } } +void ParticleSystem::setParticleAttributesToDefault(ParticleAttributes * a) { + + a->radius = 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; + a->collisionPlaneNormal = _upDirection; + a->collisionPlanePosition = glm::vec3(0.0f, 0.0f, 0.0f); + a->usingCollisionPlane = false; + a->modulationAmplitude = 0.0f; + a->modulationRate = 0.0; + a->modulationStyle = COLOR_MODULATION_STYLE_NULL; + +} + + void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleLifeStage lifeStage, ParticleAttributes attributes) { ParticleAttributes * a = &_emitter[emitterIndex].particleAttributes[lifeStage]; @@ -193,32 +227,34 @@ void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleLifeStage l a->usingCollisionPlane = attributes.usingCollisionPlane; a->collisionPlanePosition = attributes.collisionPlanePosition; a->collisionPlaneNormal = attributes.collisionPlaneNormal; + a->modulationAmplitude = attributes.modulationAmplitude; + a->modulationRate = attributes.modulationRate; + a->modulationStyle = attributes.modulationStyle; } + void ParticleSystem::updateParticle(int p, float deltaTime) { + Emitter myEmitter = _emitter[_particle[p].emitterIndex]; + + assert(_particle[p].age <= myEmitter.particleLifespan); + + float ageFraction = 0.0f; + int lifeStage = 0; + float lifeStageFraction = 0.0f; + if (_emitter[_particle[p].emitterIndex].particleLifespan > 0.0) { - - Emitter myEmitter = _emitter[_particle[p].emitterIndex]; - - assert(_particle[p].age <= myEmitter.particleLifespan); - float ageFraction = _particle[p].age / myEmitter.particleLifespan; + ageFraction = _particle[p].age / myEmitter.particleLifespan; + lifeStage = (int)( ageFraction * (NUM_PARTICLE_LIFE_STAGES-1) ); + lifeStageFraction = ageFraction * ( NUM_PARTICLE_LIFE_STAGES - 1 ) - lifeStage; - int lifeStage = (int)( ageFraction * (NUM_PARTICLE_LIFE_STAGES-1) ); - - float lifeStageFraction = ageFraction * ( NUM_PARTICLE_LIFE_STAGES - 1 ) - lifeStage; - - + // adjust radius _particle[p].radius = myEmitter.particleAttributes[lifeStage ].radius * (1.0f - lifeStageFraction) + myEmitter.particleAttributes[lifeStage+1].radius * lifeStageFraction; - - _particle[p].color - = myEmitter.particleAttributes[lifeStage ].color * (1.0f - lifeStageFraction) - + myEmitter.particleAttributes[lifeStage+1].color * lifeStageFraction; - + // apply random jitter float j = myEmitter.particleAttributes[lifeStage].jitter; _particle[p].velocity += @@ -293,8 +329,37 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { } } } - } + } + // adjust color + _particle[p].color + = myEmitter.particleAttributes[lifeStage ].color * (1.0f - lifeStageFraction) + + myEmitter.particleAttributes[lifeStage+1].color * lifeStageFraction; + + // apply color modulation + if (myEmitter.particleAttributes[lifeStage ].modulationAmplitude > 0.0f) { + float modulation = 0.0f; + float radian = _timer * myEmitter.particleAttributes[lifeStage ].modulationRate * PI_TIMES_TWO; + if (myEmitter.particleAttributes[lifeStage ].modulationStyle == COLOR_MODULATION_STYLE_LIGHNTESS_PULSE) { + if ( sinf(radian) > 0.0f ) { + modulation = myEmitter.particleAttributes[lifeStage].modulationAmplitude; + } + } else if (myEmitter.particleAttributes[lifeStage].modulationStyle == COLOR_MODULATION_STYLE_LIGHTNESS_WAVE) { + float a = myEmitter.particleAttributes[lifeStage].modulationAmplitude; + modulation = a * ONE_HALF + sinf(radian) * a * ONE_HALF; + } + + _particle[p].color.r += modulation; + _particle[p].color.g += modulation; + _particle[p].color.b += modulation; + _particle[p].color.a += modulation; + + if (_particle[p].color.r > 1.0f) {_particle[p].color.r = 1.0f;} + if (_particle[p].color.g > 1.0f) {_particle[p].color.g = 1.0f;} + if (_particle[p].color.b > 1.0f) {_particle[p].color.b = 1.0f;} + if (_particle[p].color.a > 1.0f) {_particle[p].color.a = 1.0f;} + } + // do this at the end... _particle[p].age += deltaTime; } diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index 7f2534c598..3cebbe23e5 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -22,6 +22,15 @@ enum ParticleRenderStyle }; +enum ColorModulationStyle +{ + COLOR_MODULATION_STYLE_NULL = -1, + COLOR_MODULATION_STYLE_LIGHNTESS_PULSE, + COLOR_MODULATION_STYLE_LIGHTNESS_WAVE, + NUM_COLOR_MODULATION_STYLES +}; + + enum ParticleLifeStage { PARTICLE_LIFESTAGE_0 = 0, @@ -54,6 +63,9 @@ public: bool usingCollisionPlane; // set to true to allow collision with a plane glm::vec3 collisionPlanePosition; // reference position of the collision plane glm::vec3 collisionPlaneNormal; // the surface normal of the collision plane + float modulationAmplitude; // sets the degree (from 0 to 1) of the modulating effect + float modulationRate; // the period of modulation, in seconds + ColorModulationStyle modulationStyle; // to choose between color modulation styles }; // public methods... @@ -65,6 +77,7 @@ public: void render(); void setUpDirection(glm::vec3 upDirection) {_upDirection = upDirection;} // tell particle system which direction is up + void setParticleAttributesToDefault(ParticleAttributes * attributes); // set these attributes to their default values void setParticleAttributes (int emitterIndex, ParticleAttributes attributes); // set attributes for whole life of particles void setParticleAttributes (int emitterIndex, ParticleLifeStage lifeStage, ParticleAttributes attributes); // set attributes for this life stage void setEmitterPosition (int emitterIndex, glm::vec3 position ) {_emitter[emitterIndex].position = position; } @@ -110,6 +123,7 @@ private: Particle _particle[MAX_PARTICLES]; int _numParticles; int _numEmitters; + float _timer; // private methods void updateParticle(int index, float deltaTime); diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 6f5c4159b0..8bd47a4afb 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -21,9 +21,9 @@ using namespace std; Hand::Hand(Avatar* owningAvatar) : HandData((AvatarData*)owningAvatar), - _testRaveGloveClock(0.0f), - _testRaveGloveMode(0), - _particleSystemInitialized(false), + _raveGloveClock(0.0f), + _raveGloveMode(0), + _raveGloveInitialized(false), _owningAvatar(owningAvatar), _renderAlpha(1.0), _lookingInMirror(false), @@ -33,7 +33,7 @@ Hand::Hand(Avatar* owningAvatar) : { // initialize all finger particle emitters with an invalid id as default for (int f = 0; f< NUM_FINGERS; f ++ ) { - _fingerParticleEmitter[f] = -1; + _raveGloveEmitter[f] = -1; } } @@ -53,7 +53,7 @@ void Hand::reset() { void Hand::simulate(float deltaTime, bool isMine) { if (_isRaveGloveActive) { - updateFingerParticles(deltaTime); + updateRaveGloveParticles(deltaTime); } } @@ -110,9 +110,9 @@ void Hand::render(bool lookingInMirror) { if (_isRaveGloveActive) { renderRaveGloveStage(); - if (_particleSystemInitialized) { - updateFingerParticleEmitters(); // do this after calculateGeometry - _particleSystem.render(); + if (_raveGloveInitialized) { + updateRaveGloveEmitters(); // do this after calculateGeometry + _raveGloveParticleSystem.render(); } } @@ -245,9 +245,9 @@ void Hand::setLeapHands(const std::vector& handPositions, } // call this right after the geometry of the leap hands are set -void Hand::updateFingerParticleEmitters() { +void Hand::updateRaveGloveEmitters() { - if (_particleSystemInitialized) { + if (_raveGloveInitialized) { int fingerIndex = 0; for (size_t i = 0; i < getNumPalms(); ++i) { @@ -256,7 +256,7 @@ void Hand::updateFingerParticleEmitters() { for (size_t f = 0; f < palm.getNumFingers(); ++f) { FingerData& finger = palm.getFingers()[f]; if (finger.isActive()) { - if (_fingerParticleEmitter[0] != -1) { + if (_raveGloveEmitter[0] != -1) { glm::vec3 fingerDirection = finger.getTipPosition() - finger.getRootPosition(); float fingerLength = glm::length(fingerDirection); @@ -267,8 +267,8 @@ void Hand::updateFingerParticleEmitters() { fingerDirection = IDENTITY_UP; } - _particleSystem.setEmitterPosition (_fingerParticleEmitter[fingerIndex], finger.getTipPosition()); - _particleSystem.setEmitterDirection(_fingerParticleEmitter[fingerIndex], fingerDirection); + _raveGloveParticleSystem.setEmitterPosition (_raveGloveEmitter[fingerIndex], finger.getTipPosition()); + _raveGloveParticleSystem.setEmitterDirection(_raveGloveEmitter[fingerIndex], fingerDirection); fingerIndex ++; } } @@ -280,48 +280,50 @@ void Hand::updateFingerParticleEmitters() { // call this from within the simulate method -void Hand::updateFingerParticles(float deltaTime) { +void Hand::updateRaveGloveParticles(float deltaTime) { - if (!_particleSystemInitialized) { + if (!_raveGloveInitialized) { // start up the rave glove finger particles... for ( int f = 0; f< NUM_FINGERS; f ++ ) { - _fingerParticleEmitter[f] = _particleSystem.addEmitter(); - assert( _fingerParticleEmitter[f] != -1 ); + _raveGloveEmitter[f] = _raveGloveParticleSystem.addEmitter(); + assert( _raveGloveEmitter[f] != -1 ); } setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_2); - _particleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); - _particleSystemInitialized = true; + _raveGloveParticleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); + _raveGloveInitialized = true; } else { - _testRaveGloveClock += deltaTime; + _raveGloveClock += deltaTime; - if (_testRaveGloveMode == RAVE_GLOVE_EFFECTS_MODE_0) { + if (_raveGloveMode == RAVE_GLOVE_EFFECTS_MODE_0) { ParticleSystem::ParticleAttributes attributes; - float red = 0.5f + 0.5f * sinf(_testRaveGloveClock * 1.4f); - float green = 0.5f + 0.5f * cosf(_testRaveGloveClock * 1.7f); - float blue = 0.5f + 0.5f * sinf(_testRaveGloveClock * 2.0f); + float red = 0.5f + 0.5f * sinf(_raveGloveClock * 1.4f); + float green = 0.5f + 0.5f * cosf(_raveGloveClock * 1.7f); + float blue = 0.5f + 0.5f * sinf(_raveGloveClock * 2.0f); attributes.color = glm::vec4(red, green, blue, 1.0f); - attributes.radius = 0.01f + 0.005f * sinf(_testRaveGloveClock * 2.2f); + attributes.radius = 0.01f + 0.005f * sinf(_raveGloveClock * 2.2f); + attributes.modulationAmplitude = 0.0f; + for ( int f = 0; f< NUM_FINGERS; f ++ ) { - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes); } } - _particleSystem.simulate(deltaTime); + _raveGloveParticleSystem.simulate(deltaTime); } } void Hand::setRaveGloveMode(int mode) { - _testRaveGloveMode = mode; + _raveGloveMode = mode; - _particleSystem.killAllParticles(); + _raveGloveParticleSystem.killAllParticles(); for ( int f = 0; f< NUM_FINGERS; f ++ ) { @@ -331,64 +333,55 @@ void Hand::setRaveGloveMode(int mode) { // throbbing color cycle //----------------------------------------- if (mode == RAVE_GLOVE_EFFECTS_MODE_0) { - _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); - _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.0f ); + _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); + _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 0.0f ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.0f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 30.0f ); - _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 20 ); + _raveGloveParticleSystem.setEmitterThrust (_raveGloveEmitter[f], 0.0f ); + _raveGloveParticleSystem.setEmitterRate (_raveGloveEmitter[f], 30.0f ); + _raveGloveParticleSystem.setEmitterParticleResolution (_raveGloveEmitter[f], 20 ); - attributes.radius = 0.02f; - attributes.color = glm::vec4( 0.0f, 0.0f, 0.0f, 0.0f); - attributes.gravity = 0.0f; - 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.usingCollisionPlane = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); + _raveGloveParticleSystem.setParticleAttributesToDefault(&attributes); + + attributes.radius = 0.02f; + attributes.gravity = 0.0f; + attributes.airFriction = 0.0f; + attributes.jitter = 0.0f; + attributes.bounce = 0.0f; + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // trails //----------------------------------------- } else if (mode == RAVE_GLOVE_EFFECTS_MODE_1) { - _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); - _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.0f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 50.0f ); - _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 5 ); + _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); + _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], false ); + _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 1.0f ); + _raveGloveParticleSystem.setEmitterThrust (_raveGloveEmitter[f], 0.0f ); + _raveGloveParticleSystem.setEmitterRate (_raveGloveEmitter[f], 50.0f ); + _raveGloveParticleSystem.setEmitterParticleResolution (_raveGloveEmitter[f], 5 ); - attributes.radius = 0.001f; - attributes.color = glm::vec4( 1.0f, 0.5f, 0.2f, 1.0f); - attributes.gravity = 0.005f; - 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.usingCollisionPlane = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _raveGloveParticleSystem.setParticleAttributesToDefault(&attributes); + + attributes.radius = 0.001f; + attributes.color = glm::vec4( 1.0f, 0.5f, 0.2f, 1.0f); + attributes.gravity = 0.005f; + attributes.airFriction = 0.0f; + attributes.jitter = 0.0f; + attributes.bounce = 0.0f; + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.002f; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.color = glm::vec4( 1.0f, 0.2f, 0.2f, 0.5f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.color = glm::vec4( 1.0f, 0.2f, 0.2f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes); } //----------------------------------------- @@ -396,230 +389,248 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- if (mode == RAVE_GLOVE_EFFECTS_MODE_2) { - _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); - _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0f ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 50.0 ); - _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 6 ); + _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], false ); + _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 1.0f ); + _raveGloveParticleSystem.setEmitterThrust (_raveGloveEmitter[f], 0.002f ); + _raveGloveParticleSystem.setEmitterRate (_raveGloveEmitter[f], 50.0 ); + _raveGloveParticleSystem.setEmitterParticleResolution (_raveGloveEmitter[f], 6 ); - attributes.radius = 0.005f; - attributes.color = glm::vec4( 1.0f, 1.0f, 0.5f, 0.5f); - attributes.gravity = 0.0f; - attributes.airFriction = 0.0f; - attributes.jitter = 0.002f; - attributes.emitterAttraction = 0.0f; - attributes.tornadoForce = 0.0f; - attributes.neighborAttraction = 0.0f; - attributes.neighborRepulsion = 0.0f; - attributes.bounce = 1.0f; - attributes.usingCollisionSphere = false; - attributes.usingCollisionPlane = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _raveGloveParticleSystem.setParticleAttributesToDefault(&attributes); + + attributes.radius = 0.005f; + attributes.color = glm::vec4( 1.0f, 1.0f, 0.5f, 0.5f); + attributes.airFriction = 0.0f; + attributes.jitter = 0.002f; + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.01f; attributes.jitter = 0.0f; attributes.gravity = -0.005f; attributes.color = glm::vec4( 1.0f, 0.2f, 0.0f, 0.4f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.radius = 0.01f; attributes.gravity = 0.0f; attributes.color = glm::vec4( 0.4f, 0.4f, 0.4f, 0.2f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.radius = 0.02f; attributes.color = glm::vec4( 0.4f, 0.6f, 0.9f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // water //----------------------------------------- } else if (mode == RAVE_GLOVE_EFFECTS_MODE_3) { - _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); - _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.6f ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.001f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); - _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 5 ); + _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); + _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 0.6f ); + _raveGloveParticleSystem.setEmitterThrust (_raveGloveEmitter[f], 0.001f ); + _raveGloveParticleSystem.setEmitterRate (_raveGloveEmitter[f], 100.0 ); + _raveGloveParticleSystem.setEmitterParticleResolution (_raveGloveEmitter[f], 5 ); - attributes.radius = 0.001f; - attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.5f); - attributes.gravity = -0.01f; - attributes.airFriction = 0.0f; - attributes.jitter = 0.002f; - attributes.emitterAttraction = 0.0f; - attributes.tornadoForce = 0.0f; - attributes.neighborAttraction = 0.0f; - attributes.neighborRepulsion = 0.0f; - attributes.bounce = 1.0f; - attributes.usingCollisionSphere = false; - attributes.usingCollisionPlane = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _raveGloveParticleSystem.setParticleAttributesToDefault(&attributes); + + attributes.radius = 0.001f; + attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.5f); + attributes.airFriction = 0.0f; + attributes.jitter = 0.002f; + attributes.bounce = 1.0f; + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.gravity = 0.01f; attributes.jitter = 0.0f; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.2f); attributes.radius = 0.002f; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.color = glm::vec4( 0.8f, 0.9f, 1.0f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // flashy //----------------------------------------- } else if (mode == RAVE_GLOVE_EFFECTS_MODE_4) { - _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); - _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.1 ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); - _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 12 ); + _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); + _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 0.1 ); + _raveGloveParticleSystem.setEmitterThrust (_raveGloveEmitter[f], 0.002f ); + _raveGloveParticleSystem.setEmitterRate (_raveGloveEmitter[f], 100.0 ); + _raveGloveParticleSystem.setEmitterParticleResolution (_raveGloveEmitter[f], 12 ); - attributes.radius = 0.0f; - attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); - attributes.gravity = 0.0f; - attributes.airFriction = 0.0f; - attributes.jitter = 0.05f; - attributes.emitterAttraction = 0.0f; - attributes.tornadoForce = 0.0f; - attributes.neighborAttraction = 0.0f; - attributes.neighborRepulsion = 0.0f; - attributes.bounce = 1.0f; - attributes.usingCollisionSphere = false; - attributes.usingCollisionPlane = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _raveGloveParticleSystem.setParticleAttributesToDefault(&attributes); + + attributes.radius = 0.0f; + attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); + attributes.airFriction = 0.0f; + attributes.jitter = 0.05f; + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.01f; attributes.color = glm::vec4( 1.0f, 1.0f, 0.0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.radius = 0.01f; attributes.color = glm::vec4( 1.0f, 0.0f, 1.0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.radius = 0.0f; attributes.color = glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // Bozo sparkler //----------------------------------------- } else if (mode == RAVE_GLOVE_EFFECTS_MODE_5) { - _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); - _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 0.2 ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); - _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 12 ); + _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); + _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], false ); + _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 0.2 ); + _raveGloveParticleSystem.setEmitterThrust (_raveGloveEmitter[f], 0.002f ); + _raveGloveParticleSystem.setEmitterRate (_raveGloveEmitter[f], 100.0 ); + _raveGloveParticleSystem.setEmitterParticleResolution (_raveGloveEmitter[f], 12 ); - attributes.radius = 0.0f; - attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); - attributes.gravity = 0.0f; - attributes.airFriction = 0.0f; - attributes.jitter = 0.01f; - attributes.emitterAttraction = 0.0f; - attributes.tornadoForce = 0.0f; - attributes.neighborAttraction = 0.0f; - attributes.neighborRepulsion = 0.0f; - attributes.bounce = 1.0f; - attributes.usingCollisionSphere = false; - attributes.usingCollisionPlane = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _raveGloveParticleSystem.setParticleAttributesToDefault(&attributes); + + attributes.radius = 0.0f; + attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); + attributes.airFriction = 0.0f; + attributes.jitter = 0.01f; + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.01f; attributes.color = glm::vec4( 1.0f, 1.0f, 0.0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.radius = 0.01f; attributes.color = glm::vec4( 1.0f, 0.0f, .0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.radius = 0.0f; attributes.color = glm::vec4( 0.0f, 0.0f, 1.0f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // long sparkler //----------------------------------------- } else if (mode == RAVE_GLOVE_EFFECTS_MODE_6) { - _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); - _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], false ); - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0 ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); - _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 7 ); + _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); + _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], false ); + _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 1.0 ); + _raveGloveParticleSystem.setEmitterThrust (_raveGloveEmitter[f], 0.002f ); + _raveGloveParticleSystem.setEmitterRate (_raveGloveEmitter[f], 100.0 ); + _raveGloveParticleSystem.setEmitterParticleResolution (_raveGloveEmitter[f], 7 ); - attributes.radius = 0.0f; - attributes.color = glm::vec4( 0.0f, 0.0f, 0.4f, 0.0f); - attributes.gravity = 0.0f; - attributes.airFriction = 0.0f; - attributes.jitter = 0.0001f; - attributes.emitterAttraction = 0.0f; - attributes.tornadoForce = 0.0f; - attributes.neighborAttraction = 0.0f; - attributes.neighborRepulsion = 0.0f; - attributes.bounce = 1.0f; - attributes.usingCollisionSphere = false; - attributes.usingCollisionPlane = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _raveGloveParticleSystem.setParticleAttributesToDefault(&attributes); + + attributes.radius = 0.0f; + attributes.airFriction = 0.0f; + attributes.jitter = 0.0001f; + attributes.bounce = 1.0f; + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes); attributes.radius = 0.005f; attributes.color = glm::vec4( 0.0f, 0.5f, 0.5f, 0.8f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes); attributes.radius = 0.007f; attributes.color = glm::vec4( 0.5f, 0.0f, 0.5f, 0.5f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes); attributes.radius = 0.02f; attributes.color = glm::vec4( 0.0f, 0.0f, 1.0f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes); //----------------------------------------- // bubble snake //----------------------------------------- } else if (mode == RAVE_GLOVE_EFFECTS_MODE_7) { - _particleSystem.setParticleRenderStyle (_fingerParticleEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); - _particleSystem.setShowingEmitterBaseParticle(_fingerParticleEmitter[f], true ); - _particleSystem.setEmitterParticleLifespan (_fingerParticleEmitter[f], 1.0 ); - _particleSystem.setEmitterThrust (_fingerParticleEmitter[f], 0.002f ); - _particleSystem.setEmitterRate (_fingerParticleEmitter[f], 100.0 ); - _particleSystem.setEmitterParticleResolution (_fingerParticleEmitter[f], 7 ); + _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); + _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 1.0 ); + _raveGloveParticleSystem.setEmitterThrust (_raveGloveEmitter[f], 0.002f ); + _raveGloveParticleSystem.setEmitterRate (_raveGloveEmitter[f], 100.0 ); + _raveGloveParticleSystem.setEmitterParticleResolution (_raveGloveEmitter[f], 7 ); - attributes.radius = 0.001f; - attributes.color = glm::vec4( 0.5f, 1.0f, 0.5f, 1.0f); - attributes.gravity = 0.0f; - attributes.airFriction = 0.01f; - attributes.jitter = 0.0f; - attributes.emitterAttraction = 0.0f; - attributes.tornadoForce = 1.1f; - attributes.neighborAttraction = 1.1f; - attributes.neighborRepulsion = 1.1f; - attributes.bounce = 0.0f; - attributes.usingCollisionSphere = false; - attributes.usingCollisionPlane = false; - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _raveGloveParticleSystem.setParticleAttributesToDefault(&attributes); - attributes.radius = 0.002f; - attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + attributes.radius = 0.001f; + attributes.color = glm::vec4( 0.5f, 1.0f, 0.5f, 1.0f); + attributes.airFriction = 0.01f; + attributes.jitter = 0.0f; + attributes.emitterAttraction = 0.0f; + attributes.tornadoForce = 1.1f; + attributes.neighborAttraction = 1.1f; + attributes.neighborRepulsion = 1.1f; + attributes.bounce = 0.0f; + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes); - attributes.radius = 0.003f; - attributes.color = glm::vec4( 0.3f, 0.3f, 0.3f, 0.5f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + attributes.radius = 0.002f; + attributes.color = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes); - attributes.radius = 0.004f; - attributes.color = glm::vec4( 0.3f, 0.3f, 0.3f, 0.0f); - _particleSystem.setParticleAttributes(_fingerParticleEmitter[f], PARTICLE_LIFESTAGE_3, attributes); + attributes.radius = 0.003f; + attributes.color = glm::vec4( 0.3f, 0.3f, 0.3f, 0.5f); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + + attributes.radius = 0.004f; + attributes.color = glm::vec4( 0.3f, 0.3f, 0.3f, 0.0f); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes); + + //----------------------------------------- + // pulse + //----------------------------------------- + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_8) { + + _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); + _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 0.0 ); + _raveGloveParticleSystem.setEmitterThrust (_raveGloveEmitter[f], 0.0f ); + _raveGloveParticleSystem.setEmitterRate (_raveGloveEmitter[f], 30.0 ); + _raveGloveParticleSystem.setEmitterParticleResolution (_raveGloveEmitter[f], 20 ); + + _raveGloveParticleSystem.setParticleAttributesToDefault(&attributes); + + attributes.radius = 0.01f; + attributes.color = glm::vec4( 0.1f, 0.2f, 0.4f, 0.5f); + attributes.modulationAmplitude = 0.9; + attributes.modulationRate = 7.0; + attributes.modulationStyle = COLOR_MODULATION_STYLE_LIGHNTESS_PULSE; + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes); + + //----------------------------------------- + // throb + //----------------------------------------- + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_9) { + + _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); + _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); + _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 0.0 ); + _raveGloveParticleSystem.setEmitterThrust (_raveGloveEmitter[f], 0.0f ); + _raveGloveParticleSystem.setEmitterRate (_raveGloveEmitter[f], 30.0 ); + _raveGloveParticleSystem.setEmitterParticleResolution (_raveGloveEmitter[f], 20 ); + + _raveGloveParticleSystem.setParticleAttributesToDefault(&attributes); + + attributes.radius = 0.01f; + attributes.color = glm::vec4( 0.5f, 0.4f, 0.3f, 0.5f); + attributes.modulationAmplitude = 0.3; + attributes.modulationRate = 1.0; + attributes.modulationStyle = COLOR_MODULATION_STYLE_LIGHTNESS_WAVE; + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes); + _raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes); } } } diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index 4b5afdfe5b..bfddf9811d 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -59,8 +59,8 @@ public: void render(bool lookingInMirror); void setBallColor (glm::vec3 ballColor ) { _ballColor = ballColor; } - void updateFingerParticles(float deltaTime); - void updateFingerParticleEmitters(); + void updateRaveGloveParticles(float deltaTime); + void updateRaveGloveEmitters(); void setRaveGloveActive(bool active) { _isRaveGloveActive = active; } void setRaveGloveEffectsMode(QKeyEvent* event); @@ -73,15 +73,16 @@ private: Hand(const Hand&); Hand& operator= (const Hand&); - ParticleSystem _particleSystem; - float _testRaveGloveClock; - int _testRaveGloveMode; - bool _particleSystemInitialized; - int _fingerParticleEmitter[NUM_FINGERS]; + ParticleSystem _raveGloveParticleSystem; + float _raveGloveClock; + int _raveGloveMode; + bool _raveGloveInitialized; + int _raveGloveEmitter[NUM_FINGERS]; + bool _isRaveGloveActive; + Avatar* _owningAvatar; float _renderAlpha; bool _lookingInMirror; - bool _isRaveGloveActive; glm::vec3 _ballColor; std::vector _leapBalls; From a1eba53678be50eae91cb723afc4781834c64887 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 29 Jul 2013 15:09:38 -0700 Subject: [PATCH 57/88] cleanup --- interface/src/Application.cpp | 4 ++-- interface/src/avatar/Hand.cpp | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8a967aa7d8..2bc5e4c71a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2719,8 +2719,8 @@ void Application::displaySide(Camera& whichCamera) { renderLookatIndicator(_lookatOtherPosition, whichCamera); } } - - if (TESTING_PARTICLE_SYSTEM) { + + if (_renderParticleSystemOn->isChecked()) { if (_particleSystemInitialized) { _particleSystem.render(); } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 8bd47a4afb..eaf4a8ea2b 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -336,7 +336,6 @@ void Hand::setRaveGloveMode(int mode) { _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 0.0f ); - _raveGloveParticleSystem.setEmitterThrust (_raveGloveEmitter[f], 0.0f ); _raveGloveParticleSystem.setEmitterRate (_raveGloveEmitter[f], 30.0f ); _raveGloveParticleSystem.setEmitterParticleResolution (_raveGloveEmitter[f], 20 ); From 1a73485e36400c76c446115b3a871bbb6d742533 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 29 Jul 2013 15:30:30 -0700 Subject: [PATCH 58/88] Improved VoxelNode delete callback based on CR feedback - changed hooks to use a virtual base class approach - switched account of hooks to use a vector instead of home grown solution - added support for VoxelNode to know what VoxelSystem it belongs to --- interface/src/VoxelSystem.cpp | 15 +++++----- interface/src/VoxelSystem.h | 5 ++-- libraries/voxels/src/VoxelNode.cpp | 43 ++++++++------------------- libraries/voxels/src/VoxelNode.h | 29 ++++++++++-------- libraries/voxels/src/VoxelNodeBag.cpp | 11 +++---- libraries/voxels/src/VoxelNodeBag.h | 4 ++- 6 files changed, 48 insertions(+), 59 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index af3f7ce5c2..2d1bfb577c 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -59,15 +59,13 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) : pthread_mutex_init(&_bufferWriteLock, NULL); pthread_mutex_init(&_treeLock, NULL); - _hookID = VoxelNode::addDeleteHook(voxelNodeDeleteHook, this); + VoxelNode::addDeleteHook(this); _abandonedVBOSlots = 0; } -void VoxelSystem::voxelNodeDeleteHook(VoxelNode* node, void* extraData) { - VoxelSystem* theSystem = (VoxelSystem*)extraData; - - if (node->isKnownBufferIndex()) { - theSystem->freeBufferIndex(node->getBufferIndex()); +void VoxelSystem::nodeDeleted(VoxelNode* node) { + if (node->isKnownBufferIndex() && (node->getVoxelSystem() == this)) { + freeBufferIndex(node->getBufferIndex()); } } @@ -99,7 +97,7 @@ VoxelSystem::~VoxelSystem() { pthread_mutex_destroy(&_bufferWriteLock); pthread_mutex_destroy(&_treeLock); - VoxelNode::removeDeleteHook(_hookID); + VoxelNode::removeDeleteHook(this); } void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { @@ -401,11 +399,13 @@ int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) { // and RGB color for each added vertex updateNodeInArrays(nodeIndex, startVertex, voxelScale, node->getColor()); node->setBufferIndex(nodeIndex); + node->setVoxelSystem(this); _writeVoxelDirtyArray[nodeIndex] = true; // just in case we switch to Partial mode _voxelsInWriteArrays++; // our know vertices in the arrays return 1; // rendered } else { node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN); + node->setVoxelSystem(NULL); } return 0; // not-rendered @@ -440,6 +440,7 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { } else { nodeIndex = _voxelsInWriteArrays; node->setBufferIndex(nodeIndex); + node->setVoxelSystem(this); _voxelsInWriteArrays++; } _writeVoxelDirtyArray[nodeIndex] = true; diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 1e47cda52a..ca390a5a20 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -28,7 +28,7 @@ class ProgramObject; const int NUM_CHILDREN = 8; -class VoxelSystem : public NodeData { +class VoxelSystem : public NodeData, public VoxelNodeDeleteHook { public: VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = MAX_VOXELS_PER_SYSTEM); ~VoxelSystem(); @@ -92,6 +92,8 @@ public: CoverageMapV2 myCoverageMapV2; CoverageMap myCoverageMap; + + virtual void nodeDeleted(VoxelNode* node); protected: float _treeScale; @@ -191,7 +193,6 @@ private: int _hookID; std::vector _freeIndexes; - static void voxelNodeDeleteHook(VoxelNode* node, void* extraData); void freeBufferIndex(glBufferIndex index); void clearFreeBufferIndexes(); }; diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 4a0f017326..8a76d9dfe8 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -48,6 +48,7 @@ void VoxelNode::init(unsigned char * octalCode) { _subtreeLeafNodeCount = 0; // that's me _glBufferIndex = GLBUFFER_INDEX_UNKNOWN; + _voxelSystem = NULL; _isDirty = true; _shouldRender = false; markWithChangedTime(); @@ -399,43 +400,23 @@ float VoxelNode::distanceToPoint(const glm::vec3& point) const { return distance; } -VoxelNodeDeleteHook VoxelNode::_hooks[VOXEL_NODE_MAX_DELETE_HOOKS]; -void* VoxelNode::_hooksExtraData[VOXEL_NODE_MAX_DELETE_HOOKS]; -int VoxelNode::_hooksInUse = 0; +std::vector VoxelNode::_hooks; -int VoxelNode::addDeleteHook(VoxelNodeDeleteHook hook, void* extraData) { - // If first use, initialize the _hooks array - if (_hooksInUse == 0) { - memset(_hooks, 0, sizeof(_hooks)); - memset(_hooksExtraData, 0, sizeof(_hooksExtraData)); - } - // find first available slot - for (int i = 0; i < VOXEL_NODE_MAX_DELETE_HOOKS; i++) { - if (!_hooks[i]) { - _hooks[i] = hook; - _hooksExtraData[i] = extraData; - _hooksInUse++; - return i; - } - } - // if we got here, then we're out of room in our hooks, return error - return VOXEL_NODE_NO_MORE_HOOKS_AVAILABLE; +void VoxelNode::addDeleteHook(VoxelNodeDeleteHook* hook) { + _hooks.push_back(hook); } -void VoxelNode::removeDeleteHook(int hookID) { - if (_hooks[hookID]) { - _hooks[hookID] = NULL; - _hooksExtraData[hookID] = NULL; - _hooksInUse--; +void VoxelNode::removeDeleteHook(VoxelNodeDeleteHook* hook) { + for (int i = 0; i < _hooks.size(); i++) { + if (_hooks[i] == hook) { + _hooks.erase(_hooks.begin() + i); + return; + } } } void VoxelNode::notifyDeleteHooks() { - if (_hooksInUse > 0) { - for (int i = 0; i < VOXEL_NODE_MAX_DELETE_HOOKS; i++) { - if (_hooks[i]) { - _hooks[i](this, _hooksExtraData[i]); - } - } + for (int i = 0; i < _hooks.size(); i++) { + _hooks[i]->nodeDeleted(this); } } diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index 1efab362de..38e9627848 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -14,18 +14,19 @@ #include "ViewFrustum.h" #include "VoxelConstants.h" -class VoxelTree; // forward delclaration -class VoxelNode; // forward delclaration +class VoxelTree; // forward declaration +class VoxelNode; // forward declaration +class VoxelSystem; // forward declaration typedef unsigned char colorPart; typedef unsigned char nodeColor[4]; typedef unsigned char rgbColor[3]; -// Callback function, for delete hook -typedef void (*VoxelNodeDeleteHook)(VoxelNode* node, void* extraData); -const int VOXEL_NODE_MAX_DELETE_HOOKS = 100; -const int VOXEL_NODE_NO_MORE_HOOKS_AVAILABLE = -1; - +// Callers who want delete hook callbacks should implement this class +class VoxelNodeDeleteHook { +public: + virtual void nodeDeleted(VoxelNode* node) = 0; +}; class VoxelNode { public: @@ -77,6 +78,9 @@ public: glBufferIndex getBufferIndex() const { return _glBufferIndex; }; bool isKnownBufferIndex() const { return (_glBufferIndex != GLBUFFER_INDEX_UNKNOWN); }; void setBufferIndex(glBufferIndex index) { _glBufferIndex = index; }; + VoxelSystem* getVoxelSystem() const { return _voxelSystem; }; + void setVoxelSystem(VoxelSystem* voxelSystem) { _voxelSystem = voxelSystem; }; + // Used by VoxelSystem for rendering in/out of view and LOD void setShouldRender(bool shouldRender); @@ -101,8 +105,8 @@ public: const nodeColor& getColor() const { return _trueColor; }; #endif - static int addDeleteHook(VoxelNodeDeleteHook hook, void* extraData = NULL); - static void removeDeleteHook(int hookID); + static void addDeleteHook(VoxelNodeDeleteHook* hook); + static void removeDeleteHook(VoxelNodeDeleteHook* hook); void recalculateSubTreeNodeCount(); unsigned long getSubTreeNodeCount() const { return _subtreeNodeCount; }; @@ -120,6 +124,7 @@ private: bool _falseColored; #endif glBufferIndex _glBufferIndex; + VoxelSystem* _voxelSystem; bool _isDirty; uint64_t _lastChanged; bool _shouldRender; @@ -130,10 +135,8 @@ private: unsigned long _subtreeNodeCount; unsigned long _subtreeLeafNodeCount; float _density; // If leaf: density = 1, if internal node: 0-1 density of voxels inside - - static VoxelNodeDeleteHook _hooks[VOXEL_NODE_MAX_DELETE_HOOKS]; - static void* _hooksExtraData[VOXEL_NODE_MAX_DELETE_HOOKS]; - static int _hooksInUse; + + static std::vector _hooks; }; #endif /* defined(__hifi__VoxelNode__) */ diff --git a/libraries/voxels/src/VoxelNodeBag.cpp b/libraries/voxels/src/VoxelNodeBag.cpp index 713f4de1dd..6b69edd32c 100644 --- a/libraries/voxels/src/VoxelNodeBag.cpp +++ b/libraries/voxels/src/VoxelNodeBag.cpp @@ -13,11 +13,11 @@ VoxelNodeBag::VoxelNodeBag() : _bagElements(NULL), _elementsInUse(0), _sizeOfElementsArray(0) { - _hookID = VoxelNode::addDeleteHook(voxelNodeDeleteHook, this); + VoxelNode::addDeleteHook(this); }; VoxelNodeBag::~VoxelNodeBag() { - VoxelNode::removeDeleteHook(_hookID); + VoxelNode::removeDeleteHook(this); deleteAll(); } @@ -125,9 +125,10 @@ void VoxelNodeBag::remove(VoxelNode* node) { _elementsInUse--; } } -void VoxelNodeBag::voxelNodeDeleteHook(VoxelNode* node, void* extraData) { - VoxelNodeBag* theBag = (VoxelNodeBag*)extraData; - theBag->remove(node); // note: remove can safely handle nodes that aren't in it, so we don't need to check contains() + + +void VoxelNodeBag::nodeDeleted(VoxelNode* node) { + remove(node); // note: remove can safely handle nodes that aren't in it, so we don't need to check contains() } diff --git a/libraries/voxels/src/VoxelNodeBag.h b/libraries/voxels/src/VoxelNodeBag.h index 27bd4e5b60..a29e7678c9 100644 --- a/libraries/voxels/src/VoxelNodeBag.h +++ b/libraries/voxels/src/VoxelNodeBag.h @@ -16,7 +16,7 @@ #include "VoxelNode.h" -class VoxelNodeBag { +class VoxelNodeBag : public VoxelNodeDeleteHook { public: VoxelNodeBag(); @@ -34,6 +34,8 @@ public: static void voxelNodeDeleteHook(VoxelNode* node, void* extraData); + virtual void nodeDeleted(VoxelNode* node); + private: VoxelNode** _bagElements; From 79823c6fed18d8cf16d6be7abba973f749518833 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 29 Jul 2013 15:47:01 -0700 Subject: [PATCH 59/88] cleanup --- interface/src/ParticleSystem.cpp | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 3add73c3b1..7a32bca986 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -28,7 +28,6 @@ ParticleSystem::ParticleSystem() { for (unsigned int emitterIndex = 0; emitterIndex < MAX_EMITTERS; emitterIndex++) { Emitter * e = &_emitter[emitterIndex]; - e->position = glm::vec3(0.0f, 0.0f, 0.0f); e->direction = glm::vec3(0.0f, 1.0f, 0.0f); e->visible = false; @@ -42,31 +41,7 @@ ParticleSystem::ParticleSystem() { e->particleRenderStyle = PARTICLE_RENDER_STYLE_SPHERE; for (int lifeStage = 0; lifeStageradius = 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; - a->collisionPlaneNormal = _upDirection; - a->collisionPlanePosition = glm::vec3(0.0f, 0.0f, 0.0f); - a->usingCollisionPlane = false; - a->modulationAmplitude = 0.0f; - a->modulationStyle = COLOR_MODULATION_STYLE_NULL; - */ + setParticleAttributesToDefault(&_emitter[emitterIndex].particleAttributes[lifeStage]); } }; From de52342a142cb90e74d786f9deef04b51d6d4094 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 29 Jul 2013 16:04:15 -0700 Subject: [PATCH 60/88] Working on depth data processing. --- interface/src/Webcam.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/interface/src/Webcam.cpp b/interface/src/Webcam.cpp index 814081301b..8d90cd1255 100644 --- a/interface/src/Webcam.cpp +++ b/interface/src/Webcam.cpp @@ -596,10 +596,14 @@ void FrameGrabber::grabFrame() { _faceDepth.create(ENCODED_FACE_WIDTH, ENCODED_FACE_HEIGHT, CV_8UC1); warpAffine(_grayDepthFrame, _faceDepth, transform, _faceDepth.size()); - uchar* dest = (uchar*)_encodedFace.data() + vpxImage.stride[0] * ENCODED_FACE_HEIGHT; + uchar* dline = (uchar*)_encodedFace.data() + vpxImage.stride[0] * ENCODED_FACE_HEIGHT; + uchar* src = _faceDepth.ptr(); for (int i = 0; i < ENCODED_FACE_HEIGHT; i++) { - memcpy(dest, _faceDepth.ptr(i), ENCODED_FACE_WIDTH); - dest += vpxImage.stride[0]; + uchar* dest = dline; + for (int j = 0; j < ENCODED_FACE_WIDTH; j++) { + *dest++ = *src++; + } + dline += vpxImage.stride[0]; } } From 4ae4623315784053a5e6dbffb29365e10891b852 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 29 Jul 2013 16:12:11 -0700 Subject: [PATCH 61/88] These casts should fix the warnings on OS X. --- libraries/shared/src/PerfStat.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/PerfStat.cpp b/libraries/shared/src/PerfStat.cpp index 70bcaba009..dde460dbb0 100644 --- a/libraries/shared/src/PerfStat.cpp +++ b/libraries/shared/src/PerfStat.cpp @@ -61,8 +61,8 @@ PerfStat::~PerfStat() { if (wantDebugOut) { qDebug("PerfStats: %s elapsed:%f average:%lf count:%ld total:%lf ut:%ld us:%ld ue:%ld t:%ld s:%ld e:%ld\n", this->group.c_str(),elapsed,average,count,totalTime, - (end.tv_usec-start.tv_usec),start.tv_usec,end.tv_usec, - (end.tv_sec-start.tv_sec),start.tv_sec,end.tv_sec + (long)(end.tv_usec-start.tv_usec), (long)start.tv_usec, (long)end.tv_usec, + (long)(end.tv_sec-start.tv_sec), (long)start.tv_sec, (long)end.tv_sec ); } }; From df32c189944ca43f631570827792f10891c847cf Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 29 Jul 2013 16:15:44 -0700 Subject: [PATCH 62/88] cleanup --- interface/src/ParticleSystem.cpp | 24 ++++++++++++++++++------ interface/src/ParticleSystem.h | 11 ++++------- interface/src/avatar/Hand.cpp | 9 +++++---- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 7a32bca986..f0e20420c6 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -29,6 +29,7 @@ ParticleSystem::ParticleSystem() { Emitter * e = &_emitter[emitterIndex]; e->position = glm::vec3(0.0f, 0.0f, 0.0f); + e->previousPosition = glm::vec3(0.0f, 0.0f, 0.0f); e->direction = glm::vec3(0.0f, 1.0f, 0.0f); e->visible = false; e->particleResolution = DEFAULT_PARTICLE_SPHERE_RESOLUTION; @@ -39,6 +40,7 @@ ParticleSystem::ParticleSystem() { e->rate = 0.0f; e->currentParticle = 0; e->particleRenderStyle = PARTICLE_RENDER_STYLE_SPHERE; + e->numParticlesEmittedThisTime = 0; for (int lifeStage = 0; lifeStage Date: Mon, 29 Jul 2013 17:21:45 -0700 Subject: [PATCH 63/88] cleanup --- interface/src/ParticleSystem.cpp | 34 ++++++++++++++------------------ interface/src/ParticleSystem.h | 1 - 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index f0e20420c6..6898d37e6b 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -22,7 +22,6 @@ ParticleSystem::ParticleSystem() { _timer = 0.0f; _numEmitters = 0; - _numParticles = 0; _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default for (unsigned int emitterIndex = 0; emitterIndex < MAX_EMITTERS; emitterIndex++) { @@ -94,9 +93,9 @@ void ParticleSystem::simulate(float deltaTime) { // update particles - for (unsigned int p = 0; p < _numParticles; p++) { + for (int p = 0; p < MAX_PARTICLES; p++) { if (_particle[p].alive) { - if (_particle[p].age > _emitter[_particle[p].emitterIndex].particleLifespan) { + if (_particle[p].age > _emitter[_particle[p].emitterIndex].particleLifespan) { killParticle(p); } else { updateParticle(p, deltaTime); @@ -114,10 +113,7 @@ void ParticleSystem::createParticle(int e, float timeFraction) { _particle[p].alive = true; _particle[p].age = 0.0f; _particle[p].velocity = _emitter[e].direction * _emitter[e].thrust; - -//_particle[p].position = _emitter[e].position; -_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].color = _emitter[e].particleAttributes[0].color; _particle[p].previousParticle = -1; @@ -130,10 +126,6 @@ _particle[p].position = _emitter[e].previousPosition + timeFraction * (_emitter[ _emitter[e].currentParticle = p; - _numParticles ++; - - assert(_numParticles <= MAX_PARTICLES); - break; } } @@ -143,7 +135,6 @@ void ParticleSystem::killParticle(int p) { assert( p >= 0); assert( p < MAX_PARTICLES); - assert( _numParticles > 0); _particle[p].alive = false; _particle[p].previousParticle = -1; @@ -151,8 +142,6 @@ void ParticleSystem::killParticle(int p) { _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); _particle[p].age = 0.0f; _particle[p].emitterIndex = -1; - - _numParticles --; } @@ -196,6 +185,9 @@ void ParticleSystem::setParticleAttributesToDefault(ParticleAttributes * a) { void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleLifeStage lifeStage, ParticleAttributes attributes) { + assert(lifeStage >= 0 ); + assert(lifeStage < NUM_PARTICLE_LIFE_STAGES ); + ParticleAttributes * a = &_emitter[emitterIndex].particleAttributes[lifeStage]; a->radius = attributes.radius; @@ -258,7 +250,7 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { // apply neighbor attraction int neighbor = p + 1; - if (neighbor == _numParticles ) { + if (neighbor == MAX_PARTICLES ) { neighbor = 0; } @@ -355,11 +347,15 @@ 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; + _emitter[e].currentParticle = -1; + _emitter[e].emitReserve = 0.0f; + _emitter[e].previousPosition = _emitter[e].position; + _emitter[e].rate = 0.0f; + _emitter[e].currentParticle = 0; + _emitter[e].numParticlesEmittedThisTime = 0; } - for (unsigned int p = 0; p < _numParticles; p++) { + for (int p = 0; p < MAX_PARTICLES; p++) { killParticle(p); } } @@ -383,7 +379,7 @@ void ParticleSystem::render() { }; // render the particles - for (unsigned int p = 0; p < _numParticles; p++) { + for (int p = 0; p < MAX_PARTICLES; p++) { if (_particle[p].alive) { if (_emitter[_particle[p].emitterIndex].particleLifespan > 0.0) { renderParticle(p); diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index e358b4a78b..027a166274 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -118,7 +118,6 @@ private: glm::vec3 _upDirection; Emitter _emitter[MAX_EMITTERS]; Particle _particle[MAX_PARTICLES]; - int _numParticles; int _numEmitters; float _timer; From 9c0e29b5e64deeaca53a361de06a1b10c18745e3 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 29 Jul 2013 18:16:10 -0700 Subject: [PATCH 64/88] Use only valid values to compute mean, and use the post-warp data to avoid breaking on head tilt (because we were using the bounds of the rotated rect, which included too much background). --- interface/src/Webcam.cpp | 62 ++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/interface/src/Webcam.cpp b/interface/src/Webcam.cpp index 8d90cd1255..a28bf87d10 100644 --- a/interface/src/Webcam.cpp +++ b/interface/src/Webcam.cpp @@ -480,19 +480,6 @@ void FrameGrabber::grabFrame() { _searchWindow = Rect(clip(faceBounds.tl(), imageBounds), clip(faceBounds.br(), imageBounds)); } -#ifdef HAVE_OPENNI - if (_depthGenerator.IsValid()) { - // convert from 11 to 8 bits, centered about the mean face depth (if possible) - if (_searchWindow.area() > 0) { - const double DEPTH_OFFSET_SMOOTHING = 0.95; - const double EIGHT_BIT_MIDPOINT = 128.0; - double meanOffset = EIGHT_BIT_MIDPOINT - mean(depth(_searchWindow))[0]; - _depthOffset = (_depthOffset == 0.0) ? meanOffset : glm::mix(meanOffset, _depthOffset, DEPTH_OFFSET_SMOOTHING); - } - depth.convertTo(_grayDepthFrame, CV_8UC1, 1.0, _depthOffset); - } -#endif - const int ENCODED_FACE_WIDTH = 128; const int ENCODED_FACE_HEIGHT = 128; int combinedFaceHeight = ENCODED_FACE_HEIGHT * (depth.empty() ? 1 : 2); @@ -591,19 +578,52 @@ void FrameGrabber::grabFrame() { uline += vpxImage.stride[2]; } - // if we have depth data, warp that and just copy it in if (!depth.empty()) { - _faceDepth.create(ENCODED_FACE_WIDTH, ENCODED_FACE_HEIGHT, CV_8UC1); - warpAffine(_grayDepthFrame, _faceDepth, transform, _faceDepth.size()); + // warp the face depth without interpolation (because it will contain invalid zero values) + _faceDepth.create(ENCODED_FACE_WIDTH, ENCODED_FACE_HEIGHT, CV_16UC1); + warpAffine(depth, _faceDepth, transform, _faceDepth.size(), INTER_NEAREST); - uchar* dline = (uchar*)_encodedFace.data() + vpxImage.stride[0] * ENCODED_FACE_HEIGHT; - uchar* src = _faceDepth.ptr(); + // find the mean of the valid values + qint64 depthTotal = 0; + qint64 depthSamples = 0; + ushort* src = _faceDepth.ptr(); for (int i = 0; i < ENCODED_FACE_HEIGHT; i++) { - uchar* dest = dline; for (int j = 0; j < ENCODED_FACE_WIDTH; j++) { - *dest++ = *src++; + ushort depth = *src++; + if (depth != 0) { + depthTotal += depth; + depthSamples++; + } } - dline += vpxImage.stride[0]; + } + double mean = (depthSamples == 0) ? 0.0 : depthTotal / (double)depthSamples; + + // update the depth offset based on the mean + const double DEPTH_OFFSET_SMOOTHING = 0.95; + const double EIGHT_BIT_MIDPOINT = 128.0; + double meanOffset = EIGHT_BIT_MIDPOINT - mean; + _depthOffset = (_depthOffset == 0.0) ? meanOffset : glm::mix(meanOffset, _depthOffset, DEPTH_OFFSET_SMOOTHING); + + // convert from 11 to 8 bits for preview/local display + depth.convertTo(_grayDepthFrame, CV_8UC1, 1.0, _depthOffset); + + // likewise for the encoded representation + uchar* yline = (uchar*)_encodedFace.data() + vpxImage.stride[0] * ENCODED_FACE_HEIGHT; + src = _faceDepth.ptr(); + const char UNKNOWN_DEPTH = 0; + const char MAXIMUM_DEPTH = 255; + for (int i = 0; i < ENCODED_FACE_HEIGHT; i++) { + uchar* ydest = yline; + for (int j = 0; j < ENCODED_FACE_WIDTH; j++) { + ushort depth = *src++; + if (depth == UNKNOWN_DEPTH) { + *ydest++ = MAXIMUM_DEPTH; + + } else { + *ydest++ = saturate_cast(depth + _depthOffset); + } + } + yline += vpxImage.stride[0]; } } From 3b4a4daec37cc213a81cfa38c50434808e5b186c Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 29 Jul 2013 18:26:51 -0700 Subject: [PATCH 65/88] Ignore maximum values when computing the depth. --- interface/src/Webcam.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/interface/src/Webcam.cpp b/interface/src/Webcam.cpp index a28bf87d10..2efb12aed2 100644 --- a/interface/src/Webcam.cpp +++ b/interface/src/Webcam.cpp @@ -587,10 +587,12 @@ void FrameGrabber::grabFrame() { qint64 depthTotal = 0; qint64 depthSamples = 0; ushort* src = _faceDepth.ptr(); + const ushort ELEVEN_BIT_MINIMUM = 0; + const ushort ELEVEN_BIT_MAXIMUM = 2047; for (int i = 0; i < ENCODED_FACE_HEIGHT; i++) { for (int j = 0; j < ENCODED_FACE_WIDTH; j++) { ushort depth = *src++; - if (depth != 0) { + if (depth != ELEVEN_BIT_MINIMUM && depth != ELEVEN_BIT_MAXIMUM) { depthTotal += depth; depthSamples++; } @@ -610,14 +612,13 @@ void FrameGrabber::grabFrame() { // likewise for the encoded representation uchar* yline = (uchar*)_encodedFace.data() + vpxImage.stride[0] * ENCODED_FACE_HEIGHT; src = _faceDepth.ptr(); - const char UNKNOWN_DEPTH = 0; - const char MAXIMUM_DEPTH = 255; + const char EIGHT_BIT_MAXIMUM = 255; for (int i = 0; i < ENCODED_FACE_HEIGHT; i++) { uchar* ydest = yline; for (int j = 0; j < ENCODED_FACE_WIDTH; j++) { ushort depth = *src++; - if (depth == UNKNOWN_DEPTH) { - *ydest++ = MAXIMUM_DEPTH; + if (depth == ELEVEN_BIT_MINIMUM) { + *ydest++ = EIGHT_BIT_MAXIMUM; } else { *ydest++ = saturate_cast(depth + _depthOffset); From 3c437076a7e5d30c60b9c01c5337fee164e3a387 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 30 Jul 2013 11:07:33 -0700 Subject: [PATCH 66/88] When we have a mean face depth, use that rather than the face size to estimate the z coordinate. --- interface/src/Webcam.cpp | 47 +++++++++++++++++++++++++--------------- interface/src/Webcam.h | 5 +++-- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/interface/src/Webcam.cpp b/interface/src/Webcam.cpp index 2efb12aed2..84654b8f96 100644 --- a/interface/src/Webcam.cpp +++ b/interface/src/Webcam.cpp @@ -57,8 +57,11 @@ void Webcam::setEnabled(bool enabled) { } } +const float UNINITIALIZED_FACE_DEPTH = 0.0f; + void Webcam::reset() { _initialFaceRect = RotatedRect(); + _initialFaceDepth = UNINITIALIZED_FACE_DEPTH; if (_enabled) { // send a message to the grabber @@ -149,7 +152,8 @@ Webcam::~Webcam() { delete _grabber; } -void Webcam::setFrame(const Mat& color, int format, const Mat& depth, const RotatedRect& faceRect, const JointVector& joints) { +void Webcam::setFrame(const Mat& color, int format, const Mat& depth, float meanFaceDepth, + const RotatedRect& faceRect, const JointVector& joints) { IplImage colorImage = color; glPixelStorei(GL_UNPACK_ROW_LENGTH, colorImage.widthStep / 3); if (_colorTextureID == 0) { @@ -232,22 +236,28 @@ void Webcam::setFrame(const Mat& color, int format, const Mat& depth, const Rota const float ROTATION_SMOOTHING = 0.95f; _estimatedRotation.z = glm::mix(_faceRect.angle, _estimatedRotation.z, ROTATION_SMOOTHING); - // determine position based on translation and scaling of the face rect + // determine position based on translation and scaling of the face rect/mean face depth if (_initialFaceRect.size.area() == 0) { _initialFaceRect = _faceRect; _estimatedPosition = glm::vec3(); + _initialFaceDepth = meanFaceDepth; } else { - float proportion = sqrtf(_initialFaceRect.size.area() / (float)_faceRect.size.area()); - const float DISTANCE_TO_CAMERA = 0.333f; + float proportion, z; + if (meanFaceDepth == UNINITIALIZED_FACE_DEPTH) { + proportion = sqrtf(_initialFaceRect.size.area() / (float)_faceRect.size.area()); + const float INITIAL_DISTANCE_TO_CAMERA = 0.333f; + z = INITIAL_DISTANCE_TO_CAMERA * proportion - INITIAL_DISTANCE_TO_CAMERA; + + } else { + z = (meanFaceDepth - _initialFaceDepth) / 1000.0f; + proportion = meanFaceDepth / _initialFaceDepth; + } const float POSITION_SCALE = 0.5f; - float z = DISTANCE_TO_CAMERA * proportion - DISTANCE_TO_CAMERA; - glm::vec3 position = glm::vec3( + _estimatedPosition = glm::vec3( (_faceRect.center.x - _initialFaceRect.center.x) * proportion * POSITION_SCALE / _textureSize.width, (_faceRect.center.y - _initialFaceRect.center.y) * proportion * POSITION_SCALE / _textureSize.width, z); - const float POSITION_SMOOTHING = 0.95f; - _estimatedPosition = glm::mix(position, _estimatedPosition, POSITION_SMOOTHING); } } @@ -259,7 +269,7 @@ void Webcam::setFrame(const Mat& color, int format, const Mat& depth, const Rota } FrameGrabber::FrameGrabber() : _initialized(false), _capture(0), _searchWindow(0, 0, 0, 0), - _depthOffset(0.0), _codec(), _frameCount(0) { + _smoothedMeanFaceDepth(UNINITIALIZED_FACE_DEPTH), _codec(), _frameCount(0) { } FrameGrabber::~FrameGrabber() { @@ -598,16 +608,17 @@ void FrameGrabber::grabFrame() { } } } - double mean = (depthSamples == 0) ? 0.0 : depthTotal / (double)depthSamples; + float mean = (depthSamples == 0) ? UNINITIALIZED_FACE_DEPTH : depthTotal / (float)depthSamples; - // update the depth offset based on the mean - const double DEPTH_OFFSET_SMOOTHING = 0.95; - const double EIGHT_BIT_MIDPOINT = 128.0; - double meanOffset = EIGHT_BIT_MIDPOINT - mean; - _depthOffset = (_depthOffset == 0.0) ? meanOffset : glm::mix(meanOffset, _depthOffset, DEPTH_OFFSET_SMOOTHING); + // smooth the mean over time + const float DEPTH_OFFSET_SMOOTHING = 0.95f; + _smoothedMeanFaceDepth = (_smoothedMeanFaceDepth == UNINITIALIZED_FACE_DEPTH) ? mean : + glm::mix(mean, _smoothedMeanFaceDepth, DEPTH_OFFSET_SMOOTHING); // convert from 11 to 8 bits for preview/local display - depth.convertTo(_grayDepthFrame, CV_8UC1, 1.0, _depthOffset); + const double EIGHT_BIT_MIDPOINT = 128.0; + double depthOffset = EIGHT_BIT_MIDPOINT - _smoothedMeanFaceDepth; + depth.convertTo(_grayDepthFrame, CV_8UC1, 1.0, depthOffset); // likewise for the encoded representation uchar* yline = (uchar*)_encodedFace.data() + vpxImage.stride[0] * ENCODED_FACE_HEIGHT; @@ -621,7 +632,7 @@ void FrameGrabber::grabFrame() { *ydest++ = EIGHT_BIT_MAXIMUM; } else { - *ydest++ = saturate_cast(depth + _depthOffset); + *ydest++ = saturate_cast(depth + depthOffset); } } yline += vpxImage.stride[0]; @@ -646,7 +657,7 @@ void FrameGrabber::grabFrame() { } QMetaObject::invokeMethod(Application::getInstance()->getWebcam(), "setFrame", - Q_ARG(cv::Mat, color), Q_ARG(int, format), Q_ARG(cv::Mat, _grayDepthFrame), + Q_ARG(cv::Mat, color), Q_ARG(int, format), Q_ARG(cv::Mat, _grayDepthFrame), Q_ARG(float, _smoothedMeanFaceDepth), Q_ARG(cv::RotatedRect, _smoothedFaceRect), Q_ARG(JointVector, joints)); } diff --git a/interface/src/Webcam.h b/interface/src/Webcam.h index 260eda0897..16cf3a33a1 100644 --- a/interface/src/Webcam.h +++ b/interface/src/Webcam.h @@ -62,7 +62,7 @@ public: public slots: void setEnabled(bool enabled); - void setFrame(const cv::Mat& color, int format, const cv::Mat& depth, + void setFrame(const cv::Mat& color, int format, const cv::Mat& depth, float meanFaceDepth, const cv::RotatedRect& faceRect, const JointVector& joints); private: @@ -77,6 +77,7 @@ private: cv::Size2f _textureSize; cv::RotatedRect _faceRect; cv::RotatedRect _initialFaceRect; + float _initialFaceDepth; JointVector _joints; uint64_t _startTimestamp; @@ -117,7 +118,7 @@ private: cv::Mat _backProject; cv::Rect _searchWindow; cv::Mat _grayDepthFrame; - double _depthOffset; + float _smoothedMeanFaceDepth; vpx_codec_ctx_t _codec; int _frameCount; From f8ba1c4be12599a42553ab8d2dc7a99e9db57bce Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 30 Jul 2013 13:42:29 -0700 Subject: [PATCH 67/88] Use the V channel to provide masking information, indicating invalid depths. --- interface/src/Webcam.cpp | 43 ++++++++++++++++++++++------------- interface/src/avatar/Face.cpp | 29 +++++++++++++++++++---- 2 files changed, 52 insertions(+), 20 deletions(-) diff --git a/interface/src/Webcam.cpp b/interface/src/Webcam.cpp index 84654b8f96..b73537f6ae 100644 --- a/interface/src/Webcam.cpp +++ b/interface/src/Webcam.cpp @@ -569,9 +569,9 @@ void FrameGrabber::grabFrame() { ydest[0] = (tl[redIndex] * Y_RED_WEIGHT + tl[1] * Y_GREEN_WEIGHT + tl[blueIndex] * Y_BLUE_WEIGHT) >> 8; ydest[1] = (tr[redIndex] * Y_RED_WEIGHT + tr[1] * Y_GREEN_WEIGHT + tr[blueIndex] * Y_BLUE_WEIGHT) >> 8; - ydest[ENCODED_FACE_WIDTH] = (bl[redIndex] * Y_RED_WEIGHT + bl[greenIndex] * + ydest[vpxImage.stride[0]] = (bl[redIndex] * Y_RED_WEIGHT + bl[greenIndex] * Y_GREEN_WEIGHT + bl[blueIndex] * Y_BLUE_WEIGHT) >> 8; - ydest[ENCODED_FACE_WIDTH + 1] = (br[redIndex] * Y_RED_WEIGHT + br[greenIndex] * + ydest[vpxImage.stride[0] + 1] = (br[redIndex] * Y_RED_WEIGHT + br[greenIndex] * Y_GREEN_WEIGHT + br[blueIndex] * Y_BLUE_WEIGHT) >> 8; ydest += 2; @@ -616,26 +616,37 @@ void FrameGrabber::grabFrame() { glm::mix(mean, _smoothedMeanFaceDepth, DEPTH_OFFSET_SMOOTHING); // convert from 11 to 8 bits for preview/local display - const double EIGHT_BIT_MIDPOINT = 128.0; + const uchar EIGHT_BIT_MIDPOINT = 128; double depthOffset = EIGHT_BIT_MIDPOINT - _smoothedMeanFaceDepth; depth.convertTo(_grayDepthFrame, CV_8UC1, 1.0, depthOffset); // likewise for the encoded representation - uchar* yline = (uchar*)_encodedFace.data() + vpxImage.stride[0] * ENCODED_FACE_HEIGHT; - src = _faceDepth.ptr(); - const char EIGHT_BIT_MAXIMUM = 255; - for (int i = 0; i < ENCODED_FACE_HEIGHT; i++) { + uchar* yline = vpxImage.planes[0] + vpxImage.stride[0] * ENCODED_FACE_HEIGHT; + uchar* vline = vpxImage.planes[1] + vpxImage.stride[1] * (ENCODED_FACE_HEIGHT / 2); + const uchar EIGHT_BIT_MAXIMUM = 255; + for (int i = 0; i < ENCODED_FACE_HEIGHT; i += 2) { uchar* ydest = yline; - for (int j = 0; j < ENCODED_FACE_WIDTH; j++) { - ushort depth = *src++; - if (depth == ELEVEN_BIT_MINIMUM) { - *ydest++ = EIGHT_BIT_MAXIMUM; - - } else { - *ydest++ = saturate_cast(depth + depthOffset); - } + uchar* vdest = vline; + for (int j = 0; j < ENCODED_FACE_WIDTH; j += 2) { + ushort tl = *_faceDepth.ptr(i, j); + ushort tr = *_faceDepth.ptr(i, j + 1); + ushort bl = *_faceDepth.ptr(i + 1, j); + ushort br = *_faceDepth.ptr(i + 1, j + 1); + + uchar mask = EIGHT_BIT_MIDPOINT; + + ydest[0] = (tl == ELEVEN_BIT_MINIMUM) ? (mask = EIGHT_BIT_MAXIMUM) : saturate_cast(tl + depthOffset); + ydest[1] = (tr == ELEVEN_BIT_MINIMUM) ? (mask = EIGHT_BIT_MAXIMUM) : saturate_cast(tr + depthOffset); + ydest[vpxImage.stride[0]] = (bl == ELEVEN_BIT_MINIMUM) ? + (mask = EIGHT_BIT_MAXIMUM) : saturate_cast(bl + depthOffset); + ydest[vpxImage.stride[0] + 1] = (br == ELEVEN_BIT_MINIMUM) ? + (mask = EIGHT_BIT_MAXIMUM) : saturate_cast(br + depthOffset); + ydest += 2; + + *vdest++ = mask; } - yline += vpxImage.stride[0]; + yline += vpxImage.stride[0] * 2; + vline += vpxImage.stride[1]; } } diff --git a/interface/src/avatar/Face.cpp b/interface/src/avatar/Face.cpp index d8a8d6c2a6..5d6c4984bd 100644 --- a/interface/src/avatar/Face.cpp +++ b/interface/src/avatar/Face.cpp @@ -147,10 +147,31 @@ int Face::processVideoMessage(unsigned char* packetData, size_t dataBytes) { if (image->d_h > imageHeight) { // if the height is greater than the width, we have depth data depth.create(imageHeight, image->d_w, CV_8UC1); - uchar* src = image->planes[0] + image->stride[0] * imageHeight; - for (int i = 0; i < imageHeight; i++) { - memcpy(depth.ptr(i), src, image->d_w); - src += image->stride[0]; + uchar* yline = image->planes[0] + image->stride[0] * imageHeight; + uchar* vline = image->planes[1] + image->stride[1] * (imageHeight / 2); + const uchar EIGHT_BIT_MAXIMUM = 255; + const uchar MASK_THRESHOLD = 192; + for (int i = 0; i < imageHeight; i += 2) { + uchar* ysrc = yline; + uchar* vsrc = vline; + for (int j = 0; j < image->d_w; j += 2) { + + if (*vsrc++ >= MASK_THRESHOLD) { + *depth.ptr(i, j) = EIGHT_BIT_MAXIMUM; + *depth.ptr(i, j + 1) = EIGHT_BIT_MAXIMUM; + *depth.ptr(i + 1, j) = EIGHT_BIT_MAXIMUM; + *depth.ptr(i + 1, j + 1) = EIGHT_BIT_MAXIMUM; + + } else { + *depth.ptr(i, j) = ysrc[0]; + *depth.ptr(i, j + 1) = ysrc[1]; + *depth.ptr(i + 1, j) = ysrc[image->stride[0]]; + *depth.ptr(i + 1, j + 1) = ysrc[image->stride[0] + 1]; + } + ysrc += 2; + } + yline += image->stride[0] * 2; + vline += image->stride[1]; } } QMetaObject::invokeMethod(this, "setFrame", Q_ARG(cv::Mat, color), From c787781efbc572442946d4f95da6ce375d9f63dc Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 30 Jul 2013 15:11:32 -0700 Subject: [PATCH 68/88] Send color and depth as separate streams (rather than one on top of the other) so that we can control their bitrates separately. --- interface/src/Webcam.cpp | 88 +++++++++++++++--------- interface/src/Webcam.h | 3 +- interface/src/avatar/Face.cpp | 93 +++++++++++++++----------- interface/src/avatar/Face.h | 3 +- libraries/shared/src/PacketHeaders.cpp | 7 +- 5 files changed, 120 insertions(+), 74 deletions(-) diff --git a/interface/src/Webcam.cpp b/interface/src/Webcam.cpp index b73537f6ae..2a58d51dae 100644 --- a/interface/src/Webcam.cpp +++ b/interface/src/Webcam.cpp @@ -269,7 +269,7 @@ void Webcam::setFrame(const Mat& color, int format, const Mat& depth, float mean } FrameGrabber::FrameGrabber() : _initialized(false), _capture(0), _searchWindow(0, 0, 0, 0), - _smoothedMeanFaceDepth(UNINITIALIZED_FACE_DEPTH), _codec(), _frameCount(0) { + _smoothedMeanFaceDepth(UNINITIALIZED_FACE_DEPTH), _colorCodec(), _depthCodec(), _frameCount(0) { } FrameGrabber::~FrameGrabber() { @@ -377,9 +377,13 @@ void FrameGrabber::shutdown() { cvReleaseCapture(&_capture); _capture = 0; } - if (_codec.name != 0) { - vpx_codec_destroy(&_codec); - _codec.name = 0; + if (_colorCodec.name != 0) { + vpx_codec_destroy(&_colorCodec); + _colorCodec.name = 0; + } + if (_depthCodec.name != 0) { + vpx_codec_destroy(&_depthCodec); + _depthCodec.name = 0; } _initialized = false; @@ -492,17 +496,19 @@ void FrameGrabber::grabFrame() { const int ENCODED_FACE_WIDTH = 128; const int ENCODED_FACE_HEIGHT = 128; - int combinedFaceHeight = ENCODED_FACE_HEIGHT * (depth.empty() ? 1 : 2); - if (_codec.name == 0) { - // initialize encoder context + if (_colorCodec.name == 0) { + // initialize encoder context(s) vpx_codec_enc_cfg_t codecConfig; vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &codecConfig, 0); - const int QUALITY_MULTIPLIER = 2; - codecConfig.rc_target_bitrate = QUALITY_MULTIPLIER * ENCODED_FACE_WIDTH * combinedFaceHeight * + codecConfig.rc_target_bitrate = ENCODED_FACE_WIDTH * ENCODED_FACE_HEIGHT * codecConfig.rc_target_bitrate / codecConfig.g_w / codecConfig.g_h; codecConfig.g_w = ENCODED_FACE_WIDTH; - codecConfig.g_h = combinedFaceHeight; - vpx_codec_enc_init(&_codec, vpx_codec_vp8_cx(), &codecConfig, 0); + codecConfig.g_h = ENCODED_FACE_HEIGHT; + vpx_codec_enc_init(&_colorCodec, vpx_codec_vp8_cx(), &codecConfig, 0); + + if (!depth.empty()) { + vpx_codec_enc_init(&_depthCodec, vpx_codec_vp8_cx(), &codecConfig, 0); + } } // correct for 180 degree rotations @@ -539,9 +545,9 @@ void FrameGrabber::grabFrame() { const int ENCODED_BITS_PER_VU = 2; const int ENCODED_BITS_PER_PIXEL = ENCODED_BITS_PER_Y + 2 * ENCODED_BITS_PER_VU; const int BITS_PER_BYTE = 8; - _encodedFace.fill(128, ENCODED_FACE_WIDTH * combinedFaceHeight * ENCODED_BITS_PER_PIXEL / BITS_PER_BYTE); + _encodedFace.resize(ENCODED_FACE_WIDTH * ENCODED_FACE_HEIGHT * ENCODED_BITS_PER_PIXEL / BITS_PER_BYTE); vpx_image_t vpxImage; - vpx_img_wrap(&vpxImage, VPX_IMG_FMT_YV12, ENCODED_FACE_WIDTH, combinedFaceHeight, 1, (unsigned char*)_encodedFace.data()); + vpx_img_wrap(&vpxImage, VPX_IMG_FMT_YV12, ENCODED_FACE_WIDTH, ENCODED_FACE_HEIGHT, 1, (unsigned char*)_encodedFace.data()); uchar* yline = vpxImage.planes[0]; uchar* vline = vpxImage.planes[1]; uchar* uline = vpxImage.planes[2]; @@ -588,6 +594,24 @@ void FrameGrabber::grabFrame() { uline += vpxImage.stride[2]; } + // encode the frame + vpx_codec_encode(&_colorCodec, &vpxImage, ++_frameCount, 1, 0, VPX_DL_REALTIME); + + // start the payload off with the aspect ratio + QByteArray payload(sizeof(float), 0); + *(float*)payload.data() = _smoothedFaceRect.size.width / _smoothedFaceRect.size.height; + + // extract the encoded frame + vpx_codec_iter_t iterator = 0; + const vpx_codec_cx_pkt_t* packet; + while ((packet = vpx_codec_get_cx_data(&_colorCodec, &iterator)) != 0) { + if (packet->kind == VPX_CODEC_CX_FRAME_PKT) { + // prepend the length, which will indicate whether there's a depth frame too + payload.append((const char*)&packet->data.frame.sz, sizeof(packet->data.frame.sz)); + payload.append((const char*)packet->data.frame.buf, packet->data.frame.sz); + } + } + if (!depth.empty()) { // warp the face depth without interpolation (because it will contain invalid zero values) _faceDepth.create(ENCODED_FACE_WIDTH, ENCODED_FACE_HEIGHT, CV_16UC1); @@ -621,12 +645,14 @@ void FrameGrabber::grabFrame() { depth.convertTo(_grayDepthFrame, CV_8UC1, 1.0, depthOffset); // likewise for the encoded representation - uchar* yline = vpxImage.planes[0] + vpxImage.stride[0] * ENCODED_FACE_HEIGHT; - uchar* vline = vpxImage.planes[1] + vpxImage.stride[1] * (ENCODED_FACE_HEIGHT / 2); + uchar* yline = vpxImage.planes[0]; + uchar* vline = vpxImage.planes[1]; + uchar* uline = vpxImage.planes[2]; const uchar EIGHT_BIT_MAXIMUM = 255; for (int i = 0; i < ENCODED_FACE_HEIGHT; i += 2) { uchar* ydest = yline; uchar* vdest = vline; + uchar* udest = uline; for (int j = 0; j < ENCODED_FACE_WIDTH; j += 2) { ushort tl = *_faceDepth.ptr(i, j); ushort tr = *_faceDepth.ptr(i, j + 1); @@ -644,28 +670,28 @@ void FrameGrabber::grabFrame() { ydest += 2; *vdest++ = mask; + *udest++ = EIGHT_BIT_MIDPOINT; } yline += vpxImage.stride[0] * 2; vline += vpxImage.stride[1]; + uline += vpxImage.stride[2]; + } + + // encode the frame + vpx_codec_encode(&_depthCodec, &vpxImage, _frameCount, 1, 0, VPX_DL_REALTIME); + + // extract the encoded frame + vpx_codec_iter_t iterator = 0; + const vpx_codec_cx_pkt_t* packet; + while ((packet = vpx_codec_get_cx_data(&_depthCodec, &iterator)) != 0) { + if (packet->kind == VPX_CODEC_CX_FRAME_PKT) { + payload.append((const char*)packet->data.frame.buf, packet->data.frame.sz); + } } } - // encode the frame - vpx_codec_encode(&_codec, &vpxImage, ++_frameCount, 1, 0, VPX_DL_REALTIME); - - // extract the encoded frame - vpx_codec_iter_t iterator = 0; - const vpx_codec_cx_pkt_t* packet; - while ((packet = vpx_codec_get_cx_data(&_codec, &iterator)) != 0) { - if (packet->kind == VPX_CODEC_CX_FRAME_PKT) { - // prepend the aspect ratio - QByteArray payload(sizeof(float), 0); - *(float*)payload.data() = _smoothedFaceRect.size.width / _smoothedFaceRect.size.height; - payload.append((const char*)packet->data.frame.buf, packet->data.frame.sz); - QMetaObject::invokeMethod(Application::getInstance(), "sendAvatarFaceVideoMessage", Q_ARG(int, _frameCount), - Q_ARG(QByteArray, payload)); - } - } + QMetaObject::invokeMethod(Application::getInstance(), "sendAvatarFaceVideoMessage", + Q_ARG(int, _frameCount), Q_ARG(QByteArray, payload)); QMetaObject::invokeMethod(Application::getInstance()->getWebcam(), "setFrame", Q_ARG(cv::Mat, color), Q_ARG(int, format), Q_ARG(cv::Mat, _grayDepthFrame), Q_ARG(float, _smoothedMeanFaceDepth), diff --git a/interface/src/Webcam.h b/interface/src/Webcam.h index 16cf3a33a1..6c6d250897 100644 --- a/interface/src/Webcam.h +++ b/interface/src/Webcam.h @@ -120,7 +120,8 @@ private: cv::Mat _grayDepthFrame; float _smoothedMeanFaceDepth; - vpx_codec_ctx_t _codec; + vpx_codec_ctx_t _colorCodec; + vpx_codec_ctx_t _depthCodec; int _frameCount; cv::Mat _faceColor; cv::Mat _faceDepth; diff --git a/interface/src/avatar/Face.cpp b/interface/src/avatar/Face.cpp index 5d6c4984bd..f25426a5be 100644 --- a/interface/src/avatar/Face.cpp +++ b/interface/src/avatar/Face.cpp @@ -30,19 +30,25 @@ GLuint Face::_vboID; GLuint Face::_iboID; Face::Face(Head* owningHead) : _owningHead(owningHead), _renderMode(MESH), - _colorTextureID(0), _depthTextureID(0), _codec(), _frameCount(0) { + _colorTextureID(0), _depthTextureID(0), _colorCodec(), _depthCodec(), _frameCount(0) { // we may have been created in the network thread, but we live in the main thread moveToThread(Application::getInstance()->thread()); } Face::~Face() { - if (_codec.name != 0) { - vpx_codec_destroy(&_codec); + if (_colorCodec.name != 0) { + vpx_codec_destroy(&_colorCodec); - // delete our textures, since we know that we own them + // delete our texture, since we know that we own it if (_colorTextureID != 0) { glDeleteTextures(1, &_colorTextureID); } + + } + if (_depthCodec.name != 0) { + vpx_codec_destroy(&_depthCodec); + + // delete our texture, since we know that we own it if (_depthTextureID != 0) { glDeleteTextures(1, &_depthTextureID); } @@ -55,9 +61,9 @@ void Face::setTextureRect(const cv::RotatedRect& textureRect) { } int Face::processVideoMessage(unsigned char* packetData, size_t dataBytes) { - if (_codec.name == 0) { + if (_colorCodec.name == 0) { // initialize decoder context - vpx_codec_dec_init(&_codec, vpx_codec_vp8_dx(), 0, 0); + vpx_codec_dec_init(&_colorCodec, vpx_codec_vp8_dx(), 0, 0); } // skip the header unsigned char* packetPosition = packetData; @@ -85,14 +91,14 @@ int Face::processVideoMessage(unsigned char* packetData, size_t dataBytes) { if ((_frameBytesRemaining -= payloadSize) <= 0) { float aspectRatio = *(const float*)_arrivingFrame.constData(); - vpx_codec_decode(&_codec, (const uint8_t*)_arrivingFrame.constData() + sizeof(float), - _arrivingFrame.size() - sizeof(float), 0, 0); + size_t colorSize = *(const size_t*)(_arrivingFrame.constData() + sizeof(float)); + const uint8_t* colorData = (const uint8_t*)(_arrivingFrame.constData() + sizeof(float) + sizeof(size_t)); + vpx_codec_decode(&_colorCodec, colorData, colorSize, 0, 0); vpx_codec_iter_t iterator = 0; vpx_image_t* image; - while ((image = vpx_codec_get_frame(&_codec, &iterator)) != 0) { + while ((image = vpx_codec_get_frame(&_colorCodec, &iterator)) != 0) { // convert from YV12 to RGB - const int imageHeight = image->d_w; - Mat color(imageHeight, image->d_w, CV_8UC3); + Mat color(image->d_h, image->d_w, CV_8UC3); uchar* yline = image->planes[0]; uchar* vline = image->planes[1]; uchar* uline = image->planes[2]; @@ -100,7 +106,7 @@ int Face::processVideoMessage(unsigned char* packetData, size_t dataBytes) { const int GREEN_V_WEIGHT = (int)(0.714 * 256); const int GREEN_U_WEIGHT = (int)(0.344 * 256); const int BLUE_U_WEIGHT = (int)(1.773 * 256); - for (int i = 0; i < imageHeight; i += 2) { + for (int i = 0; i < image->d_h; i += 2) { uchar* ysrc = yline; uchar* vsrc = vline; uchar* usrc = uline; @@ -144,34 +150,45 @@ int Face::processVideoMessage(unsigned char* packetData, size_t dataBytes) { uline += image->stride[2]; } Mat depth; - if (image->d_h > imageHeight) { - // if the height is greater than the width, we have depth data - depth.create(imageHeight, image->d_w, CV_8UC1); - uchar* yline = image->planes[0] + image->stride[0] * imageHeight; - uchar* vline = image->planes[1] + image->stride[1] * (imageHeight / 2); - const uchar EIGHT_BIT_MAXIMUM = 255; - const uchar MASK_THRESHOLD = 192; - for (int i = 0; i < imageHeight; i += 2) { - uchar* ysrc = yline; - uchar* vsrc = vline; - for (int j = 0; j < image->d_w; j += 2) { - - if (*vsrc++ >= MASK_THRESHOLD) { - *depth.ptr(i, j) = EIGHT_BIT_MAXIMUM; - *depth.ptr(i, j + 1) = EIGHT_BIT_MAXIMUM; - *depth.ptr(i + 1, j) = EIGHT_BIT_MAXIMUM; - *depth.ptr(i + 1, j + 1) = EIGHT_BIT_MAXIMUM; - - } else { - *depth.ptr(i, j) = ysrc[0]; - *depth.ptr(i, j + 1) = ysrc[1]; - *depth.ptr(i + 1, j) = ysrc[image->stride[0]]; - *depth.ptr(i + 1, j + 1) = ysrc[image->stride[0] + 1]; + + const uint8_t* depthData = colorData + colorSize; + int depthSize = _arrivingFrame.size() - ((const char*)depthData - _arrivingFrame.constData()); + if (depthSize > 0) { + if (_depthCodec.name == 0) { + // initialize decoder context + vpx_codec_dec_init(&_depthCodec, vpx_codec_vp8_dx(), 0, 0); + } + vpx_codec_decode(&_depthCodec, depthData, depthSize, 0, 0); + vpx_codec_iter_t iterator = 0; + vpx_image_t* image; + while ((image = vpx_codec_get_frame(&_depthCodec, &iterator)) != 0) { + depth.create(image->d_h, image->d_w, CV_8UC1); + uchar* yline = image->planes[0]; + uchar* vline = image->planes[1]; + const uchar EIGHT_BIT_MAXIMUM = 255; + const uchar MASK_THRESHOLD = 192; + for (int i = 0; i < image->d_h; i += 2) { + uchar* ysrc = yline; + uchar* vsrc = vline; + for (int j = 0; j < image->d_w; j += 2) { + + if (*vsrc++ >= MASK_THRESHOLD) { + *depth.ptr(i, j) = EIGHT_BIT_MAXIMUM; + *depth.ptr(i, j + 1) = EIGHT_BIT_MAXIMUM; + *depth.ptr(i + 1, j) = EIGHT_BIT_MAXIMUM; + *depth.ptr(i + 1, j + 1) = EIGHT_BIT_MAXIMUM; + + } else { + *depth.ptr(i, j) = ysrc[0]; + *depth.ptr(i, j + 1) = ysrc[1]; + *depth.ptr(i + 1, j) = ysrc[image->stride[0]]; + *depth.ptr(i + 1, j + 1) = ysrc[image->stride[0] + 1]; + } + ysrc += 2; } - ysrc += 2; + yline += image->stride[0] * 2; + vline += image->stride[1]; } - yline += image->stride[0] * 2; - vline += image->stride[1]; } } QMetaObject::invokeMethod(this, "setFrame", Q_ARG(cv::Mat, color), diff --git a/interface/src/avatar/Face.h b/interface/src/avatar/Face.h index 1f9d41a1b3..d4812fecfb 100644 --- a/interface/src/avatar/Face.h +++ b/interface/src/avatar/Face.h @@ -57,7 +57,8 @@ private: cv::RotatedRect _textureRect; float _aspectRatio; - vpx_codec_ctx_t _codec; + vpx_codec_ctx_t _colorCodec; + vpx_codec_ctx_t _depthCodec; QByteArray _arrivingFrame; int _frameCount; diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 292c4bbc0a..2e7b95c7f7 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -18,14 +18,15 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) { case PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO: case PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO: return 1; - break; case PACKET_TYPE_HEAD_DATA: return 2; - break; + + case PACKET_TYPE_AVATAR_FACE_VIDEO: + return 1; + default: return 0; - break; } } From 96bd7dbe25016b77c530a7e3d67c0ad2ac7500a9 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 30 Jul 2013 15:30:34 -0700 Subject: [PATCH 69/88] Removed the magic from a number. --- interface/src/Webcam.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/Webcam.cpp b/interface/src/Webcam.cpp index 2a58d51dae..b39f11aa67 100644 --- a/interface/src/Webcam.cpp +++ b/interface/src/Webcam.cpp @@ -152,6 +152,8 @@ Webcam::~Webcam() { delete _grabber; } +const float METERS_PER_MM = 1.0f / 1000.0f; + void Webcam::setFrame(const Mat& color, int format, const Mat& depth, float meanFaceDepth, const RotatedRect& faceRect, const JointVector& joints) { IplImage colorImage = color; @@ -250,7 +252,7 @@ void Webcam::setFrame(const Mat& color, int format, const Mat& depth, float mean z = INITIAL_DISTANCE_TO_CAMERA * proportion - INITIAL_DISTANCE_TO_CAMERA; } else { - z = (meanFaceDepth - _initialFaceDepth) / 1000.0f; + z = (meanFaceDepth - _initialFaceDepth) * METERS_PER_MM; proportion = meanFaceDepth / _initialFaceDepth; } const float POSITION_SCALE = 0.5f; @@ -437,7 +439,6 @@ void FrameGrabber::grabFrame() { _userID, (XnSkeletonJoint)parentJoint, parentOrientation); rotation = glm::inverse(xnToGLM(parentOrientation.orientation)) * rotation; } - const float METERS_PER_MM = 1.0f / 1000.0f; joints[avatarJoint] = Joint(xnToGLM(transform.position.position, true) * METERS_PER_MM, rotation, xnToGLM(projected)); } From 353d674ad95a34a6b515c827dce33d1d4b6b926a Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 30 Jul 2013 15:56:47 -0700 Subject: [PATCH 70/88] Masking tweak. --- interface/src/Webcam.cpp | 12 +++++++----- interface/src/avatar/Face.cpp | 3 +-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/interface/src/Webcam.cpp b/interface/src/Webcam.cpp index b39f11aa67..d4fa015ba0 100644 --- a/interface/src/Webcam.cpp +++ b/interface/src/Webcam.cpp @@ -508,6 +508,8 @@ void FrameGrabber::grabFrame() { vpx_codec_enc_init(&_colorCodec, vpx_codec_vp8_cx(), &codecConfig, 0); if (!depth.empty()) { + int DEPTH_BITRATE_MULTIPLIER = 2; + codecConfig.rc_target_bitrate *= 2; vpx_codec_enc_init(&_depthCodec, vpx_codec_vp8_cx(), &codecConfig, 0); } } @@ -660,14 +662,14 @@ void FrameGrabber::grabFrame() { ushort bl = *_faceDepth.ptr(i + 1, j); ushort br = *_faceDepth.ptr(i + 1, j + 1); - uchar mask = EIGHT_BIT_MIDPOINT; + uchar mask = EIGHT_BIT_MAXIMUM; - ydest[0] = (tl == ELEVEN_BIT_MINIMUM) ? (mask = EIGHT_BIT_MAXIMUM) : saturate_cast(tl + depthOffset); - ydest[1] = (tr == ELEVEN_BIT_MINIMUM) ? (mask = EIGHT_BIT_MAXIMUM) : saturate_cast(tr + depthOffset); + ydest[0] = (tl == ELEVEN_BIT_MINIMUM) ? (mask = EIGHT_BIT_MIDPOINT) : saturate_cast(tl + depthOffset); + ydest[1] = (tr == ELEVEN_BIT_MINIMUM) ? (mask = EIGHT_BIT_MIDPOINT) : saturate_cast(tr + depthOffset); ydest[vpxImage.stride[0]] = (bl == ELEVEN_BIT_MINIMUM) ? - (mask = EIGHT_BIT_MAXIMUM) : saturate_cast(bl + depthOffset); + (mask = EIGHT_BIT_MIDPOINT) : saturate_cast(bl + depthOffset); ydest[vpxImage.stride[0] + 1] = (br == ELEVEN_BIT_MINIMUM) ? - (mask = EIGHT_BIT_MAXIMUM) : saturate_cast(br + depthOffset); + (mask = EIGHT_BIT_MIDPOINT) : saturate_cast(br + depthOffset); ydest += 2; *vdest++ = mask; diff --git a/interface/src/avatar/Face.cpp b/interface/src/avatar/Face.cpp index f25426a5be..ff31241c54 100644 --- a/interface/src/avatar/Face.cpp +++ b/interface/src/avatar/Face.cpp @@ -171,8 +171,7 @@ int Face::processVideoMessage(unsigned char* packetData, size_t dataBytes) { uchar* ysrc = yline; uchar* vsrc = vline; for (int j = 0; j < image->d_w; j += 2) { - - if (*vsrc++ >= MASK_THRESHOLD) { + if (*vsrc++ < MASK_THRESHOLD) { *depth.ptr(i, j) = EIGHT_BIT_MAXIMUM; *depth.ptr(i, j + 1) = EIGHT_BIT_MAXIMUM; *depth.ptr(i + 1, j) = EIGHT_BIT_MAXIMUM; From 0086dfdb26643d5db01b4bf1b05cea5de5e594e1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 31 Jul 2013 11:53:48 -0700 Subject: [PATCH 71/88] redundant setting of CMAKE_PREFIX_PATH in interface CMakeLists --- interface/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index e5a2880cfd..635d20924b 100755 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 2.8) set(ROOT_DIR ..) set(MACRO_DIR ${ROOT_DIR}/cmake/macros) +set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{QT_CMAKE_PREFIX_PATH}) + set(TARGET_NAME interface) project(${TARGET_NAME}) From 43fad3037f6503e88c2e9933396aa880d8e169bf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 31 Jul 2013 12:04:47 -0700 Subject: [PATCH 72/88] fix link to QtWebKit lib to be fervor specific --- interface/CMakeLists.txt | 5 +---- interface/external/fervor/CMakeLists.txt | 6 +++++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 635d20924b..e22ea6d628 100755 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -3,8 +3,6 @@ cmake_minimum_required(VERSION 2.8) set(ROOT_DIR ..) set(MACRO_DIR ${ROOT_DIR}/cmake/macros) -set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{QT_CMAKE_PREFIX_PATH}) - set(TARGET_NAME interface) project(${TARGET_NAME}) @@ -73,7 +71,6 @@ find_package(Qt5Core REQUIRED) find_package(Qt5Gui REQUIRED) find_package(Qt5Network REQUIRED) find_package(Qt5OpenGL REQUIRED) -find_package(Qt5WebKit REQUIRED) find_package(Qt5Svg REQUIRED) set(QUAZIP_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/quazip) @@ -83,7 +80,7 @@ include_directories(external/fervor/) # create the executable, make it a bundle on OS X add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS}) -qt5_use_modules(${TARGET_NAME} Core Gui Network OpenGL WebKit Svg) +qt5_use_modules(${TARGET_NAME} Core Gui Network OpenGL Svg) # link in the hifi shared library include(${MACRO_DIR}/LinkHifiLibrary.cmake) diff --git a/interface/external/fervor/CMakeLists.txt b/interface/external/fervor/CMakeLists.txt index 62968d8833..84d059b95c 100644 --- a/interface/external/fervor/CMakeLists.txt +++ b/interface/external/fervor/CMakeLists.txt @@ -1,7 +1,11 @@ cmake_minimum_required(VERSION 2.8) project(Fervor) + +set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{QT_CMAKE_PREFIX_PATH}) + find_package(Qt5Core REQUIRED) find_package(Qt5Network REQUIRED) +find_package(Qt5WebKit REQUIRED) find_package(Qt5Widgets REQUIRED) add_definitions(-DFV_GUI) @@ -30,4 +34,4 @@ include_directories( add_library(fervor ${FERVOR_SOURCES} ${FERVOR_HEADERS} ${FERVOR_MOC_SOURCES} ${FERVOR_WRAPPED_UI}) target_link_libraries(fervor ${QUAZIP_LIBRARIES}) -qt5_use_modules(fervor Core Network Widgets) \ No newline at end of file +qt5_use_modules(fervor Core Network Widgets WebKit) \ No newline at end of file From 482c5f0f4a713da4f02062a6f0c3f5da7657211d Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 31 Jul 2013 12:09:46 -0700 Subject: [PATCH 73/88] turned on leap hand diagram --- interface/src/avatar/Hand.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 44539243a4..6ec1c0371b 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -14,7 +14,7 @@ #include "Util.h" #include "renderer/ProgramObject.h" -const bool SHOW_LEAP_HAND = false; +const bool SHOW_LEAP_HAND = true; using namespace std; @@ -58,7 +58,7 @@ void Hand::simulate(float deltaTime, bool isMine) { } void Hand::calculateGeometry() { - glm::vec3 offset(0.2, -0.2, -0.3); // place the hand in front of the face where we can see it + glm::vec3 offset(0.0, -0.2, -0.3); // place the hand in front of the face where we can see it Head& head = _owningAvatar->getHead(); _basePosition = head.getPosition() + head.getOrientation() * offset; From 2c5b8d31214f2859724972355b8954076f3f1b31 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 31 Jul 2013 12:21:49 -0700 Subject: [PATCH 74/88] cmake source is root, make specific target --- interface/external/fervor/CMakeLists.txt | 2 -- jenkins/jobs.groovy | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/interface/external/fervor/CMakeLists.txt b/interface/external/fervor/CMakeLists.txt index 84d059b95c..a8b37ba9d0 100644 --- a/interface/external/fervor/CMakeLists.txt +++ b/interface/external/fervor/CMakeLists.txt @@ -1,8 +1,6 @@ cmake_minimum_required(VERSION 2.8) project(Fervor) -set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{QT_CMAKE_PREFIX_PATH}) - find_package(Qt5Core REQUIRED) find_package(Qt5Network REQUIRED) find_package(Qt5WebKit REQUIRED) diff --git a/jenkins/jobs.groovy b/jenkins/jobs.groovy index 5acf313a9a..a7be662df6 100644 --- a/jenkins/jobs.groovy +++ b/jenkins/jobs.groovy @@ -81,12 +81,12 @@ def hifiJob(String targetName, Boolean deploy) { static Closure cmakeBuild(srcDir, instCommand) { return { project -> project / 'builders' / 'hudson.plugins.cmake.CmakeBuilder' { - sourceDir srcDir + sourceDir '.' buildDir 'build' installDir '' buildType 'RelWithDebInfo' generator 'Unix Makefiles' - makeCommand 'make' + makeCommand "make ${srcDir}" installCommand instCommand preloadScript '' cmakeArgs '' From 2901b58059c4ac0cb1f3aba8cea5cd84715388cb Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 31 Jul 2013 12:34:43 -0700 Subject: [PATCH 75/88] changed variable name from t to effectsTimer --- interface/src/avatar/Hand.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 6ec1c0371b..eda17076b6 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -267,6 +267,8 @@ void Hand::updateRaveGloveEmitters() { fingerDirection = IDENTITY_UP; } + assert(_raveGloveEmitter[fingerIndex] >=0 ); + assert(_raveGloveEmitter[fingerIndex] < NUM_FINGERS ); _raveGloveParticleSystem.setEmitterPosition (_raveGloveEmitter[fingerIndex], finger.getTipPosition()); _raveGloveParticleSystem.setEmitterDirection(_raveGloveEmitter[fingerIndex], fingerDirection); fingerIndex ++; From 89f36a7eb7849b39be9251114d6c35302d382ca0 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 31 Jul 2013 12:38:40 -0700 Subject: [PATCH 76/88] cleanup --- interface/src/Application.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2bc5e4c71a..452cf4dcb8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3679,8 +3679,8 @@ void Application::updateParticleSystem(float deltaTime) { // update the particle system static bool emitting = true; - static float t = 0.0f; - t += deltaTime; + static float effectsTimer = 0.0f; + effectsTimer += deltaTime; if (_coolDemoParticleEmitter != -1) { @@ -3690,13 +3690,13 @@ void Application::updateParticleSystem(float deltaTime) { 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 ); - attributes.emitterAttraction = 0.015f + 0.015f * cosf( t * 0.6f ); - attributes.tornadoForce = 0.0f + 0.03f * sinf( t * 0.7f ); - attributes.neighborAttraction = 0.1f + 0.1f * cosf( t * 0.8f ); - attributes.neighborRepulsion = 0.2f + 0.2f * sinf( t * 0.4f ); + attributes.gravity = 0.0f + 0.05f * sinf( effectsTimer * 0.52f ); + attributes.airFriction = 2.5 + 2.0f * sinf( effectsTimer * 0.32f ); + attributes.jitter = 0.05f + 0.05f * sinf( effectsTimer * 0.42f ); + attributes.emitterAttraction = 0.015f + 0.015f * cosf( effectsTimer * 0.6f ); + attributes.tornadoForce = 0.0f + 0.03f * sinf( effectsTimer * 0.7f ); + attributes.neighborAttraction = 0.1f + 0.1f * cosf( effectsTimer * 0.8f ); + attributes.neighborRepulsion = 0.2f + 0.2f * sinf( effectsTimer * 0.4f ); attributes.bounce = 1.0f; attributes.usingCollisionSphere = true; attributes.collisionSpherePosition = glm::vec3( 5.0f, 0.5f, 5.0f ); @@ -3715,9 +3715,11 @@ void Application::updateParticleSystem(float deltaTime) { _particleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); _particleSystem.simulate(deltaTime); + const float EMIT_RATE_IN_SECONDS = 0.0; + if (_coolDemoParticleEmitter != -1) { if (emitting) { - _particleSystem.setEmitterRate(_coolDemoParticleEmitter, 0.0); // stop emitter + _particleSystem.setEmitterRate(_coolDemoParticleEmitter, EMIT_RATE_IN_SECONDS); // stop emitter emitting = false; } } From 0aaeb4550afe4a607e6cf742dbfee6121fb45f72 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 31 Jul 2013 13:07:52 -0700 Subject: [PATCH 77/88] cleanup --- interface/src/ParticleSystem.cpp | 120 +++++++++++++++---------------- interface/src/ParticleSystem.h | 2 + interface/src/avatar/Hand.cpp | 22 +++--- 3 files changed, 73 insertions(+), 71 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 6898d37e6b..1d3de9da1a 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -51,7 +51,7 @@ ParticleSystem::ParticleSystem() { _particle[p].age = 0.0f; _particle[p].radius = 0.0f; _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].velocity = glm::vec3(0.0f, 0.0f, 0.0f); } @@ -64,7 +64,7 @@ int ParticleSystem::addEmitter() { return _numEmitters - 1; } - return -1; + return NULL_EMITTER; } @@ -75,9 +75,9 @@ 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 ); + assert(e >= 0); + assert(e <= MAX_EMITTERS); + assert(_emitter[e].rate >= 0); _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].radius = _emitter[e].particleAttributes[0].radius; _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].emitterIndex == e ) { + if (_particle[_emitter[e].currentParticle].alive) { + if (_particle[_emitter[e].currentParticle].emitterIndex == e) { _particle[p].previousParticle = _emitter[e].currentParticle; } } @@ -133,15 +133,15 @@ void ParticleSystem::createParticle(int e, float timeFraction) { void ParticleSystem::killParticle(int p) { - assert( p >= 0); - assert( p < MAX_PARTICLES); + assert(p >= 0); + assert(p < MAX_PARTICLES); _particle[p].alive = false; - _particle[p].previousParticle = -1; + _particle[p].previousParticle = NULL_PARTICLE; _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; + _particle[p].emitterIndex = NULL_PARTICLE; } @@ -153,7 +153,7 @@ void ParticleSystem::setEmitterPosition(int emitterIndex, glm::vec3 position) { 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); } } @@ -185,8 +185,8 @@ void ParticleSystem::setParticleAttributesToDefault(ParticleAttributes * a) { void ParticleSystem::setParticleAttributes(int emitterIndex, ParticleLifeStage lifeStage, ParticleAttributes attributes) { - assert(lifeStage >= 0 ); - assert(lifeStage < NUM_PARTICLE_LIFE_STAGES ); + assert(lifeStage >= 0); + assert(lifeStage < NUM_PARTICLE_LIFE_STAGES); 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) { ageFraction = _particle[p].age / myEmitter.particleLifespan; - lifeStage = (int)( ageFraction * (NUM_PARTICLE_LIFE_STAGES-1) ); - lifeStageFraction = ageFraction * ( NUM_PARTICLE_LIFE_STAGES - 1 ) - lifeStage; + lifeStage = (int)(ageFraction * (NUM_PARTICLE_LIFE_STAGES - 1)); + lifeStageFraction = ageFraction * (NUM_PARTICLE_LIFE_STAGES - 1) - lifeStage; // adjust radius _particle[p].radius @@ -250,18 +250,18 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { // apply neighbor attraction int neighbor = p + 1; - if (neighbor == MAX_PARTICLES ) { + if (neighbor == MAX_PARTICLES) { 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; _particle[p].velocity -= vectorToNeighbor * myEmitter.particleAttributes[lifeStage].neighborAttraction * deltaTime; float distanceToNeighbor = glm::length(vectorToNeighbor); 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 radian = _timer * myEmitter.particleAttributes[lifeStage ].modulationRate * PI_TIMES_TWO; 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; } } 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() { for (int e = 0; e < _numEmitters; e++) { - _emitter[e].currentParticle = -1; + _emitter[e].currentParticle = NULL_PARTICLE; _emitter[e].emitReserve = 0.0f; _emitter[e].previousPosition = _emitter[e].position; _emitter[e].rate = 0.0f; @@ -366,7 +366,7 @@ void ParticleSystem::render() { for (int e = 0; e < _numEmitters; e++) { 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(); glTranslatef(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); glutSolidSphere(_particle[0].radius, _emitter[e].particleResolution, _emitter[e].particleResolution); @@ -390,7 +390,7 @@ void ParticleSystem::render() { 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) { 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) { - if (_particle[p].previousParticle != -1) { + if (_particle[p].previousParticle != NULL_PARTICLE) { if ((_particle[p].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 v = _particle[p].position - _particle[pp].position; - float distance = glm::length(v); + glm::vec3 vectorFromPreviousParticle = _particle[p].position - _particle[_particle[p].previousParticle].position; + float distance = glm::length(vectorFromPreviousParticle); if (distance > 0.0f) { - v /= distance; + vectorFromPreviousParticle /= distance; - glm::vec3 up = glm::normalize(glm::cross(v, _upDirection)) * _particle[p].radius; - glm::vec3 right = glm::normalize(glm::cross(up, v )) * _particle[p].radius; + glm::vec3 up = glm::normalize(glm::cross(vectorFromPreviousParticle, _upDirection)) * _particle[p].radius; + glm::vec3 right = glm::normalize(glm::cross(up, vectorFromPreviousParticle )) * _particle[p].radius; glm::vec3 p0Left = _particle[p ].position - right; glm::vec3 p0Right = _particle[p ].position + right; glm::vec3 p0Down = _particle[p ].position - up; glm::vec3 p0Up = _particle[p ].position + up; - glm::vec3 ppLeft = _particle[pp].position - right; - glm::vec3 ppRight = _particle[pp].position + right; - glm::vec3 ppDown = _particle[pp].position - up; - glm::vec3 ppUp = _particle[pp].position + up; + glm::vec3 ppLeft = _particle[_particle[p].previousParticle].position - right; + glm::vec3 ppRight = _particle[_particle[p].previousParticle].position + right; + glm::vec3 ppDown = _particle[_particle[p].previousParticle].position - up; + glm::vec3 ppUp = _particle[_particle[p].previousParticle].position + up; glBegin(GL_TRIANGLES); - glVertex3f(p0Left.x, p0Left.y, p0Left.z ); - glVertex3f(p0Right.x, p0Right.y, p0Right.z ); - glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); + glVertex3f(p0Left.x, p0Left.y, p0Left.z ); + glVertex3f(p0Right.x, p0Right.y, p0Right.z); + glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); - glVertex3f(p0Right.x, p0Right.y, p0Right.z ); - glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); - glVertex3f(ppRight.x, ppRight.y, ppRight.z ); + glVertex3f(p0Right.x, p0Right.y, p0Right.z); + glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); + glVertex3f(ppRight.x, ppRight.y, ppRight.z); - glVertex3f(p0Up.x, p0Up.y, p0Up.z ); - glVertex3f(p0Down.x, p0Down.y, p0Down.z ); - glVertex3f(ppDown.x, ppDown.y, ppDown.z ); + glVertex3f(p0Up.x, p0Up.y, p0Up.z ); + glVertex3f(p0Down.x, p0Down.y, p0Down.z ); + glVertex3f(ppDown.x, ppDown.y, ppDown.z ); - glVertex3f(p0Up.x, p0Up.y, p0Up.z ); - glVertex3f(ppUp.x, ppUp.y, ppUp.z ); - glVertex3f(ppDown.x, ppDown.y, ppDown.z ); + glVertex3f(p0Up.x, p0Up.y, p0Up.z ); + glVertex3f(ppUp.x, ppUp.y, ppUp.z ); + glVertex3f(ppDown.x, ppDown.y, ppDown.z ); - glVertex3f(p0Up.x, p0Up.y, p0Left.z ); - glVertex3f(p0Right.x, p0Right.y, p0Right.z ); - glVertex3f(p0Down.x, p0Down.y, p0Down.z ); + glVertex3f(p0Up.x, p0Up.y, p0Left.z ); + glVertex3f(p0Right.x, p0Right.y, p0Right.z); + glVertex3f(p0Down.x, p0Down.y, p0Down.z ); - glVertex3f(p0Up.x, p0Up.y, p0Left.z ); - glVertex3f(p0Left.x, p0Left.y, p0Left.z ); - glVertex3f(p0Down.x, p0Down.y, p0Down.z ); + glVertex3f(p0Up.x, p0Up.y, p0Left.z ); + glVertex3f(p0Left.x, p0Left.y, p0Left.z ); + glVertex3f(p0Down.x, p0Down.y, p0Down.z ); - glVertex3f(ppUp.x, ppUp.y, ppLeft.z ); - glVertex3f(ppRight.x, ppRight.y, ppRight.z ); - glVertex3f(ppDown.x, ppDown.y, ppDown.z ); + glVertex3f(ppUp.x, ppUp.y, ppLeft.z ); + glVertex3f(ppRight.x, ppRight.y, ppRight.z); + glVertex3f(ppDown.x, ppDown.y, ppDown.z ); - glVertex3f(ppUp.x, ppUp.y, ppLeft.z ); - glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); - glVertex3f(ppDown.x, ppDown.y, ppDown.z ); + glVertex3f(ppUp.x, ppUp.y, ppLeft.z ); + glVertex3f(ppLeft.x, ppLeft.y, ppLeft.z ); + glVertex3f(ppDown.x, ppDown.y, ppDown.z ); glEnd(); } diff --git a/interface/src/ParticleSystem.h b/interface/src/ParticleSystem.h index 027a166274..d79f621f69 100644 --- a/interface/src/ParticleSystem.h +++ b/interface/src/ParticleSystem.h @@ -11,6 +11,8 @@ #include const int MAX_PARTICLES = 5000; +const int NULL_EMITTER = -1; +const int NULL_PARTICLE = -1; const int MAX_EMITTERS = 100; enum ParticleRenderStyle diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index eda17076b6..5b1f5cae2c 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -14,7 +14,7 @@ #include "Util.h" #include "renderer/ProgramObject.h" -const bool SHOW_LEAP_HAND = true; +const bool SHOW_LEAP_HAND = false; using namespace std; @@ -22,18 +22,17 @@ Hand::Hand(Avatar* owningAvatar) : HandData((AvatarData*)owningAvatar), _raveGloveClock(0.0f), - _raveGloveMode(0), + _raveGloveMode(RAVE_GLOVE_EFFECTS_MODE_0), _raveGloveInitialized(false), + _isRaveGloveActive(false), _owningAvatar(owningAvatar), _renderAlpha(1.0), _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 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() { - 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(); _basePosition = head.getPosition() + head.getOrientation() * offset; @@ -256,7 +255,7 @@ void Hand::updateRaveGloveEmitters() { for (size_t f = 0; f < palm.getNumFingers(); ++f) { FingerData& finger = palm.getFingers()[f]; if (finger.isActive()) { - if (_raveGloveEmitter[0] != -1) { + if (_raveGloveEmitter[0] != NULL_EMITTER) { glm::vec3 fingerDirection = finger.getTipPosition() - finger.getRootPosition(); float fingerLength = glm::length(fingerDirection); @@ -269,6 +268,7 @@ void Hand::updateRaveGloveEmitters() { assert(_raveGloveEmitter[fingerIndex] >=0 ); assert(_raveGloveEmitter[fingerIndex] < NUM_FINGERS ); + _raveGloveParticleSystem.setEmitterPosition (_raveGloveEmitter[fingerIndex], finger.getTipPosition()); _raveGloveParticleSystem.setEmitterDirection(_raveGloveEmitter[fingerIndex], fingerDirection); fingerIndex ++; @@ -289,7 +289,7 @@ void Hand::updateRaveGloveParticles(float deltaTime) { // start up the rave glove finger particles... for ( int f = 0; f< NUM_FINGERS; f ++ ) { _raveGloveEmitter[f] = _raveGloveParticleSystem.addEmitter(); - assert( _raveGloveEmitter[f] != -1 ); + assert( _raveGloveEmitter[f] != NULL_EMITTER ); } setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_2); @@ -299,13 +299,15 @@ void Hand::updateRaveGloveParticles(float 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) { ParticleSystem::ParticleAttributes attributes; float red = 0.5f + 0.5f * sinf(_raveGloveClock * 1.4f); float green = 0.5f + 0.5f * cosf(_raveGloveClock * 1.7f); 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.modulationAmplitude = 0.0f; From 10b57bca80e44e1e62418eedce0704043ba0ceb3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 31 Jul 2013 14:24:30 -0700 Subject: [PATCH 78/88] remove useless link to QT_LIBRARIES --- interface/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index e22ea6d628..79b2dffea5 100755 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -130,8 +130,7 @@ include_directories( SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${OPENCV_INCLUDE_DIRS}") target_link_libraries( - ${TARGET_NAME} - ${QT_LIBRARIES} + ${TARGET_NAME} ${LIBVPX_LIBRARIES} ${MOTIONDRIVER_LIBRARIES} ${OPENCV_LIBRARIES} From 5b1ba56d67f1c3e7954a6a58a808199a98f1f781 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 31 Jul 2013 15:12:29 -0700 Subject: [PATCH 79/88] toggle debug print statements for Leap fingers --- interface/src/ParticleSystem.cpp | 8 ++--- interface/src/avatar/Hand.cpp | 58 ++++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index 1d3de9da1a..fb5ecca9f4 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -80,9 +80,7 @@ void ParticleSystem::simulate(float deltaTime) { assert(_emitter[e].rate >= 0); _emitter[e].emitReserve += _emitter[e].rate * deltaTime; - _emitter[e].numParticlesEmittedThisTime = (int)_emitter[e].emitReserve; - _emitter[e].emitReserve -= _emitter[e].numParticlesEmittedThisTime; for (int p = 0; p < _emitter[e].numParticlesEmittedThisTime; p++) { @@ -114,8 +112,8 @@ void ParticleSystem::createParticle(int e, float timeFraction) { _particle[p].age = 0.0f; _particle[p].velocity = _emitter[e].direction * _emitter[e].thrust; _particle[p].position = _emitter[e].previousPosition + timeFraction * (_emitter[e].position - _emitter[e].previousPosition); - _particle[p].radius = _emitter[e].particleAttributes[0].radius; - _particle[p].color = _emitter[e].particleAttributes[0].color; + _particle[p].radius = _emitter[e].particleAttributes[PARTICLE_LIFESTAGE_0].radius; + _particle[p].color = _emitter[e].particleAttributes[PARTICLE_LIFESTAGE_0].color; _particle[p].previousParticle = NULL_PARTICLE; if (_particle[_emitter[e].currentParticle].alive) { @@ -142,6 +140,8 @@ void ParticleSystem::killParticle(int p) { _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); _particle[p].age = 0.0f; _particle[p].emitterIndex = NULL_PARTICLE; + _particle[p].color = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f); + _particle[p].radius = 0.0f; } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 5b1f5cae2c..d51c65891c 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -14,7 +14,7 @@ #include "Util.h" #include "renderer/ProgramObject.h" -const bool SHOW_LEAP_HAND = false; +const bool SHOW_LEAP_HAND = true; using namespace std; @@ -246,17 +246,42 @@ void Hand::setLeapHands(const std::vector& handPositions, // call this right after the geometry of the leap hands are set void Hand::updateRaveGloveEmitters() { + bool debug = false; + if (_raveGloveInitialized) { - - int fingerIndex = 0; + + if(debug) printf( "\n" ); + if(debug) printf( "------------------------------------\n" ); + if(debug) printf( "updating rave glove emitters:\n" ); + if(debug) printf( "------------------------------------\n" ); + + int emitterIndex = 0; + for (size_t i = 0; i < getNumPalms(); ++i) { PalmData& palm = getPalms()[i]; + + if(debug) printf( "\n" ); + if(debug) printf( "palm %d ", (int)i ); + if (palm.isActive()) { + + if(debug) printf( "is active\n" ); + for (size_t f = 0; f < palm.getNumFingers(); ++f) { FingerData& finger = palm.getFingers()[f]; + + if(debug) printf( "emitterIndex %d: ", emitterIndex ); + if (finger.isActive()) { - if (_raveGloveEmitter[0] != NULL_EMITTER) { - + + if ((emitterIndex >=0) + && (emitterIndex < NUM_FINGERS)) { + + assert(emitterIndex >=0 ); + assert(emitterIndex < NUM_FINGERS ); + + if(debug) printf( "_raveGloveEmitter[%d] = %d\n", emitterIndex, _raveGloveEmitter[emitterIndex] ); + glm::vec3 fingerDirection = finger.getTipPosition() - finger.getRootPosition(); float fingerLength = glm::length(fingerDirection); @@ -266,15 +291,20 @@ void Hand::updateRaveGloveEmitters() { fingerDirection = IDENTITY_UP; } - assert(_raveGloveEmitter[fingerIndex] >=0 ); - assert(_raveGloveEmitter[fingerIndex] < NUM_FINGERS ); + assert(_raveGloveEmitter[emitterIndex] >=0 ); + assert(_raveGloveEmitter[emitterIndex] < NUM_FINGERS ); - _raveGloveParticleSystem.setEmitterPosition (_raveGloveEmitter[fingerIndex], finger.getTipPosition()); - _raveGloveParticleSystem.setEmitterDirection(_raveGloveEmitter[fingerIndex], fingerDirection); - fingerIndex ++; - } + _raveGloveParticleSystem.setEmitterPosition (_raveGloveEmitter[emitterIndex], finger.getTipPosition()); + _raveGloveParticleSystem.setEmitterDirection(_raveGloveEmitter[emitterIndex], fingerDirection); + } + } else { + if(debug) printf( "BOGUS finger\n" ); } + + emitterIndex ++; } + } else { + if(debug) printf( "is NOT active\n" ); } } } @@ -286,10 +316,16 @@ void Hand::updateRaveGloveParticles(float deltaTime) { if (!_raveGloveInitialized) { + //printf( "Initializing rave glove emitters:\n" ); + //printf( "The indices of the emitters are:\n" ); + // start up the rave glove finger particles... for ( int f = 0; f< NUM_FINGERS; f ++ ) { _raveGloveEmitter[f] = _raveGloveParticleSystem.addEmitter(); + assert( _raveGloveEmitter[f] >= 0 ); assert( _raveGloveEmitter[f] != NULL_EMITTER ); + + //printf( "%d\n", _raveGloveEmitter[f] ); } setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_2); From c34bc4173b4188cd6a2343726208f508d3d98858 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 31 Jul 2013 15:45:22 -0700 Subject: [PATCH 80/88] call use modules after OpenNI is linked --- interface/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 79b2dffea5..17967c5f42 100755 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -80,8 +80,6 @@ include_directories(external/fervor/) # create the executable, make it a bundle on OS X add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS}) -qt5_use_modules(${TARGET_NAME} Core Gui Network OpenGL Svg) - # link in the hifi shared library include(${MACRO_DIR}/LinkHifiLibrary.cmake) @@ -110,6 +108,8 @@ if (OPENNI_FOUND) target_link_libraries(${TARGET_NAME} ${OPENNI_LIBRARIES}) endif (OPENNI_FOUND) +qt5_use_modules(${TARGET_NAME} Core Gui Network OpenGL Svg) + # include headers for interface and InterfaceConfig. include_directories( ${PROJECT_SOURCE_DIR}/src From be8a587d49028d4942220b0009b44e7e7ace3cbc Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 31 Jul 2013 16:07:21 -0700 Subject: [PATCH 81/88] named rave glove effects --- interface/src/ParticleSystem.cpp | 2 +- interface/src/avatar/Hand.cpp | 53 ++++++++++++++++---------------- interface/src/avatar/Hand.h | 20 ++++++------ 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/interface/src/ParticleSystem.cpp b/interface/src/ParticleSystem.cpp index fb5ecca9f4..5e2b92bb64 100644 --- a/interface/src/ParticleSystem.cpp +++ b/interface/src/ParticleSystem.cpp @@ -41,7 +41,7 @@ ParticleSystem::ParticleSystem() { e->particleRenderStyle = PARTICLE_RENDER_STYLE_SPHERE; e->numParticlesEmittedThisTime = 0; - for (int lifeStage = 0; lifeStagekey()) { - case Qt::Key_0: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_0); break; - case Qt::Key_1: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_1); break; - case Qt::Key_2: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_2); break; - case Qt::Key_3: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_3); break; - case Qt::Key_4: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_4); break; - case Qt::Key_5: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_5); break; - case Qt::Key_6: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_6); break; - case Qt::Key_7: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_7); break; - case Qt::Key_8: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_8); break; - case Qt::Key_9: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_9); break; - }; + + case Qt::Key_0: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_THROBBING_COLOR); break; + case Qt::Key_1: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_TRAILS ); break; + case Qt::Key_2: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_FIRE ); break; + case Qt::Key_3: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_WATER ); break; + case Qt::Key_4: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_FLASHY ); break; + case Qt::Key_5: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_BOZO_SPARKLER ); break; + case Qt::Key_6: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_LONG_SPARKLER ); break; + case Qt::Key_7: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_SNAKE ); break; + case Qt::Key_8: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_PULSE ); break; + case Qt::Key_9: setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_THROB ); break; + }; } void Hand::render(bool lookingInMirror) { @@ -327,8 +328,8 @@ void Hand::updateRaveGloveParticles(float deltaTime) { //printf( "%d\n", _raveGloveEmitter[f] ); } - - setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_2); + + setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_FIRE); _raveGloveParticleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); _raveGloveInitialized = true; } else { @@ -336,7 +337,7 @@ void Hand::updateRaveGloveParticles(float 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_THROBBING_COLOR) { ParticleSystem::ParticleAttributes attributes; float red = 0.5f + 0.5f * sinf(_raveGloveClock * 1.4f); float green = 0.5f + 0.5f * cosf(_raveGloveClock * 1.7f); @@ -372,7 +373,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // throbbing color cycle //----------------------------------------- - if (mode == RAVE_GLOVE_EFFECTS_MODE_0) { + if (mode == RAVE_GLOVE_EFFECTS_MODE_THROBBING_COLOR) { _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 0.0f ); @@ -395,7 +396,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // trails //----------------------------------------- - } else if (mode == RAVE_GLOVE_EFFECTS_MODE_1) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_TRAILS) { _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], false ); _raveGloveParticleSystem.setEmitterParticleLifespan (_raveGloveEmitter[f], 1.0f ); @@ -426,7 +427,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // Fire! //----------------------------------------- - if (mode == RAVE_GLOVE_EFFECTS_MODE_2) { + if (mode == RAVE_GLOVE_EFFECTS_MODE_FIRE) { _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], false ); @@ -461,7 +462,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // water //----------------------------------------- - } else if (mode == RAVE_GLOVE_EFFECTS_MODE_3) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_WATER) { _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); @@ -493,7 +494,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // flashy //----------------------------------------- - } else if (mode == RAVE_GLOVE_EFFECTS_MODE_4) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_FLASHY) { _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); @@ -525,7 +526,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // Bozo sparkler //----------------------------------------- - } else if (mode == RAVE_GLOVE_EFFECTS_MODE_5) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_BOZO_SPARKLER) { _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], false ); @@ -557,7 +558,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // long sparkler //----------------------------------------- - } else if (mode == RAVE_GLOVE_EFFECTS_MODE_6) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_LONG_SPARKLER) { _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_RIBBON ); _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], false ); @@ -590,7 +591,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // bubble snake //----------------------------------------- - } else if (mode == RAVE_GLOVE_EFFECTS_MODE_7) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_SNAKE) { _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); @@ -627,7 +628,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // pulse //----------------------------------------- - } else if (mode == RAVE_GLOVE_EFFECTS_MODE_8) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_PULSE) { _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); @@ -651,7 +652,7 @@ void Hand::setRaveGloveMode(int mode) { //----------------------------------------- // throb //----------------------------------------- - } else if (mode == RAVE_GLOVE_EFFECTS_MODE_9) { + } else if (mode == RAVE_GLOVE_EFFECTS_MODE_LONG_SPARKLER) { _raveGloveParticleSystem.setParticleRenderStyle (_raveGloveEmitter[f], PARTICLE_RENDER_STYLE_SPHERE ); _raveGloveParticleSystem.setShowingEmitterBaseParticle(_raveGloveEmitter[f], true ); diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index bfddf9811d..a3a00beb96 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -26,16 +26,16 @@ class ProgramObject; enum RaveGloveEffectsMode { RAVE_GLOVE_EFFECTS_MODE_NULL = -1, - RAVE_GLOVE_EFFECTS_MODE_0, - RAVE_GLOVE_EFFECTS_MODE_1, - RAVE_GLOVE_EFFECTS_MODE_2, - RAVE_GLOVE_EFFECTS_MODE_3, - RAVE_GLOVE_EFFECTS_MODE_4, - RAVE_GLOVE_EFFECTS_MODE_5, - RAVE_GLOVE_EFFECTS_MODE_6, - RAVE_GLOVE_EFFECTS_MODE_7, - RAVE_GLOVE_EFFECTS_MODE_8, - RAVE_GLOVE_EFFECTS_MODE_9, + RAVE_GLOVE_EFFECTS_MODE_THROBBING_COLOR, + RAVE_GLOVE_EFFECTS_MODE_TRAILS, + RAVE_GLOVE_EFFECTS_MODE_FIRE, + RAVE_GLOVE_EFFECTS_MODE_WATER, + RAVE_GLOVE_EFFECTS_MODE_FLASHY, + RAVE_GLOVE_EFFECTS_MODE_BOZO_SPARKLER, + RAVE_GLOVE_EFFECTS_MODE_LONG_SPARKLER, + RAVE_GLOVE_EFFECTS_MODE_SNAKE, + RAVE_GLOVE_EFFECTS_MODE_PULSE, + RAVE_GLOVE_EFFECTS_MODE_THROB, NUM_RAVE_GLOVE_EFFECTS_MODES }; From 5c040ad84d43cc0e15271d902cd3e94f5091c706 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 31 Jul 2013 16:08:46 -0700 Subject: [PATCH 82/88] test --- interface/CMakeLists.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 interface/CMakeLists.txt diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt old mode 100755 new mode 100644 From b3fc378a0f3008c73dd521904e3e5033c733ce83 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 31 Jul 2013 16:14:17 -0700 Subject: [PATCH 83/88] don't include XnCppWrapper if Q_MOC_RUN is defined --- interface/src/Webcam.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/Webcam.h b/interface/src/Webcam.h index 6c6d250897..19f0265530 100644 --- a/interface/src/Webcam.h +++ b/interface/src/Webcam.h @@ -9,6 +9,10 @@ #ifndef __interface__Webcam__ #define __interface__Webcam__ +#if defined(HAVE_OPENNI) && !defined(Q_MOC_RUN) +#include +#endif + #include #include #include @@ -19,9 +23,6 @@ #include -#ifdef HAVE_OPENNI - #include -#endif #include From 8166ed3a77c5028c3455e92530ed304dab76111e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 31 Jul 2013 16:15:39 -0700 Subject: [PATCH 84/88] move OpenNI include --- interface/src/Webcam.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/interface/src/Webcam.h b/interface/src/Webcam.h index 19f0265530..3910bb4a19 100644 --- a/interface/src/Webcam.h +++ b/interface/src/Webcam.h @@ -9,10 +9,6 @@ #ifndef __interface__Webcam__ #define __interface__Webcam__ -#if defined(HAVE_OPENNI) && !defined(Q_MOC_RUN) -#include -#endif - #include #include #include @@ -23,6 +19,9 @@ #include +#if defined(HAVE_OPENNI) && !defined(Q_MOC_RUN) +#include +#endif #include From 71ab8ae4f862839cde0b8bb729dd8e1f930135bb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 1 Aug 2013 10:07:10 -0700 Subject: [PATCH 85/88] some necessary changes for AvatarData transmission --- interface/src/Application.cpp | 2 +- libraries/avatars/src/AvatarData.cpp | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a4279a7e58..9b292b3d50 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2357,7 +2357,7 @@ void Application::updateAvatar(float deltaTime) { NodeList* nodeList = NodeList::getInstance(); if (nodeList->getOwnerID() != UNKNOWN_NODE_ID) { // if I know my ID, send head/hand data to the avatar mixer and voxel server - unsigned char broadcastString[200]; + unsigned char broadcastString[MAX_PACKET_SIZE]; unsigned char* endOfBroadcastStringWrite = broadcastString; endOfBroadcastStringWrite += populateTypeAndVersion(endOfBroadcastStringWrite, PACKET_TYPE_HEAD_DATA); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 01907b92f4..65ae0c6952 100755 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -132,10 +132,6 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { std::vector fingerVectors; _handData->encodeRemoteData(fingerVectors); - ///////////////////////////////// - // Temporarily disable Leap finger sending, as it's causing a crash whenever someone's got a Leap connected - fingerVectors.clear(); - ///////////////////////////////// if (fingerVectors.size() > 255) fingerVectors.clear(); // safety. We shouldn't ever get over 255, so consider that invalid. @@ -249,8 +245,8 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { _handState = getSemiNibbleAt(bitItems,HAND_STATE_START_BIT); // leap hand data - if (sourceBuffer - startPosition < numBytes) // safety check - { + if (sourceBuffer - startPosition < numBytes) { + // check passed, bytes match unsigned int numFingerVectors = *sourceBuffer++; if (numFingerVectors > 0) { std::vector fingerVectors(numFingerVectors); @@ -264,8 +260,8 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { } // skeleton joints - if (sourceBuffer - startPosition < numBytes) // safety check - { + if (sourceBuffer - startPosition < numBytes) { + // check passed, bytes match _joints.resize(*sourceBuffer++); for (vector::iterator it = _joints.begin(); it != _joints.end(); it++) { it->jointID = *sourceBuffer++; From 2fde29e04a1a6e7c033ba0b73065589265e68466 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 1 Aug 2013 11:53:18 -0700 Subject: [PATCH 86/88] use a 0 public address to designate server local to DS --- domain-server/src/main.cpp | 5 +++-- libraries/shared/src/NodeList.cpp | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 5d41efdc67..f62ce10e92 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -104,9 +104,10 @@ int main(int argc, const char * argv[]) // so hardcode the EC2 public address for now if (nodePublicAddress.sin_addr.s_addr == serverLocalAddress) { // If we're not running "local" then we do replace the IP - // with the EC2 IP. Otherwise, we use our normal public IP + // with 0. This designates to clients that the server is reachable + // at the same IP address if (!isLocalMode) { - nodePublicAddress.sin_addr.s_addr = 895283510; // local IP in this format... + nodePublicAddress.sin_addr.s_addr = 0; destinationSocket = (sockaddr*) &nodeLocalAddress; } } diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 42aa024e9d..8819677bcc 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -352,6 +352,12 @@ int NodeList::processDomainServerList(unsigned char* packetData, size_t dataByte readPtr += unpackSocket(readPtr, (sockaddr*) &nodePublicSocket); readPtr += unpackSocket(readPtr, (sockaddr*) &nodeLocalSocket); + // if the public socket address is 0 then it's reachable at the same IP + // as the domain server + if (nodePublicSocket.sin_addr.s_addr == 0) { + inet_aton(_domainIP, &nodePublicSocket.sin_addr); + } + addOrUpdateNode((sockaddr*) &nodePublicSocket, (sockaddr*) &nodeLocalSocket, nodeType, nodeId); } From 2b31a3586e059ee9736e1b484d37d6c416ec9e19 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 1 Aug 2013 12:01:48 -0700 Subject: [PATCH 87/88] comment changes for local vs. non-local --- domain-server/src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index f62ce10e92..13865cbacc 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -55,10 +55,10 @@ int main(int argc, const char * argv[]) // domain server bool isLocalMode = cmdOptionExists(argc, argv, "--local"); if (isLocalMode) { - printf("NOTE: Running in Local Mode!\n"); + printf("NOTE: Running in local mode!\n"); } else { printf("--------------------------------------------------\n"); - printf("NOTE: Running in EC2 Mode. \n"); + printf("NOTE: Not running in local mode. \n"); printf("If you're a developer testing a local system, you\n"); printf("probably want to include --local on command line.\n"); printf("--------------------------------------------------\n"); From 9ba0e3bb0c25fb745ebf42d5a6d7c11772b23358 Mon Sep 17 00:00:00 2001 From: Mark Peng Date: Thu, 1 Aug 2013 13:03:17 -0700 Subject: [PATCH 88/88] Add reference lines to mouse voxel when adding/deleting voxels. --- interface/src/Application.cpp | 3 ++- interface/src/Util.cpp | 26 ++++++++++++++++++++++++++ interface/src/Util.h | 3 ++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9b292b3d50..7fc9bd7ac8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2676,13 +2676,14 @@ void Application::displaySide(Camera& whichCamera) { if (_mouseVoxel.s != 0) { glDisable(GL_LIGHTING); glPushMatrix(); + glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE); + renderMouseVoxelGrid(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); if (_addVoxelMode->isChecked()) { // use a contrasting color so that we can see what we're doing glColor3ub(_mouseVoxel.red + 128, _mouseVoxel.green + 128, _mouseVoxel.blue + 128); } else { glColor3ub(_mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue); } - glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE); glTranslatef(_mouseVoxel.x + _mouseVoxel.s*0.5f, _mouseVoxel.y + _mouseVoxel.s*0.5f, _mouseVoxel.z + _mouseVoxel.s*0.5f); diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 0f2c3a8955..d2f9e56462 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -365,7 +365,33 @@ void renderGroundPlaneGrid(float size, float impact) { glEnd(); } +void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS) { + glm::vec3 origin = glm::vec3(mouseVoxelX, mouseVoxelY, mouseVoxelZ); + glLineWidth(3.0); + + const int HALF_GRID_DIMENSIONS = 4; + glBegin(GL_LINES); + + glm::vec3 xColor(0.0, 0.6, 0.0); + glColor3fv(&xColor.x); + + glVertex3f(origin.x + HALF_GRID_DIMENSIONS * mouseVoxelS, 0, origin.z); + glVertex3f(origin.x - HALF_GRID_DIMENSIONS * mouseVoxelS, 0, origin.z); + + glm::vec3 zColor(0.0, 0.0, 0.6); + glColor3fv(&zColor.x); + + glVertex3f(origin.x, 0, origin.z + HALF_GRID_DIMENSIONS * mouseVoxelS); + glVertex3f(origin.x, 0, origin.z - HALF_GRID_DIMENSIONS * mouseVoxelS); + + glm::vec3 yColor(0.6, 0.0, 0.0); + glColor3fv(&yColor.x); + + glVertex3f(origin.x, 0, origin.z); + glVertex3f(origin.x, origin.y, origin.z); + glEnd(); +} void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, float darkness) { diff --git a/interface/src/Util.h b/interface/src/Util.h index fe59637a42..67ffebf4b3 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -59,8 +59,9 @@ double diffclock(timeval *clock1,timeval *clock2); void renderGroundPlaneGrid(float size, float impact); -void renderCollisionOverlay(int width, int height, float magnitude); +void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS); +void renderCollisionOverlay(int width, int height, float magnitude); void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, float darkness);