From 36f06720d09fb89e75992da1f25f4359da7327d0 Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Wed, 16 Oct 2013 08:21:35 -0700 Subject: [PATCH] Add left-arm movement to remote avatars without changing network packet structure. Move MyAvatar leap hand arm-movement into Avatar::updateLeapHandPositions(), to enable remote avatars to position fingertips and IK-arms based on Leap hand data. --- interface/src/avatar/Avatar.cpp | 47 +++++++++++++++++++++++++++++++ interface/src/avatar/Avatar.h | 1 + interface/src/avatar/MyAvatar.cpp | 38 +------------------------ 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 7fcca723f6..9c755a24c1 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -460,6 +460,8 @@ void Avatar::updateHandMovementAndTouching(float deltaTime, bool enableHandMovem _skeleton.joint[AVATAR_JOINT_RIGHT_FINGERTIPS].position += transformedHandMovement; } + enableHandMovement |= updateLeapHandPositions(); + //constrain right arm length and re-adjust elbow position as it bends // NOTE - the following must be called on all avatars - not just _isMine if (enableHandMovement) { @@ -641,6 +643,51 @@ void Avatar::updateBodyBalls(float deltaTime) { _bodyBall[BODY_BALL_HEAD_TOP].rotation * _skeleton.joint[BODY_BALL_HEAD_TOP].bindPosePosition; } +// returns true if the Leap controls any of the avatar's hands. +bool Avatar::updateLeapHandPositions() { + bool returnValue = false; + // If there are leap-interaction hands visible, see if we can use them as the endpoints for IK + if (getHand().getPalms().size() > 0) { + PalmData const* leftLeapHand = NULL; + PalmData const* rightLeapHand = NULL; + // Look through all of the palms available (there may be more than two), and pick + // the leftmost and rightmost. If there's only one, we'll use a heuristic below + // to decode whether it's the left or right. + for (size_t i = 0; i < getHand().getPalms().size(); ++i) { + PalmData& palm = getHand().getPalms()[i]; + if (palm.isActive()) { + if (!rightLeapHand || !leftLeapHand) { + rightLeapHand = leftLeapHand = &palm; + } + else if (palm.getRawPosition().x > rightLeapHand->getRawPosition().x) { + rightLeapHand = &palm; + } + else if (palm.getRawPosition().x < leftLeapHand->getRawPosition().x) { + leftLeapHand = &palm; + } + } + } + // If there's only one palm visible. Decide if it's the left or right + if (leftLeapHand == rightLeapHand && leftLeapHand) { + if (leftLeapHand->getRawPosition().x > 0) { + leftLeapHand = NULL; + } + else { + rightLeapHand = NULL; + } + } + if (leftLeapHand) { + _skeleton.joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].position = leftLeapHand->getPosition(); + returnValue = true; + } + if (rightLeapHand) { + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = rightLeapHand->getPosition(); + returnValue = true; + } + } + return returnValue; +} + void Avatar::updateArmIKAndConstraints(float deltaTime, AvatarJointID fingerTipJointID) { Skeleton::AvatarJoint& fingerJoint = _skeleton.joint[fingerTipJointID]; Skeleton::AvatarJoint& wristJoint = _skeleton.joint[fingerJoint.parent]; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 7e11a0b9df..b46f461389 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -231,6 +231,7 @@ protected: glm::vec3 getBodyFrontDirection() const { return getOrientation() * IDENTITY_FRONT; } glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const; void updateBodyBalls(float deltaTime); + bool updateLeapHandPositions(); void updateArmIKAndConstraints(float deltaTime, AvatarJointID fingerTipJointID); void setScale(const float scale); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 509935b3cf..8cbcabe6e8 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -912,43 +912,7 @@ void MyAvatar::updateHandMovementAndTouching(float deltaTime, bool enableHandMov _avatarTouch.setHasInteractingOther(false); } - // If there are leap-interaction hands visible, see if we can use them as the endpoints for IK - if (getHand().getPalms().size() > 0) { - PalmData const* leftLeapHand = NULL; - PalmData const* rightLeapHand = NULL; - // Look through all of the palms available (there may be more than two), and pick - // the leftmost and rightmost. If there's only one, we'll use a heuristic below - // to decode whether it's the left or right. - for (size_t i = 0; i < getHand().getPalms().size(); ++i) { - PalmData& palm = getHand().getPalms()[i]; - if (palm.isActive()) { - if (!rightLeapHand || !leftLeapHand) { - rightLeapHand = leftLeapHand = &palm; - } - else if (palm.getRawPosition().x > rightLeapHand->getRawPosition().x) { - rightLeapHand = &palm; - } - else if (palm.getRawPosition().x < leftLeapHand->getRawPosition().x) { - leftLeapHand = &palm; - } - } - } - // If there's only one palm visible. Decide if it's the left or right - if (leftLeapHand == rightLeapHand && leftLeapHand) { - if (leftLeapHand->getRawPosition().x > 0) { - leftLeapHand = NULL; - } - else { - rightLeapHand = NULL; - } - } - if (leftLeapHand) { - _skeleton.joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].position = leftLeapHand->getPosition(); - } - if (rightLeapHand) { - _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = rightLeapHand->getPosition(); - } - } + enableHandMovement |= updateLeapHandPositions(); //constrain right arm length and re-adjust elbow position as it bends // NOTE - the following must be called on all avatars - not just _isMine