From da63e85699c62271145962f7a1b1d95ab87a70f4 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 1 Nov 2017 09:17:04 -0700 Subject: [PATCH 1/5] Bug 8270 fixed --- libraries/animation/src/AnimClip.h | 1 + libraries/animation/src/Rig.cpp | 21 +++++++++++++++++++ libraries/animation/src/Rig.h | 2 ++ .../src/avatars-renderer/Avatar.cpp | 12 +++++++++++ .../src/avatars-renderer/Avatar.h | 3 +++ 5 files changed, 39 insertions(+) diff --git a/libraries/animation/src/AnimClip.h b/libraries/animation/src/AnimClip.h index c7e7ebf3ee..7121cff356 100644 --- a/libraries/animation/src/AnimClip.h +++ b/libraries/animation/src/AnimClip.h @@ -54,6 +54,7 @@ public: void setMirrorFlag(bool mirrorFlag) { _mirrorFlag = mirrorFlag; } void loadURL(const QString& url); + const QString& getURL() { return _url; } protected: virtual void setCurrentFrameInternal(float frame) override; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 0f2bce5ca4..8293cb91f4 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -144,6 +144,27 @@ QStringList Rig::getAnimationRoles() const { } } +QVector> Rig::getAnimationClips() const { + QVector> list; + if (_animNode) { + _animNode->traverse([&](AnimNode::Pointer node) { + // only report clip nodes as valid roles. + auto clipNode = std::dynamic_pointer_cast(node); + if (clipNode) { + // filter out the userAnims, they are for internal use only. + if (!clipNode->getID().startsWith("userAnim")) { + list.append(clipNode); + } + } + return true; + }); + return list; + } + else { + return list; + } +} + void Rig::overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame) { if (_animNode) { AnimNode::Pointer node = _animNode->findByName(role); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 18d49c5f1e..9290b41513 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -21,6 +21,7 @@ #include #include +#include "AnimClip.h" #include "AnimNode.h" #include "AnimNodeLoader.h" #include "SimpleMovingAverage.h" @@ -107,6 +108,7 @@ public: QStringList getAnimationRoles() const; void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame); void restoreRoleAnimation(const QString& role); + QVector> getAnimationClips() const; void initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset); void reset(const FBXGeometry& geometry); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 142e57c9e5..0d2e730a1a 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -139,6 +139,7 @@ Avatar::~Avatar() { void Avatar::init() { getHead()->init(); _skeletonModel->init(); + connect(&_skeletonModel->getRig(), &Rig::onLoadComplete, this, &Avatar::restoreAnimations); _initialized = true; } @@ -198,6 +199,16 @@ void Avatar::setTargetScale(float targetScale) { } } +void Avatar::restoreAnimations() { + for (int i = 0; i < _animationCache.size(); i++) { + auto clip = _animationCache[i]; + const float REFERENCE_FRAMES_PER_SECOND = 30.0f; + float fps = REFERENCE_FRAMES_PER_SECOND / clip->getTimeScale(); + qDebug() << clip->getID() << " " << clip->getURL() << " " << fps << " " << clip->getLoopFlag() << " " << clip->getStartFrame() << " " << clip->getEndFrame(); + _skeletonModel->getRig().overrideRoleAnimation(clip->getID(), clip->getURL(), fps, clip->getLoopFlag(), clip->getStartFrame(), clip->getEndFrame()); + } +} + void Avatar::updateAvatarEntities() { PerformanceTimer perfTimer("attachments"); // - if queueEditEntityMessage sees clientOnly flag it does _myAvatar->updateAvatarEntity() @@ -1177,6 +1188,7 @@ void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const { } void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { + _animationCache = _skeletonModel->getRig().getAnimationClips(); AvatarData::setSkeletonModelURL(skeletonModelURL); if (QThread::currentThread() == thread()) { _skeletonModel->setURL(_skeletonModelURL); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index a5ec307c50..09e1451aa9 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -274,6 +274,7 @@ public slots: glm::vec3 getRightPalmPosition() const; glm::quat getRightPalmRotation() const; + void restoreAnimations(); void setModelURLFinished(bool success); protected: @@ -377,6 +378,8 @@ private: float _displayNameTargetAlpha { 1.0f }; float _displayNameAlpha { 1.0f }; + + QVector> _animationCache; }; #endif // hifi_Avatar_h From 6a2dc38fdd402e42b648a74b2254387f85ae1665 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 1 Nov 2017 19:38:37 -0700 Subject: [PATCH 2/5] restoring previous roles --- libraries/animation/src/Rig.cpp | 30 +++++-------------- libraries/animation/src/Rig.h | 17 +++++++++-- .../src/avatars-renderer/Avatar.cpp | 12 -------- .../src/avatars-renderer/Avatar.h | 4 +-- 4 files changed, 24 insertions(+), 39 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 8293cb91f4..e16afc65c2 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -144,27 +144,6 @@ QStringList Rig::getAnimationRoles() const { } } -QVector> Rig::getAnimationClips() const { - QVector> list; - if (_animNode) { - _animNode->traverse([&](AnimNode::Pointer node) { - // only report clip nodes as valid roles. - auto clipNode = std::dynamic_pointer_cast(node); - if (clipNode) { - // filter out the userAnims, they are for internal use only. - if (!clipNode->getID().startsWith("userAnim")) { - list.append(clipNode); - } - } - return true; - }); - return list; - } - else { - return list; - } -} - void Rig::overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame) { if (_animNode) { AnimNode::Pointer node = _animNode->findByName(role); @@ -173,6 +152,7 @@ void Rig::overrideRoleAnimation(const QString& role, const QString& url, float f const float REFERENCE_FRAMES_PER_SECOND = 30.0f; float timeScale = fps / REFERENCE_FRAMES_PER_SECOND; auto clipNode = std::make_shared(role, url, firstFrame, lastFrame, timeScale, loop, false); + _roleAnimState[role] = { role, url, fps, loop, firstFrame, lastFrame }; AnimNode::Pointer parent = node->getParent(); parent->replaceChild(node, clipNode); } else { @@ -1659,8 +1639,14 @@ void Rig::initAnimGraph(const QUrl& url) { _userAnimState = { UserAnimState::None, "", 30.0f, false, 0.0f, 0.0f }; overrideAnimation(origState.url, origState.fps, origState.loop, origState.firstFrame, origState.lastFrame); } + // restore the role animations we had before reset. + for (auto ite = _roleAnimState.begin(); ite != _roleAnimState.end(); ite++) { + auto role = ite->first; + auto roleState = _roleAnimState[role]; + overrideRoleAnimation(roleState.role, roleState.url, roleState.fps, roleState.loop, roleState.firstFrame, roleState.lastFrame); + } _animLoading = false; - + emit onLoadComplete(); }); connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) { diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 9290b41513..a63d5eb0a5 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -21,7 +21,6 @@ #include #include -#include "AnimClip.h" #include "AnimNode.h" #include "AnimNodeLoader.h" #include "SimpleMovingAverage.h" @@ -108,7 +107,7 @@ public: QStringList getAnimationRoles() const; void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame); void restoreRoleAnimation(const QString& role); - QVector> getAnimationClips() const; + //QVector> getAnimationClips() const; void initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset); void reset(const FBXGeometry& geometry); @@ -337,8 +336,22 @@ protected: float firstFrame; float lastFrame; }; + + struct RoleAnimState { + RoleAnimState() {} + RoleAnimState(const QString& roleId, const QString& urlIn, float fpsIn, bool loopIn, float firstFrameIn, float lastFrameIn) : + role(roleId), url(urlIn), fps(fpsIn), loop(loopIn), firstFrame(firstFrameIn), lastFrame(lastFrameIn) {} + + QString role; + QString url; + float fps; + bool loop; + float firstFrame; + float lastFrame; + }; UserAnimState _userAnimState; + std::map _roleAnimState; float _leftHandOverlayAlpha { 0.0f }; float _rightHandOverlayAlpha { 0.0f }; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 0d2e730a1a..142e57c9e5 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -139,7 +139,6 @@ Avatar::~Avatar() { void Avatar::init() { getHead()->init(); _skeletonModel->init(); - connect(&_skeletonModel->getRig(), &Rig::onLoadComplete, this, &Avatar::restoreAnimations); _initialized = true; } @@ -199,16 +198,6 @@ void Avatar::setTargetScale(float targetScale) { } } -void Avatar::restoreAnimations() { - for (int i = 0; i < _animationCache.size(); i++) { - auto clip = _animationCache[i]; - const float REFERENCE_FRAMES_PER_SECOND = 30.0f; - float fps = REFERENCE_FRAMES_PER_SECOND / clip->getTimeScale(); - qDebug() << clip->getID() << " " << clip->getURL() << " " << fps << " " << clip->getLoopFlag() << " " << clip->getStartFrame() << " " << clip->getEndFrame(); - _skeletonModel->getRig().overrideRoleAnimation(clip->getID(), clip->getURL(), fps, clip->getLoopFlag(), clip->getStartFrame(), clip->getEndFrame()); - } -} - void Avatar::updateAvatarEntities() { PerformanceTimer perfTimer("attachments"); // - if queueEditEntityMessage sees clientOnly flag it does _myAvatar->updateAvatarEntity() @@ -1188,7 +1177,6 @@ void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const { } void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { - _animationCache = _skeletonModel->getRig().getAnimationClips(); AvatarData::setSkeletonModelURL(skeletonModelURL); if (QThread::currentThread() == thread()) { _skeletonModel->setURL(_skeletonModelURL); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 09e1451aa9..a06ba0fb82 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -274,7 +274,7 @@ public slots: glm::vec3 getRightPalmPosition() const; glm::quat getRightPalmRotation() const; - void restoreAnimations(); + //void restoreAnimations(); void setModelURLFinished(bool success); protected: @@ -378,8 +378,6 @@ private: float _displayNameTargetAlpha { 1.0f }; float _displayNameAlpha { 1.0f }; - - QVector> _animationCache; }; #endif // hifi_Avatar_h From e201e82ec26aa0ce28b63a1bf36b6c0828e9e6fd Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 1 Nov 2017 19:45:56 -0700 Subject: [PATCH 3/5] formatting --- libraries/animation/src/AnimClip.h | 1 - libraries/animation/src/Rig.cpp | 2 +- libraries/avatars-renderer/src/avatars-renderer/Avatar.h | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/animation/src/AnimClip.h b/libraries/animation/src/AnimClip.h index 7121cff356..c7e7ebf3ee 100644 --- a/libraries/animation/src/AnimClip.h +++ b/libraries/animation/src/AnimClip.h @@ -54,7 +54,6 @@ public: void setMirrorFlag(bool mirrorFlag) { _mirrorFlag = mirrorFlag; } void loadURL(const QString& url); - const QString& getURL() { return _url; } protected: virtual void setCurrentFrameInternal(float frame) override; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index e16afc65c2..9df12de540 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1646,7 +1646,7 @@ void Rig::initAnimGraph(const QUrl& url) { overrideRoleAnimation(roleState.role, roleState.url, roleState.fps, roleState.loop, roleState.firstFrame, roleState.lastFrame); } _animLoading = false; - + emit onLoadComplete(); }); connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) { diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index a06ba0fb82..a5ec307c50 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -274,7 +274,6 @@ public slots: glm::vec3 getRightPalmPosition() const; glm::quat getRightPalmRotation() const; - //void restoreAnimations(); void setModelURLFinished(bool success); protected: From 9e0e1ab5a54c85f3721a629aee5e2e9e67e3dae4 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 1 Nov 2017 19:56:16 -0700 Subject: [PATCH 4/5] erase comment --- libraries/animation/src/Rig.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index a63d5eb0a5..8ca701ec2d 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -107,7 +107,6 @@ public: QStringList getAnimationRoles() const; void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame); void restoreRoleAnimation(const QString& role); - //QVector> getAnimationClips() const; void initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset); void reset(const FBXGeometry& geometry); From 81509b3e92e4a13b3129a97a6ef71e5fcc15869e Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 2 Nov 2017 10:34:57 -0700 Subject: [PATCH 5/5] coding standard --- libraries/animation/src/Rig.cpp | 7 +++---- libraries/animation/src/Rig.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 9df12de540..acf7bf81d8 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -152,7 +152,7 @@ void Rig::overrideRoleAnimation(const QString& role, const QString& url, float f const float REFERENCE_FRAMES_PER_SECOND = 30.0f; float timeScale = fps / REFERENCE_FRAMES_PER_SECOND; auto clipNode = std::make_shared(role, url, firstFrame, lastFrame, timeScale, loop, false); - _roleAnimState[role] = { role, url, fps, loop, firstFrame, lastFrame }; + _roleAnimStates[role] = { role, url, fps, loop, firstFrame, lastFrame }; AnimNode::Pointer parent = node->getParent(); parent->replaceChild(node, clipNode); } else { @@ -1640,9 +1640,8 @@ void Rig::initAnimGraph(const QUrl& url) { overrideAnimation(origState.url, origState.fps, origState.loop, origState.firstFrame, origState.lastFrame); } // restore the role animations we had before reset. - for (auto ite = _roleAnimState.begin(); ite != _roleAnimState.end(); ite++) { - auto role = ite->first; - auto roleState = _roleAnimState[role]; + for (auto& roleAnimState : _roleAnimStates) { + auto roleState = roleAnimState.second; overrideRoleAnimation(roleState.role, roleState.url, roleState.fps, roleState.loop, roleState.firstFrame, roleState.lastFrame); } _animLoading = false; diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 8ca701ec2d..e9cc444bd4 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -350,7 +350,7 @@ protected: }; UserAnimState _userAnimState; - std::map _roleAnimState; + std::map _roleAnimStates; float _leftHandOverlayAlpha { 0.0f }; float _rightHandOverlayAlpha { 0.0f };