From a2562c92f44d4d54b914c74f58538191b1734b17 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Sun, 27 Sep 2015 16:24:55 -0700 Subject: [PATCH 1/5] Small changes to Anim System for Debugging * Added constant for Rig animation fade time * Added index output for AnimSkeleton::dump() --- libraries/animation/src/AnimSkeleton.cpp | 2 ++ libraries/animation/src/Rig.cpp | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) 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/Rig.cpp b/libraries/animation/src/Rig.cpp index 1874939b3d..130398eb4a 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -145,16 +145,19 @@ AnimationHandlePointer Rig::addAnimationByRole(const QString& role, const QStrin } return handle; } + +const float FADE_FRAMES = 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(30.0f / 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(-(30.0f / FADE_FRAMES)); // For now. Could be individualized later. } } } @@ -163,7 +166,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(-(30.0f / FADE_FRAMES)); // so that the updateAnimation code notices } } } From 5a24a020ca5069a0e23f3b0052744c9b1b18f435 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Sun, 27 Sep 2015 17:44:54 -0700 Subject: [PATCH 2/5] Fix for HMD rotation sticking between 2d & HMD mode The main fix for this was to set the JointState animation priority to 3.0 The secondary fix was only noticed when we changed the animation priority Basically, the debugRendering was using the JointStates after they were manipulated by SkeletonModel to 'relax' them toward thier default pose for IK purposes. --- interface/src/avatar/SkeletonModel.cpp | 53 ++++++++++++++------------ libraries/animation/src/Rig.cpp | 4 +- 2 files changed, 30 insertions(+), 27 deletions(-) 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/Rig.cpp b/libraries/animation/src/Rig.cpp index 130398eb4a..491a390025 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -591,9 +591,9 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { } // copy poses into jointStates - const float PRIORITY = 1.0f; + const float PRIORITY = 3.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 { From 4b31d87bf5b11c312d6d4f53db18bfd305487895 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Sun, 27 Sep 2015 17:52:53 -0700 Subject: [PATCH 3/5] renamed magic constant to FRAMES_PER_SECOND. --- libraries/animation/src/Rig.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 491a390025..a0cb278ef3 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -147,17 +147,18 @@ AnimationHandlePointer Rig::addAnimationByRole(const QString& role, const QStrin } 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(30.0f / FADE_FRAMES); // 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(-(30.0f / FADE_FRAMES)); // For now. Could be individualized later. + handle->setFadePerSecond(-(FRAMES_PER_SECOND / FADE_FRAMES)); // For now. Could be individualized later. } } } @@ -166,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(-(30.0f / FADE_FRAMES)); // so that the updateAnimation code notices + handle->setFadePerSecond(-(FRAMES_PER_SECOND / FADE_FRAMES)); // so that the updateAnimation code notices } } } From c970ff0c0cc60fefba2041d09d0fd0f4534dce16 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Sun, 27 Sep 2015 18:25:28 -0700 Subject: [PATCH 4/5] Reset joint priorities back to 0 for new animation system. Added Rig::clearJointStatePriorities() to do this. --- libraries/animation/src/Rig.cpp | 10 +++++++++- libraries/animation/src/Rig.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index a0cb278ef3..192af54201 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -591,8 +591,10 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { _animVars.setTrigger(trigger); } + clearJointStatePriorities(); + // copy poses into jointStates - const float PRIORITY = 3.0f; + 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, 1.0f); } @@ -930,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; 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; From a495a45ed0b939045f20a108cce1658fe8fe9a83 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 28 Sep 2015 11:10:22 -0700 Subject: [PATCH 5/5] unset "lean" when headParams.enableLean is false Also added AnimVariantMap::dump() which will print out all the currently set anim vars and their values. --- libraries/animation/src/AnimVariant.h | 33 +++++++++++++++++++++++++++ libraries/animation/src/Rig.cpp | 2 ++ 2 files changed, 35 insertions(+) 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 192af54201..0022749d51 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -962,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,