From f08e639cb295ca190bdbdb4775f28295b6fb4eaf Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 17 Jan 2014 11:22:50 -0800 Subject: [PATCH 1/6] fixes for avatar paddle-hands, plus some hackery for demo --- interface/src/avatar/Avatar.cpp | 9 ++++++-- interface/src/avatar/Hand.cpp | 3 +++ interface/src/avatar/Hand.h | 2 +- interface/src/devices/SixenseManager.cpp | 9 ++++++++ libraries/avatars/src/HandData.cpp | 3 ++- libraries/avatars/src/HandData.h | 9 ++++++-- .../particles/src/ParticleCollisionSystem.cpp | 22 +++++++++++++++---- libraries/shared/src/CollisionInfo.h | 2 +- libraries/shared/src/GeometryUtil.cpp | 17 +++++++------- libraries/shared/src/GeometryUtil.h | 5 +++-- libraries/shared/src/PacketHeaders.cpp | 2 +- 11 files changed, 60 insertions(+), 23 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 144c9f4c2a..41698834a4 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -334,7 +334,7 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi if (handData) { for (int i = 0; i < 2; i++) { const PalmData* palm = handData->getPalm(i); - if (palm) { + if (palm && palm->hasPaddle()) { // create a disk collision proxy where the hand is glm::vec3 fingerAxis(0.f); for (size_t f = 0; f < palm->getNumFingers(); ++f) { @@ -356,10 +356,12 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi } glm::vec3 diskCenter = handPosition + HAND_PADDLE_OFFSET * fingerAxis; glm::vec3 diskNormal = palm->getNormal(); + float diskThickness = 0.08f; // collide against the disk if (findSphereDiskPenetration(sphereCenter, sphereRadius, - diskCenter, HAND_PADDLE_RADIUS, diskNormal, collision._penetration)) { + diskCenter, HAND_PADDLE_RADIUS, diskThickness, diskNormal, + collision._penetration)) { collision._addedVelocity = palm->getVelocity(); return true; } @@ -367,11 +369,14 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi } } + /* HACK : disable collisions with avatar proper for now -- sometimes interferes with paddle + * TODO: disable regular collisions with hand capsules if (_skeletonModel.findSpherePenetration(sphereCenter, sphereRadius, collision._penetration)) { collision._penetration /= (float)(TREE_SCALE); collision._addedVelocity = getVelocity(); return true; } + */ return false; } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 0b399c4287..6bd25b5c54 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -187,6 +187,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f const float THROWN_VELOCITY_SCALING = 1.5f; _toyBallInHand[handID] = false; + palm.updateCollisionlessPaddleExpiry(); glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; glm::vec3 ballVelocity = ballFromHand ? palm.getRawVelocity() : palm.getTipVelocity(); glm::quat avatarRotation = _owningAvatar->getOrientation(); @@ -562,6 +563,8 @@ void Hand::renderLeapHands(bool isMine) { continue; } glm::vec3 targetPosition = ballFromHand ? palm.getPosition() : palm.getTipPosition(); + const float BALL_FORWARD_OFFSET = 0.08f; // put the ball a bit forward of fingers + targetPosition += BALL_FORWARD_OFFSET * palm.getNormal(); glPushMatrix(); ParticleTree* particles = Application::getInstance()->getParticles()->getTree(); diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index bc671d1926..0552c021f1 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -31,7 +31,7 @@ class Avatar; class ProgramObject; const float HAND_PADDLE_OFFSET = 0.1f; -const float HAND_PADDLE_THICKNESS = 0.05f; +const float HAND_PADDLE_THICKNESS = 0.01f; const float HAND_PADDLE_RADIUS = 0.15f; class Hand : public HandData { diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 24caa33533..12d045dea3 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -98,6 +98,15 @@ void SixenseManager::update(float deltaTime) { // Compute current velocity from position change glm::vec3 rawVelocity = (position - palm->getRawPosition()) / deltaTime / 1000.f; palm->setRawVelocity(rawVelocity); // meters/sec + /* + if (i == 0) + { + printf("ADEBUG rawVelocity = [%e, %e, %e]\n", + rawVelocity.x, + rawVelocity.y, + rawVelocity.z); + } + */ palm->setRawPosition(position); // use the velocity to determine whether there's any movement (if the hand isn't new) diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 1b942e8f07..291bbcbb13 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -79,7 +79,8 @@ _sixenseID(SIXENSEID_INVALID), _numFramesWithoutData(0), _owningHandData(owningHandData), _isCollidingWithVoxel(false), -_isCollidingWithPalm(false) +_isCollidingWithPalm(false), +_collisionlessPaddleExpiry(0) { 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 1aa60da927..1dbce223dd 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -15,6 +15,8 @@ #include #include +#include "SharedUtil.h" + class AvatarData; class FingerData; class PalmData; @@ -51,7 +53,7 @@ public: return _basePosition + _baseOrientation * (leapPosition * LEAP_UNIT_SCALE); } glm::vec3 leapDirectionToWorldDirection(const glm::vec3& leapDirection) { - return glm::normalize(_baseOrientation * leapDirection); + return _baseOrientation * leapDirection; } glm::vec3 worldPositionToLeapPosition(const glm::vec3& worldPosition) const; glm::vec3 worldVectorToLeapVector(const glm::vec3& worldVector) const; @@ -193,6 +195,9 @@ public: bool getIsCollidingWithPalm() const { return _isCollidingWithPalm; } void setIsCollidingWithPalm(bool isCollidingWithPalm) { _isCollidingWithPalm = isCollidingWithPalm; } + bool hasPaddle() const { return _collisionlessPaddleExpiry < usecTimestampNow(); } + void updateCollisionlessPaddleExpiry() { _collisionlessPaddleExpiry = usecTimestampNow() + USECS_PER_SECOND; } + private: std::vector _fingers; glm::quat _rawRotation; @@ -217,7 +222,7 @@ private: bool _isCollidingWithVoxel; /// Whether the finger of this palm is inside a leaf voxel bool _isCollidingWithPalm; - + uint64_t _collisionlessPaddleExpiry; /// Timestamp after which paddle starts colliding }; #endif /* defined(__hifi__HandData__) */ diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index ed62da8791..0e6306f434 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -145,7 +145,7 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) { glm::vec3 center = particle->getPosition() * (float)(TREE_SCALE); float radius = particle->getRadius() * (float)(TREE_SCALE); - const float ELASTICITY = 0.95f; + const float ELASTICITY = 0.9f; const float DAMPING = 0.0f; const float COLLISION_FREQUENCY = 0.5f; glm::vec3 penetration; @@ -155,12 +155,26 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) { AvatarData* avatar = (AvatarData*)_selfAvatar; CollisionInfo collision; if (avatar->findSphereCollision(center, radius, collision)) { - if (glm::dot(particle->getVelocity(), collision._addedVelocity) < 0.f) { + collision._addedVelocity /= (float)(TREE_SCALE); + glm::vec3 relativeVelocity = collision._addedVelocity - particle->getVelocity(); + if (glm::dot(relativeVelocity, collision._penetration) < 0.f) { // only collide when particle and collision point are moving toward each other + + // HACK BEGIN: to make slow particle-paddle collisions mellower + float elasticity = ELASTICITY; + float damping = glm::length(collision._addedVelocity) / 5.0e-5f; + if (damping < 1.f) { + collision._addedVelocity *= (damping * damping); + elasticity = ELASTICITY * damping; + damping = 0.1f; + } else { + damping = DAMPING; + } + // HACK END + collision._penetration /= (float)(TREE_SCALE); - collision._addedVelocity /= (float)(TREE_SCALE); updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY); - applyHardCollision(particle, collision._penetration, ELASTICITY, DAMPING, collision._addedVelocity); + applyHardCollision(particle, collision._penetration, elasticity, damping, collision._addedVelocity); } } } diff --git a/libraries/shared/src/CollisionInfo.h b/libraries/shared/src/CollisionInfo.h index 4f46a6bfd3..1e4801788e 100644 --- a/libraries/shared/src/CollisionInfo.h +++ b/libraries/shared/src/CollisionInfo.h @@ -18,7 +18,7 @@ public: //glm::vec3 _point; //glm::vec3 _normal; - glm::vec3 _penetration; + glm::vec3 _penetration; // depth that bodyA is penetrates bodyB glm::vec3 _addedVelocity; }; diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index 2627a9035a..ac8e4e97c4 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -6,6 +6,7 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. #include +#include #include "SharedUtil.h" #include "GeometryUtil.h" @@ -115,20 +116,18 @@ bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadiu } bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius, - const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal, + const glm::vec3& diskCenter, float diskRadius, float diskThickness, const glm::vec3& diskNormal, glm::vec3& penetration) { glm::vec3 localCenter = sphereCenter - diskCenter; - float verticalDistance = glm::dot(localCenter, diskNormal); - - - if (abs(verticalDistance) < sphereRadius) { + float axialDistance = glm::dot(localCenter, diskNormal); + if (std::fabs(axialDistance) < (sphereRadius + 0.5f * diskThickness)) { // sphere hit the plane, but does it hit the disk? // Note: this algorithm ignores edge hits. - glm::vec3 verticalOffset = verticalDistance * diskNormal; - if (glm::length(localCenter - verticalOffset) < diskRadius) { + glm::vec3 axialOffset = axialDistance * diskNormal; + if (glm::length(localCenter - axialOffset) < diskRadius) { // yes, hit the disk - penetration = (sphereRadius - abs(verticalDistance)) * diskNormal; - if (verticalDistance < 0.f) { + penetration = (std::fabs(axialDistance) - (sphereRadius + 0.5f * diskThickness) ) * diskNormal; + if (axialDistance < 0.f) { // hit the backside of the disk, so negate penetration vector penetration *= -1.f; } diff --git a/libraries/shared/src/GeometryUtil.h b/libraries/shared/src/GeometryUtil.h index 59ad055445..12afc7c59c 100644 --- a/libraries/shared/src/GeometryUtil.h +++ b/libraries/shared/src/GeometryUtil.h @@ -17,7 +17,7 @@ glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec /// \param point the point location relative to sphere center (origin) /// \param defaultDirection the direction of the pentration when the point is near the origin /// \param sphereRadius the radius of the sphere -/// \param penetration the displacement that would move the point out of penetration with the sphere +/// \param penetration[out] the displacement that would move the point out of penetration with the sphere /// \return true if point is inside sphere, otherwise false bool findSpherePenetration(const glm::vec3& point, const glm::vec3& defaultDirection, float sphereRadius, glm::vec3& penetration); @@ -53,9 +53,10 @@ bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadiu /// \param diskCenter center of disk /// \param diskRadius radius of disk /// \param diskNormal normal of disk plan +/// \param penetration[out] the depth that the sphere penetrates the disk /// \return true if sphere touches disk (does not handle collisions with disk edge) bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius, - const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal, + const glm::vec3& diskCenter, float diskRadius, float diskThickness, const glm::vec3& diskNormal, glm::vec3& penetration); bool findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius, diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 973738280f..0d91bd3687 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -70,7 +70,7 @@ bool packetVersionMatch(unsigned char* packetHeader) { if (packetHeader[1] == versionForPacketType(packetHeader[0]) || packetHeader[0] == PACKET_TYPE_STUN_RESPONSE) { return true; } else { - qDebug("There is a packet version mismatch for packet with header %c", packetHeader[0]); + //qDebug("There is a packet version mismatch for packet with header %c", packetHeader[0]); return false; } } From 562b29b293d254ee7273ce58e9ec6f87dfb8e1ab Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 17 Jan 2014 11:35:16 -0800 Subject: [PATCH 2/6] adding back log about mismatching packet type --- libraries/shared/src/PacketHeaders.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 928905e194..0d468f0e1d 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -67,7 +67,7 @@ bool packetVersionMatch(unsigned char* packetHeader) { if (packetHeader[1] == versionForPacketType(packetHeader[0]) || packetHeader[0] == PACKET_TYPE_STUN_RESPONSE) { return true; } else { - //qDebug("There is a packet version mismatch for packet with header %c", packetHeader[0]); + qDebug("There is a packet version mismatch for packet with header %c", packetHeader[0]); return false; } } From aac1764243cd73f976c3e9209b394910e4500aff Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 17 Jan 2014 16:30:07 -0800 Subject: [PATCH 3/6] Re-enabling particle-avatar collisions. --- interface/src/avatar/Avatar.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 85254eee66..069ad0b7d9 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -352,14 +352,11 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi } } - /* HACK : disable collisions with avatar proper for now -- sometimes interferes with paddle - * TODO: disable regular collisions with hand capsules if (_skeletonModel.findSpherePenetration(sphereCenter, sphereRadius, collision._penetration)) { collision._penetration /= (float)(TREE_SCALE); collision._addedVelocity = getVelocity(); return true; } - */ return false; } From 3750aa902a5a8ec1ad515b7e834fa3c069f848c3 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 17 Jan 2014 16:31:06 -0800 Subject: [PATCH 4/6] Cleanup of "soft hand paddle" collision hackery. Still a hack, but more commented and readable. --- .../particles/src/ParticleCollisionSystem.cpp | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index 0e6306f434..8544932181 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -159,22 +159,23 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) { glm::vec3 relativeVelocity = collision._addedVelocity - particle->getVelocity(); if (glm::dot(relativeVelocity, collision._penetration) < 0.f) { // only collide when particle and collision point are moving toward each other + // (doing this prevents some "collision snagging" when particle penetrates the object) - // HACK BEGIN: to make slow particle-paddle collisions mellower + // HACK BEGIN: to allow paddle hands to "hold" particles we attenuate soft collisions against the avatar. + // NOTE: the physics are wrong (particles cannot roll) but it IS possible to catch a slow moving particle. + // TODO: make this less hacky when we have more per-collision details float elasticity = ELASTICITY; - float damping = glm::length(collision._addedVelocity) / 5.0e-5f; - if (damping < 1.f) { - collision._addedVelocity *= (damping * damping); - elasticity = ELASTICITY * damping; - damping = 0.1f; - } else { - damping = DAMPING; + float SLOW_PADDLE_SPEED = 5.0e-5f; + float attenuationFactor = glm::length(collision._addedVelocity) / SLOW_PADDLE_SPEED; + if (attenuationFactor < 1.f) { + collision._addedVelocity *= attenuationFactor; + elasticity *= attenuationFactor; } // HACK END collision._penetration /= (float)(TREE_SCALE); updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY); - applyHardCollision(particle, collision._penetration, elasticity, damping, collision._addedVelocity); + applyHardCollision(particle, collision._penetration, elasticity, DAMPING, collision._addedVelocity); } } } @@ -184,13 +185,24 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) { //qDebug() << "updateCollisionWithAvatars()... node:" << *node << "\n"; if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) { AvatarData* avatar = static_cast(node->getLinkedData()); - CollisionInfo collision; if (avatar->findSphereCollision(center, radius, collision)) { - if (glm::dot(particle->getVelocity(), collision._addedVelocity) < 0.f) { - // only collide when particle and collision point are moving toward each other + collision._addedVelocity /= (float)(TREE_SCALE); + glm::vec3 relativeVelocity = collision._addedVelocity - particle->getVelocity(); + if (glm::dot(relativeVelocity, collision._penetration) < 0.f) { + // HACK BEGIN: to allow paddle hands to "hold" particles we attenuate soft collisions against the avatar. + // NOTE: the physics are wrong (particles cannot roll) but it IS possible to catch a slow moving particle. + // TODO: make this less hacky when we have more per-collision details + float elasticity = ELASTICITY; + float SLOW_PADDLE_SPEED = 5.0e-5f; + float attenuationFactor = glm::length(collision._addedVelocity) / SLOW_PADDLE_SPEED; + if (attenuationFactor < 1.f) { + collision._addedVelocity *= attenuationFactor; + elasticity *= attenuationFactor; + } + // HACK END + collision._penetration /= (float)(TREE_SCALE); - collision._addedVelocity /= (float)(TREE_SCALE); updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY); applyHardCollision(particle, collision._penetration, ELASTICITY, DAMPING, collision._addedVelocity); } From 6c6a59b2525f3d2328d2d96518bd64d15ffeca8b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 17 Jan 2014 16:36:50 -0800 Subject: [PATCH 5/6] Hand now holds a ball a bit forward, which prevents the body from colliding with the ball on throw. --- interface/src/avatar/Hand.cpp | 21 +++++++++++---------- libraries/avatars/src/HandData.cpp | 9 +++++++++ libraries/avatars/src/HandData.h | 3 +++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 6bd25b5c54..201b332a8c 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -83,7 +83,6 @@ void Hand::reset() { void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime) { Application* app = Application::getInstance(); ParticleTree* particles = app->getParticles()->getTree(); - bool ballFromHand = Menu::getInstance()->isOptionChecked(MenuOption::BallFromHand); int handID = palm.getSixenseID(); const int NEW_BALL_BUTTON = BUTTON_3; @@ -93,7 +92,8 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f bool ballAlreadyInHand = _toyBallInHand[handID]; - glm::vec3 targetPosition = (ballFromHand ? palm.getPosition() : fingerTipPosition) / (float)TREE_SCALE; + glm::vec3 targetPosition; + palm.getBallHoldPosition(targetPosition); float targetRadius = CATCH_RADIUS / (float)TREE_SCALE; // If I don't currently have a ball in my hand, then try to catch closest one @@ -148,7 +148,8 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f if ((palm.getControllerButtons() & NEW_BALL_BUTTON) && (_toyBallInHand[handID] == false)) { _toyBallInHand[handID] = true; // Create a particle on the particle server - glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; + glm::vec3 ballPosition; + palm.getBallHoldPosition(ballPosition); _ballParticleEditHandles[handID] = app->makeParticle( ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, @@ -171,7 +172,8 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f xColor colorForParticleInHand = particleInHand ? particleInHand->getXColor() : TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]]; - glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; + glm::vec3 ballPosition; + palm.getBallHoldPosition(ballPosition); _ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, colorForParticleInHand, @@ -188,8 +190,9 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f const float THROWN_VELOCITY_SCALING = 1.5f; _toyBallInHand[handID] = false; palm.updateCollisionlessPaddleExpiry(); - glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; - glm::vec3 ballVelocity = ballFromHand ? palm.getRawVelocity() : palm.getTipVelocity(); + glm::vec3 ballPosition; + palm.getBallHoldPosition(ballPosition); + glm::vec3 ballVelocity = palm.getTipVelocity(); glm::quat avatarRotation = _owningAvatar->getOrientation(); ballVelocity = avatarRotation * ballVelocity; ballVelocity *= THROWN_VELOCITY_SCALING; @@ -551,7 +554,6 @@ void Hand::renderLeapHands(bool isMine) { //const glm::vec3 handColor = _ballColor; const glm::vec3 handColor(1.0, 0.84, 0.66); // use the skin color - bool ballFromHand = Menu::getInstance()->isOptionChecked(MenuOption::BallFromHand); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); @@ -562,9 +564,8 @@ void Hand::renderLeapHands(bool isMine) { if (!palm.isActive()) { continue; } - glm::vec3 targetPosition = ballFromHand ? palm.getPosition() : palm.getTipPosition(); - const float BALL_FORWARD_OFFSET = 0.08f; // put the ball a bit forward of fingers - targetPosition += BALL_FORWARD_OFFSET * palm.getNormal(); + glm::vec3 targetPosition; + palm.getBallHoldPosition(targetPosition); glPushMatrix(); ParticleTree* particles = Application::getInstance()->getParticles()->getTree(); diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 291bbcbb13..7fc0c79b47 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -295,6 +295,15 @@ const glm::vec3& FingerData::getTrailPosition(int index) { return _tipTrailPositions[posIndex]; } +void PalmData::getBallHoldPosition(glm::vec3& position) const { + const float BALL_FORWARD_OFFSET = 0.08f; // put the ball a bit forward of fingers + position = BALL_FORWARD_OFFSET * getNormal(); + if (_fingers.size() > 0) { + position += _fingers[0].getTipPosition(); + } else { + position += getPosition(); + } +} diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index 1dbce223dd..ef9009312e 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -198,6 +198,9 @@ public: bool hasPaddle() const { return _collisionlessPaddleExpiry < usecTimestampNow(); } void updateCollisionlessPaddleExpiry() { _collisionlessPaddleExpiry = usecTimestampNow() + USECS_PER_SECOND; } + /// Store position where the palm holds the ball. + void getBallHoldPosition(glm::vec3& position) const; + private: std::vector _fingers; glm::quat _rawRotation; From 0921999c3b5b086895050fc3187a7061276b5484 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 17 Jan 2014 16:37:44 -0800 Subject: [PATCH 6/6] Removing menu option for where to hold the ball -- we always hold from the finger tip (approximately). --- interface/src/Menu.cpp | 1 - interface/src/Menu.h | 1 - 2 files changed, 2 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index b2583d7c51..d7e051b3cf 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -350,7 +350,6 @@ Menu::Menu() : SLOT(setFilter(bool))); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); - addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::BallFromHand, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::VoxelDrumming, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 3f97af9981..aee36dafba 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -155,7 +155,6 @@ namespace MenuOption { const QString Avatars = "Avatars"; const QString Atmosphere = "Atmosphere"; const QString AutomaticallyAuditTree = "Automatically Audit Tree Stats"; - const QString BallFromHand = "Ball from Hand"; const QString Bandwidth = "Bandwidth Display"; const QString BandwidthDetails = "Bandwidth Details"; const QString ChatCircling = "Chat Circling";