diff options
author | Mike Krus <mike.krus@kdab.com> | 2020-04-24 13:43:56 +0100 |
---|---|---|
committer | Mike Krus <mike.krus@kdab.com> | 2020-04-27 11:57:33 +0100 |
commit | 6c1758d35e20655f46ba3696671068f4862c8878 (patch) | |
tree | d4b4fc2ae8f5a4512de4eb015667b024b6a8e6b9 /src/animation | |
parent | b7967a8abcdac438a1f31800b71e219e3c52c24a (diff) | |
parent | 37735f11f9437b916b194cfd48c452c7c70682f8 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: Id669d5c1aab29965eac0dabd1cb497e908dac23e
Diffstat (limited to 'src/animation')
-rw-r--r-- | src/animation/backend/animationutils.cpp | 8 | ||||
-rw-r--r-- | src/animation/backend/animationutils_p.h | 12 | ||||
-rw-r--r-- | src/animation/backend/blendedclipanimator.cpp | 4 | ||||
-rw-r--r-- | src/animation/backend/blendedclipanimator_p.h | 2 | ||||
-rw-r--r-- | src/animation/backend/clipanimator.cpp | 4 | ||||
-rw-r--r-- | src/animation/backend/clipanimator_p.h | 2 | ||||
-rw-r--r-- | src/animation/backend/evaluateblendclipanimatorjob.cpp | 8 | ||||
-rw-r--r-- | src/animation/backend/evaluateclipanimatorjob.cpp | 6 | ||||
-rw-r--r-- | src/animation/backend/handler.cpp | 28 | ||||
-rw-r--r-- | src/animation/backend/handler_p.h | 1 | ||||
-rw-r--r-- | src/animation/frontend/qchannelmapper.cpp | 3 | ||||
-rw-r--r-- | src/animation/frontend/qclock.cpp | 5 |
12 files changed, 46 insertions, 37 deletions
diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp index 3f386d92a..a5656e230 100644 --- a/src/animation/backend/animationutils.cpp +++ b/src/animation/backend/animationutils.cpp @@ -80,7 +80,8 @@ ClipEvaluationData evaluationDataForClip(AnimationClip *clip, animatorData.playbackRate, clip->duration(), animatorData.loopCount, result.currentLoop); result.isFinalFrame = isFinalFrame(result.localTime, clip->duration(), - result.currentLoop, animatorData.loopCount); + result.currentLoop, animatorData.loopCount, + animatorData.playbackRate); const bool hasNormalizedTime = isValidNormalizedTime(animatorData.normalizedLocalTime); result.normalizedLocalTime = hasNormalizedTime ? animatorData.normalizedLocalTime : result.localTime / clip->duration(); @@ -112,9 +113,10 @@ double localTimeFromElapsedTime(double t_current_local, t_local = std::fmod(t_local, duration); // Ensure we clamp to end of final loop - if (int(loopNumber) == loopCount) { + + if (int(loopNumber) == loopCount || int(loopNumber) < 0) { loopNumber = loopCount - 1; - t_local = duration; + t_local = playbackRate >= 0.0 ? duration : 0.0; } } diff --git a/src/animation/backend/animationutils_p.h b/src/animation/backend/animationutils_p.h index 81a964046..0e74728c2 100644 --- a/src/animation/backend/animationutils_p.h +++ b/src/animation/backend/animationutils_p.h @@ -317,11 +317,15 @@ AnimatorEvaluationData evaluationDataForAnimator(Animator animator, inline bool isFinalFrame(double localTime, double duration, int currentLoop, - int loopCount) + int loopCount, + double playbackRate) { - return (localTime >= duration && - loopCount != 0 && - currentLoop >= loopCount - 1); + // We must be on the final loop and + // - if playing forward, localTime must be equal or above the duration + // - if playing backward, localTime must be equal or below 0 + if (playbackRate >= 0.0) + return (loopCount != 0 && currentLoop >= loopCount - 1 && localTime >= duration); + return (loopCount != 0 && currentLoop <= 0 && localTime <= 0); } inline bool isValidNormalizedTime(float t) diff --git a/src/animation/backend/blendedclipanimator.cpp b/src/animation/backend/blendedclipanimator.cpp index 7d771745b..14771247a 100644 --- a/src/animation/backend/blendedclipanimator.cpp +++ b/src/animation/backend/blendedclipanimator.cpp @@ -127,10 +127,10 @@ Qt3DCore::QNodeId BlendedClipAnimator::blendTreeRootId() const return m_blendTreeRootId; } -void BlendedClipAnimator::setNormalizedLocalTime(float normalizedTime) +void BlendedClipAnimator::setNormalizedLocalTime(float normalizedTime, bool allowMarkDirty) { m_normalizedLocalTime = normalizedTime; - if (isValidNormalizedTime(m_normalizedLocalTime)) + if (isValidNormalizedTime(m_normalizedLocalTime) && allowMarkDirty) setDirty(Handler::BlendedClipAnimatorDirty); } diff --git a/src/animation/backend/blendedclipanimator_p.h b/src/animation/backend/blendedclipanimator_p.h index 04f609438..2396cdd74 100644 --- a/src/animation/backend/blendedclipanimator_p.h +++ b/src/animation/backend/blendedclipanimator_p.h @@ -70,7 +70,7 @@ public: Qt3DCore::QNodeId mapperId() const { return m_mapperId; } Qt3DCore::QNodeId clockId() const { return m_clockId; } bool isRunning() const { return m_running; } - void setNormalizedLocalTime(float normalizedTime); + void setNormalizedLocalTime(float normalizedTime, bool allowMarkDirty = true); float normalizedLocalTime() const { return m_normalizedLocalTime; } // Called by BuildBlendTreeJob diff --git a/src/animation/backend/clipanimator.cpp b/src/animation/backend/clipanimator.cpp index 32b02d2bb..5d46e321a 100644 --- a/src/animation/backend/clipanimator.cpp +++ b/src/animation/backend/clipanimator.cpp @@ -95,10 +95,10 @@ void ClipAnimator::setRunning(bool running) setDirty(Handler::ClipAnimatorDirty); } -void ClipAnimator::setNormalizedLocalTime(float normalizedTime) +void ClipAnimator::setNormalizedLocalTime(float normalizedTime, bool allowMarkDirty) { m_normalizedLocalTime = normalizedTime; - if (isValidNormalizedTime(normalizedTime)) + if (isValidNormalizedTime(normalizedTime) && allowMarkDirty) setDirty(Handler::ClipAnimatorDirty); } diff --git a/src/animation/backend/clipanimator_p.h b/src/animation/backend/clipanimator_p.h index d154bdab9..65fc6bdc8 100644 --- a/src/animation/backend/clipanimator_p.h +++ b/src/animation/backend/clipanimator_p.h @@ -77,7 +77,7 @@ public: bool isRunning() const { return m_running; } void setLoops(int loops) { m_loops = loops; } int loops() const { return m_loops; } - void setNormalizedLocalTime(float normalizedLocalTime); + void setNormalizedLocalTime(float normalizedLocalTime, bool allowMarkDirty = true); float normalizedLocalTime() const { return m_normalizedLocalTime; } void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; diff --git a/src/animation/backend/evaluateblendclipanimatorjob.cpp b/src/animation/backend/evaluateblendclipanimatorjob.cpp index 765531902..69df26992 100644 --- a/src/animation/backend/evaluateblendclipanimatorjob.cpp +++ b/src/animation/backend/evaluateblendclipanimatorjob.cpp @@ -125,11 +125,10 @@ void EvaluateBlendClipAnimatorJob::run() blendedClipAnimator->setLastGlobalTimeNS(globalTimeNS); blendedClipAnimator->setLastLocalTime(localTime); blendedClipAnimator->setLastNormalizedLocalTime(float(phase)); - blendedClipAnimator->setNormalizedLocalTime(-1.0f); // Re-set to something invalid. blendedClipAnimator->setCurrentLoop(animatorData.currentLoop); // Prepare the change record - const bool finalFrame = isFinalFrame(localTime, duration, animatorData.currentLoop, animatorData.loopCount); + const bool finalFrame = isFinalFrame(localTime, duration, animatorData.currentLoop, animatorData.loopCount, animatorData.playbackRate); const QVector<MappingData> mappingData = blendedClipAnimator->mappingData(); auto record = prepareAnimationRecord(blendedClipAnimator->peerId(), mappingData, @@ -140,6 +139,11 @@ void EvaluateBlendClipAnimatorJob::run() // Trigger callbacks either on this thread or by notifying the gui thread. auto callbacks = prepareCallbacks(mappingData, blendedResults); + // Update the normalized time on the backend node so that + // frontend <-> backend sync will not mark things dirty + // unless the frontend normalized time really is different + blendedClipAnimator->setNormalizedLocalTime(record.normalizedTime, false); + setPostFrameData(record, callbacks); } diff --git a/src/animation/backend/evaluateclipanimatorjob.cpp b/src/animation/backend/evaluateclipanimatorjob.cpp index 914a38139..84d08543e 100644 --- a/src/animation/backend/evaluateclipanimatorjob.cpp +++ b/src/animation/backend/evaluateclipanimatorjob.cpp @@ -100,7 +100,6 @@ void EvaluateClipAnimatorJob::run() clipAnimator->setLastGlobalTimeNS(globalTimeNS); clipAnimator->setLastLocalTime(preEvaluationDataForClip.localTime); clipAnimator->setLastNormalizedLocalTime(preEvaluationDataForClip.normalizedLocalTime); - clipAnimator->setNormalizedLocalTime(-1.0f); // Re-set to something invalid. // Prepare property changes (if finalFrame it also prepares the change for the running property for the frontend) auto record = prepareAnimationRecord(clipAnimator->peerId(), @@ -112,6 +111,11 @@ void EvaluateClipAnimatorJob::run() // Trigger callbacks either on this thread or by notifying the gui thread. auto callbacks = prepareCallbacks(clipAnimator->mappingData(), formattedClipResults); + // Update the normalized time on the backend node so that + // frontend <-> backend sync will not mark things dirty + // unless the frontend normalized time really is different + clipAnimator->setNormalizedLocalTime(record.normalizedTime, false); + setPostFrameData(record, callbacks); } diff --git a/src/animation/backend/handler.cpp b/src/animation/backend/handler.cpp index 112e2742b..95363d56f 100644 --- a/src/animation/backend/handler.cpp +++ b/src/animation/backend/handler.cpp @@ -44,6 +44,7 @@ #include <Qt3DAnimation/private/animationlogging_p.h> #include <Qt3DAnimation/private/buildblendtreesjob_p.h> #include <Qt3DAnimation/private/evaluateblendclipanimatorjob_p.h> +#include <Qt3DCore/private/qaspectjob_p.h> QT_BEGIN_NAMESPACE @@ -84,9 +85,6 @@ void Handler::setDirty(DirtyFlag flag, Qt3DCore::QNodeId nodeId) } case ChannelMappingsDirty: { - QMutexLocker lock(&m_mutex); - const auto handle = m_channelMapperManager->lookupHandle(nodeId); - m_dirtyChannelMappers.push_back(handle); break; } @@ -118,11 +116,7 @@ void Handler::setClipAnimatorRunning(const HClipAnimator &handle, bool running) // If being marked as not running, remove from set of running clips if (!running) { - const auto it = std::find_if(m_runningClipAnimators.begin(), - m_runningClipAnimators.end(), - [handle](const HClipAnimator &h) { return h == handle; }); - if (it != m_runningClipAnimators.end()) - m_runningClipAnimators.erase(it); + m_runningClipAnimators.removeAll(handle); } } @@ -208,13 +202,14 @@ QVector<Qt3DCore::QAspectJobPtr> Handler::jobsToExecute(qint64 time) const bool hasFindRunningClipAnimatorsJob = !m_dirtyClipAnimators.isEmpty(); if (hasFindRunningClipAnimatorsJob) { qCDebug(HandlerLogic) << "Added FindRunningClipAnimatorsJob"; - m_findRunningClipAnimatorsJob->removeDependency(QWeakPointer<Qt3DCore::QAspectJob>()); cleanupHandleList(&m_dirtyClipAnimators); m_findRunningClipAnimatorsJob->setDirtyClipAnimators(m_dirtyClipAnimators); + // Only set the dependency once + if (Q_UNLIKELY(m_findRunningClipAnimatorsJob->dependencies().empty())) + m_findRunningClipAnimatorsJob->addDependency(m_loadAnimationClipJob); jobs.push_back(m_findRunningClipAnimatorsJob); if (hasLoadAnimationClipJob) - m_findRunningClipAnimatorsJob->addDependency(m_loadAnimationClipJob); - m_dirtyClipAnimators.clear(); + m_dirtyClipAnimators.clear(); } // Rebuild blending trees if a blend tree is dirty @@ -247,13 +242,10 @@ QVector<Qt3DCore::QAspectJobPtr> Handler::jobsToExecute(qint64 time) // Set each job up with an animator to process and set dependencies for (int i = 0; i < newSize; ++i) { m_evaluateClipAnimatorJobs[i]->setClipAnimator(m_runningClipAnimators[i]); - m_evaluateClipAnimatorJobs[i]->removeDependency(QWeakPointer<Qt3DCore::QAspectJob>()); - if (hasLoadAnimationClipJob && - !m_evaluateClipAnimatorJobs[i]->dependencies().contains(m_loadAnimationClipJob)) + Qt3DCore::QAspectJobPrivate::get(m_evaluateClipAnimatorJobs[i].data())->clearDependencies(); + if (hasLoadAnimationClipJob) m_evaluateClipAnimatorJobs[i]->addDependency(m_loadAnimationClipJob); - - if (hasFindRunningClipAnimatorsJob && - !m_evaluateClipAnimatorJobs[i]->dependencies().contains(m_findRunningClipAnimatorsJob)) + if (hasFindRunningClipAnimatorsJob) m_evaluateClipAnimatorJobs[i]->addDependency(m_findRunningClipAnimatorsJob); jobs.push_back(m_evaluateClipAnimatorJobs[i]); } @@ -276,7 +268,7 @@ QVector<Qt3DCore::QAspectJobPtr> Handler::jobsToExecute(qint64 time) // Set each job up with an animator to process and set dependencies for (int i = 0; i < newSize; ++i) { m_evaluateBlendClipAnimatorJobs[i]->setBlendClipAnimator(m_runningBlendedClipAnimators[i]); - m_evaluateBlendClipAnimatorJobs[i]->removeDependency(QWeakPointer<Qt3DCore::QAspectJob>()); + Qt3DCore::QAspectJobPrivate::get(m_evaluateBlendClipAnimatorJobs[i].data())->clearDependencies(); if (hasLoadAnimationClipJob) m_evaluateBlendClipAnimatorJobs[i]->addDependency(m_loadAnimationClipJob); if (hasBuildBlendTreesJob) diff --git a/src/animation/backend/handler_p.h b/src/animation/backend/handler_p.h index 99e2ae1f6..e65bc0797 100644 --- a/src/animation/backend/handler_p.h +++ b/src/animation/backend/handler_p.h @@ -137,7 +137,6 @@ private: QScopedPointer<SkeletonManager> m_skeletonManager; QVector<HAnimationClip> m_dirtyAnimationClips; - QVector<HChannelMapper> m_dirtyChannelMappers; QVector<HClipAnimator> m_dirtyClipAnimators; QVector<HBlendedClipAnimator> m_dirtyBlendedAnimators; diff --git a/src/animation/frontend/qchannelmapper.cpp b/src/animation/frontend/qchannelmapper.cpp index 2d0e0dd2d..711259e7f 100644 --- a/src/animation/frontend/qchannelmapper.cpp +++ b/src/animation/frontend/qchannelmapper.cpp @@ -93,7 +93,8 @@ void QChannelMapper::removeMapping(QAbstractChannelMapping *mapping) { Q_ASSERT(mapping); Q_D(QChannelMapper); - d->m_mappings.removeOne(mapping); + if (!d->m_mappings.removeOne(mapping)) + return; d->update(); // Remove bookkeeping connection d->unregisterDestructionHelper(mapping); diff --git a/src/animation/frontend/qclock.cpp b/src/animation/frontend/qclock.cpp index 8d1cb5991..5fa727474 100644 --- a/src/animation/frontend/qclock.cpp +++ b/src/animation/frontend/qclock.cpp @@ -63,7 +63,10 @@ QClock::~QClock() /*! \property Qt3DAnimation::QClock::playbackRate - The playback speed of the animation. + The playback speed of the animation. The playback speed can be negative. + When that is the case the animation will be played back from the current + normalized time value back to 0 and for the number of loops it had been + played for with a positive playback rate. */ double QClock::playbackRate() const |