diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 88b92e1d45..b770e3ae7d 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"); @@ -2287,6 +2292,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 @@ -3054,6 +3109,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 dfb38d5dd5..0e789c4041 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(); @@ -216,6 +217,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); @@ -294,6 +296,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 b67a32887c..efd8c714ab 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -497,10 +497,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; } } @@ -627,9 +630,12 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter, float gyroCamer _velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime); } } - updateCollisionWithEnvironment(deltaTime); - updateCollisionWithVoxels(deltaTime); - updateAvatarCollisions(deltaTime); + + if (_isCollisionsOn) { + updateCollisionWithEnvironment(deltaTime); + updateCollisionWithVoxels(deltaTime); + updateAvatarCollisions(deltaTime); + } } // update body balls @@ -637,7 +643,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter, float gyroCamer // 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 fc475a5bd2..9b1029ce18 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 @@ -140,6 +140,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;} @@ -261,6 +262,7 @@ private: glm::vec3 _lastCollisionPosition; bool _speedBrakes; bool _isThrustOn; + bool _isCollisionsOn; Avatar* _leadingAvatar; float _stringLength; diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 4043f1e42f..43b7bfc2e3 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -54,8 +54,8 @@ void Hand::reset() { void Hand::simulate(float deltaTime, bool isMine) { if (_isRaveGloveActive) { - if (_raveGloveEffectsModeChanged) { - setRaveGloveMode(_raveGloveEffectsMode); + if (_raveGloveEffectsModeChanged && _raveGloveInitialized) { + 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,14 @@ 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; - + if (!_raveGloveInitialized) { + return; + } + + 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/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 08d9856634..8f1d511b02 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..6d5d0a6528 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(uint16_t)); + 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(uint16_t)); + 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/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 644a0764b7..2f6e8aa560 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,9 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) { } setRaveGloveActive((gloveFlags & GLOVE_FLAG_RAVE) != 0); -// This is disabled for crash tracing. -// setRaveGloveMode(effectsMode); + if (numHands > 0) { + setRaveGloveMode(effectsMode); + } // One byte for error checking safety. unsigned char requiredLength = (unsigned char)(sourceBuffer - startPosition); @@ -171,6 +173,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&); 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;