mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-08 01:42:25 +02:00
Merge pull request #16104 from luiscuenca/fixRandomAnim
DEV-327: Prevent AnimRandomSwitch from repeating same animation twice in a row.
This commit is contained in:
commit
55238200f1
5 changed files with 32 additions and 6 deletions
|
@ -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;
|
||||
|
|
|
@ -73,6 +73,7 @@ public:
|
|||
}
|
||||
|
||||
void setCurrentFrame(float frame);
|
||||
void setActive(bool active);
|
||||
|
||||
template <typename F>
|
||||
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<AnimNode> _parent;
|
||||
std::vector<QString> _outputJointNames;
|
||||
bool _active { false };
|
||||
|
||||
// no copies
|
||||
AnimNode(const AnimNode&) = delete;
|
||||
|
|
|
@ -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<RandomSwitchState::Pointer> 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);
|
||||
|
@ -165,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;
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue