diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4e6aba85f9..d1d62333a7 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1245,7 +1245,7 @@ void MyAvatar::setupNewAnimationSystem() { // load the anim graph // https://gist.github.com/hyperlogic/7d6a0892a7319c69e2b9 - auto graphUrl = QUrl("https://gist.githubusercontent.com/hyperlogic/7d6a0892a7319c69e2b9/raw/c684000794675bc84ed63efefc21870e47c58d6a/avatar.json"); + auto graphUrl = QUrl("https://gist.githubusercontent.com/hyperlogic/7d6a0892a7319c69e2b9/raw/250ce1f207e23c74694351f04367063cf1269f94/avatar.json"); _animLoader.reset(new AnimNodeLoader(graphUrl)); connect(_animLoader.get(), &AnimNodeLoader::success, [this](AnimNode::Pointer nodeIn) { _animNode = nodeIn; diff --git a/libraries/animation/src/AnimBlendLinear.cpp b/libraries/animation/src/AnimBlendLinear.cpp index c505984b87..102d0e4df6 100644 --- a/libraries/animation/src/AnimBlendLinear.cpp +++ b/libraries/animation/src/AnimBlendLinear.cpp @@ -48,7 +48,7 @@ const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, flo if (prevPoses.size() > 0 && prevPoses.size() == nextPoses.size()) { _poses.resize(prevPoses.size()); - blend(_poses.size(), &prevPoses[0], &nextPoses[0], alpha, &_poses[0]); + ::blend(_poses.size(), &prevPoses[0], &nextPoses[0], alpha, &_poses[0]); } } } diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index e4eb63f23a..4f3ea54e34 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -61,7 +61,7 @@ const AnimPoseVec& AnimClip::evaluate(const AnimVariantMap& animVars, float dt) const AnimPoseVec& nextFrame = _anim[nextIndex]; float alpha = glm::fract(_frame); - blend(_poses.size(), &prevFrame[0], &nextFrame[0], alpha, &_poses[0]); + ::blend(_poses.size(), &prevFrame[0], &nextFrame[0], alpha, &_poses[0]); } return _poses; diff --git a/libraries/animation/src/AnimNode.h b/libraries/animation/src/AnimNode.h index b6eedf9b2e..0b521211a2 100644 --- a/libraries/animation/src/AnimNode.h +++ b/libraries/animation/src/AnimNode.h @@ -44,6 +44,7 @@ public: friend class AnimDebugDraw; friend void buildChildMap(std::map& map, Pointer node); + friend class AnimStateMachine; AnimNode(Type type, const std::string& id) : _type(type), _id(id) {} virtual ~AnimNode() {} diff --git a/libraries/animation/src/AnimOverlay.cpp b/libraries/animation/src/AnimOverlay.cpp index 21c893810a..81df5811d7 100644 --- a/libraries/animation/src/AnimOverlay.cpp +++ b/libraries/animation/src/AnimOverlay.cpp @@ -57,7 +57,7 @@ const AnimPoseVec& AnimOverlay::evaluate(const AnimVariantMap& animVars, float d for (size_t i = 0; i < _poses.size(); i++) { float alpha = _boneSetVec[i] * _alpha; - blend(1, &underPoses[i], &overPoses[i], alpha, &_poses[i]); + ::blend(1, &underPoses[i], &overPoses[i], alpha, &_poses[i]); } } } diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp index 2faea905de..43bb305797 100644 --- a/libraries/animation/src/AnimStateMachine.cpp +++ b/libraries/animation/src/AnimStateMachine.cpp @@ -8,6 +8,7 @@ // #include "AnimStateMachine.h" +#include "AnimUtil.h" #include "AnimationLogging.h" AnimStateMachine::AnimStateMachine(const std::string& id) : @@ -19,8 +20,6 @@ AnimStateMachine::~AnimStateMachine() { } - - const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, float dt) { std::string desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID()); @@ -29,7 +28,7 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, fl bool foundState = false; for (auto& state : _states) { if (state->getID() == desiredStateID) { - switchState(state); + switchState(animVars, state); foundState = true; break; } @@ -42,26 +41,27 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, fl // evaluate currentState transitions auto desiredState = evaluateTransitions(animVars); if (desiredState != _currentState) { - switchState(desiredState); + switchState(animVars, desiredState); } + + assert(_currentState); + auto currentStateNode = _currentState->getNode(); + assert(currentStateNode); + if (_duringInterp) { - // TODO: do interpolation - /* - const float FRAMES_PER_SECOND = 30.0f; - // blend betwen poses - blend(_poses.size(), _prevPose, _nextPose, _alpha, &_poses[0]); - */ - } else { - // eval current state - assert(_currentState); - auto currentStateNode = _currentState->getNode(); - assert(currentStateNode); + _alpha += _alphaVel * dt; + if (_alpha < 1.0f) { + ::blend(_poses.size(), &_prevPoses[0], &_nextPoses[0], _alpha, &_poses[0]); + } else { + _duringInterp = false; + _prevPoses.clear(); + _nextPoses.clear(); + } + } + if (!_duringInterp) { _poses = currentStateNode->evaluate(animVars, dt); } - - qCDebug(animation) << "StateMachine::evalute"; - return _poses; } @@ -73,9 +73,23 @@ void AnimStateMachine::addState(State::Pointer state) { _states.push_back(state); } -void AnimStateMachine::switchState(State::Pointer desiredState) { +void AnimStateMachine::switchState(const AnimVariantMap& animVars, State::Pointer desiredState) { + qCDebug(animation) << "AnimStateMachine::switchState:" << _currentState->getID().c_str() << "->" << desiredState->getID().c_str(); - // TODO: interp. + + const float FRAMES_PER_SECOND = 30.0f; + + auto prevStateNode = _currentState->getNode(); + auto nextStateNode = desiredState->getNode(); + + _duringInterp = true; + _alpha = 0.0f; + float duration = std::max(0.001f, animVars.lookup(desiredState->_interpDurationVar, desiredState->_interpDuration)); + _alphaVel = FRAMES_PER_SECOND / duration; + _prevPoses = _poses; + nextStateNode->setCurrentFrame(desiredState->_interpTarget); + _nextPoses = nextStateNode->evaluate(animVars, 0.0f); + _currentState = desiredState; } diff --git a/libraries/animation/src/AnimStateMachine.h b/libraries/animation/src/AnimStateMachine.h index 148429e722..4e9a4b3214 100644 --- a/libraries/animation/src/AnimStateMachine.h +++ b/libraries/animation/src/AnimStateMachine.h @@ -87,7 +87,7 @@ protected: void addState(State::Pointer state); - void switchState(State::Pointer desiredState); + void switchState(const AnimVariantMap& animVars, State::Pointer desiredState); State::Pointer evaluateTransitions(const AnimVariantMap& animVars) const; // for AnimDebugDraw rendering @@ -97,9 +97,8 @@ protected: // interpolation state bool _duringInterp = false; - float _interpFrame; - float _interpDuration; - float _alpha; + float _alphaVel = 0.0f; + float _alpha = 0.0f; AnimPoseVec _prevPoses; AnimPoseVec _nextPoses;