mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Rig: save and restore user animations across resets
This commit is contained in:
parent
b758acb7d8
commit
a1bbb63ec4
2 changed files with 61 additions and 27 deletions
|
@ -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;
|
||||
|
|
|
@ -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 };
|
||||
|
||||
|
|
Loading…
Reference in a new issue