Rig: save and restore user animations across resets

This commit is contained in:
Anthony J. Thibault 2016-04-12 14:51:17 -07:00
parent b758acb7d8
commit a1bbb63ec4
2 changed files with 61 additions and 27 deletions

View file

@ -48,36 +48,47 @@ const glm::vec3 DEFAULT_NECK_POS(0.0f, 0.70f, 0.0f);
void Rig::overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame) { void Rig::overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame) {
// find an unused AnimClip clipNode UserAnimState::ClipNodeEnum clipNodeEnum;
std::shared_ptr<AnimClip> clip; if (_userAnimState.clipNodeEnum == UserAnimState::None || _userAnimState.clipNodeEnum == UserAnimState::B) {
if (_userAnimState == UserAnimState::None || _userAnimState == UserAnimState::B) { clipNodeEnum = UserAnimState::A;
_userAnimState = UserAnimState::A; } else {
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("userAnimA")); clipNodeEnum = UserAnimState::B;
} else if (_userAnimState == UserAnimState::A) {
_userAnimState = UserAnimState::B;
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("userAnimB"));
} }
// set parameters if (_animNode) {
clip->setLoopFlag(loop); // find an unused AnimClip clipNode
clip->setStartFrame(firstFrame); std::shared_ptr<AnimClip> clip;
clip->setEndFrame(lastFrame); if (clipNodeEnum == UserAnimState::A) {
const float REFERENCE_FRAMES_PER_SECOND = 30.0f; clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("userAnimA"));
float timeScale = fps / REFERENCE_FRAMES_PER_SECOND; } else {
clip->setTimeScale(timeScale); clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("userAnimB"));
clip->loadURL(url); }
_currentUserAnimURL = url; if (clip) {
// set parameters
clip->setLoopFlag(loop);
clip->setStartFrame(firstFrame);
clip->setEndFrame(lastFrame);
const float REFERENCE_FRAMES_PER_SECOND = 30.0f;
float timeScale = fps / REFERENCE_FRAMES_PER_SECOND;
clip->setTimeScale(timeScale);
clip->loadURL(url);
}
}
// store current user anim state.
_userAnimState = { clipNodeEnum, url, fps, loop, firstFrame, lastFrame };
// notify the userAnimStateMachine the desired state. // notify the userAnimStateMachine the desired state.
_animVars.set("userAnimNone", false); _animVars.set("userAnimNone", false);
_animVars.set("userAnimA", _userAnimState == UserAnimState::A); _animVars.set("userAnimA", clipNodeEnum == UserAnimState::A);
_animVars.set("userAnimB", _userAnimState == UserAnimState::B); _animVars.set("userAnimB", clipNodeEnum == UserAnimState::B);
} }
void Rig::restoreAnimation() { void Rig::restoreAnimation() {
if (_currentUserAnimURL != "") { if (_userAnimState.clipNodeEnum != UserAnimState::None) {
_currentUserAnimURL = ""; _userAnimState.clipNodeEnum = UserAnimState::None;
// notify the userAnimStateMachine the desired state. // notify the userAnimStateMachine the desired state.
_animVars.set("userAnimNone", true); _animVars.set("userAnimNone", true);
_animVars.set("userAnimA", false); _animVars.set("userAnimA", false);
@ -1129,6 +1140,14 @@ void Rig::initAnimGraph(const QUrl& url) {
connect(_animLoader.get(), &AnimNodeLoader::success, [this](AnimNode::Pointer nodeIn) { connect(_animLoader.get(), &AnimNodeLoader::success, [this](AnimNode::Pointer nodeIn) {
_animNode = nodeIn; _animNode = nodeIn;
_animNode->setSkeleton(_animSkeleton); _animNode->setSkeleton(_animSkeleton);
if (_userAnimState.clipNodeEnum != UserAnimState::None) {
// restore the user animation we had before reset.
UserAnimState origState = _userAnimState;
_userAnimState = { UserAnimState::None, "", 30.0f, false, 0.0f, 0.0f };
overrideAnimation(origState.url, origState.fps, origState.loop, origState.firstFrame, origState.lastFrame);
}
}); });
connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) { connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) {
qCCritical(animation) << "Error loading" << url.toDisplayString() << "code = " << error << "str =" << str; qCCritical(animation) << "Error loading" << url.toDisplayString() << "code = " << error << "str =" << str;

View file

@ -289,13 +289,28 @@ public:
RigRole _state { RigRole::Idle }; RigRole _state { RigRole::Idle };
RigRole _desiredState { RigRole::Idle }; RigRole _desiredState { RigRole::Idle };
float _desiredStateAge { 0.0f }; float _desiredStateAge { 0.0f };
enum class UserAnimState {
None = 0, struct UserAnimState {
A, enum ClipNodeEnum {
B None = 0,
A,
B
};
UserAnimState() : clipNodeEnum(UserAnimState::None) {}
UserAnimState(ClipNodeEnum clipNodeEnumIn, const QString& urlIn, float fpsIn, bool loopIn, float firstFrameIn, float lastFrameIn) :
clipNodeEnum(clipNodeEnumIn), url(urlIn), fps(fpsIn), loop(loopIn), firstFrame(firstFrameIn), lastFrame(lastFrameIn) {}
ClipNodeEnum clipNodeEnum;
QString url;
float fps;
bool loop;
float firstFrame;
float lastFrame;
}; };
UserAnimState _userAnimState { UserAnimState::None };
QString _currentUserAnimURL; UserAnimState _userAnimState;
float _leftHandOverlayAlpha { 0.0f }; float _leftHandOverlayAlpha { 0.0f };
float _rightHandOverlayAlpha { 0.0f }; float _rightHandOverlayAlpha { 0.0f };