mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 16:23:16 +02:00
Added basic interpolation support to AnimStateMachine
This commit is contained in:
parent
3286a32afc
commit
19e91bb392
7 changed files with 42 additions and 28 deletions
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
|
||||
friend class AnimDebugDraw;
|
||||
friend void buildChildMap(std::map<std::string, Pointer>& map, Pointer node);
|
||||
friend class AnimStateMachine;
|
||||
|
||||
AnimNode(Type type, const std::string& id) : _type(type), _id(id) {}
|
||||
virtual ~AnimNode() {}
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue