From 7f1f6dba311820f839d2fb0be229854cd7f8cb5a Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 27 Aug 2019 10:25:35 -0700 Subject: [PATCH 1/3] Implement activation on nodes and use it to trigger random states --- libraries/animation/src/AnimNode.cpp | 7 +++++++ libraries/animation/src/AnimNode.h | 3 +++ libraries/animation/src/AnimRandomSwitch.cpp | 13 ++++++++----- libraries/animation/src/AnimRandomSwitch.h | 3 ++- libraries/animation/src/AnimStateMachine.cpp | 4 ++++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/libraries/animation/src/AnimNode.cpp b/libraries/animation/src/AnimNode.cpp index f055e6b473..930be9769c 100644 --- a/libraries/animation/src/AnimNode.cpp +++ b/libraries/animation/src/AnimNode.cpp @@ -60,6 +60,13 @@ void AnimNode::setCurrentFrame(float frame) { } } +void AnimNode::setActive(bool active) { + setActiveInternal(active); + for (auto&& child : _children) { + child->setActiveInternal(active); + } +} + void AnimNode::processOutputJoints(AnimVariantMap& triggersOut) const { if (!_skeleton) { return; diff --git a/libraries/animation/src/AnimNode.h b/libraries/animation/src/AnimNode.h index ec5f2b7375..a0fb51e891 100644 --- a/libraries/animation/src/AnimNode.h +++ b/libraries/animation/src/AnimNode.h @@ -73,6 +73,7 @@ public: } void setCurrentFrame(float frame); + void setActive(bool active); template bool traverse(F func) { @@ -104,6 +105,7 @@ protected: virtual void setCurrentFrameInternal(float frame) {} virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { _skeleton = skeleton; } + virtual void setActiveInternal(bool active) {} // for AnimDebugDraw rendering virtual const AnimPoseVec& getPosesInternal() const = 0; @@ -116,6 +118,7 @@ protected: AnimSkeleton::ConstPointer _skeleton; std::weak_ptr _parent; std::vector _outputJointNames; + bool _active { false }; // no copies AnimNode(const AnimNode&) = delete; diff --git a/libraries/animation/src/AnimRandomSwitch.cpp b/libraries/animation/src/AnimRandomSwitch.cpp index 68c7031de8..3fbd57dde4 100644 --- a/libraries/animation/src/AnimRandomSwitch.cpp +++ b/libraries/animation/src/AnimRandomSwitch.cpp @@ -21,12 +21,16 @@ AnimRandomSwitch::~AnimRandomSwitch() { } +void AnimRandomSwitch::setActiveInternal(bool active) { + _active = active; + _triggerNewRandomState = active; +} + const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { float parentDebugAlpha = context.getDebugAlpha(_id); AnimRandomSwitch::RandomSwitchState::Pointer desiredState = _currentState; - if (abs(_randomSwitchEvaluationCount - context.getEvaluationCount()) > 1 || animVars.lookup(_triggerRandomSwitchVar, false)) { - + if (_triggerNewRandomState || animVars.lookup(_triggerRandomSwitchVar, false)) { // filter states different to the last random state and with priorities. bool currentStateHasPriority = false; std::vector randomStatesToConsider; @@ -56,8 +60,9 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co } lowerBound = upperBound; } - if (abs(_randomSwitchEvaluationCount - context.getEvaluationCount()) > 1) { + if (_triggerNewRandomState) { switchRandomState(animVars, context, desiredState, false); + _triggerNewRandomState = false; } else { // firing a random switch, be sure that we aren't completing a previously triggered transition if (currentStateHasPriority) { @@ -70,7 +75,6 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co } _triggerTime = randFloatInRange(_triggerTimeMin, _triggerTimeMax); _randomSwitchTime = randFloatInRange(_randomSwitchTimeMin, _randomSwitchTimeMax); - } else { // here we are checking to see if we want a temporary movement @@ -143,7 +147,6 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co _poses = currentStateNode->evaluate(animVars, context, dt, triggersOut); } - _randomSwitchEvaluationCount = context.getEvaluationCount(); processOutputJoints(triggersOut); context.addStateMachineInfo(_id, _currentState->getID(), _previousState->getID(), _duringInterp, _alpha); diff --git a/libraries/animation/src/AnimRandomSwitch.h b/libraries/animation/src/AnimRandomSwitch.h index 888ed1f6b5..490e2f86e1 100644 --- a/libraries/animation/src/AnimRandomSwitch.h +++ b/libraries/animation/src/AnimRandomSwitch.h @@ -151,10 +151,11 @@ protected: // for AnimDebugDraw rendering virtual const AnimPoseVec& getPosesInternal() const override; + virtual void setActiveInternal(bool active) override; AnimPoseVec _poses; - int _randomSwitchEvaluationCount { 0 }; + bool _triggerNewRandomState = false; // interpolation state bool _duringInterp = false; InterpType _interpType { InterpType::SnapshotPrev }; diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp index 658309ce71..51e7a24136 100644 --- a/libraries/animation/src/AnimStateMachine.cpp +++ b/libraries/animation/src/AnimStateMachine.cpp @@ -128,6 +128,10 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon auto prevStateNode = _children[_currentState->getChildIndex()]; auto nextStateNode = _children[desiredState->getChildIndex()]; + // activate/deactivate states + prevStateNode->setActive(false); + nextStateNode->setActive(true); + bool interpActive = _duringInterp; _duringInterp = true; _alpha = 0.0f; From acbeb326a70fbf4cae30790bcd256656f135dc0c Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 27 Aug 2019 10:57:22 -0700 Subject: [PATCH 2/3] Set activation when switching random states --- libraries/animation/src/AnimContext.h | 2 -- libraries/animation/src/AnimRandomSwitch.cpp | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h index 5f353fcae4..9ad37b513e 100644 --- a/libraries/animation/src/AnimContext.h +++ b/libraries/animation/src/AnimContext.h @@ -45,7 +45,6 @@ public: bool getEnableDebugDrawIKChains() const { return _enableDebugDrawIKChains; } const glm::mat4& getGeometryToRigMatrix() const { return _geometryToRigMatrix; } const glm::mat4& getRigToWorldMatrix() const { return _rigToWorldMatrix; } - int getEvaluationCount() const { return _evaluationCount; } float getDebugAlpha(const QString& key) const { auto it = _debugAlphaMap.find(key); @@ -87,7 +86,6 @@ protected: bool _enableDebugDrawIKChains { false }; glm::mat4 _geometryToRigMatrix; glm::mat4 _rigToWorldMatrix; - int _evaluationCount{ 0 }; // used for debugging internal state of animation system. mutable DebugAlphaMap _debugAlphaMap; diff --git a/libraries/animation/src/AnimRandomSwitch.cpp b/libraries/animation/src/AnimRandomSwitch.cpp index 3fbd57dde4..4f137f7be4 100644 --- a/libraries/animation/src/AnimRandomSwitch.cpp +++ b/libraries/animation/src/AnimRandomSwitch.cpp @@ -168,8 +168,16 @@ void AnimRandomSwitch::addState(RandomSwitchState::Pointer randomState) { } void AnimRandomSwitch::switchRandomState(const AnimVariantMap& animVars, const AnimContext& context, RandomSwitchState::Pointer desiredState, bool shouldInterp) { + + auto prevStateNode = _children[_currentState->getChildIndex()]; auto nextStateNode = _children[desiredState->getChildIndex()]; + + // activate/deactivate states + prevStateNode->setActive(false); + nextStateNode->setActive(true); + _lastPlayedState = nextStateNode->getID(); + if (shouldInterp) { bool interpActive = _duringInterp; From 55b54b02a0a558228c779bd08242f03d14438c1b Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 27 Aug 2019 10:59:03 -0700 Subject: [PATCH 3/3] Restate evaluation count on AnimContext --- libraries/animation/src/AnimContext.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h index 9ad37b513e..5f353fcae4 100644 --- a/libraries/animation/src/AnimContext.h +++ b/libraries/animation/src/AnimContext.h @@ -45,6 +45,7 @@ public: bool getEnableDebugDrawIKChains() const { return _enableDebugDrawIKChains; } const glm::mat4& getGeometryToRigMatrix() const { return _geometryToRigMatrix; } const glm::mat4& getRigToWorldMatrix() const { return _rigToWorldMatrix; } + int getEvaluationCount() const { return _evaluationCount; } float getDebugAlpha(const QString& key) const { auto it = _debugAlphaMap.find(key); @@ -86,6 +87,7 @@ protected: bool _enableDebugDrawIKChains { false }; glm::mat4 _geometryToRigMatrix; glm::mat4 _rigToWorldMatrix; + int _evaluationCount{ 0 }; // used for debugging internal state of animation system. mutable DebugAlphaMap _debugAlphaMap;