From 8b5f24e4df09515c5a58f9515d6c00fc3eb5cdd3 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 24 Jul 2015 22:02:39 -0700 Subject: [PATCH] Keep list of animations in Rig, not MyAvatar. --- interface/src/avatar/MyAvatar.cpp | 92 +++++++------------------------ interface/src/avatar/MyAvatar.h | 8 +-- libraries/animation/src/Rig.cpp | 87 +++++++++++++++++++++++++++-- libraries/animation/src/Rig.h | 13 ++++- 4 files changed, 118 insertions(+), 82 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 00fce3a1e7..655af63c55 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -491,17 +491,6 @@ void MyAvatar::loadLastRecording() { _player->loadRecording(_recorder->getRecording()); } -AnimationHandlePointer MyAvatar::addAnimationHandle() { - AnimationHandlePointer handle = _rig->createAnimationHandle(); - _animationHandles.append(handle); - return handle; -} - -void MyAvatar::removeAnimationHandle(const AnimationHandlePointer& handle) { - handle->stop(); - _animationHandles.removeOne(handle); -} - void MyAvatar::startAnimation(const QString& url, float fps, float priority, bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) { if (QThread::currentThread() != thread()) { @@ -510,16 +499,7 @@ void MyAvatar::startAnimation(const QString& url, float fps, float priority, Q_ARG(float, lastFrame), Q_ARG(const QStringList&, maskedJoints)); return; } - AnimationHandlePointer handle = _rig->createAnimationHandle(); - handle->setURL(url); - handle->setFPS(fps); - handle->setPriority(priority); - handle->setLoop(loop); - handle->setHold(hold); - handle->setFirstFrame(firstFrame); - handle->setLastFrame(lastFrame); - handle->setMaskedJoints(maskedJoints); - handle->start(); + _rig->startAnimation(url, fps, priority, loop, hold, firstFrame, lastFrame, maskedJoints); } void MyAvatar::startAnimationByRole(const QString& role, const QString& url, float fps, float priority, @@ -530,25 +510,7 @@ void MyAvatar::startAnimationByRole(const QString& role, const QString& url, flo Q_ARG(float, lastFrame), Q_ARG(const QStringList&, maskedJoints)); return; } - // check for a configured animation for the role - foreach (const AnimationHandlePointer& handle, _animationHandles) { - if (handle->getRole() == role) { - handle->start(); - return; - } - } - // no joy; use the parameters provided - AnimationHandlePointer handle = _rig->createAnimationHandle(); - handle->setRole(role); - handle->setURL(url); - handle->setFPS(fps); - handle->setPriority(priority); - handle->setLoop(loop); - handle->setHold(hold); - handle->setFirstFrame(firstFrame); - handle->setLastFrame(lastFrame); - handle->setMaskedJoints(maskedJoints); - handle->start(); + _rig->startAnimationByRole(role, url, fps, priority, loop, hold, firstFrame, lastFrame, maskedJoints); } void MyAvatar::stopAnimationByRole(const QString& role) { @@ -556,11 +518,7 @@ void MyAvatar::stopAnimationByRole(const QString& role) { QMetaObject::invokeMethod(this, "stopAnimationByRole", Q_ARG(const QString&, role)); return; } - foreach (const AnimationHandlePointer& handle, _skeletonModel.getRunningAnimations()) { - if (handle->getRole() == role) { - handle->stop(); - } - } + _rig->stopAnimationByRole(role); } void MyAvatar::stopAnimation(const QString& url) { @@ -568,11 +526,7 @@ void MyAvatar::stopAnimation(const QString& url) { QMetaObject::invokeMethod(this, "stopAnimation", Q_ARG(const QString&, url)); return; } - foreach (const AnimationHandlePointer& handle, _skeletonModel.getRunningAnimations()) { - if (handle->getURL() == url) { - handle->stop(); - } - } + _rig->stopAnimation(url); } AnimationDetails MyAvatar::getAnimationDetailsByRole(const QString& role) { @@ -583,7 +537,7 @@ AnimationDetails MyAvatar::getAnimationDetailsByRole(const QString& role) { Q_ARG(const QString&, role)); return result; } - foreach (const AnimationHandlePointer& handle, _skeletonModel.getRunningAnimations()) { + foreach (const AnimationHandlePointer& handle, _rig->getRunningAnimations()) { if (handle->getRole() == role) { result = handle->getAnimationDetails(); break; @@ -600,7 +554,7 @@ AnimationDetails MyAvatar::getAnimationDetails(const QString& url) { Q_ARG(const QString&, url)); return result; } - foreach (const AnimationHandlePointer& handle, _skeletonModel.getRunningAnimations()) { + foreach (const AnimationHandlePointer& handle, _rig->getRunningAnimations()) { if (handle->getURL() == url) { result = handle->getAnimationDetails(); break; @@ -646,9 +600,11 @@ void MyAvatar::saveData() { settings.endArray(); settings.beginWriteArray("animationHandles"); - for (int i = 0; i < _animationHandles.size(); i++) { + auto animationHandles = _rig->getAnimationHandles(); + for (int i = 0; i < animationHandles.size(); i++) { settings.setArrayIndex(i); - const AnimationHandlePointer& pointer = _animationHandles.at(i); + const AnimationHandlePointer& pointer = animationHandles.at(i); + qCDebug(interfaceapp) << "Save animation" << pointer->getURL().toString(); settings.setValue("role", pointer->getRole()); settings.setValue("url", pointer->getURL()); settings.setValue("fps", pointer->getFPS()); @@ -766,25 +722,19 @@ void MyAvatar::loadData() { setAttachmentData(attachmentData); int animationCount = settings.beginReadArray("animationHandles"); - while (_animationHandles.size() > animationCount) { - _animationHandles.takeLast()->stop(); - } - while (_animationHandles.size() < animationCount) { - addAnimationHandle(); - } + _rig->deleteAnimations(); for (int i = 0; i < animationCount; i++) { settings.setArrayIndex(i); - const AnimationHandlePointer& handle = _animationHandles.at(i); - handle->setRole(settings.value("role", "idle").toString()); - handle->setURL(settings.value("url").toUrl()); - handle->setFPS(loadSetting(settings, "fps", 30.0f)); - handle->setPriority(loadSetting(settings, "priority", 1.0f)); - handle->setLoop(settings.value("loop", true).toBool()); - handle->setHold(settings.value("hold", false).toBool()); - handle->setFirstFrame(settings.value("firstFrame", 0.0f).toFloat()); - handle->setLastFrame(settings.value("lastFrame", INT_MAX).toFloat()); - handle->setMaskedJoints(settings.value("maskedJoints").toStringList()); - handle->setStartAutomatically(settings.value("startAutomatically", true).toBool()); + _rig->addAnimationByRole(settings.value("role", "idle").toString(), + settings.value("url").toString(), + loadSetting(settings, "fps", 30.0f), + loadSetting(settings, "priority", 1.0f), + settings.value("loop", true).toBool(), + settings.value("hold", false).toBool(), + settings.value("firstFrame", 0.0f).toFloat(), + settings.value("lastFrame", INT_MAX).toFloat(), + settings.value("maskedJoints").toStringList(), + settings.value("startAutomatically", true).toBool()); } settings.endArray(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index c6cb48878f..802c92ec2c 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -61,9 +61,9 @@ public: bool getShouldRenderLocally() const { return _shouldRender; } float getRealWorldFieldOfView() { return _realWorldFieldOfView.get(); } - const QList& getAnimationHandles() const { return _animationHandles; } - AnimationHandlePointer addAnimationHandle(); - void removeAnimationHandle(const AnimationHandlePointer& handle); + const QList& getAnimationHandles() const { return _rig->getAnimationHandles(); } + AnimationHandlePointer addAnimationHandle() { return _rig->createAnimationHandle(); } + void removeAnimationHandle(const AnimationHandlePointer& handle) { _rig->removeAnimationHandle(handle); } /// Allows scripts to run animations. Q_INVOKABLE void startAnimation(const QString& url, float fps = 30.0f, float priority = 1.0f, bool loop = false, @@ -256,8 +256,6 @@ private: bool _shouldRender; bool _billboardValid; float _oculusYawOffset; - - QList _animationHandles; bool _feetTouchFloor; eyeContactTarget _eyeContactTarget; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 8f4047bc71..7d520e7930 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -12,7 +12,7 @@ #include #include "AnimationHandle.h" - +#include "AnimationLogging.h" #include "Rig.h" void insertSorted(QList& handles, const AnimationHandlePointer& handle) { @@ -27,9 +27,86 @@ void insertSorted(QList& handles, const AnimationHandleP AnimationHandlePointer Rig::createAnimationHandle() { AnimationHandlePointer handle(new AnimationHandle(getRigPointer())); - _animationHandles.insert(handle); + _animationHandles.append(handle); return handle; } +void Rig::removeAnimationHandle(const AnimationHandlePointer& handle) { + handle->stop(); + // FIXME? Do we need to also animationHandle->clearJoints()? deleteAnimations(), below, was first written to do so, but did not first stop it. + _animationHandles.removeOne(handle); +} + +void Rig::startAnimation(const QString& url, float fps, float priority, + bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) { + qCDebug(animation) << "startAnimation" << url << fps << priority << loop << hold << firstFrame << lastFrame << maskedJoints; + AnimationHandlePointer handle = nullptr; + foreach (const AnimationHandlePointer& candidate, _animationHandles) { + if (candidate->getURL() == url) { + handle = candidate; + break; + } + } + if (!handle) { + handle = createAnimationHandle(); + handle->setURL(url); + } + handle->setFPS(fps); + handle->setPriority(priority); + handle->setLoop(loop); + handle->setHold(hold); + handle->setFirstFrame(firstFrame); + handle->setLastFrame(lastFrame); + handle->setMaskedJoints(maskedJoints); + handle->start(); +} + +void Rig::addAnimationByRole(const QString& role, const QString& url, float fps, float priority, + bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints, bool startAutomatically) { + // check for a configured animation for the role + qCDebug(animation) << "addAnimationByRole" << role << url << fps << priority << loop << hold << firstFrame << lastFrame << maskedJoints << startAutomatically; + AnimationHandlePointer handle = nullptr; + foreach (const AnimationHandlePointer& candidate, _animationHandles) { + if (candidate->getRole() == role) { + handle = candidate; + break; + } + } + if (!handle) { + handle = createAnimationHandle(); + handle->setRole(role); + } + handle->setURL(url); + handle->setFPS(fps); + handle->setPriority(priority); + handle->setLoop(loop); + handle->setHold(hold); + handle->setFirstFrame(firstFrame); + handle->setLastFrame(lastFrame); + handle->setMaskedJoints(maskedJoints); + if (startAutomatically) { + handle->start(); + } +} +void Rig::startAnimationByRole(const QString& role, const QString& url, float fps, float priority, + bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) { + addAnimationByRole(role, url, fps, priority, loop, hold, firstFrame, lastFrame, maskedJoints, true); +} + +void Rig::stopAnimationByRole(const QString& role) { + foreach (const AnimationHandlePointer& handle, getRunningAnimations()) { + if (handle->getRole() == role) { + handle->stop(); + } + } +} + +void Rig::stopAnimation(const QString& url) { + foreach (const AnimationHandlePointer& handle, getRunningAnimations()) { + if (handle->getURL() == url) { + handle->stop(); + } + } +} bool Rig::removeRunningAnimation(AnimationHandlePointer animationHandle) { return _runningAnimations.removeOne(animationHandle); @@ -44,10 +121,10 @@ bool Rig::isRunningAnimation(AnimationHandlePointer animationHandle) { } void Rig::deleteAnimations() { - for (QSet::iterator it = _animationHandles.begin(); it != _animationHandles.end(); ) { - (*it)->clearJoints(); - it = _animationHandles.erase(it); + for (auto animation : _animationHandles) { + removeAnimationHandle(animation); } + _animationHandles.clear(); } float Rig::initJointStates(QVector states, glm::mat4 parentTransform, int neckJointIndex) { diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 0af4073c96..2087ad6800 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -57,11 +57,22 @@ public: RigPointer getRigPointer() { return shared_from_this(); } AnimationHandlePointer createAnimationHandle(); + void removeAnimationHandle(const AnimationHandlePointer& handle); bool removeRunningAnimation(AnimationHandlePointer animationHandle); void addRunningAnimation(AnimationHandlePointer animationHandle); bool isRunningAnimation(AnimationHandlePointer animationHandle); const QList& getRunningAnimations() const { return _runningAnimations; } void deleteAnimations(); + const QList& getAnimationHandles() const { return _animationHandles; } + void startAnimation(const QString& url, float fps = 30.0f, float priority = 1.0f, bool loop = false, + bool hold = false, float firstFrame = 0.0f, float lastFrame = FLT_MAX, const QStringList& maskedJoints = QStringList()); + void stopAnimation(const QString& url); + void startAnimationByRole(const QString& role, const QString& url = QString(), float fps = 30.0f, + float priority = 1.0f, bool loop = false, bool hold = false, float firstFrame = 0.0f, + float lastFrame = FLT_MAX, const QStringList& maskedJoints = QStringList()); + void stopAnimationByRole(const QString& role); + void addAnimationByRole(const QString& role, const QString& url, float fps, float priority, + bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints, bool startAutomatically); float initJointStates(QVector states, glm::mat4 parentTransform, int neckJointIndex); bool jointStatesEmpty() { return _jointStates.isEmpty(); }; @@ -124,7 +135,7 @@ public: protected: QVector _jointStates; - QSet _animationHandles; + QList _animationHandles; QList _runningAnimations; JointState maybeCauterizeHead(int jointIndex) const;