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) {
// find an unused AnimClip clipNode
std::shared_ptr<AnimClip> clip;
if (_userAnimState == UserAnimState::None || _userAnimState == UserAnimState::B) {
_userAnimState = UserAnimState::A;
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("userAnimA"));
} else if (_userAnimState == UserAnimState::A) {
_userAnimState = UserAnimState::B;
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("userAnimB"));
UserAnimState::ClipNodeEnum clipNodeEnum;
if (_userAnimState.clipNodeEnum == UserAnimState::None || _userAnimState.clipNodeEnum == UserAnimState::B) {
clipNodeEnum = UserAnimState::A;
} else {
clipNodeEnum = UserAnimState::B;
}
// 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);
if (_animNode) {
// find an unused AnimClip clipNode
std::shared_ptr<AnimClip> clip;
if (clipNodeEnum == UserAnimState::A) {
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("userAnimA"));
} else {
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("userAnimB"));
}
_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.
_animVars.set("userAnimNone", false);
_animVars.set("userAnimA", _userAnimState == UserAnimState::A);
_animVars.set("userAnimB", _userAnimState == UserAnimState::B);
_animVars.set("userAnimA", clipNodeEnum == UserAnimState::A);
_animVars.set("userAnimB", clipNodeEnum == UserAnimState::B);
}
void Rig::restoreAnimation() {
if (_currentUserAnimURL != "") {
_currentUserAnimURL = "";
if (_userAnimState.clipNodeEnum != UserAnimState::None) {
_userAnimState.clipNodeEnum = UserAnimState::None;
// notify the userAnimStateMachine the desired state.
_animVars.set("userAnimNone", true);
_animVars.set("userAnimA", false);
@ -1129,6 +1140,14 @@ void Rig::initAnimGraph(const QUrl& url) {
connect(_animLoader.get(), &AnimNodeLoader::success, [this](AnimNode::Pointer nodeIn) {
_animNode = nodeIn;
_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) {
qCCritical(animation) << "Error loading" << url.toDisplayString() << "code = " << error << "str =" << str;

View file

@ -289,13 +289,28 @@ public:
RigRole _state { RigRole::Idle };
RigRole _desiredState { RigRole::Idle };
float _desiredStateAge { 0.0f };
enum class UserAnimState {
None = 0,
A,
B
struct UserAnimState {
enum ClipNodeEnum {
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 _rightHandOverlayAlpha { 0.0f };