diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 703f3983ee..b1f6e6d8d1 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -246,33 +246,36 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { Hand* hand = _owningAvatar->getHand(); hand->getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex); - const float HAND_RESTORATION_RATE = 0.25f; - if (leftPalmIndex == -1 && rightPalmIndex == -1) { - // palms are not yet set, use mouse - if (_owningAvatar->getHandState() == HAND_STATE_NULL) { - restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); - } else { - // transform into model-frame - glm::vec3 handPosition = glm::inverse(_rotation) * (_owningAvatar->getHandPosition() - _translation); - applyHandPosition(geometry.rightHandJointIndex, handPosition); - } - restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); - - } else if (leftPalmIndex == rightPalmIndex) { - // right hand only - applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[leftPalmIndex]); - restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); - - } else { - if (leftPalmIndex != -1) { - applyPalmData(geometry.leftHandJointIndex, hand->getPalms()[leftPalmIndex]); - } else { + // Don't Relax toward hand positions when in animGraph mode. + if (!_rig->getEnableAnimGraph()) { + const float HAND_RESTORATION_RATE = 0.25f; + if (leftPalmIndex == -1 && rightPalmIndex == -1) { + // palms are not yet set, use mouse + if (_owningAvatar->getHandState() == HAND_STATE_NULL) { + restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); + } else { + // transform into model-frame + glm::vec3 handPosition = glm::inverse(_rotation) * (_owningAvatar->getHandPosition() - _translation); + applyHandPosition(geometry.rightHandJointIndex, handPosition); + } restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); - } - if (rightPalmIndex != -1) { - applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[rightPalmIndex]); + + } else if (leftPalmIndex == rightPalmIndex) { + // right hand only + applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[leftPalmIndex]); + restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); + } else { - restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); + if (leftPalmIndex != -1) { + applyPalmData(geometry.leftHandJointIndex, hand->getPalms()[leftPalmIndex]); + } else { + restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); + } + if (rightPalmIndex != -1) { + applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[rightPalmIndex]); + } else { + restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); + } } } } diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 6731756aeb..173e387608 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -173,6 +173,7 @@ void AnimSkeleton::dump() const { qCDebug(animation) << "["; for (int i = 0; i < getNumJoints(); i++) { qCDebug(animation) << " {"; + qCDebug(animation) << " index =" << i; qCDebug(animation) << " name =" << getJointName(i); qCDebug(animation) << " absBindPose =" << getAbsoluteBindPose(i); qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i); @@ -188,6 +189,7 @@ void AnimSkeleton::dump(const AnimPoseVec& poses) const { qCDebug(animation) << "["; for (int i = 0; i < getNumJoints(); i++) { qCDebug(animation) << " {"; + qCDebug(animation) << " index =" << i; qCDebug(animation) << " name =" << getJointName(i); qCDebug(animation) << " absBindPose =" << getAbsoluteBindPose(i); qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i); diff --git a/libraries/animation/src/AnimVariant.h b/libraries/animation/src/AnimVariant.h index de224f936a..700a8b4121 100644 --- a/libraries/animation/src/AnimVariant.h +++ b/libraries/animation/src/AnimVariant.h @@ -16,6 +16,7 @@ #include #include #include +#include "AnimationLogging.h" class AnimVariant { public: @@ -46,6 +47,7 @@ public: bool isQuat() const { return _type == Type::Quat; } bool isMat4() const { return _type == Type::Mat4; } bool isString() const { return _type == Type::String; } + Type getType() const { return _type; } void setBool(bool value) { assert(_type == Type::Bool); _val.boolVal = value; } void setInt(int value) { assert(_type == Type::Int); _val.intVal = value; } @@ -156,6 +158,37 @@ public: bool hasKey(const QString& key) const { return _map.find(key) != _map.end(); } +#ifdef NDEBUG + void dump() const { + qCDebug(animation) << "AnimVariantMap ="; + for (auto& pair : _map) { + switch (pair.second.getType()) { + case AnimVariant::Type::Bool: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getBool(); + break; + case AnimVariant::Type::Int: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getInt(); + break; + case AnimVariant::Type::Float: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getFloat(); + break; + case AnimVariant::Type::Vec3: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getVec3(); + break; + case AnimVariant::Type::Quat: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getQuat(); + break; + case AnimVariant::Type::Mat4: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getMat4(); + break; + case AnimVariant::Type::String: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getString(); + break; + } + } + } +#endif + protected: std::map _map; std::set _triggers; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 1874939b3d..0022749d51 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -145,16 +145,20 @@ AnimationHandlePointer Rig::addAnimationByRole(const QString& role, const QStrin } return handle; } + +const float FADE_FRAMES = 30.0f; +const float FRAMES_PER_SECOND = 30.0f; + void Rig::startAnimationByRole(const QString& role, const QString& url, float fps, float priority, bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) { AnimationHandlePointer handle = addAnimationByRole(role, url, fps, priority, loop, hold, firstFrame, lastFrame, maskedJoints, true); - handle->setFadePerSecond(1.0f); // For now. Could be individualized later. + handle->setFadePerSecond(FRAMES_PER_SECOND / FADE_FRAMES); // For now. Could be individualized later. } void Rig::stopAnimationByRole(const QString& role) { foreach (const AnimationHandlePointer& handle, getRunningAnimations()) { if (handle->getRole() == role) { - handle->setFadePerSecond(-1.0f); // For now. Could be individualized later. + handle->setFadePerSecond(-(FRAMES_PER_SECOND / FADE_FRAMES)); // For now. Could be individualized later. } } } @@ -163,7 +167,7 @@ void Rig::stopAnimation(const QString& url) { foreach (const AnimationHandlePointer& handle, getRunningAnimations()) { if (handle->getURL() == url) { handle->setFade(0.0f); // right away. Will be remove during updateAnimations, without locking - handle->setFadePerSecond(-1.0f); // so that the updateAnimation code notices + handle->setFadePerSecond(-(FRAMES_PER_SECOND / FADE_FRAMES)); // so that the updateAnimation code notices } } } @@ -587,10 +591,12 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { _animVars.setTrigger(trigger); } + clearJointStatePriorities(); + // copy poses into jointStates const float PRIORITY = 1.0f; for (size_t i = 0; i < poses.size(); i++) { - setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, PRIORITY, false); + setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, PRIORITY, false, 1.0f); } } else { @@ -926,6 +932,12 @@ void Rig::updateVisibleJointStates() { } } +void Rig::clearJointStatePriorities() { + for (int i = 0; i < _jointStates.size(); i++) { + _jointStates[i].setAnimationPriority(0.0f); + } +} + void Rig::setJointVisibleTransform(int jointIndex, glm::mat4 newTransform) { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return; @@ -950,6 +962,8 @@ glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) { void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) { if (params.enableLean) { updateLeanJoint(params.leanJointIndex, params.leanSideways, params.leanForward, params.torsoTwist); + } else { + _animVars.unset("lean"); } updateNeckJoint(params.neckJointIndex, params); updateEyeJoints(params.leftEyeJointIndex, params.rightEyeJointIndex, params.modelTranslation, params.modelRotation, diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 90082ca38b..6dad58db87 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -172,6 +172,7 @@ public: bool getJointRotationInConstrainedFrame(int jointIndex, glm::quat& rotOut) const; glm::quat getJointDefaultRotationInParentFrame(int jointIndex); void updateVisibleJointStates(); + void clearJointStatePriorities(); virtual void updateJointState(int index, glm::mat4 rootTransform) = 0;