summaryrefslogtreecommitdiffstats
path: root/src/animation
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2020-04-24 13:43:56 +0100
committerMike Krus <mike.krus@kdab.com>2020-04-27 11:57:33 +0100
commit6c1758d35e20655f46ba3696671068f4862c8878 (patch)
treed4b4fc2ae8f5a4512de4eb015667b024b6a8e6b9 /src/animation
parentb7967a8abcdac438a1f31800b71e219e3c52c24a (diff)
parent37735f11f9437b916b194cfd48c452c7c70682f8 (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Diffstat (limited to 'src/animation')
-rw-r--r--src/animation/backend/animationutils.cpp8
-rw-r--r--src/animation/backend/animationutils_p.h12
-rw-r--r--src/animation/backend/blendedclipanimator.cpp4
-rw-r--r--src/animation/backend/blendedclipanimator_p.h2
-rw-r--r--src/animation/backend/clipanimator.cpp4
-rw-r--r--src/animation/backend/clipanimator_p.h2
-rw-r--r--src/animation/backend/evaluateblendclipanimatorjob.cpp8
-rw-r--r--src/animation/backend/evaluateclipanimatorjob.cpp6
-rw-r--r--src/animation/backend/handler.cpp28
-rw-r--r--src/animation/backend/handler_p.h1
-rw-r--r--src/animation/frontend/qchannelmapper.cpp3
-rw-r--r--src/animation/frontend/qclock.cpp5
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