mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-29 14:02:59 +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
|
// load the anim graph
|
||||||
// https://gist.github.com/hyperlogic/7d6a0892a7319c69e2b9
|
// 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));
|
_animLoader.reset(new AnimNodeLoader(graphUrl));
|
||||||
connect(_animLoader.get(), &AnimNodeLoader::success, [this](AnimNode::Pointer nodeIn) {
|
connect(_animLoader.get(), &AnimNodeLoader::success, [this](AnimNode::Pointer nodeIn) {
|
||||||
_animNode = nodeIn;
|
_animNode = nodeIn;
|
||||||
|
|
|
@ -48,7 +48,7 @@ const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, flo
|
||||||
if (prevPoses.size() > 0 && prevPoses.size() == nextPoses.size()) {
|
if (prevPoses.size() > 0 && prevPoses.size() == nextPoses.size()) {
|
||||||
_poses.resize(prevPoses.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];
|
const AnimPoseVec& nextFrame = _anim[nextIndex];
|
||||||
float alpha = glm::fract(_frame);
|
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;
|
return _poses;
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
|
|
||||||
friend class AnimDebugDraw;
|
friend class AnimDebugDraw;
|
||||||
friend void buildChildMap(std::map<std::string, Pointer>& map, Pointer node);
|
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) {}
|
AnimNode(Type type, const std::string& id) : _type(type), _id(id) {}
|
||||||
virtual ~AnimNode() {}
|
virtual ~AnimNode() {}
|
||||||
|
|
|
@ -57,7 +57,7 @@ const AnimPoseVec& AnimOverlay::evaluate(const AnimVariantMap& animVars, float d
|
||||||
|
|
||||||
for (size_t i = 0; i < _poses.size(); i++) {
|
for (size_t i = 0; i < _poses.size(); i++) {
|
||||||
float alpha = _boneSetVec[i] * _alpha;
|
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 "AnimStateMachine.h"
|
||||||
|
#include "AnimUtil.h"
|
||||||
#include "AnimationLogging.h"
|
#include "AnimationLogging.h"
|
||||||
|
|
||||||
AnimStateMachine::AnimStateMachine(const std::string& id) :
|
AnimStateMachine::AnimStateMachine(const std::string& id) :
|
||||||
|
@ -19,8 +20,6 @@ AnimStateMachine::~AnimStateMachine() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, float dt) {
|
const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, float dt) {
|
||||||
|
|
||||||
std::string desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID());
|
std::string desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID());
|
||||||
|
@ -29,7 +28,7 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, fl
|
||||||
bool foundState = false;
|
bool foundState = false;
|
||||||
for (auto& state : _states) {
|
for (auto& state : _states) {
|
||||||
if (state->getID() == desiredStateID) {
|
if (state->getID() == desiredStateID) {
|
||||||
switchState(state);
|
switchState(animVars, state);
|
||||||
foundState = true;
|
foundState = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -42,26 +41,27 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, fl
|
||||||
// evaluate currentState transitions
|
// evaluate currentState transitions
|
||||||
auto desiredState = evaluateTransitions(animVars);
|
auto desiredState = evaluateTransitions(animVars);
|
||||||
if (desiredState != _currentState) {
|
if (desiredState != _currentState) {
|
||||||
switchState(desiredState);
|
switchState(animVars, desiredState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
assert(_currentState);
|
||||||
|
auto currentStateNode = _currentState->getNode();
|
||||||
|
assert(currentStateNode);
|
||||||
|
|
||||||
if (_duringInterp) {
|
if (_duringInterp) {
|
||||||
// TODO: do interpolation
|
_alpha += _alphaVel * dt;
|
||||||
/*
|
if (_alpha < 1.0f) {
|
||||||
const float FRAMES_PER_SECOND = 30.0f;
|
::blend(_poses.size(), &_prevPoses[0], &_nextPoses[0], _alpha, &_poses[0]);
|
||||||
// blend betwen poses
|
} else {
|
||||||
blend(_poses.size(), _prevPose, _nextPose, _alpha, &_poses[0]);
|
_duringInterp = false;
|
||||||
*/
|
_prevPoses.clear();
|
||||||
} else {
|
_nextPoses.clear();
|
||||||
// eval current state
|
}
|
||||||
assert(_currentState);
|
}
|
||||||
auto currentStateNode = _currentState->getNode();
|
if (!_duringInterp) {
|
||||||
assert(currentStateNode);
|
|
||||||
_poses = currentStateNode->evaluate(animVars, dt);
|
_poses = currentStateNode->evaluate(animVars, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(animation) << "StateMachine::evalute";
|
|
||||||
|
|
||||||
return _poses;
|
return _poses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,9 +73,23 @@ void AnimStateMachine::addState(State::Pointer state) {
|
||||||
_states.push_back(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();
|
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;
|
_currentState = desiredState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ protected:
|
||||||
|
|
||||||
void addState(State::Pointer state);
|
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;
|
State::Pointer evaluateTransitions(const AnimVariantMap& animVars) const;
|
||||||
|
|
||||||
// for AnimDebugDraw rendering
|
// for AnimDebugDraw rendering
|
||||||
|
@ -97,9 +97,8 @@ protected:
|
||||||
|
|
||||||
// interpolation state
|
// interpolation state
|
||||||
bool _duringInterp = false;
|
bool _duringInterp = false;
|
||||||
float _interpFrame;
|
float _alphaVel = 0.0f;
|
||||||
float _interpDuration;
|
float _alpha = 0.0f;
|
||||||
float _alpha;
|
|
||||||
AnimPoseVec _prevPoses;
|
AnimPoseVec _prevPoses;
|
||||||
AnimPoseVec _nextPoses;
|
AnimPoseVec _nextPoses;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue