From 9460fb87c23de9fcf56fbc654d1bc199da819d35 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 5 Nov 2013 16:06:11 -0800 Subject: [PATCH] Return arm to neutral position when mouse pointer is invisible. --- interface/src/avatar/MyAvatar.cpp | 4 ++++ interface/src/avatar/SkeletonModel.cpp | 7 ++++++- interface/src/renderer/Model.cpp | 20 ++++++++++++++++++++ interface/src/renderer/Model.h | 16 ++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7d6877e693..0a95e78b91 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -831,6 +831,7 @@ void MyAvatar::updateHandMovementAndTouching(float deltaTime, bool enableHandMov // reset hand and arm positions according to hand movement glm::vec3 up = orientation * IDENTITY_UP; + bool pointing = false; if (enableHandMovement && glm::length(_mouseRayDirection) > EPSILON && !Application::getInstance()->isMouseHidden()) { // confine to the approximate shoulder plane glm::vec3 pointDirection = _mouseRayDirection; @@ -842,6 +843,7 @@ void MyAvatar::updateHandMovementAndTouching(float deltaTime, bool enableHandMov } const float FAR_AWAY_POINT = TREE_SCALE; _skeleton.joint[AVATAR_JOINT_RIGHT_FINGERTIPS].position = _mouseRayOrigin + pointDirection * FAR_AWAY_POINT; + pointing = true; } _avatarTouch.setMyBodyPosition(_position); @@ -933,6 +935,8 @@ void MyAvatar::updateHandMovementAndTouching(float deltaTime, bool enableHandMov if (_mousePressed) { _handState = HAND_STATE_GRASPING; + } else if (pointing) { + _handState = HAND_STATE_POINTING; } else { _handState = HAND_STATE_NULL; } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index aa5cb6cfd0..ffc4f1981f 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -28,7 +28,12 @@ void SkeletonModel::simulate(float deltaTime) { Model::simulate(deltaTime); - setRightHandPosition(_owningAvatar->getHandPosition()); + if (_owningAvatar->getHandState() == HAND_STATE_NULL) { + const float HAND_RESTORATION_RATE = 0.25f; + restoreRightHandPosition(HAND_RESTORATION_RATE); + } else { + setRightHandPosition(_owningAvatar->getHandPosition()); + } } bool SkeletonModel::render(float alpha) { diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 529bd67da8..8867fb2562 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -477,6 +477,10 @@ bool Model::setLeftHandPosition(const glm::vec3& position) { return isActive() && setJointPosition(_geometry->getFBXGeometry().leftHandJointIndex, position); } +bool Model::restoreLeftHandPosition(float percent) { + return isActive() && restoreJointPosition(_geometry->getFBXGeometry().leftHandJointIndex, percent); +} + bool Model::setLeftHandRotation(const glm::quat& rotation) { return isActive() && setJointRotation(_geometry->getFBXGeometry().leftHandJointIndex, rotation); } @@ -485,6 +489,10 @@ bool Model::setRightHandPosition(const glm::vec3& position) { return isActive() && setJointPosition(_geometry->getFBXGeometry().rightHandJointIndex, position); } +bool Model::restoreRightHandPosition(float percent) { + return isActive() && restoreJointPosition(_geometry->getFBXGeometry().rightHandJointIndex, percent); +} + bool Model::setRightHandRotation(const glm::quat& rotation) { return isActive() && setJointRotation(_geometry->getFBXGeometry().rightHandJointIndex, rotation); } @@ -617,6 +625,18 @@ bool Model::setJointRotation(int jointIndex, const glm::quat& rotation) { return true; } +bool Model::restoreJointPosition(int jointIndex, float percent) { + if (jointIndex == -1 || _jointStates.isEmpty()) { + return false; + } + const FBXGeometry& geometry = _geometry->getFBXGeometry(); + const QVector& freeLineage = geometry.joints.at(jointIndex).freeLineage; + + foreach (int index, freeLineage) { + _jointStates[index].rotation = safeMix(_jointStates[index].rotation, geometry.joints.at(index).rotation, percent); + } +} + void Model::deleteGeometry() { foreach (Model* attachment, _attachments) { delete attachment; diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 2c0c553719..f4b07f8242 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -74,6 +74,11 @@ public: /// \return whether or not the left hand joint was found bool setLeftHandPosition(const glm::vec3& position); + /// Restores some percentage of the default position of the left hand. + /// \param percent the percentage of the default position to restore + /// \return whether or not the left hand joint was found + bool restoreLeftHandPosition(float percent = 1.0f); + /// Sets the rotation of the left hand. /// \return whether or not the left hand joint was found bool setLeftHandRotation(const glm::quat& rotation); @@ -82,6 +87,11 @@ public: /// \return whether or not the right hand joint was found bool setRightHandPosition(const glm::vec3& position); + /// Restores some percentage of the default position of the right hand. + /// \param percent the percentage of the default position to restore + /// \return whether or not the right hand joint was found + bool restoreRightHandPosition(float percent = 1.0f); + /// Sets the rotation of the right hand. /// \return whether or not the right hand joint was found bool setRightHandRotation(const glm::quat& rotation); @@ -130,6 +140,12 @@ protected: bool setJointPosition(int jointIndex, const glm::vec3& position); bool setJointRotation(int jointIndex, const glm::quat& rotation); + /// Restores the indexed joint to its default position. + /// \param percent the percentage of the default position to apply (i.e., 0.25f to slerp one fourth of the way to + /// the original position + /// \return true if the joint was found + bool restoreJointPosition(int jointIndex, float percent = 1.0f); + private: void deleteGeometry();