Bugfix for evaluateBoth interpType.

It wouldn't pick the correct starting frame of the state being switched to.
Also, interping out of a evaluateBoth interp uses a snapshot.
This commit is contained in:
Anthony J. Thibault 2019-08-06 17:40:28 -07:00
parent 3f6b488f27
commit b306ed69d6
2 changed files with 25 additions and 8 deletions

View file

@ -44,14 +44,12 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
}
}
if (abs(_randomSwitchEvaluationCount - context.getEvaluationCount()) > 1) {
_duringInterp = false;
switchRandomState(animVars, context, desiredState, _duringInterp);
switchRandomState(animVars, context, desiredState, false);
} else {
// firing a random switch, be sure that we aren't completing a previously triggered transition
if (currentStateHasPriority) {
if (desiredState->getID() != _currentState->getID()) {
_duringInterp = true;
switchRandomState(animVars, context, desiredState, _duringInterp);
switchRandomState(animVars, context, desiredState, true);
} else {
_duringInterp = false;
}
@ -66,8 +64,7 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
// evaluate currentState transitions
auto transitionState = evaluateTransitions(animVars);
if (transitionState != _currentState) {
_duringInterp = true;
switchRandomState(animVars, context, transitionState, _duringInterp);
switchRandomState(animVars, context, transitionState, true);
_triggerTime = randFloatInRange(_triggerTimeMin, _triggerTimeMax);
_randomSwitchTime = randFloatInRange(_randomSwitchTimeMin, _randomSwitchTimeMax);
}
@ -159,6 +156,9 @@ void AnimRandomSwitch::switchRandomState(const AnimVariantMap& animVars, const A
auto nextStateNode = _children[desiredState->getChildIndex()];
if (shouldInterp) {
bool interpActive = _duringInterp;
_duringInterp = true;
const float FRAMES_PER_SECOND = 30.0f;
auto prevStateNode = _children[_currentState->getChildIndex()];
@ -182,13 +182,21 @@ void AnimRandomSwitch::switchRandomState(const AnimVariantMap& animVars, const A
}
_nextPoses = nextStateNode->evaluate(animVars, context, dt, triggers);
} else if (_interpType == InterpType::SnapshotPrev) {
// snapshot previoius pose
// snapshot previous pose
_prevPoses = _poses;
// no need to evaluate _nextPoses we will do it dynamically during the interp,
// however we need to set the current frame.
if (!desiredState->getResume()) {
nextStateNode->setCurrentFrame(desiredState->_interpTarget - duration);
}
} else if (_interpType == InterpType::EvaluateBoth) {
// need to set current frame in destination branch.
nextStateNode->setCurrentFrame(desiredState->_interpTarget - duration);
if (interpActive) {
// snapshot previous pose
_prevPoses = _poses;
_interpType = InterpType::SnapshotPrev;
}
} else {
assert(false);
}

View file

@ -128,6 +128,7 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon
auto prevStateNode = _children[_currentState->getChildIndex()];
auto nextStateNode = _children[desiredState->getChildIndex()];
bool interpActive = _duringInterp;
_duringInterp = true;
_alpha = 0.0f;
float duration = std::max(0.001f, animVars.lookup(desiredState->_interpDurationVar, desiredState->_interpDuration));
@ -146,11 +147,19 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon
nextStateNode->setCurrentFrame(desiredState->_interpTarget);
_nextPoses = nextStateNode->evaluate(animVars, context, dt, triggers);
} else if (_interpType == InterpType::SnapshotPrev) {
// snapshot previoius pose
// snapshot previous pose
_prevPoses = _poses;
// no need to evaluate _nextPoses we will do it dynamically during the interp,
// however we need to set the current frame.
nextStateNode->setCurrentFrame(desiredState->_interpTarget - duration);
} else if (_interpType == InterpType::EvaluateBoth) {
// need to set current frame in destination branch.
nextStateNode->setCurrentFrame(desiredState->_interpTarget - duration);
if (interpActive) {
// snapshot previous pose
_prevPoses = _poses;
_interpType = InterpType::SnapshotPrev;
}
} else {
assert(false);
}