From 6c591131ba32315b5fb2c3dfeac97e7d54bf6869 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 10 Jul 2015 12:01:51 -0700 Subject: [PATCH] Made Animations safe for resource reload --- .../src/avatars/ScriptableAvatar.cpp | 2 +- libraries/animation/src/AnimationCache.cpp | 4 +--- libraries/animation/src/AnimationCache.h | 3 --- libraries/audio/src/AudioInjector.cpp | 2 +- libraries/entities/src/ModelEntityItem.cpp | 17 ++++++++++------- libraries/entities/src/ModelEntityItem.h | 2 +- libraries/networking/src/ResourceCache.cpp | 9 ++++----- libraries/networking/src/ResourceCache.h | 1 + libraries/render-utils/src/AnimationHandle.cpp | 11 ++++++++++- libraries/render-utils/src/AnimationHandle.h | 2 ++ 10 files changed, 31 insertions(+), 22 deletions(-) diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp index e2f0449216..3d243d78ec 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.cpp +++ b/assignment-client/src/avatars/ScriptableAvatar.cpp @@ -53,7 +53,7 @@ AnimationDetails ScriptableAvatar::getAnimationDetails() { void ScriptableAvatar::update(float deltatime) { // Run animation - if (_animation != NULL && _animation->isValid() && _animation->getFrames().size() > 0) { + if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0) { QStringList modelJoints = getJointNames(); QStringList animationJoints = _animation->getJointNames(); diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index 6c02ccbd2b..9eb68cedc2 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -39,8 +39,7 @@ QSharedPointer AnimationCache::createResource(const QUrl& url, const Q } Animation::Animation(const QUrl& url) : - Resource(url), - _isValid(false) { + Resource(url) { } class AnimationReader : public QRunnable { @@ -97,7 +96,6 @@ QVector Animation::getFrames() const { void Animation::setGeometry(const FBXGeometry& geometry) { _geometry = geometry; finishedLoading(true); - _isValid = true; } void Animation::downloadFinished(QNetworkReply* reply) { diff --git a/libraries/animation/src/AnimationCache.h b/libraries/animation/src/AnimationCache.h index 6dbd5fdaad..c90c4c9225 100644 --- a/libraries/animation/src/AnimationCache.h +++ b/libraries/animation/src/AnimationCache.h @@ -57,8 +57,6 @@ public: Q_INVOKABLE QStringList getJointNames() const; Q_INVOKABLE QVector getFrames() const; - - bool isValid() const { return _isValid; } protected: @@ -69,7 +67,6 @@ protected: private: FBXGeometry _geometry; - bool _isValid; }; diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 36b0345d34..f49d51bb8b 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -294,7 +294,7 @@ AudioInjector* AudioInjector::playSound(const QString& soundUrl, const float vol if (soundCache.isNull()) { return NULL; } - SharedSoundPointer sound = soundCache.data()->getSound(QUrl(soundUrl)); + SharedSoundPointer sound = soundCache->getSound(QUrl(soundUrl)); if (sound.isNull() || !sound->isReady()) { return NULL; } diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index a6ae9e04de..b72dd5fab4 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -184,7 +184,7 @@ void ModelEntityItem::cleanupLoadedAnimations() { _loadedAnimations.clear(); } -Animation* ModelEntityItem::getAnimation(const QString& url) { +AnimationPointer ModelEntityItem::getAnimation(const QString& url) { AnimationPointer animation; // if we don't already have this model then create it and initialize it @@ -194,7 +194,7 @@ Animation* ModelEntityItem::getAnimation(const QString& url) { } else { animation = _loadedAnimations[url]; } - return animation.data(); + return animation; } void ModelEntityItem::mapJoints(const QStringList& modelJointNames) { @@ -203,9 +203,8 @@ void ModelEntityItem::mapJoints(const QStringList& modelJointNames) { return; } - Animation* myAnimation = getAnimation(_animationURL); - - if (!_jointMappingCompleted) { + AnimationPointer myAnimation = getAnimation(_animationURL); + if (myAnimation && myAnimation->isLoaded()) { QStringList animationJointNames = myAnimation->getJointNames(); if (modelJointNames.size() > 0 && animationJointNames.size() > 0) { @@ -220,8 +219,12 @@ void ModelEntityItem::mapJoints(const QStringList& modelJointNames) { QVector ModelEntityItem::getAnimationFrame() { QVector frameData; - if (hasAnimation() && _jointMappingCompleted) { - Animation* myAnimation = getAnimation(_animationURL); + if (!hasAnimation() || !_jointMappingCompleted) { + return frameData; + } + + AnimationPointer myAnimation = getAnimation(_animationURL); + if (myAnimation && myAnimation->isLoaded()) { QVector frames = myAnimation->getFrames(); int frameCount = frames.size(); if (frameCount > 0) { diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 32441decd3..ae6a86cde1 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -141,7 +141,7 @@ protected: bool _jointMappingCompleted; QVector _jointMapping; - static Animation* getAnimation(const QString& url); + static AnimationPointer getAnimation(const QString& url); static QMap _loadedAnimations; static AnimationCache _animationCache; diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index f3ed60c281..e127380630 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -271,11 +271,11 @@ void Resource::refresh() { _replyTimer->deleteLater(); _replyTimer = nullptr; } + init(); _request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); - if (!_startedLoading) { - attemptRequest(); - } + ensureLoading(); + emit onRefresh(); } void Resource::allReferencesCleared() { @@ -331,8 +331,7 @@ void Resource::reinsert() { _cache->_resources.insert(_url, _self); } -const int REPLY_TIMEOUT_MS = 5000; - +static const int REPLY_TIMEOUT_MS = 5000; void Resource::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { if (!_reply->isFinished()) { _bytesReceived = bytesReceived; diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index 4997826870..93ddfe77be 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -175,6 +175,7 @@ public: signals: /// Fired when the resource has been loaded. void loaded(); + void onRefresh(); protected slots: void attemptRequest(); diff --git a/libraries/render-utils/src/AnimationHandle.cpp b/libraries/render-utils/src/AnimationHandle.cpp index 55995b87d8..217c4948e8 100644 --- a/libraries/render-utils/src/AnimationHandle.cpp +++ b/libraries/render-utils/src/AnimationHandle.cpp @@ -15,6 +15,7 @@ void AnimationHandle::setURL(const QUrl& url) { if (_url != url) { _animation = DependencyManager::get()->getAnimation(_url = url); + QObject::connect(_animation.data(), &Resource::onRefresh, this, &AnimationHandle::clearJoints); _jointMappings.clear(); } } @@ -110,11 +111,15 @@ void AnimationHandle::setAnimationDetails(const AnimationDetails& details) { void AnimationHandle::simulate(float deltaTime) { + if (!_animation->isLoaded()) { + return; + } + _animationLoop.simulate(deltaTime); // update the joint mappings if necessary/possible if (_jointMappings.isEmpty()) { - if (_model->isActive()) { + if (_model && _model->isActive()) { _jointMappings = _model->getGeometry()->getJointMappings(_animation); } if (_jointMappings.isEmpty()) { @@ -146,6 +151,10 @@ void AnimationHandle::simulate(float deltaTime) { } void AnimationHandle::applyFrame(float frameIndex) { + if (!_animation->isLoaded()) { + return; + } + const FBXGeometry& animationGeometry = _animation->getGeometry(); int frameCount = animationGeometry.animationFrames.size(); const FBXAnimationFrame& floorFrame = animationGeometry.animationFrames.at((int)glm::floor(frameIndex) % frameCount); diff --git a/libraries/render-utils/src/AnimationHandle.h b/libraries/render-utils/src/AnimationHandle.h index 13a1b97dc1..ca9c2eb6d0 100644 --- a/libraries/render-utils/src/AnimationHandle.h +++ b/libraries/render-utils/src/AnimationHandle.h @@ -94,6 +94,8 @@ private: void replaceMatchingPriorities(float newPriority); void restoreJoints(); + void clearJoints() { _jointMappings.clear(); } + Model* _model; WeakAnimationHandlePointer _self; AnimationPointer _animation;