From f21d2a477db893186f9e876e16a95380d189bfe6 Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Wed, 17 Jul 2013 08:29:50 -0700 Subject: [PATCH 1/4] Rave Glove Demo: Restructuring palm and finger data structures --- interface/src/Hand.cpp | 17 ++++--------- interface/src/Hand.h | 7 ++--- libraries/avatars/src/HandData.cpp | 24 ++++++++++++++++- libraries/avatars/src/HandData.h | 41 ++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 18 deletions(-) diff --git a/interface/src/Hand.cpp b/interface/src/Hand.cpp index d0ff0abd5a..80af40fbbb 100755 --- a/interface/src/Hand.cpp +++ b/interface/src/Hand.cpp @@ -21,9 +21,7 @@ Hand::Hand(Avatar* owningAvatar) : _owningAvatar(owningAvatar), _renderAlpha(1.0), _lookingInMirror(false), - _ballColor(0.0, 0.0, 0.4), - _position(0.0, 0.4, 0.0), - _orientation(0.0, 0.0, 0.0, 1.0) + _ballColor(0.0, 0.0, 0.4) { } @@ -42,23 +40,18 @@ void Hand::reset() { void Hand::simulate(float deltaTime, bool isMine) { } -glm::vec3 Hand::leapPositionToWorldPosition(const glm::vec3& leapPosition) { - float unitScale = 0.001; // convert mm to meters - return _position + _orientation * (leapPosition * unitScale); -} - 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 handOffset(0.2, -0.2, -0.3); // place the hand in front of the face where we can see it Head& head = _owningAvatar->getHead(); - _position = head.getPosition() + head.getOrientation() * offset; - _orientation = head.getOrientation(); + _basePosition = head.getPosition() + head.getOrientation() * handOffset; + _baseOrientation = head.getOrientation(); int numLeapBalls = _fingerTips.size(); _leapBalls.resize(numLeapBalls); for (int i = 0; i < _fingerTips.size(); ++i) { - _leapBalls[i].rotation = _orientation; + _leapBalls[i].rotation = _baseOrientation; _leapBalls[i].position = leapPositionToWorldPosition(_fingerTips[i]); _leapBalls[i].radius = 0.01; _leapBalls[i].touchForce = 0.0; diff --git a/interface/src/Hand.h b/interface/src/Hand.h index e1b0dc9ff0..eb49703468 100755 --- a/interface/src/Hand.h +++ b/interface/src/Hand.h @@ -52,9 +52,6 @@ public: const glm::vec3& getLeapBallPosition (int ball) const { return _leapBalls[ball].position;} bool isRaveGloveActive () const { return _isRaveGloveActive; } - // position conversion - glm::vec3 leapPositionToWorldPosition(const glm::vec3& leapPosition); - private: // disallow copies of the Hand, copy of owning Avatar is disallowed too Hand(const Hand&); @@ -65,8 +62,8 @@ private: bool _lookingInMirror; bool _isRaveGloveActive; glm::vec3 _ballColor; - glm::vec3 _position; - glm::quat _orientation; +// glm::vec3 _position; +// glm::quat _orientation; std::vector _leapBalls; // private methods diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 986d030a3c..1eba9d2e4d 100755 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -9,7 +9,29 @@ #include "HandData.h" HandData::HandData(AvatarData* owningAvatar) : + _basePosition(0.0f, 0.0f, 0.0f), + _baseOrientation(0.0f, 0.0f, 0.0f, 1.0f), _owningAvatarData(owningAvatar) { - + for (int i = 0; i < 2; ++i) + _palms.push_back(PalmData(this)); +} + +PalmData::PalmData(HandData* owningHandData) : +_rawPosition(0, 0, 0), +_rawNormal(0, 1, 0), +_isActive(false), +_owningHandData(owningHandData) +{ + for (int i = 0; i < 5; ++i) + _fingers.push_back(FingerData(this, owningHandData)); +} + +FingerData::FingerData(PalmData* owningPalmData, HandData* owningHandData) : +_tipRawPosition(0, 0, 0), +_rootRawPosition(0, 0, 0), +_isActive(false), +_owningPalmData(owningPalmData), +_owningHandData(owningHandData) +{ } diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index 50a4843153..d32498a5a1 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -13,8 +13,11 @@ #include #include +#include class AvatarData; +class FingerData; +class PalmData; class HandData { public: @@ -31,17 +34,55 @@ public: void setHandPositions(const std::vector& handPositons) { _handPositions = handPositons; } void setHandNormals(const std::vector& handNormals) { _handNormals = handNormals; } + // position conversion + glm::vec3 leapPositionToWorldPosition(const glm::vec3& leapPosition) { + float unitScale = 0.001; // convert mm to meters + return _basePosition + _baseOrientation * (leapPosition * unitScale); + } + glm::vec3 leapDirectionToWorldDirection(const glm::vec3& leapDirection) { + return glm::normalize(_baseOrientation * leapDirection); + } + friend class AvatarData; protected: std::vector _fingerTips; std::vector _fingerRoots; std::vector _handPositions; std::vector _handNormals; + glm::vec3 _basePosition; // Hands are placed relative to this + glm::quat _baseOrientation; // Hands are placed relative to this AvatarData* _owningAvatarData; + std::vector _palms; private: // privatize copy ctor and assignment operator so copies of this object cannot be made HandData(const HandData&); HandData& operator= (const HandData&); }; +class FingerData { +public: + FingerData(PalmData* owningPalmData, HandData* owningHandData); +private: + glm::vec3 _tipRawPosition; + glm::vec3 _rootRawPosition; + bool _isActive; // This has current valid data + PalmData* _owningPalmData; + HandData* _owningHandData; +}; + +class PalmData { +public: + PalmData(HandData* owningHandData); + glm::vec3 getPosition() const { return _owningHandData->leapPositionToWorldPosition(_rawPosition); } + glm::vec3 getNormal() const { return _owningHandData->leapDirectionToWorldDirection(_rawNormal); } + const glm::vec3& getRawPosition() const { return _rawPosition; } + const glm::vec3& getRawNormal() const { return _rawNormal; } +private: + std::vector _fingers; + glm::vec3 _rawPosition; + glm::vec3 _rawNormal; + bool _isActive; // This has current valid data + HandData* _owningHandData; +}; + #endif /* defined(__hifi__HandData__) */ From 46c5383d10a8acf4757a26157560f1c5f8051fca Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Wed, 17 Jul 2013 12:54:44 -0700 Subject: [PATCH 2/4] minor cleanup --- interface/src/Hand.h | 4 ---- libraries/avatars/src/HandData.cpp | 2 +- libraries/avatars/src/HandData.h | 2 ++ 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/Hand.h b/interface/src/Hand.h index 44c7345100..fb6b863458 100755 --- a/interface/src/Hand.h +++ b/interface/src/Hand.h @@ -19,8 +19,6 @@ #include #include -const int NUM_FINGERS_PER_HAND = 5; - class Avatar; class ProgramObject; @@ -68,8 +66,6 @@ private: bool _lookingInMirror; bool _isRaveGloveActive; glm::vec3 _ballColor; -// glm::vec3 _position; -// glm::quat _orientation; std::vector _leapBalls; bool _particleSystemInitialized; diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 1eba9d2e4d..a4e8e9560c 100755 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -23,7 +23,7 @@ _rawNormal(0, 1, 0), _isActive(false), _owningHandData(owningHandData) { - for (int i = 0; i < 5; ++i) + for (int i = 0; i < NUM_FINGERS_PER_HAND; ++i) _fingers.push_back(FingerData(this, owningHandData)); } diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index d32498a5a1..ef322261c5 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -19,6 +19,8 @@ class AvatarData; class FingerData; class PalmData; +const int NUM_FINGERS_PER_HAND = 5; + class HandData { public: HandData(AvatarData* owningAvatar); From 8ebf5fbd6b938f4294763b2b945274e8bdcf72cf Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Wed, 17 Jul 2013 14:54:18 -0700 Subject: [PATCH 3/4] Rave & Leap: cleanup and move over to new hand/finger structures --- interface/src/Avatar.cpp | 9 +- interface/src/Hand.cpp | 146 ++++++++++++++++--------- libraries/avatars/src/AvatarData.cpp | 63 ++++------- libraries/avatars/src/HandData.cpp | 43 ++++++++ libraries/avatars/src/HandData.h | 43 +++++--- libraries/shared/src/PacketHeaders.cpp | 2 +- 6 files changed, 196 insertions(+), 110 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index e92394af22..26cd241b5c 100755 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -821,10 +821,13 @@ void Avatar::updateHandMovementAndTouching(float deltaTime, bool enableHandMovem } // If there's a leap-interaction hand visible, use that as the endpoint - if (getHand().getHandPositions().size() > 0) { - _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = - getHand().leapPositionToWorldPosition(getHand().getHandPositions()[0]); + for (size_t i = 0; i < getHand().getPalms().size(); ++i) { + PalmData& palm = getHand().getPalms()[i]; + if (palm.isActive()) { + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = palm.getPosition(); + } } + }//if (_isMine) //constrain right arm length and re-adjust elbow position as it bends diff --git a/interface/src/Hand.cpp b/interface/src/Hand.cpp index e2b2b66a46..5693ce7e2e 100755 --- a/interface/src/Hand.cpp +++ b/interface/src/Hand.cpp @@ -55,15 +55,23 @@ void Hand::calculateGeometry() { _basePosition = head.getPosition() + head.getOrientation() * offset; _baseOrientation = head.getOrientation(); - int numLeapBalls = _fingerTips.size(); - _leapBalls.resize(numLeapBalls); - - for (int i = 0; i < _fingerTips.size(); ++i) { - _leapBalls[i].rotation = _baseOrientation; - _leapBalls[i].position = leapPositionToWorldPosition(_fingerTips[i]); - _leapBalls[i].radius = 0.01; - _leapBalls[i].touchForce = 0.0; - _leapBalls[i].isCollidable = true; + _leapBalls.clear(); + 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()) { + _leapBalls.resize(_leapBalls.size() + 1); + HandBall& ball = _leapBalls.back(); + ball.rotation = _baseOrientation; + ball.position = finger.getTipPosition(); + ball.radius = 0.01; + ball.touchForce = 0.0; + ball.isCollidable = true; + } + } + } } } @@ -134,21 +142,28 @@ void Hand::renderHandSpheres() { } // Draw the finger root cones - if (_fingerTips.size() == _fingerRoots.size()) { - for (size_t i = 0; i < _fingerTips.size(); ++i) { - glColor4f(_ballColor.r, _ballColor.g, _ballColor.b, 0.5); - glm::vec3 tip = leapPositionToWorldPosition(_fingerTips[i]); - glm::vec3 root = leapPositionToWorldPosition(_fingerRoots[i]); - Avatar::renderJointConnectingCone(root, tip, 0.001, 0.003); + 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()) { + glColor4f(_ballColor.r, _ballColor.g, _ballColor.b, 0.5); + glm::vec3 tip = finger.getTipPosition(); + glm::vec3 root = finger.getRootPosition(); + Avatar::renderJointConnectingCone(root, tip, 0.001, 0.003); + } + } } } // Draw the palms - if (_handPositions.size() == _handNormals.size()) { - for (size_t i = 0; i < _handPositions.size(); ++i) { + for (size_t i = 0; i < getNumPalms(); ++i) { + PalmData& palm = getPalms()[i]; + if (palm.isActive()) { glColor4f(_ballColor.r, _ballColor.g, _ballColor.b, 0.25); - glm::vec3 tip = leapPositionToWorldPosition(_handPositions[i]); - glm::vec3 root = leapPositionToWorldPosition(_handPositions[i] + (_handNormals[i] * 2.0f)); + glm::vec3 tip = palm.getPosition(); + glm::vec3 root = palm.getPosition() + palm.getNormal() * 0.002f; Avatar::renderJointConnectingCone(root, tip, 0.05, 0.03); } } @@ -158,14 +173,39 @@ void Hand::renderHandSpheres() { void Hand::setLeapFingers(const std::vector& fingerTips, const std::vector& fingerRoots) { - _fingerTips = fingerTips; - _fingerRoots = fingerRoots; + // TODO: add id-checking here to increase finger stability + + size_t fingerIndex = 0; + for (size_t i = 0; i < getNumPalms(); ++i) { + PalmData& palm = getPalms()[i]; + for (size_t f = 0; f < palm.getNumFingers(); ++f) { + FingerData& finger = palm.getFingers()[f]; + if (fingerIndex < fingerTips.size()) { + finger.setActive(true); + finger.setRawTipPosition(fingerTips[fingerIndex]); + finger.setRawRootPosition(fingerRoots[fingerIndex]); + fingerIndex++; + } + else { + finger.setActive(false); + } + } + } } void Hand::setLeapHands(const std::vector& handPositions, const std::vector& handNormals) { - _handPositions = handPositions; - _handNormals = handNormals; + for (size_t i = 0; i < getNumPalms(); ++i) { + PalmData& palm = getPalms()[i]; + if (i < handPositions.size()) { + palm.setActive(true); + palm.setRawPosition(handPositions[i]); + palm.setRawNormal(handNormals[i]); + } + else { + palm.setActive(false); + } + } } @@ -182,33 +222,41 @@ void Hand::updateFingerParticles(float deltaTime) { static float t = 0.0f; t += deltaTime; - - for ( int f = 0; f< _fingerTips.size(); f ++ ) { - - if (_fingerParticleEmitter[f] != -1) { - - glm::vec3 particleEmitterPosition = leapPositionToWorldPosition(_fingerTips[f]); - - // this aspect is still being designed.... - - glm::vec3 tilt = glm::vec3 - ( - 30.0f * sinf( t * 0.55f ), - 0.0f, - 30.0f * cosf( t * 0.75f ) - ); - - glm::quat particleEmitterRotation = glm::quat(glm::radians(tilt)); - _particleSystem.setEmitterPosition(_fingerParticleEmitter[0], particleEmitterPosition); - _particleSystem.setEmitterRotation(_fingerParticleEmitter[0], particleEmitterRotation); - - float radius = 0.005f; - glm::vec4 color(1.0f, 0.6f, 0.0f, 0.5f); - glm::vec3 velocity(0.0f, 0.005f, 0.0f); - float lifespan = 0.3f; - _particleSystem.emitParticlesNow(_fingerParticleEmitter[0], 1, radius, color, velocity, lifespan); - } + 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 particleEmitterPosition = finger.getTipPosition(); + + // this aspect is still being designed.... + + glm::vec3 tilt = glm::vec3 + ( + 30.0f * sinf( t * 0.55f ), + 0.0f, + 30.0f * cosf( t * 0.75f ) + ); + + glm::quat particleEmitterRotation = glm::quat(glm::radians(tilt)); + + _particleSystem.setEmitterPosition(_fingerParticleEmitter[0], particleEmitterPosition); + _particleSystem.setEmitterRotation(_fingerParticleEmitter[0], particleEmitterRotation); + + float radius = 0.005f; + glm::vec4 color(1.0f, 0.6f, 0.0f, 0.5f); + glm::vec3 velocity(0.0f, 0.005f, 0.0f); + float lifespan = 0.3f; + _particleSystem.emitParticlesNow(_fingerParticleEmitter[0], 1, radius, color, velocity, lifespan); + } + } + } + } } _particleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f)); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 86895410dd..fa0bffded0 100755 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -127,36 +127,22 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { *destinationBuffer++ = bitItems; // leap hand data - // In order to make the hand data version-robust, hand data packing is just a series of vec3's, - // with conventions. If a client doesn't know the conventions, they can just get the vec3's - // and render them as balls, or ignore them, without crashing or disrupting anyone. - // Current convention: - // Zero or more fingetTip positions, followed by the same number of fingerRoot positions - - const std::vector& fingerTips = _handData->getFingerTips(); - const std::vector& fingerRoots = _handData->getFingerRoots(); - size_t numFingerVectors = fingerTips.size() + fingerRoots.size(); - if (numFingerVectors > 255) - numFingerVectors = 0; // safety. We shouldn't ever get over 255, so consider that invalid. + std::vector fingerVectors; + _handData->encodeRemoteData(fingerVectors); ///////////////////////////////// // Temporarily disable Leap finger sending, as it's causing a crash whenever someone's got a Leap connected - numFingerVectors = 0; + fingerVectors.clear(); ///////////////////////////////// - - *destinationBuffer++ = (unsigned char)numFingerVectors; - - if (numFingerVectors > 0) { - for (size_t i = 0; i < fingerTips.size(); ++i) { - destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerTips[i].x, 4); - destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerTips[i].y, 4); - destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerTips[i].z, 4); - } - for (size_t i = 0; i < fingerRoots.size(); ++i) { - destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerRoots[i].x, 4); - destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerRoots[i].y, 4); - destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerRoots[i].z, 4); - } + if (fingerVectors.size() > 255) + fingerVectors.clear(); // safety. We shouldn't ever get over 255, so consider that invalid. + + *destinationBuffer++ = (unsigned char)fingerVectors.size(); + + for (size_t i = 0; i < fingerVectors.size(); ++i) { + destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerVectors[i].x, 4); + destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerVectors[i].y, 4); + destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerVectors[i].z, 4); } // skeleton joints @@ -263,25 +249,16 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { // leap hand data if (sourceBuffer - startPosition < numBytes) // safety check { - std::vector fingerTips; - std::vector fingerRoots; unsigned int numFingerVectors = *sourceBuffer++; - unsigned int numFingerTips = numFingerVectors / 2; - unsigned int numFingerRoots = numFingerVectors - numFingerTips; - fingerTips.resize(numFingerTips); - fingerRoots.resize(numFingerRoots); - for (size_t i = 0; i < numFingerTips; ++i) { - sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerTips[i].x), 4); - sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerTips[i].y), 4); - sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerTips[i].z), 4); + if (numFingerVectors > 0) { + std::vector fingerVectors(numFingerVectors); + for (size_t i = 0; i < numFingerVectors; ++i) { + sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerVectors[i].x), 4); + sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerVectors[i].y), 4); + sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerVectors[i].z), 4); + } + _handData->decodeRemoteData(fingerVectors); } - for (size_t i = 0; i < numFingerRoots; ++i) { - sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerRoots[i].x), 4); - sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerRoots[i].y), 4); - sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerRoots[i].z), 4); - } - _handData->setFingerTips(fingerTips); - _handData->setFingerRoots(fingerRoots); } // skeleton joints diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index a4e8e9560c..f119472fa1 100755 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -35,3 +35,46 @@ _owningPalmData(owningPalmData), _owningHandData(owningHandData) { } + +void HandData::encodeRemoteData(std::vector& fingerVectors) { + fingerVectors.clear(); + for (size_t i = 0; i < getNumPalms(); ++i) { + PalmData& palm = getPalms()[i]; + fingerVectors.push_back(palm.getRawPosition()); + fingerVectors.push_back(palm.getRawNormal()); + for (size_t f = 0; f < palm.getNumFingers(); ++f) { + FingerData& finger = palm.getFingers()[f]; + if (finger.isActive()) { + fingerVectors.push_back(finger.getTipRawPosition()); + fingerVectors.push_back(finger.getRootRawPosition()); + } + else { + fingerVectors.push_back(glm::vec3(0,0,0)); + fingerVectors.push_back(glm::vec3(0,0,0)); + } + } + } +} + +void HandData::decodeRemoteData(const std::vector& fingerVectors) { + size_t vectorIndex = 0; + for (size_t i = 0; i < getNumPalms(); ++i) { + PalmData& palm = getPalms()[i]; + // If a palm is active, there will be + // 1 vector for its position + // 1 vector for normal + // 10 vectors for fingers (5 tip/root pairs) + bool palmActive = fingerVectors.size() >= i * 12; + palm.setActive(palmActive); + if (palmActive) { + palm.setRawPosition(fingerVectors[vectorIndex++]); + palm.setRawNormal(fingerVectors[vectorIndex++]); + for (size_t f = 0; f < NUM_FINGERS_PER_HAND; ++f) { + FingerData& finger = palm.getFingers()[i]; + finger.setRawTipPosition(fingerVectors[vectorIndex++]); + finger.setRawRootPosition(fingerVectors[vectorIndex++]); + } + } + } +} + diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index ef322261c5..ac5c509f55 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -27,14 +27,6 @@ public: // These methods return the positions in Leap-relative space. // To convert to world coordinates, use Hand::leapPositionToWorldPosition. - const std::vector& getFingerTips() const { return _fingerTips; } - const std::vector& getFingerRoots() const { return _fingerRoots; } - const std::vector& getHandPositions() const { return _handPositions; } - const std::vector& getHandNormals() const { return _handNormals; } - void setFingerTips(const std::vector& fingerTips) { _fingerTips = fingerTips; } - void setFingerRoots(const std::vector& fingerRoots) { _fingerRoots = fingerRoots; } - void setHandPositions(const std::vector& handPositons) { _handPositions = handPositons; } - void setHandNormals(const std::vector& handNormals) { _handNormals = handNormals; } // position conversion glm::vec3 leapPositionToWorldPosition(const glm::vec3& leapPosition) { @@ -45,12 +37,15 @@ public: return glm::normalize(_baseOrientation * leapDirection); } + std::vector& getPalms() { return _palms; } + size_t getNumPalms() { return _palms.size(); } + + // Use these for sending and receiving hand data + void encodeRemoteData(std::vector& fingerVectors); + void decodeRemoteData(const std::vector& fingerVectors); + friend class AvatarData; protected: - std::vector _fingerTips; - std::vector _fingerRoots; - std::vector _handPositions; - std::vector _handNormals; glm::vec3 _basePosition; // Hands are placed relative to this glm::quat _baseOrientation; // Hands are placed relative to this AvatarData* _owningAvatarData; @@ -64,6 +59,17 @@ private: class FingerData { public: FingerData(PalmData* owningPalmData, HandData* owningHandData); + + glm::vec3 getTipPosition() const { return _owningHandData->leapPositionToWorldPosition(_tipRawPosition); } + glm::vec3 getRootPosition() const { return _owningHandData->leapPositionToWorldPosition(_rootRawPosition); } + const glm::vec3& getTipRawPosition() const { return _tipRawPosition; } + const glm::vec3& getRootRawPosition() const { return _rootRawPosition; } + bool isActive() const { return _isActive; } + + void setActive(bool active) { _isActive = active; } + void setRawTipPosition(const glm::vec3& pos) { _tipRawPosition = pos; } + void setRawRootPosition(const glm::vec3& pos) { _rootRawPosition = pos; } + private: glm::vec3 _tipRawPosition; glm::vec3 _rootRawPosition; @@ -75,10 +81,19 @@ private: class PalmData { public: PalmData(HandData* owningHandData); - glm::vec3 getPosition() const { return _owningHandData->leapPositionToWorldPosition(_rawPosition); } - glm::vec3 getNormal() const { return _owningHandData->leapDirectionToWorldDirection(_rawNormal); } + glm::vec3 getPosition() const { return _owningHandData->leapPositionToWorldPosition(_rawPosition); } + glm::vec3 getNormal() const { return _owningHandData->leapDirectionToWorldDirection(_rawNormal); } const glm::vec3& getRawPosition() const { return _rawPosition; } const glm::vec3& getRawNormal() const { return _rawNormal; } + bool isActive() const { return _isActive; } + + std::vector& getFingers() { return _fingers; } + size_t getNumFingers() { return _fingers.size(); } + + void setActive(bool active) { _isActive = active; } + void setRawPosition(const glm::vec3& pos) { _rawPosition = pos; } + void setRawNormal(const glm::vec3& normal) { _rawNormal = normal; } + private: std::vector _fingers; glm::vec3 _rawPosition; diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 7b4a0509f3..821a2d0247 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -15,7 +15,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) { switch (type) { case PACKET_TYPE_HEAD_DATA: - return 1; + return 2; break; default: return 0; From aa0cab2180b943974ccaf3e16ff387be48e892dd Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Wed, 17 Jul 2013 16:09:24 -0700 Subject: [PATCH 4/4] Code review issues addressed. --- interface/src/Hand.cpp | 27 ++++++++++++++------------- libraries/avatars/src/AvatarData.cpp | 14 ++++++++------ libraries/avatars/src/HandData.cpp | 6 ++++-- libraries/avatars/src/HandData.h | 2 +- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/interface/src/Hand.cpp b/interface/src/Hand.cpp index 5693ce7e2e..ec123beede 100755 --- a/interface/src/Hand.cpp +++ b/interface/src/Hand.cpp @@ -62,11 +62,12 @@ void Hand::calculateGeometry() { for (size_t f = 0; f < palm.getNumFingers(); ++f) { FingerData& finger = palm.getFingers()[f]; if (finger.isActive()) { + const float standardBallRadius = 0.01f; _leapBalls.resize(_leapBalls.size() + 1); HandBall& ball = _leapBalls.back(); ball.rotation = _baseOrientation; ball.position = finger.getTipPosition(); - ball.radius = 0.01; + ball.radius = standardBallRadius; ball.touchForce = 0.0; ball.isCollidable = true; } @@ -161,9 +162,10 @@ void Hand::renderHandSpheres() { for (size_t i = 0; i < getNumPalms(); ++i) { PalmData& palm = getPalms()[i]; if (palm.isActive()) { + const float palmThickness = 0.002f; glColor4f(_ballColor.r, _ballColor.g, _ballColor.b, 0.25); glm::vec3 tip = palm.getPosition(); - glm::vec3 root = palm.getPosition() + palm.getNormal() * 0.002f; + glm::vec3 root = palm.getPosition() + palm.getNormal() * palmThickness; Avatar::renderJointConnectingCone(root, tip, 0.05, 0.03); } } @@ -235,23 +237,22 @@ void Hand::updateFingerParticles(float deltaTime) { glm::vec3 particleEmitterPosition = finger.getTipPosition(); // this aspect is still being designed.... - - glm::vec3 tilt = glm::vec3 - ( - 30.0f * sinf( t * 0.55f ), - 0.0f, - 30.0f * cosf( t * 0.75f ) - ); + const float tiltMag = 30.0f; + const float tiltXFreq = 0.55f; + const float tiltZFreq = 0.75f; + glm::vec3 tilt = glm::vec3(tiltMag * sinf( t * tiltXFreq ), + 0.0f, + tiltMag * cosf( t * tiltZFreq )); glm::quat particleEmitterRotation = glm::quat(glm::radians(tilt)); _particleSystem.setEmitterPosition(_fingerParticleEmitter[0], particleEmitterPosition); _particleSystem.setEmitterRotation(_fingerParticleEmitter[0], particleEmitterRotation); - float radius = 0.005f; - glm::vec4 color(1.0f, 0.6f, 0.0f, 0.5f); - glm::vec3 velocity(0.0f, 0.005f, 0.0f); - float lifespan = 0.3f; + const float radius = 0.005f; + const glm::vec4 color(1.0f, 0.6f, 0.0f, 0.5f); + const glm::vec3 velocity(0.0f, 0.005f, 0.0f); + const float lifespan = 0.3f; _particleSystem.emitParticlesNow(_fingerParticleEmitter[0], 1, radius, color, velocity, lifespan); } } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index fa0bffded0..01907b92f4 100755 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -18,6 +18,8 @@ using namespace std; +static const float fingerVectorRadix = 4; // bits of precision when converting from float<->fixed + AvatarData::AvatarData(Node* owningNode) : NodeData(owningNode), _handPosition(0,0,0), @@ -140,9 +142,9 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { *destinationBuffer++ = (unsigned char)fingerVectors.size(); for (size_t i = 0; i < fingerVectors.size(); ++i) { - destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerVectors[i].x, 4); - destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerVectors[i].y, 4); - destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerVectors[i].z, 4); + destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerVectors[i].x, fingerVectorRadix); + destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerVectors[i].y, fingerVectorRadix); + destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerVectors[i].z, fingerVectorRadix); } // skeleton joints @@ -253,9 +255,9 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { if (numFingerVectors > 0) { std::vector fingerVectors(numFingerVectors); for (size_t i = 0; i < numFingerVectors; ++i) { - sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerVectors[i].x), 4); - sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerVectors[i].y), 4); - sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerVectors[i].z), 4); + sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerVectors[i].x), fingerVectorRadix); + sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerVectors[i].y), fingerVectorRadix); + sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(fingerVectors[i].z), fingerVectorRadix); } _handData->decodeRemoteData(fingerVectors); } diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index f119472fa1..32e83b352d 100755 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -13,8 +13,9 @@ HandData::HandData(AvatarData* owningAvatar) : _baseOrientation(0.0f, 0.0f, 0.0f, 1.0f), _owningAvatarData(owningAvatar) { - for (int i = 0; i < 2; ++i) + for (int i = 0; i < 2; ++i) { _palms.push_back(PalmData(this)); + } } PalmData::PalmData(HandData* owningHandData) : @@ -23,8 +24,9 @@ _rawNormal(0, 1, 0), _isActive(false), _owningHandData(owningHandData) { - for (int i = 0; i < NUM_FINGERS_PER_HAND; ++i) + for (int i = 0; i < NUM_FINGERS_PER_HAND; ++i) { _fingers.push_back(FingerData(this, owningHandData)); + } } FingerData::FingerData(PalmData* owningPalmData, HandData* owningHandData) : diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index ac5c509f55..65b32ff5c6 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -30,7 +30,7 @@ public: // position conversion glm::vec3 leapPositionToWorldPosition(const glm::vec3& leapPosition) { - float unitScale = 0.001; // convert mm to meters + const float unitScale = 0.001; // convert mm to meters return _basePosition + _baseOrientation * (leapPosition * unitScale); } glm::vec3 leapDirectionToWorldDirection(const glm::vec3& leapDirection) {