From 16aae5993ab64c430e6fdd9763b55d5472da2df8 Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Tue, 6 Aug 2013 07:33:18 -0700 Subject: [PATCH 1/6] Rave glove fixes: removed double-stored glove mode members Uncommented glove mode switch, which now calls a non-crashing method. Fixed overlapping method names for very different methods (setRaveGloveMode becomes activateNewRaveGloveMode). --- interface/src/avatar/Hand.cpp | 10 +++++----- interface/src/avatar/Hand.h | 4 +--- libraries/avatars/src/HandData.cpp | 13 ++++++++++--- libraries/avatars/src/HandData.h | 7 ++++--- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 4043f1e42f..e445f89472 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -55,7 +55,7 @@ void Hand::simulate(float deltaTime, bool isMine) { if (_isRaveGloveActive) { if (_raveGloveEffectsModeChanged) { - setRaveGloveMode(_raveGloveEffectsMode); + activateNewRaveGloveMode(); _raveGloveEffectsModeChanged = false; } @@ -352,6 +352,7 @@ void Hand::updateRaveGloveParticles(float deltaTime) { } setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_FIRE); + activateNewRaveGloveMode(); _raveGloveParticleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); _raveGloveInitialized = true; } else { @@ -359,11 +360,10 @@ void Hand::updateRaveGloveParticles(float deltaTime) { } } +// The rave glove mode has changed, so activate the effects. +void Hand::activateNewRaveGloveMode() { -void Hand::setRaveGloveMode(int mode) { - - _raveGloveMode = mode; - + int mode = _raveGloveEffectsMode; _raveGloveParticleSystem.killAllParticles(); for ( int f = 0; f< NUM_FINGERS; f ++ ) { diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index 6df97ea106..d2a36b97b1 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -60,8 +60,6 @@ private: float _raveGloveClock; bool _raveGloveInitialized; int _raveGloveEmitter[NUM_FINGERS]; - int _raveGloveEffectsMode; - bool _raveGloveEffectsModeChanged; Avatar* _owningAvatar; float _renderAlpha; @@ -74,7 +72,7 @@ private: void setLeapHands(const std::vector& handPositions, const std::vector& handNormals); - virtual void setRaveGloveMode(int mode); + void activateNewRaveGloveMode(); void renderRaveGloveStage(); void renderLeapHandSpheres(); diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 644a0764b7..e8e623decd 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -20,7 +20,8 @@ HandData::HandData(AvatarData* owningAvatar) : _baseOrientation(0.0f, 0.0f, 0.0f, 1.0f), _owningAvatarData(owningAvatar), _isRaveGloveActive(false), - _raveGloveMode(RAVE_GLOVE_EFFECTS_MODE_THROBBING_COLOR) + _raveGloveEffectsMode(RAVE_GLOVE_EFFECTS_MODE_THROBBING_COLOR), + _raveGloveEffectsModeChanged(false) { // Start with two palms addNewPalm(); @@ -160,8 +161,7 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) { } setRaveGloveActive((gloveFlags & GLOVE_FLAG_RAVE) != 0); -// This is disabled for crash tracing. -// setRaveGloveMode(effectsMode); + setRaveGloveMode(effectsMode); // One byte for error checking safety. unsigned char requiredLength = (unsigned char)(sourceBuffer - startPosition); @@ -171,6 +171,13 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) { return sourceBuffer - startPosition; } +void HandData::setRaveGloveMode(int effectsMode) +{ + if (effectsMode != _raveGloveEffectsMode) + _raveGloveEffectsModeChanged = true; + _raveGloveEffectsMode = effectsMode; +} + void HandData::setFingerTrailLength(unsigned int length) { for (size_t i = 0; i < getNumPalms(); ++i) { PalmData& palm = getPalms()[i]; diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index fd820bccc0..c871c568bb 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -70,9 +70,9 @@ public: int decodeRemoteData(unsigned char* sourceBuffer); void setRaveGloveActive(bool active) { _isRaveGloveActive = active; } - virtual void setRaveGloveMode(int effectsMode) { _raveGloveMode = effectsMode; } + void setRaveGloveMode(int effectsMode); bool isRaveGloveActive() const { return _isRaveGloveActive; } - int getRaveGloveMode() { return _raveGloveMode; } + int getRaveGloveMode() { return _raveGloveEffectsMode; } friend class AvatarData; protected: @@ -81,7 +81,8 @@ protected: AvatarData* _owningAvatarData; std::vector _palms; bool _isRaveGloveActive; - int _raveGloveMode; + int _raveGloveEffectsMode; + bool _raveGloveEffectsModeChanged; private: // privatize copy ctor and assignment operator so copies of this object cannot be made HandData(const HandData&); From fc23eaa8257f2a92fffcd89b26477930f7a0ebc5 Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Tue, 6 Aug 2013 10:28:31 -0700 Subject: [PATCH 2/6] Fixed per github feedback. Also, to prevent a repeat of yesterday's crash trouble, disabled the mode switch, so that those working on the rave mode can enable it locally for testing. --- libraries/avatars/src/HandData.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index e8e623decd..b60b423627 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -161,7 +161,8 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) { } setRaveGloveActive((gloveFlags & GLOVE_FLAG_RAVE) != 0); - setRaveGloveMode(effectsMode); +// Jeffrey: uncomment this to test locally, before unrolling it to the team. +// setRaveGloveMode(effectsMode); // One byte for error checking safety. unsigned char requiredLength = (unsigned char)(sourceBuffer - startPosition); @@ -171,10 +172,10 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) { return sourceBuffer - startPosition; } -void HandData::setRaveGloveMode(int effectsMode) -{ - if (effectsMode != _raveGloveEffectsMode) +void HandData::setRaveGloveMode(int effectsMode) { + if (effectsMode != _raveGloveEffectsMode) { _raveGloveEffectsModeChanged = true; + } _raveGloveEffectsMode = effectsMode; } From 32c155ef71b0ff09b1e9a1cd7827a7b442acde11 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Tue, 6 Aug 2013 10:53:10 -0700 Subject: [PATCH 3/6] Render a string to show who is following who --- interface/src/Application.cpp | 52 ++++++++++++++++++++++++++ interface/src/Application.h | 1 + interface/src/avatar/Avatar.cpp | 3 ++ interface/src/avatar/Avatar.h | 2 +- interface/src/avatar/Head.cpp | 2 +- libraries/avatars/src/AvatarData.cpp | 15 +++++++- libraries/avatars/src/AvatarData.h | 12 ++++-- libraries/shared/src/NodeList.h | 2 +- libraries/shared/src/PacketHeaders.cpp | 2 +- 9 files changed, 83 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 772908abe5..c2f0564cec 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2287,6 +2287,56 @@ void Application::renderLookatIndicator(glm::vec3 pointOfInterest, Camera& which renderCircle(haloOrigin, INDICATOR_RADIUS, IDENTITY_UP, NUM_SEGMENTS); } +void Application::renderFollowIndicator() { + NodeList* nodeList = NodeList::getInstance(); + + glLineWidth(5); + glBegin(GL_LINES); + for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); ++node) { + if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) { + Avatar* avatar = (Avatar *) node->getLinkedData(); + Avatar* leader = NULL; + + if (avatar->getLeaderID() != UNKNOWN_NODE_ID) { + if (avatar->getLeaderID() == NodeList::getInstance()->getOwnerID()) { + leader = &_myAvatar; + } else { + for (NodeList::iterator it = nodeList->begin(); it != nodeList->end(); ++it) { + if(it->getNodeID() == avatar->getLeaderID() + && it->getType() == NODE_TYPE_AGENT) { + leader = (Avatar*) it->getLinkedData(); + } + } + } + + if (leader != NULL) { + glColor3f(1.f, 0.f, 0.f); + glVertex3f(avatar->getPosition().x, + avatar->getPosition().y, + avatar->getPosition().z); + glColor3f(0.f, 1.f, 0.f); + glVertex3f(leader->getPosition().x, + leader->getPosition().y, + leader->getPosition().z); + } + } + } + } + + if (_myAvatar.getLeadingAvatar() != NULL) { + glColor3f(1.f, 0.f, 0.f); + glVertex3f(_myAvatar.getPosition().x, + _myAvatar.getPosition().y, + _myAvatar.getPosition().z); + glColor3f(0.f, 1.f, 0.f); + glVertex3f(_myAvatar.getLeadingAvatar()->getPosition().x, + _myAvatar.getLeadingAvatar()->getPosition().y, + _myAvatar.getLeadingAvatar()->getPosition().z); + } + + glEnd(); +} + void Application::update(float deltaTime) { // Use Transmitter Hand to move hand if connected, else use mouse @@ -3060,6 +3110,8 @@ void Application::displaySide(Camera& whichCamera) { // brad's frustum for debugging if (_frustumOn->isChecked()) renderViewFrustum(_viewFrustum); + + renderFollowIndicator(); } void Application::displayOverlay() { diff --git a/interface/src/Application.h b/interface/src/Application.h index cb851c1dfc..df14a4eec0 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -216,6 +216,7 @@ private: bool isLookingAtMyAvatar(Avatar* avatar); void renderLookatIndicator(glm::vec3 pointOfInterest, Camera& whichCamera); + void renderFollowIndicator(); void updateAvatar(float deltaTime); void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 26192ffe5a..4ae49ce5ef 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -493,10 +493,13 @@ void Avatar::follow(Avatar* leadingAvatar) { _leadingAvatar = leadingAvatar; if (_leadingAvatar != NULL) { + _leaderID = leadingAvatar->getOwningNode()->getNodeID(); _stringLength = glm::length(_position - _leadingAvatar->getPosition()) / _scale; if (_stringLength > MAX_STRING_LENGTH) { _stringLength = MAX_STRING_LENGTH; } + } else { + _leaderID = UNKNOWN_NODE_ID; } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index b490429ec9..21f413a693 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -27,7 +27,7 @@ #include "world.h" -static const float MAX_SCALE = 5.f; +static const float MAX_SCALE = 10.f; static const float MIN_SCALE = .5f; static const float SCALING_RATIO = .05f; static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1 diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index b88802b7f1..1188e8cb08 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -338,7 +338,7 @@ void Head::setScale (float scale) { } void Head::createMohawk() { - uint16_t nodeId = 0; + uint16_t nodeId = UNKNOWN_NODE_ID; if (_owningAvatar->getOwningNode()) { nodeId = _owningAvatar->getOwningNode()->getNodeID(); } else { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 1dd6a0787b..60307e3172 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -41,7 +41,8 @@ AvatarData::AvatarData(Node* owningNode) : _wantLowResMoving(false), _wantOcclusionCulling(true), _headData(NULL), - _handData(NULL) + _handData(NULL), + _leaderID(UNKNOWN_NODE_ID) { } @@ -91,8 +92,14 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); + + // Body scale destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _newScale); + // Follow mode info + memcpy(destinationBuffer, &_leaderID, sizeof(_leaderID)); + destinationBuffer += sizeof(uint16_t); + // Head rotation (NOTE: This needs to become a quaternion to save two bytes) destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_yaw); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_pitch); @@ -188,8 +195,14 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyYaw); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyPitch); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyRoll); + + // Body scale sourceBuffer += unpackFloatRatioFromTwoByte( sourceBuffer, _newScale); + // Follow mode info + memcpy(&_leaderID, sourceBuffer, sizeof(_leaderID)); + sourceBuffer += sizeof(uint16_t); + // Head rotation (NOTE: This needs to become a quaternion to save two bytes) float headYaw, headPitch, headRoll; sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index a9e14caaa6..bdcf74904e 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -92,10 +92,11 @@ public: const std::string& chatMessage () const { return _chatMessage; } // related to Voxel Sending strategies - bool getWantColor() const { return _wantColor; } - bool getWantDelta() const { return _wantDelta; } - bool getWantLowResMoving() const { return _wantLowResMoving; } + bool getWantColor() const { return _wantColor; } + bool getWantDelta() const { return _wantDelta; } + bool getWantLowResMoving() const { return _wantLowResMoving; } bool getWantOcclusionCulling() const { return _wantOcclusionCulling; } + uint16_t getLeaderID() const { return _leaderID; } void setWantColor(bool wantColor) { _wantColor = wantColor; } void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; } @@ -118,8 +119,13 @@ protected: float _bodyYaw; float _bodyPitch; float _bodyRoll; + + // Body scale float _newScale; + // Following mode infos + uint16_t _leaderID; + // Hand state (are we grabbing something or not) char _handState; diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 260fddf96f..566cd8ba40 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -66,7 +66,7 @@ public: void setDomainIPToLocalhost(); uint16_t getLastNodeID() const { return _lastNodeID; } - void increaseNodeID() { ++_lastNodeID; } + void increaseNodeID() { (++_lastNodeID == UNKNOWN_NODE_ID) ? ++_lastNodeID : _lastNodeID; } uint16_t getOwnerID() const { return _ownerID; } void setOwnerID(uint16_t ownerID) { _ownerID = ownerID; } diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 99c887614c..d435e1bd1b 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -20,7 +20,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) { return 1; case PACKET_TYPE_HEAD_DATA: - return 3; + return 4; case PACKET_TYPE_AVATAR_FACE_VIDEO: return 1; From 97239968a536b3a51d4944094ce0d858ab18fe9c Mon Sep 17 00:00:00 2001 From: atlante45 Date: Tue, 6 Aug 2013 11:05:00 -0700 Subject: [PATCH 4/6] Corrected wrong argument in sizeof --- libraries/avatars/src/AvatarData.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 60307e3172..6d5d0a6528 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -97,7 +97,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _newScale); // Follow mode info - memcpy(destinationBuffer, &_leaderID, sizeof(_leaderID)); + memcpy(destinationBuffer, &_leaderID, sizeof(uint16_t)); destinationBuffer += sizeof(uint16_t); // Head rotation (NOTE: This needs to become a quaternion to save two bytes) @@ -200,7 +200,7 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += unpackFloatRatioFromTwoByte( sourceBuffer, _newScale); // Follow mode info - memcpy(&_leaderID, sourceBuffer, sizeof(_leaderID)); + memcpy(&_leaderID, sourceBuffer, sizeof(uint16_t)); sourceBuffer += sizeof(uint16_t); // Head rotation (NOTE: This needs to become a quaternion to save two bytes) From ddf1b06bf9bc9f4c976bed39a385a207a085292c Mon Sep 17 00:00:00 2001 From: atlante45 Date: Tue, 6 Aug 2013 11:33:59 -0700 Subject: [PATCH 5/6] Add option to turn collisions on and off --- interface/src/Application.cpp | 5 +++++ interface/src/Application.h | 2 ++ interface/src/avatar/Avatar.cpp | 11 +++++++---- interface/src/avatar/Avatar.h | 2 ++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 772908abe5..2ec249677c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1944,6 +1944,7 @@ void Application::initMenu() { (_fullScreenMode = optionsMenu->addAction("Fullscreen", this, SLOT(setFullscreen(bool)), Qt::Key_F))->setCheckable(true); optionsMenu->addAction("Webcam", &_webcam, SLOT(setEnabled(bool)))->setCheckable(true); optionsMenu->addAction("Toggle Skeleton Tracking", &_webcam, SLOT(setSkeletonTrackingOn(bool)))->setCheckable(true); + (_wantCollisionsOn = optionsMenu->addAction("Turn collisions On", this, SLOT(toggleWantCollisionsOn())))->setCheckable(true); optionsMenu->addAction("Cycle Webcam Send Mode", _webcam.getGrabber(), SLOT(cycleVideoSendMode())); optionsMenu->addAction("Go Home", this, SLOT(goHome()), Qt::CTRL | Qt::Key_G); @@ -2137,6 +2138,10 @@ void Application::toggleMixedSong() { } } +void Application::toggleWantCollisionsOn() { + _myAvatar.setWantCollisionsOn(_wantCollisionsOn->isChecked()); +} + void Application::resetSongMixMenuItem() { if (_audio.getSongFileBytes() == 0) { _rawAudioMicrophoneMix->setText("Mix RAW Song"); diff --git a/interface/src/Application.h b/interface/src/Application.h index cb851c1dfc..c946e100b5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -179,6 +179,7 @@ private slots: void setListenModePoint(); void setListenModeSingleSource(); void toggleMixedSong(); + void toggleWantCollisionsOn(); void renderCoverageMap(); @@ -294,6 +295,7 @@ private: QAction* _rawAudioMicrophoneMix; // Mixing of a RAW audio file with microphone stream for rave gloves QAction* _noise; QAction* _occlusionCulling; + QAction* _wantCollisionsOn; QAction* _renderCoverageMapV2; QAction* _renderCoverageMap; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 26192ffe5a..e54f14e8f3 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -623,9 +623,12 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime); } } - updateCollisionWithEnvironment(deltaTime); - updateCollisionWithVoxels(deltaTime); - updateAvatarCollisions(deltaTime); + + if (_isCollisionsOn) { + updateCollisionWithEnvironment(deltaTime); + updateCollisionWithVoxels(deltaTime); + updateAvatarCollisions(deltaTime); + } } // update body balls @@ -633,7 +636,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // test for avatar collision response with the big sphere - if (usingBigSphereCollisionTest) { + if (usingBigSphereCollisionTest && _isCollisionsOn) { updateCollisionWithSphere(_TEST_bigSpherePosition, _TEST_bigSphereRadius, deltaTime); } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index b490429ec9..acb6cac098 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -142,6 +142,7 @@ public: void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction); void setOrientation (const glm::quat& orientation); void setNewScale (const float scale); + void setWantCollisionsOn (bool wantCollisionsOn ) { _isCollisionsOn = wantCollisionsOn; } //getters bool isInitialized () const { return _initialized;} @@ -263,6 +264,7 @@ private: glm::vec3 _lastCollisionPosition; bool _speedBrakes; bool _isThrustOn; + bool _isCollisionsOn; Avatar* _leadingAvatar; float _stringLength; From ab31c3f82d1e5dece3f9a66f6ad51244cf04fffb Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Tue, 6 Aug 2013 11:59:58 -0700 Subject: [PATCH 6/6] Rave glove: Fix initialization issues and activate mode switch. Note that this change will have no effect until the Avatar Mixer gets it, because the mixer will continue to send "glove mode 0" until it receives this update. --- interface/src/avatar/Hand.cpp | 6 +++++- libraries/avatars/src/HandData.cpp | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index e445f89472..43b7bfc2e3 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -54,7 +54,7 @@ void Hand::reset() { void Hand::simulate(float deltaTime, bool isMine) { if (_isRaveGloveActive) { - if (_raveGloveEffectsModeChanged) { + if (_raveGloveEffectsModeChanged && _raveGloveInitialized) { activateNewRaveGloveMode(); _raveGloveEffectsModeChanged = false; } @@ -363,6 +363,10 @@ void Hand::updateRaveGloveParticles(float deltaTime) { // The rave glove mode has changed, so activate the effects. void Hand::activateNewRaveGloveMode() { + if (!_raveGloveInitialized) { + return; + } + int mode = _raveGloveEffectsMode; _raveGloveParticleSystem.killAllParticles(); diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index b60b423627..2f6e8aa560 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -161,8 +161,9 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) { } setRaveGloveActive((gloveFlags & GLOVE_FLAG_RAVE) != 0); -// Jeffrey: uncomment this to test locally, before unrolling it to the team. -// setRaveGloveMode(effectsMode); + if (numHands > 0) { + setRaveGloveMode(effectsMode); + } // One byte for error checking safety. unsigned char requiredLength = (unsigned char)(sourceBuffer - startPosition);