Implement activation on nodes and use it to trigger random states

This commit is contained in:
luiscuenca 2019-08-27 10:25:35 -07:00
parent 860b5d0970
commit 7f1f6dba31
No known key found for this signature in database
GPG key ID: 2387ECD129A6961D
5 changed files with 24 additions and 6 deletions

View file

@ -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 { void AnimNode::processOutputJoints(AnimVariantMap& triggersOut) const {
if (!_skeleton) { if (!_skeleton) {
return; return;

View file

@ -73,6 +73,7 @@ public:
} }
void setCurrentFrame(float frame); void setCurrentFrame(float frame);
void setActive(bool active);
template <typename F> template <typename F>
bool traverse(F func) { bool traverse(F func) {
@ -104,6 +105,7 @@ protected:
virtual void setCurrentFrameInternal(float frame) {} virtual void setCurrentFrameInternal(float frame) {}
virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { _skeleton = skeleton; } virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { _skeleton = skeleton; }
virtual void setActiveInternal(bool active) {}
// for AnimDebugDraw rendering // for AnimDebugDraw rendering
virtual const AnimPoseVec& getPosesInternal() const = 0; virtual const AnimPoseVec& getPosesInternal() const = 0;
@ -116,6 +118,7 @@ protected:
AnimSkeleton::ConstPointer _skeleton; AnimSkeleton::ConstPointer _skeleton;
std::weak_ptr<AnimNode> _parent; std::weak_ptr<AnimNode> _parent;
std::vector<QString> _outputJointNames; std::vector<QString> _outputJointNames;
bool _active { false };
// no copies // no copies
AnimNode(const AnimNode&) = delete; AnimNode(const AnimNode&) = delete;

View file

@ -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) { const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
float parentDebugAlpha = context.getDebugAlpha(_id); float parentDebugAlpha = context.getDebugAlpha(_id);
AnimRandomSwitch::RandomSwitchState::Pointer desiredState = _currentState; 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. // filter states different to the last random state and with priorities.
bool currentStateHasPriority = false; bool currentStateHasPriority = false;
std::vector<RandomSwitchState::Pointer> randomStatesToConsider; std::vector<RandomSwitchState::Pointer> randomStatesToConsider;
@ -56,8 +60,9 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
} }
lowerBound = upperBound; lowerBound = upperBound;
} }
if (abs(_randomSwitchEvaluationCount - context.getEvaluationCount()) > 1) { if (_triggerNewRandomState) {
switchRandomState(animVars, context, desiredState, false); switchRandomState(animVars, context, desiredState, false);
_triggerNewRandomState = false;
} else { } else {
// firing a random switch, be sure that we aren't completing a previously triggered transition // firing a random switch, be sure that we aren't completing a previously triggered transition
if (currentStateHasPriority) { if (currentStateHasPriority) {
@ -70,7 +75,6 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
} }
_triggerTime = randFloatInRange(_triggerTimeMin, _triggerTimeMax); _triggerTime = randFloatInRange(_triggerTimeMin, _triggerTimeMax);
_randomSwitchTime = randFloatInRange(_randomSwitchTimeMin, _randomSwitchTimeMax); _randomSwitchTime = randFloatInRange(_randomSwitchTimeMin, _randomSwitchTimeMax);
} else { } else {
// here we are checking to see if we want a temporary movement // 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); _poses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
} }
_randomSwitchEvaluationCount = context.getEvaluationCount();
processOutputJoints(triggersOut); processOutputJoints(triggersOut);
context.addStateMachineInfo(_id, _currentState->getID(), _previousState->getID(), _duringInterp, _alpha); context.addStateMachineInfo(_id, _currentState->getID(), _previousState->getID(), _duringInterp, _alpha);

View file

@ -151,10 +151,11 @@ protected:
// for AnimDebugDraw rendering // for AnimDebugDraw rendering
virtual const AnimPoseVec& getPosesInternal() const override; virtual const AnimPoseVec& getPosesInternal() const override;
virtual void setActiveInternal(bool active) override;
AnimPoseVec _poses; AnimPoseVec _poses;
int _randomSwitchEvaluationCount { 0 }; bool _triggerNewRandomState = false;
// interpolation state // interpolation state
bool _duringInterp = false; bool _duringInterp = false;
InterpType _interpType { InterpType::SnapshotPrev }; InterpType _interpType { InterpType::SnapshotPrev };

View file

@ -128,6 +128,10 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon
auto prevStateNode = _children[_currentState->getChildIndex()]; auto prevStateNode = _children[_currentState->getChildIndex()];
auto nextStateNode = _children[desiredState->getChildIndex()]; auto nextStateNode = _children[desiredState->getChildIndex()];
// activate/deactivate states
prevStateNode->setActive(false);
nextStateNode->setActive(true);
bool interpActive = _duringInterp; bool interpActive = _duringInterp;
_duringInterp = true; _duringInterp = true;
_alpha = 0.0f; _alpha = 0.0f;