corrected the case where you have a random switch state trigger and a random transition trigger in the same random state machine

This commit is contained in:
Angus Antley 2019-04-25 13:57:58 -07:00
parent baca58360e
commit 76164ecee8
2 changed files with 17 additions and 9 deletions

View file

@ -27,6 +27,7 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
AnimRandomSwitch::RandomSwitchState::Pointer desiredState = _currentState; AnimRandomSwitch::RandomSwitchState::Pointer desiredState = _currentState;
if (abs(_framesActive - context.getFramesAnimatedThisSession()) > 1 || animVars.lookup(_triggerRandomSwitchVar, false)) { if (abs(_framesActive - context.getFramesAnimatedThisSession()) > 1 || animVars.lookup(_triggerRandomSwitchVar, false)) {
// get a random number and decide which motion to choose. // get a random number and decide which motion to choose.
bool currentStateHasPriority = false;
float dice = randFloatInRange(0.0f, 1.0f); float dice = randFloatInRange(0.0f, 1.0f);
float lowerBound = 0.0f; float lowerBound = 0.0f;
for (const RandomSwitchState::Pointer& randState : _randomStates) { for (const RandomSwitchState::Pointer& randState : _randomStates) {
@ -38,17 +39,22 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
} else { } else {
lowerBound = upperBound; lowerBound = upperBound;
} }
// this indicates if the curent state is one that can be selected randomly, or is one that was transitioned to by the random duration timer.
currentStateHasPriority = currentStateHasPriority || (_currentState == randState);
} }
} }
if (abs(_framesActive - context.getFramesAnimatedThisSession()) > 1) { if (abs(_framesActive - context.getFramesAnimatedThisSession()) > 1) {
_duringInterp = false; _duringInterp = false;
switchRandomState(animVars, context, desiredState, _duringInterp); switchRandomState(animVars, context, desiredState, _duringInterp);
} else { } else {
if (desiredState->getID() != _currentState->getID()) { // firing a random switch, be sure that we aren't completing a previously triggered transition
_duringInterp = true; if (currentStateHasPriority) {
switchRandomState(animVars, context, desiredState, _duringInterp); if (desiredState->getID() != _currentState->getID()) {
} else { _duringInterp = true;
_duringInterp = false; switchRandomState(animVars, context, desiredState, _duringInterp);
} else {
_duringInterp = false;
}
} }
} }
_triggerTime = randFloatInRange(_triggerTimeMin, _triggerTimeMax); _triggerTime = randFloatInRange(_triggerTimeMin, _triggerTimeMax);
@ -72,9 +78,12 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
_triggerTime = randFloatInRange(_triggerTimeMin, _triggerTimeMax); _triggerTime = randFloatInRange(_triggerTimeMin, _triggerTimeMax);
triggersOut.setTrigger(_transitionVar); triggersOut.setTrigger(_transitionVar);
} }
_randomSwitchTime -= dt; _randomSwitchTime -= dt;
if ((_randomSwitchTime < 0.0f) && (_randomSwitchTimeMin > 0.0f) && (_randomSwitchTimeMax > 0.0f)) { if ((_randomSwitchTime < 0.0f) && (_randomSwitchTimeMin > 0.0f) && (_randomSwitchTimeMax > 0.0f)) {
_randomSwitchTime = randFloatInRange(_randomSwitchTimeMin, _randomSwitchTimeMax); _randomSwitchTime = randFloatInRange(_randomSwitchTimeMin, _randomSwitchTimeMax);
// restart the trigger timer if it is also enabled
_triggerTime = randFloatInRange(_triggerTimeMin, _triggerTimeMax);
triggersOut.setTrigger(_triggerRandomSwitchVar); triggersOut.setTrigger(_triggerRandomSwitchVar);
} }
@ -106,7 +115,6 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
} }
context.setDebugAlpha(_currentState->getID(), _alpha * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType()); context.setDebugAlpha(_currentState->getID(), _alpha * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType());
} else { } else {
AnimPoseVec checkNodes = currentStateNode->evaluate(animVars, context, dt, triggersOut);
_duringInterp = false; _duringInterp = false;
_prevPoses.clear(); _prevPoses.clear();
_nextPoses.clear(); _nextPoses.clear();

View file

@ -2025,7 +2025,7 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
if (params.isTalking) { if (params.isTalking) {
if (_talkIdleInterpTime < 1.0f) { if (_talkIdleInterpTime < 1.0f) {
_talkIdleInterpTime += dt / TOTAL_EASE_IN_TIME; _talkIdleInterpTime += dt / TOTAL_EASE_IN_TIME;
float easeOutInValue = _talkIdleInterpTime < 0.5f ? (4.0f * _talkIdleInterpTime * _talkIdleInterpTime * _talkIdleInterpTime) : (4.0f * (_talkIdleInterpTime - 1.0f) * (_talkIdleInterpTime - 1.0f) * (_talkIdleInterpTime - 1.0f)) + 1.0f; float easeOutInValue = _talkIdleInterpTime < 0.5f ? 4.0f * powf(_talkIdleInterpTime, 3.0f) : 4.0f * powf((_talkIdleInterpTime - 1.0f), 3.0f) + 1.0f;
_animVars.set("idleOverlayAlpha", easeOutInValue); _animVars.set("idleOverlayAlpha", easeOutInValue);
} else { } else {
_animVars.set("idleOverlayAlpha", 1.0f); _animVars.set("idleOverlayAlpha", 1.0f);
@ -2033,7 +2033,7 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
} else { } else {
if (_talkIdleInterpTime < 1.0f) { if (_talkIdleInterpTime < 1.0f) {
_talkIdleInterpTime += dt / TOTAL_EASE_OUT_TIME; _talkIdleInterpTime += dt / TOTAL_EASE_OUT_TIME;
float easeOutInValue = _talkIdleInterpTime < 0.5f ? (4.0f * _talkIdleInterpTime * _talkIdleInterpTime * _talkIdleInterpTime) : (4.0f * (_talkIdleInterpTime - 1.0f) * (_talkIdleInterpTime - 1.0f) * (_talkIdleInterpTime - 1.0f)) + 1.0f; float easeOutInValue = _talkIdleInterpTime < 0.5f ? 4.0f * powf(_talkIdleInterpTime, 3.0f) : 4.0f * powf((_talkIdleInterpTime - 1.0f), 3.0f) + 1.0f;
float talkAlpha = 1.0f - easeOutInValue; float talkAlpha = 1.0f - easeOutInValue;
_animVars.set("idleOverlayAlpha", talkAlpha); _animVars.set("idleOverlayAlpha", talkAlpha);
} else { } else {