summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2019-10-01 22:59:52 +0100
committerMike Krus <mike.krus@kdab.com>2019-10-08 12:48:13 +0100
commit7433513f5f08d02b9ed6233c4159f8f32f0db556 (patch)
tree0508fcebaf55981de53026bf954c366240aff098
parentcae430b9ede8327217e5fa8e48b0de1f3d7cc364 (diff)
Update animation evaluation jobs to use direct sync
Animation data is now stored in the job which propagates them to the frontend at the end of the frame. Animated properties are passed using Qt's property system. Animated poses are passed via the frontend skeleton node. Syncing on new frame will take care of propagating both for use in other aspects. Callbacks are called by the job directly or stored and invoked on the main thread depending on the callback setting. Change-Id: I78675715799300bc1b27f854f1a445c00a2ac734 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--src/animation/backend/abstractevaluateclipanimatorjob.cpp127
-rw-r--r--src/animation/backend/abstractevaluateclipanimatorjob_p.h77
-rw-r--r--src/animation/backend/animationutils.cpp53
-rw-r--r--src/animation/backend/animationutils_p.h37
-rw-r--r--src/animation/backend/backend.pri2
-rw-r--r--src/animation/backend/blendedclipanimator.cpp22
-rw-r--r--src/animation/backend/blendedclipanimator_p.h3
-rw-r--r--src/animation/backend/clipanimator.cpp22
-rw-r--r--src/animation/backend/clipanimator_p.h3
-rw-r--r--src/animation/backend/evaluateblendclipanimatorjob.cpp32
-rw-r--r--src/animation/backend/evaluateblendclipanimatorjob_p.h5
-rw-r--r--src/animation/backend/evaluateclipanimatorjob.cpp27
-rw-r--r--src/animation/backend/evaluateclipanimatorjob_p.h4
-rw-r--r--src/animation/backend/skeleton.cpp9
-rw-r--r--src/animation/backend/skeleton_p.h3
-rw-r--r--src/animation/frontend/qabstractclipanimator.cpp13
-rw-r--r--src/animation/frontend/qabstractclipanimator.h2
-rw-r--r--src/core/transforms/qabstractskeleton.cpp8
-rw-r--r--src/core/transforms/qabstractskeleton_p.h3
-rw-r--r--src/render/backend/transform.cpp22
-rw-r--r--src/render/backend/transform_p.h1
-rw-r--r--src/render/geometry/skeleton.cpp23
-rw-r--r--src/render/geometry/skeleton_p.h1
-rw-r--r--tests/auto/animation/animationutils/tst_animationutils.cpp208
24 files changed, 361 insertions, 346 deletions
diff --git a/src/animation/backend/abstractevaluateclipanimatorjob.cpp b/src/animation/backend/abstractevaluateclipanimatorjob.cpp
new file mode 100644
index 000000000..236a96efe
--- /dev/null
+++ b/src/animation/backend/abstractevaluateclipanimatorjob.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractevaluateclipanimatorjob_p.h"
+#include <Qt3DCore/private/qaspectjob_p.h>
+#include <Qt3DCore/private/qaspectmanager_p.h>
+#include <Qt3DCore/private/qskeleton_p.h>
+#include <Qt3DAnimation/qabstractclipanimator.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+namespace Animation {
+
+class AbstractEvaluateClipAnimatorJobPrivate : public Qt3DCore::QAspectJobPrivate
+{
+public:
+ AbstractEvaluateClipAnimatorJobPrivate() { }
+ ~AbstractEvaluateClipAnimatorJobPrivate() override { }
+
+ void postFrame(Qt3DCore::QAspectManager *manager) override;
+
+ Q_DECLARE_PUBLIC(AbstractEvaluateClipAnimatorJob)
+
+ AnimationRecord m_record;
+ QVector<AnimationCallbackAndValue> m_callbacks;
+
+private:
+ AbstractEvaluateClipAnimatorJob *q_ptr;
+};
+
+AbstractEvaluateClipAnimatorJob::AbstractEvaluateClipAnimatorJob()
+ : Qt3DCore::QAspectJob(*new AbstractEvaluateClipAnimatorJobPrivate)
+{
+}
+
+void AbstractEvaluateClipAnimatorJob::setPostFrameData(const AnimationRecord &record, const QVector<AnimationCallbackAndValue> &callbacks)
+{
+ auto mainThreadCB = callbacks;
+ mainThreadCB.erase(std::remove_if(mainThreadCB.begin(), mainThreadCB.end(), [](const AnimationCallbackAndValue &callback) {
+ if (callback.flags.testFlag(QAnimationCallback::OnThreadPool)) {
+ // call these now and remove them from the list
+ callback.callback->valueChanged(callback.value);
+ return true;
+ }
+ return false;
+ }), mainThreadCB.end());
+ // Should now only have callbacks to be called on main thread
+
+ Q_D(AbstractEvaluateClipAnimatorJob);
+ d->m_record = record;
+ d->m_callbacks = mainThreadCB;
+}
+
+void AbstractEvaluateClipAnimatorJobPrivate::postFrame(Qt3DCore::QAspectManager *manager)
+{
+ if (m_record.animatorId.isNull())
+ return;
+
+ for (auto targetData : qAsConst(m_record.targetChanges)) {
+ Qt3DCore::QNode *node = manager->lookupNode(targetData.targetId);
+ if (node)
+ node->setProperty(targetData.propertyName, targetData.value);
+ }
+
+ for (auto skeletonData : qAsConst(m_record.skeletonChanges)) {
+ Qt3DCore::QAbstractSkeleton *node = qobject_cast<Qt3DCore::QAbstractSkeleton *>(manager->lookupNode(skeletonData.first));
+ if (node) {
+ auto d = Qt3DCore::QAbstractSkeletonPrivate::get(node);
+ d->m_localPoses = skeletonData.second;
+ d->update();
+ }
+ }
+
+ QAbstractClipAnimator *animator = qobject_cast<QAbstractClipAnimator *>(manager->lookupNode(m_record.animatorId));
+ if (animator) {
+ if (isValidNormalizedTime(m_record.normalizedTime))
+ animator->setNormalizedTime(m_record.normalizedTime);
+ if (m_record.finalFrame)
+ animator->setRunning(false);
+ }
+
+ for (const AnimationCallbackAndValue &callback: qAsConst(m_callbacks)) {
+ if (callback.callback)
+ callback.callback->valueChanged(callback.value);
+ }
+
+ m_record = {};
+}
+
+} // Animation
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/backend/abstractevaluateclipanimatorjob_p.h b/src/animation/backend/abstractevaluateclipanimatorjob_p.h
new file mode 100644
index 000000000..2a8914faa
--- /dev/null
+++ b/src/animation/backend/abstractevaluateclipanimatorjob_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DANIMATION_ANIMATION_ABSTRACTEVALUATECLIPANIMATORJOB_P_H
+#define QT3DANIMATION_ANIMATION_ABSTRACTEVALUATECLIPANIMATORJOB_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DCore/qaspectjob.h>
+#include <Qt3DAnimation/private/animationutils_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+namespace Animation {
+
+class AbstractEvaluateClipAnimatorJobPrivate;
+
+class AbstractEvaluateClipAnimatorJob : public Qt3DCore::QAspectJob
+{
+protected:
+ AbstractEvaluateClipAnimatorJob();
+
+ void setPostFrameData(const AnimationRecord &record, const QVector<AnimationCallbackAndValue> &callbacks);
+
+private:
+ Q_DECLARE_PRIVATE(AbstractEvaluateClipAnimatorJob)
+};
+
+} // Animation
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_ANIMATION_ABSTRACTEVALUATECLIPANIMATORJOB_P_H
diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp
index 24c484dc2..80c296a89 100644
--- a/src/animation/backend/animationutils.cpp
+++ b/src/animation/backend/animationutils.cpp
@@ -40,8 +40,6 @@
#include <Qt3DAnimation/private/clipblendnode_p.h>
#include <Qt3DAnimation/private/clipblendnodevisitor_p.h>
#include <Qt3DAnimation/private/clipblendvalue_p.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
-#include <Qt3DCore/private/qpropertyupdatedchangebase_p.h>
#include <QtGui/qvector2d.h>
#include <QtGui/qvector3d.h>
#include <QtGui/qvector4d.h>
@@ -407,13 +405,17 @@ QVariant buildPropertyValue(const MappingData &mappingData, const QVector<float>
return QVariant();
}
-QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId animatorId,
- const QVector<MappingData> &mappingDataVec,
- const QVector<float> &channelResults,
- bool finalFrame,
- float normalizedLocalTime)
+AnimationRecord prepareAnimationRecord(Qt3DCore::QNodeId animatorId,
+ const QVector<MappingData> &mappingDataVec,
+ const QVector<float> &channelResults,
+ bool finalFrame,
+ float normalizedLocalTime)
{
- QVector<Qt3DCore::QSceneChangePtr> changes;
+ AnimationRecord record;
+ record.finalFrame = finalFrame;
+ record.animatorId = animatorId;
+ record.normalizedTime = normalizedLocalTime;
+
QVarLengthArray<Skeleton *, 4> dirtySkeletons;
// Iterate over the mappings
@@ -453,43 +455,14 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim
break;
}
} else {
- // TODOSYNC remove once we've found a way to propagate animation changes
- // Construct a property update change, set target, property and delivery options
- auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(mappingData.targetId);
- e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- e->setPropertyName(mappingData.propertyName);
- // Handle intermediate updates vs final flag properly
- Qt3DCore::QPropertyUpdatedChangeBasePrivate::get(e.data())->m_isIntermediate = !finalFrame;
- // Assign new value and send
- e->setValue(v);
- changes.push_back(e);
+ record.targetChanges.push_back({mappingData.targetId, mappingData.propertyName, v});
}
}
for (const auto skeleton : dirtySkeletons)
- skeleton->sendLocalPoses();
-
- if (isValidNormalizedTime(normalizedLocalTime)) {
- // TODOSYNC remove once we've found a way to propagate animation changes
- auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(animatorId);
- e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- e->setPropertyName("normalizedTime");
- e->setValue(normalizedLocalTime);
- Qt3DCore::QPropertyUpdatedChangeBasePrivate::get(e.data())->m_isIntermediate = !finalFrame;
- changes.push_back(e);
- }
-
- // If it's the final frame, notify the frontend that we've stopped
- if (finalFrame) {
- // TODOSYNC remove once we've found a way to propagate animation changes
- auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(animatorId);
- e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- e->setPropertyName("running");
- e->setValue(false);
- changes.push_back(e);
- }
+ record.skeletonChanges.push_back({skeleton->peerId(), skeleton->joints()});
- return changes;
+ return record;
}
QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> &mappingDataVec,
diff --git a/src/animation/backend/animationutils_p.h b/src/animation/backend/animationutils_p.h
index bded12bd2..eab15f0e5 100644
--- a/src/animation/backend/animationutils_p.h
+++ b/src/animation/backend/animationutils_p.h
@@ -53,6 +53,7 @@
#include <Qt3DAnimation/qanimationcallback.h>
#include <Qt3DCore/qnodeid.h>
#include <Qt3DCore/qscenechange.h>
+#include <Qt3DCore/private/sqt_p.h>
#include <QtCore/qbitarray.h>
#include <QtCore/qdebug.h>
@@ -183,7 +184,7 @@ struct ChannelNameAndType
case Rotation:
componentCount = 4;
break;
- };
+ }
}
bool operator==(const ChannelNameAndType &rhs) const
@@ -264,6 +265,32 @@ struct AnimationCallbackAndValue
QVariant value;
};
+struct AnimationRecord {
+ struct TargetChange {
+ TargetChange(Qt3DCore::QNodeId id, const char *name, QVariant v)
+ : targetId(id), propertyName(name), value(v) {
+
+ }
+
+ Qt3DCore::QNodeId targetId;
+ const char *propertyName = nullptr;
+ QVariant value;
+ };
+
+ Qt3DCore::QNodeId animatorId;
+ QVector<TargetChange> targetChanges;
+ QVector<QPair<Qt3DCore::QNodeId, QVector<Qt3DCore::Sqt>>> skeletonChanges;
+ float normalizedTime = -1.f;
+ bool finalFrame = false;
+};
+
+Q_AUTOTEST_EXPORT
+AnimationRecord prepareAnimationRecord(Qt3DCore::QNodeId animatorId,
+ const QVector<MappingData> &mappingDataVec,
+ const QVector<float> &channelResults,
+ bool finalFrame,
+ float normalizedLocalTime);
+
inline constexpr double toSecs(qint64 nsecs) { return nsecs / 1.0e9; }
inline qint64 toNsecs(double seconds) { return qRound64(seconds * 1.0e9); }
@@ -328,12 +355,6 @@ ClipResults evaluateClipAtPhase(AnimationClip *clip,
float phase);
Q_AUTOTEST_EXPORT
-QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId animatorId,
- const QVector<MappingData> &mappingDataVec,
- const QVector<float> &channelResults,
- bool finalFrame, float normalizedLocalTime);
-
-Q_AUTOTEST_EXPORT
QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> &mappingDataVec,
const QVector<float> &channelResults);
@@ -390,5 +411,7 @@ void applyComponentDefaultValues(const QVector<ComponentValue> &componentDefault
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(Qt3DAnimation::Animation::AnimationRecord) // LCOV_EXCL_LINE
+
#endif // QT3DANIMATION_ANIMATION_ANIMATIONUTILS_P_H
diff --git a/src/animation/backend/backend.pri b/src/animation/backend/backend.pri
index cc1104102..ef7da55f0 100644
--- a/src/animation/backend/backend.pri
+++ b/src/animation/backend/backend.pri
@@ -17,6 +17,7 @@ HEADERS += \
$$PWD/channelmapping_p.h \
$$PWD/channelmapper_p.h \
$$PWD/findrunningclipanimatorsjob_p.h \
+ $$PWD/abstractevaluateclipanimatorjob_p.h \
$$PWD/evaluateclipanimatorjob_p.h \
$$PWD/clipblendnode_p.h \
$$PWD/clipblendnodevisitor_p.h \
@@ -43,6 +44,7 @@ SOURCES += \
$$PWD/channelmapping.cpp \
$$PWD/channelmapper.cpp \
$$PWD/findrunningclipanimatorsjob.cpp \
+ $$PWD/abstractevaluateclipanimatorjob.cpp \
$$PWD/evaluateclipanimatorjob.cpp \
$$PWD/clipblendnode.cpp \
$$PWD/managers.cpp \
diff --git a/src/animation/backend/blendedclipanimator.cpp b/src/animation/backend/blendedclipanimator.cpp
index 8e76ec233..7d771745b 100644
--- a/src/animation/backend/blendedclipanimator.cpp
+++ b/src/animation/backend/blendedclipanimator.cpp
@@ -40,7 +40,6 @@
#include <Qt3DAnimation/qclock.h>
#include <Qt3DAnimation/qabstractclipblendnode.h>
#include <Qt3DAnimation/private/qblendedclipanimator_p.h>
-#include <Qt3DAnimation/private/qanimationcallbacktrigger_p.h>
QT_BEGIN_NAMESPACE
@@ -122,27 +121,6 @@ void BlendedClipAnimator::setRunning(bool running)
setDirty(Handler::BlendedClipAnimatorDirty);
}
-void BlendedClipAnimator::sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes)
-{
- for (const Qt3DCore::QSceneChangePtr &change : changes)
- notifyObservers(change);
-}
-
-void BlendedClipAnimator::sendCallbacks(const QVector<AnimationCallbackAndValue> &callbacks)
-{
- for (const AnimationCallbackAndValue &callback : callbacks) {
- if (callback.flags.testFlag(QAnimationCallback::OnThreadPool)) {
- callback.callback->valueChanged(callback.value);
- } else {
- auto e = QAnimationCallbackTriggerPtr::create(peerId());
- e->setCallback(callback.callback);
- e->setValue(callback.value);
- e->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
- notifyObservers(e);
- }
- }
-}
-
Qt3DCore::QNodeId BlendedClipAnimator::blendTreeRootId() const
{
diff --git a/src/animation/backend/blendedclipanimator_p.h b/src/animation/backend/blendedclipanimator_p.h
index f47b55796..04f609438 100644
--- a/src/animation/backend/blendedclipanimator_p.h
+++ b/src/animation/backend/blendedclipanimator_p.h
@@ -92,9 +92,6 @@ public:
void setMappingData(const QVector<MappingData> &mappingData) { m_mappingData = mappingData; }
QVector<MappingData> mappingData() const { return m_mappingData; }
- void sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes);
- void sendCallbacks(const QVector<AnimationCallbackAndValue> &callbacks);
-
void animationClipMarkedDirty() { setDirty(Handler::BlendedClipAnimatorDirty); }
qint64 nsSincePreviousFrame(qint64 currentGlobalTimeNS);
diff --git a/src/animation/backend/clipanimator.cpp b/src/animation/backend/clipanimator.cpp
index 4fe23819e..32b02d2bb 100644
--- a/src/animation/backend/clipanimator.cpp
+++ b/src/animation/backend/clipanimator.cpp
@@ -42,7 +42,6 @@
#include <Qt3DAnimation/private/animationclip_p.h>
#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DAnimation/private/animationlogging_p.h>
-#include <Qt3DAnimation/private/qanimationcallbacktrigger_p.h>
QT_BEGIN_NAMESPACE
@@ -144,27 +143,6 @@ void ClipAnimator::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstT
setDirty(Handler::ClipAnimatorDirty);
}
-void ClipAnimator::sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes)
-{
- for (const Qt3DCore::QSceneChangePtr &change : changes)
- notifyObservers(change);
-}
-
-void ClipAnimator::sendCallbacks(const QVector<AnimationCallbackAndValue> &callbacks)
-{
- for (const AnimationCallbackAndValue &callback : callbacks) {
- if (callback.flags.testFlag(QAnimationCallback::OnThreadPool)) {
- callback.callback->valueChanged(callback.value);
- } else {
- auto e = QAnimationCallbackTriggerPtr::create(peerId());
- e->setCallback(callback.callback);
- e->setValue(callback.value);
- e->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
- notifyObservers(e);
- }
- }
-}
-
qint64 ClipAnimator::nsSincePreviousFrame(qint64 currentGlobalTimeNS)
{
return currentGlobalTimeNS - m_lastGlobalTimeNS;
diff --git a/src/animation/backend/clipanimator_p.h b/src/animation/backend/clipanimator_p.h
index 54d1527a4..d154bdab9 100644
--- a/src/animation/backend/clipanimator_p.h
+++ b/src/animation/backend/clipanimator_p.h
@@ -93,9 +93,6 @@ public:
int currentLoop() const { return m_currentLoop; }
void setCurrentLoop(int currentLoop) { m_currentLoop = currentLoop; }
- void sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes);
- void sendCallbacks(const QVector<AnimationCallbackAndValue> &callbacks);
-
void animationClipMarkedDirty() { setDirty(Handler::ClipAnimatorDirty); }
void setClipFormat(const ClipFormat &clipFormat) { m_clipFormat = clipFormat; }
diff --git a/src/animation/backend/evaluateblendclipanimatorjob.cpp b/src/animation/backend/evaluateblendclipanimatorjob.cpp
index e0bb8b155..9b6802d3b 100644
--- a/src/animation/backend/evaluateblendclipanimatorjob.cpp
+++ b/src/animation/backend/evaluateblendclipanimatorjob.cpp
@@ -35,6 +35,9 @@
****************************************************************************/
#include "evaluateblendclipanimatorjob_p.h"
+#include <Qt3DCore/private/qaspectmanager_p.h>
+#include <Qt3DCore/private/qskeleton_p.h>
+#include <Qt3DAnimation/qblendedclipanimator.h>
#include <Qt3DAnimation/private/handler_p.h>
#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DAnimation/private/animationlogging_p.h>
@@ -50,9 +53,9 @@ namespace Qt3DAnimation {
namespace Animation {
EvaluateBlendClipAnimatorJob::EvaluateBlendClipAnimatorJob()
- : Qt3DCore::QAspectJob()
+ : AbstractEvaluateClipAnimatorJob()
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::EvaluateBlendClipAnimator, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::EvaluateBlendClipAnimator, 0)
}
void EvaluateBlendClipAnimatorJob::run()
@@ -105,7 +108,7 @@ void EvaluateBlendClipAnimatorJob::run()
AnimationClip *clip = clipLoaderManager->lookupResource(valueNode->clipId());
Q_ASSERT(clip);
- ClipResults rawClipResults = evaluateClipAtPhase(clip, phase);
+ ClipResults rawClipResults = evaluateClipAtPhase(clip, float(phase));
// Reformat the clip results into the layout used by this animator/blend tree
const ClipFormat format = valueNode->clipFormat(blendedClipAnimator->peerId());
@@ -120,24 +123,23 @@ void EvaluateBlendClipAnimatorJob::run()
const double localTime = phase * duration;
blendedClipAnimator->setLastGlobalTimeNS(globalTimeNS);
blendedClipAnimator->setLastLocalTime(localTime);
- blendedClipAnimator->setLastNormalizedLocalTime(phase);
+ blendedClipAnimator->setLastNormalizedLocalTime(float(phase));
blendedClipAnimator->setNormalizedLocalTime(-1.0f); // Re-set to something invalid.
blendedClipAnimator->setCurrentLoop(animatorData.currentLoop);
- const bool finalFrame = isFinalFrame(localTime, duration, animatorData.currentLoop, animatorData.loopCount);
- // Prepare the property change events
+ // Prepare the change record
+ const bool finalFrame = isFinalFrame(localTime, duration, animatorData.currentLoop, animatorData.loopCount);
const QVector<MappingData> mappingData = blendedClipAnimator->mappingData();
- const QVector<Qt3DCore::QSceneChangePtr> changes = preparePropertyChanges(blendedClipAnimator->peerId(),
- mappingData,
- blendedResults,
- finalFrame,
- phase);
- // Send the property changes
- blendedClipAnimator->sendPropertyChanges(changes);
+ auto record = prepareAnimationRecord(blendedClipAnimator->peerId(),
+ mappingData,
+ blendedResults,
+ finalFrame,
+ float(phase));
// Trigger callbacks either on this thread or by notifying the gui thread.
- const QVector<AnimationCallbackAndValue> callbacks = prepareCallbacks(mappingData, blendedResults);
- blendedClipAnimator->sendCallbacks(callbacks);
+ auto callbacks = prepareCallbacks(mappingData, blendedResults);
+
+ setPostFrameData(record, callbacks);
}
} // Animation
diff --git a/src/animation/backend/evaluateblendclipanimatorjob_p.h b/src/animation/backend/evaluateblendclipanimatorjob_p.h
index 7548168e9..b2a5a6d17 100644
--- a/src/animation/backend/evaluateblendclipanimatorjob_p.h
+++ b/src/animation/backend/evaluateblendclipanimatorjob_p.h
@@ -48,7 +48,7 @@
// We mean it.
//
-#include <Qt3DCore/qaspectjob.h>
+#include <Qt3DAnimation/private/abstractevaluateclipanimatorjob_p.h>
#include <Qt3DAnimation/private/handle_types_p.h>
#include <Qt3DAnimation/private/animationutils_p.h>
#include <Qt3DAnimation/private/blendedclipanimator_p.h>
@@ -60,8 +60,9 @@ namespace Animation {
class Handler;
class ClipBlendNode;
+class EvaluateBlendClipAnimatorJobPrivate;
-class EvaluateBlendClipAnimatorJob : public Qt3DCore::QAspectJob
+class EvaluateBlendClipAnimatorJob : public AbstractEvaluateClipAnimatorJob
{
public:
EvaluateBlendClipAnimatorJob();
diff --git a/src/animation/backend/evaluateclipanimatorjob.cpp b/src/animation/backend/evaluateclipanimatorjob.cpp
index 74f9012d7..7a568e829 100644
--- a/src/animation/backend/evaluateclipanimatorjob.cpp
+++ b/src/animation/backend/evaluateclipanimatorjob.cpp
@@ -35,6 +35,9 @@
****************************************************************************/
#include "evaluateclipanimatorjob_p.h"
+#include <Qt3DCore/private/qaspectjob_p.h>
+#include <Qt3DCore/private/qaspectmanager_p.h>
+#include <Qt3DAnimation/qclipanimator.h>
#include <Qt3DAnimation/private/handler_p.h>
#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DAnimation/private/animationlogging_p.h>
@@ -46,10 +49,11 @@ QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
namespace Animation {
+
EvaluateClipAnimatorJob::EvaluateClipAnimatorJob()
- : Qt3DCore::QAspectJob()
+ : AbstractEvaluateClipAnimatorJob()
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::EvaluateClipAnimator, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::EvaluateClipAnimator, 0)
}
void EvaluateClipAnimatorJob::run()
@@ -98,19 +102,16 @@ void EvaluateClipAnimatorJob::run()
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)
- const QVector<Qt3DCore::QSceneChangePtr> changes = preparePropertyChanges(clipAnimator->peerId(),
- clipAnimator->mappingData(),
- formattedClipResults,
- preEvaluationDataForClip.isFinalFrame,
- preEvaluationDataForClip.normalizedLocalTime);
-
- // Send the property changes
- clipAnimator->sendPropertyChanges(changes);
+ auto record = prepareAnimationRecord(clipAnimator->peerId(),
+ clipAnimator->mappingData(),
+ formattedClipResults,
+ preEvaluationDataForClip.isFinalFrame,
+ preEvaluationDataForClip.normalizedLocalTime);
// Trigger callbacks either on this thread or by notifying the gui thread.
- const QVector<AnimationCallbackAndValue> callbacks = prepareCallbacks(clipAnimator->mappingData(),
- formattedClipResults);
- clipAnimator->sendCallbacks(callbacks);
+ auto callbacks = prepareCallbacks(clipAnimator->mappingData(), formattedClipResults);
+
+ setPostFrameData(record, callbacks);
}
} // namespace Animation
diff --git a/src/animation/backend/evaluateclipanimatorjob_p.h b/src/animation/backend/evaluateclipanimatorjob_p.h
index c9b1a8f96..2e88c9579 100644
--- a/src/animation/backend/evaluateclipanimatorjob_p.h
+++ b/src/animation/backend/evaluateclipanimatorjob_p.h
@@ -48,7 +48,7 @@
// We mean it.
//
-#include <Qt3DCore/qaspectjob.h>
+#include <Qt3DAnimation/private/abstractevaluateclipanimatorjob_p.h>
#include <Qt3DAnimation/private/handle_types_p.h>
QT_BEGIN_NAMESPACE
@@ -58,7 +58,7 @@ namespace Animation {
class Handler;
-class EvaluateClipAnimatorJob : public Qt3DCore::QAspectJob
+class EvaluateClipAnimatorJob : public AbstractEvaluateClipAnimatorJob
{
public:
EvaluateClipAnimatorJob();
diff --git a/src/animation/backend/skeleton.cpp b/src/animation/backend/skeleton.cpp
index 720b43e33..2d395848c 100644
--- a/src/animation/backend/skeleton.cpp
+++ b/src/animation/backend/skeleton.cpp
@@ -89,15 +89,6 @@ void Skeleton::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
BackendNode::sceneChangeEvent(e);
}
-void Skeleton::sendLocalPoses()
-{
- auto e = QPropertyUpdatedChangePtr::create(peerId());
- e->setDeliveryFlags(Qt3DCore::QSceneChange::BackendNodes);
- e->setPropertyName("localPoses");
- e->setValue(QVariant::fromValue(m_jointLocalPoses));
- notifyObservers(e);
-}
-
} // namespace Animation
} // namespace Qt3DAnimation
diff --git a/src/animation/backend/skeleton_p.h b/src/animation/backend/skeleton_p.h
index 668ff8712..544eb08be 100644
--- a/src/animation/backend/skeleton_p.h
+++ b/src/animation/backend/skeleton_p.h
@@ -64,6 +64,7 @@ public:
void cleanup();
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE;
+ QVector<Qt3DCore::Sqt> joints() const { return m_jointLocalPoses; }
int jointCount() const { return m_jointLocalPoses.size(); }
QString jointName(int jointIndex) const { return m_jointNames.at(jointIndex); }
@@ -97,8 +98,6 @@ public:
return m_jointLocalPoses[jointIndex].translation;
}
- void sendLocalPoses();
-
#if defined(QT_BUILD_INTERNAL)
void setJointCount(int jointCount)
{
diff --git a/src/animation/frontend/qabstractclipanimator.cpp b/src/animation/frontend/qabstractclipanimator.cpp
index 238dbea8c..b2f6f817f 100644
--- a/src/animation/frontend/qabstractclipanimator.cpp
+++ b/src/animation/frontend/qabstractclipanimator.cpp
@@ -41,7 +41,6 @@
#include "qabstractclipanimator_p.h"
#include <Qt3DAnimation/qchannelmapper.h>
#include <Qt3DAnimation/qclock.h>
-#include <Qt3DAnimation/private/qanimationcallbacktrigger_p.h>
QT_BEGIN_NAMESPACE
@@ -123,18 +122,6 @@ QAbstractClipAnimator::QAbstractClipAnimator(QAbstractClipAnimatorPrivate &dd, Q
{
}
-/*! \internal */
-void QAbstractClipAnimator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
-{
- if (change->type() == Qt3DCore::CallbackTriggered) {
- QAnimationCallbackTriggerPtr callbackTrigger = qSharedPointerCast<Qt3DAnimation::QAnimationCallbackTrigger>(change);
- if (callbackTrigger->callback())
- callbackTrigger->callback()->valueChanged(callbackTrigger->value());
- } else {
- QComponent::sceneChangeEvent(change);
- }
-}
-
QAbstractClipAnimator::~QAbstractClipAnimator()
{
}
diff --git a/src/animation/frontend/qabstractclipanimator.h b/src/animation/frontend/qabstractclipanimator.h
index a3bce0600..687589b5e 100644
--- a/src/animation/frontend/qabstractclipanimator.h
+++ b/src/animation/frontend/qabstractclipanimator.h
@@ -94,8 +94,6 @@ protected:
explicit QAbstractClipAnimator(Qt3DCore::QNode *parent = nullptr);
QAbstractClipAnimator(QAbstractClipAnimatorPrivate &dd, Qt3DCore::QNode *parent = nullptr);
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
-
private:
Q_DECLARE_PRIVATE(QAbstractClipAnimator)
};
diff --git a/src/core/transforms/qabstractskeleton.cpp b/src/core/transforms/qabstractskeleton.cpp
index 1bc7247a7..5f3b05eb8 100644
--- a/src/core/transforms/qabstractskeleton.cpp
+++ b/src/core/transforms/qabstractskeleton.cpp
@@ -60,6 +60,14 @@ const QAbstractSkeletonPrivate *QAbstractSkeletonPrivate::get(const QAbstractSke
}
/*!
+ \internal
+ */
+QAbstractSkeletonPrivate *QAbstractSkeletonPrivate::get(QAbstractSkeleton *q)
+{
+ return q->d_func();
+}
+
+/*!
\qmltype AbstractSkeleton
\inqmlmodule Qt3D.Core
\inherits Node
diff --git a/src/core/transforms/qabstractskeleton_p.h b/src/core/transforms/qabstractskeleton_p.h
index e4db7b11e..be50c24f5 100644
--- a/src/core/transforms/qabstractskeleton_p.h
+++ b/src/core/transforms/qabstractskeleton_p.h
@@ -53,6 +53,7 @@
#include <Qt3DCore/private/qnode_p.h>
#include <Qt3DCore/private/qskeletoncreatedchange_p.h>
+#include <Qt3DCore/private/sqt_p.h>
QT_BEGIN_NAMESPACE
@@ -67,10 +68,12 @@ public:
Q_DECLARE_PUBLIC(QAbstractSkeleton)
static const QAbstractSkeletonPrivate *get(const QAbstractSkeleton *q);
+ static QAbstractSkeletonPrivate *get(QAbstractSkeleton *q);
QSkeletonCreatedChangeBase::SkeletonType m_type;
int m_jointCount;
+ QVector<Sqt> m_localPoses;
};
} // namespace Qt3DCore
diff --git a/src/render/backend/transform.cpp b/src/render/backend/transform.cpp
index 7c9afc3cf..8e98801b7 100644
--- a/src/render/backend/transform.cpp
+++ b/src/render/backend/transform.cpp
@@ -88,28 +88,6 @@ QVector3D Transform::translation() const
return m_translation;
}
-// TODOSYNC remove once we've found a way to propagate animation changes
-void Transform::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- // TODO: Flag the matrix as dirty and update all matrices batched in a job
- if (e->type() == PropertyUpdated) {
- const QPropertyUpdatedChangePtr &propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("scale3D")) {
- m_scale = propertyChange->value().value<QVector3D>();
- updateMatrix();
- } else if (propertyChange->propertyName() == QByteArrayLiteral("rotation")) {
- m_rotation = propertyChange->value().value<QQuaternion>();
- updateMatrix();
- } else if (propertyChange->propertyName() == QByteArrayLiteral("translation")) {
- m_translation = propertyChange->value().value<QVector3D>();
- updateMatrix();
- }
- }
- markDirty(AbstractRenderer::TransformDirty);
-
- BackendNode::sceneChangeEvent(e);
-}
-
void Transform::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
const Qt3DCore::QTransform *transform = qobject_cast<const Qt3DCore::QTransform *>(frontEnd);
diff --git a/src/render/backend/transform_p.h b/src/render/backend/transform_p.h
index 12b1bbf90..8c0cd826a 100644
--- a/src/render/backend/transform_p.h
+++ b/src/render/backend/transform_p.h
@@ -76,7 +76,6 @@ public:
QQuaternion rotation() const;
QVector3D translation() const;
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) final;
private:
diff --git a/src/render/geometry/skeleton.cpp b/src/render/geometry/skeleton.cpp
index d4af1fe3c..14892922a 100644
--- a/src/render/geometry/skeleton.cpp
+++ b/src/render/geometry/skeleton.cpp
@@ -139,28 +139,9 @@ void Skeleton::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
}
}
}
-}
-
-// TODOSYNC remove once animation aspect no longer requires messages
-void Skeleton::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case Qt3DCore::PropertyUpdated: {
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("localPoses")) {
- // When the animation aspect sends us a new set of local poses, all we
- // need to do is copy them into place. The existing jobs will then update
- // the skinning matrix palette.
- m_skeletonData.localPoses = change->value().value<QVector<Qt3DCore::Sqt>>();
- }
-
- break;
- }
- default:
- break;
- }
- QBackendNode::sceneChangeEvent(e);
+ auto d = Qt3DCore::QAbstractSkeletonPrivate::get(node);
+ m_skeletonData.localPoses = d->m_localPoses;
}
void Skeleton::setStatus(QSkeletonLoader::Status status)
diff --git a/src/render/geometry/skeleton_p.h b/src/render/geometry/skeleton_p.h
index d71b404e5..d1c6befe9 100644
--- a/src/render/geometry/skeleton_p.h
+++ b/src/render/geometry/skeleton_p.h
@@ -84,7 +84,6 @@ public:
JointManager *jointManager() const { return m_jointManager; }
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void setStatus(Qt3DCore::QSkeletonLoader::Status status);
Qt3DCore::QSkeletonLoader::Status status() const { return m_status; }
diff --git a/tests/auto/animation/animationutils/tst_animationutils.cpp b/tests/auto/animation/animationutils/tst_animationutils.cpp
index 36f1cbe2f..385398bd1 100644
--- a/tests/auto/animation/animationutils/tst_animationutils.cpp
+++ b/tests/auto/animation/animationutils/tst_animationutils.cpp
@@ -795,16 +795,12 @@ private Q_SLOTS:
QTest::addColumn<Qt3DCore::QNodeId>("animatorId");
QTest::addColumn<QVector<MappingData>>("mappingData");
QTest::addColumn<QVector<float>>("channelResults");
- QTest::addColumn<float>("normalizedTime");
- QTest::addColumn<bool>("finalFrame");
- QTest::addColumn<QVector<Qt3DCore::QPropertyUpdatedChangePtr>>("expectedChanges");
+ QTest::addColumn<AnimationRecord>("expectedChanges");
Qt3DCore::QNodeId animatorId;
QVector<MappingData> mappingData;
QVector<float> channelResults;
- bool finalFrame;
- float normalizedTime;
- QVector<Qt3DCore::QPropertyUpdatedChangePtr> expectedChanges;
+ AnimationRecord expectedChanges;
// Single property, vec3
{
@@ -816,40 +812,22 @@ private Q_SLOTS:
mapping.channelIndices = QVector<int>() << 0 << 1 << 2;
mappingData.push_back(mapping);
channelResults = QVector<float>() << 1.0f << 2.0f << 3.0f;
- finalFrame = false;
- normalizedTime = 1.1f; // Invalid
-
- auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(mapping.targetId);
- change->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- change->setPropertyName(mapping.propertyName);
- change->setValue(QVariant::fromValue(QVector3D(1.0f, 2.0f, 3.0f)));
- expectedChanges.push_back(change);
+ expectedChanges.normalizedTime = 1.1f; // Invalid
+ expectedChanges.finalFrame = false;
+ expectedChanges.targetChanges.push_back({mapping.targetId, mapping.propertyName, QVariant::fromValue(QVector3D(1.0f, 2.0f, 3.0f))});
QTest::newRow("vec3 translation, final = false")
- << animatorId << mappingData << channelResults << normalizedTime
- << finalFrame << expectedChanges;
-
- normalizedTime = 1.0f;
- auto normalizedTimeChange = Qt3DCore::QPropertyUpdatedChangePtr::create(animatorId);
- normalizedTimeChange->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- normalizedTimeChange->setPropertyName("normalizedTime");
- normalizedTimeChange->setValue(normalizedTime);
- expectedChanges.push_back(normalizedTimeChange);
-
- finalFrame = true;
- auto animatorChange = Qt3DCore::QPropertyUpdatedChangePtr::create(animatorId);
- animatorChange->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- animatorChange->setPropertyName("running");
- animatorChange->setValue(false);
- expectedChanges.push_back(animatorChange);
+ << animatorId << mappingData << channelResults << expectedChanges;
+
+ expectedChanges.normalizedTime = 1.0f;
+ expectedChanges.finalFrame = true;
QTest::newRow("vec3 translation, final = true, normalizedTime = 1.0f")
- << animatorId << mappingData << channelResults << normalizedTime
- << finalFrame << expectedChanges;
+ << animatorId << mappingData << channelResults << expectedChanges;
mappingData.clear();
channelResults.clear();
- expectedChanges.clear();
+ expectedChanges.targetChanges.clear();
}
// Multiple properties, all vec3
@@ -871,46 +849,24 @@ private Q_SLOTS:
channelResults = QVector<float>() << 1.0f << 2.0f << 3.0f
<< 4.0f << 5.0f << 6.0f;
- finalFrame = false;
- normalizedTime = -0.1f; // Invalid
-
- auto translationChange = Qt3DCore::QPropertyUpdatedChangePtr::create(translationMapping.targetId);
- translationChange->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- translationChange->setPropertyName(translationMapping.propertyName);
- translationChange->setValue(QVariant::fromValue(QVector3D(1.0f, 2.0f, 3.0f)));
- expectedChanges.push_back(translationChange);
+ expectedChanges.finalFrame = false;
+ expectedChanges.normalizedTime = -0.1f; // Invalid
- auto scaleChange = Qt3DCore::QPropertyUpdatedChangePtr::create(scaleMapping.targetId);
- scaleChange->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- scaleChange->setPropertyName(scaleMapping.propertyName);
- scaleChange->setValue(QVariant::fromValue(QVector3D(4.0f, 5.0f, 6.0f)));
- expectedChanges.push_back(scaleChange);
+ expectedChanges.targetChanges.push_back({translationMapping.targetId, translationMapping.propertyName, QVariant::fromValue(QVector3D(1.0f, 2.0f, 3.0f))});
+ expectedChanges.targetChanges.push_back({scaleMapping.targetId, scaleMapping.propertyName, QVariant::fromValue(QVector3D(4.0f, 5.0f, 6.0f))});
QTest::newRow("vec3 translation, vec3 scale, final = false")
- << animatorId << mappingData << channelResults << normalizedTime
- << finalFrame << expectedChanges;
-
- normalizedTime = 0.5f;
- auto normalizedTimeChange = Qt3DCore::QPropertyUpdatedChangePtr::create(animatorId);
- normalizedTimeChange->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- normalizedTimeChange->setPropertyName("normalizedTime");
- normalizedTimeChange->setValue(normalizedTime);
- expectedChanges.push_back(normalizedTimeChange);
-
- finalFrame = true;
- auto animatorChange = Qt3DCore::QPropertyUpdatedChangePtr::create(animatorId);
- animatorChange->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- animatorChange->setPropertyName("running");
- animatorChange->setValue(false);
- expectedChanges.push_back(animatorChange);
+ << animatorId << mappingData << channelResults << expectedChanges;
+
+ expectedChanges.normalizedTime = 0.5f;
+ expectedChanges.finalFrame = true;
QTest::newRow("vec3 translation, vec3 scale, final = true")
- << animatorId << mappingData << channelResults << normalizedTime
- << finalFrame << expectedChanges;
+ << animatorId << mappingData << channelResults << expectedChanges;
mappingData.clear();
channelResults.clear();
- expectedChanges.clear();
+ expectedChanges.targetChanges.clear();
}
// Single property, double
@@ -923,22 +879,16 @@ private Q_SLOTS:
mapping.channelIndices = QVector<int>() << 0;
mappingData.push_back(mapping);
channelResults = QVector<float>() << 3.5f;
- finalFrame = false;
- normalizedTime = -1.0f; // Invalid
-
- auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(mapping.targetId);
- change->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- change->setPropertyName(mapping.propertyName);
- change->setValue(QVariant::fromValue(3.5f));
- expectedChanges.push_back(change);
+ expectedChanges.finalFrame = false;
+ expectedChanges.normalizedTime = -1.0f; // Invalid
+ expectedChanges.targetChanges.push_back({mapping.targetId, mapping.propertyName, QVariant::fromValue(3.5f)});
QTest::newRow("double mass")
- << animatorId << mappingData << channelResults << normalizedTime
- << finalFrame << expectedChanges;
+ << animatorId << mappingData << channelResults << expectedChanges;
mappingData.clear();
channelResults.clear();
- expectedChanges.clear();
+ expectedChanges.targetChanges.clear();
}
// Single property, vec2
@@ -951,22 +901,16 @@ private Q_SLOTS:
mapping.channelIndices = QVector<int>() << 0 << 1;
mappingData.push_back(mapping);
channelResults = QVector<float>() << 2.0f << 1.0f;
- finalFrame = false;
- normalizedTime = 1.1f; // Invalid
-
- auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(mapping.targetId);
- change->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- change->setPropertyName(mapping.propertyName);
- change->setValue(QVariant::fromValue(QVector2D(2.0f, 1.0f)));
- expectedChanges.push_back(change);
+ expectedChanges.finalFrame = false;
+ expectedChanges.normalizedTime = 1.1f; // Invalid
+ expectedChanges.targetChanges.push_back({mapping.targetId, mapping.propertyName, QVariant::fromValue(QVector2D(2.0f, 1.0f))});
QTest::newRow("vec2 pos")
- << animatorId << mappingData << channelResults << normalizedTime
- << finalFrame << expectedChanges;
+ << animatorId << mappingData << channelResults << expectedChanges;
mappingData.clear();
channelResults.clear();
- expectedChanges.clear();
+ expectedChanges.targetChanges.clear();
}
// Single property, vec4
@@ -979,22 +923,16 @@ private Q_SLOTS:
mapping.channelIndices = QVector<int>() << 0 << 1 << 2 << 3;
mappingData.push_back(mapping);
channelResults = QVector<float>() << 4.0f << 3.0f << 2.0f << 1.0f;
- finalFrame = false;
- normalizedTime = 1.1f; // Invalid
-
- auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(mapping.targetId);
- change->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- change->setPropertyName(mapping.propertyName);
- change->setValue(QVariant::fromValue(QVector4D(4.0f, 3.0f, 2.0f, 1.0f)));
- expectedChanges.push_back(change);
+ expectedChanges.finalFrame = false;
+ expectedChanges.normalizedTime = 1.1f; // Invalid
+ expectedChanges.targetChanges.push_back({mapping.targetId, mapping.propertyName, QVariant::fromValue(QVector4D(4.0f, 3.0f, 2.0f, 1.0f))});
QTest::newRow("vec4 foo")
- << animatorId << mappingData << channelResults << normalizedTime
- << finalFrame << expectedChanges;
+ << animatorId << mappingData << channelResults << expectedChanges;
mappingData.clear();
channelResults.clear();
- expectedChanges.clear();
+ expectedChanges.targetChanges.clear();
}
// Single property, quaternion
@@ -1007,22 +945,16 @@ private Q_SLOTS:
mapping.channelIndices = QVector<int>() << 0 << 1 << 2 << 3;
mappingData.push_back(mapping);
channelResults = QVector<float>() << 1.0f << 0.0f << 0.0f << 1.0f;
- finalFrame = false;
- normalizedTime = -0.1f; // Invalid
-
- auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(mapping.targetId);
- change->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- change->setPropertyName(mapping.propertyName);
- change->setValue(QVariant::fromValue(QQuaternion(1.0f, 0.0f, 0.0f, 1.0f).normalized()));
- expectedChanges.push_back(change);
+ expectedChanges.finalFrame = false;
+ expectedChanges.normalizedTime = -0.1f; // Invalid
+ expectedChanges.targetChanges.push_back({mapping.targetId, mapping.propertyName, QVariant::fromValue(QQuaternion(1.0f, 0.0f, 0.0f, 1.0f).normalized())});
QTest::newRow("quaternion rotation")
- << animatorId << mappingData << channelResults << normalizedTime
- << finalFrame << expectedChanges;
+ << animatorId << mappingData << channelResults << expectedChanges;
mappingData.clear();
channelResults.clear();
- expectedChanges.clear();
+ expectedChanges.targetChanges.clear();
}
// Single property, QColor
@@ -1035,22 +967,16 @@ private Q_SLOTS:
mapping.channelIndices = QVector<int>() << 0 << 1 << 2;
mappingData.push_back(mapping);
channelResults = QVector<float>() << 0.5f << 0.4f << 0.3f;
- finalFrame = false;
- normalizedTime = 1.1f; // Invalid
-
- auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(mapping.targetId);
- change->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- change->setPropertyName(mapping.propertyName);
- change->setValue(QVariant::fromValue(QColor::fromRgbF(0.5f, 0.4f, 0.3f)));
- expectedChanges.push_back(change);
+ expectedChanges.finalFrame = false;
+ expectedChanges.normalizedTime = 1.1f; // Invalid
+ expectedChanges.targetChanges.push_back({mapping.targetId, mapping.propertyName, QVariant::fromValue(QColor::fromRgbF(0.5f, 0.4f, 0.3f))});
QTest::newRow("QColor color")
- << animatorId << mappingData << channelResults << normalizedTime
- << finalFrame << expectedChanges;
+ << animatorId << mappingData << channelResults << expectedChanges;
mappingData.clear();
channelResults.clear();
- expectedChanges.clear();
+ expectedChanges.targetChanges.clear();
}
// Single property, QVariantList
@@ -1063,23 +989,17 @@ private Q_SLOTS:
mapping.channelIndices = QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6;
mappingData.push_back(mapping);
channelResults = QVector<float>() << 0.5f << 0.4f << 0.3f << 0.0f << 1.0f << 0.6f << 0.9f;
- finalFrame = false;
- normalizedTime = 1.1f; // Invalid
-
- auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(mapping.targetId);
- change->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- change->setPropertyName(mapping.propertyName);
+ expectedChanges.finalFrame = false;
+ expectedChanges.normalizedTime = 1.1f; // Invalid
QVariantList expectedValue = QVariantList() << 0.5f << 0.4f << 0.3f << 0.0f << 1.0f << 0.6f << 0.9f;
- change->setValue(QVariant::fromValue(expectedValue));
- expectedChanges.push_back(change);
+ expectedChanges.targetChanges.push_back({mapping.targetId, mapping.propertyName, QVariant::fromValue(expectedValue)});
QTest::newRow("QVariantList weights")
- << animatorId << mappingData << channelResults << normalizedTime
- << finalFrame << expectedChanges;
+ << animatorId << mappingData << channelResults << expectedChanges;
mappingData.clear();
channelResults.clear();
- expectedChanges.clear();
+ expectedChanges.targetChanges.clear();
}
}
@@ -1090,25 +1010,21 @@ private Q_SLOTS:
QFETCH(Qt3DCore::QNodeId, animatorId);
QFETCH(QVector<MappingData>, mappingData);
QFETCH(QVector<float>, channelResults);
- QFETCH(float, normalizedTime);
- QFETCH(bool, finalFrame);
- QFETCH(QVector<Qt3DCore::QPropertyUpdatedChangePtr>, expectedChanges);
+ QFETCH(AnimationRecord, expectedChanges);
// WHEN
- QVector<Qt3DCore::QSceneChangePtr> actualChanges
- = preparePropertyChanges(animatorId, mappingData, channelResults, finalFrame, normalizedTime);
+ AnimationRecord actualChanges = prepareAnimationRecord(animatorId, mappingData, channelResults,
+ expectedChanges.finalFrame, expectedChanges.normalizedTime);
// THEN
- QCOMPARE(actualChanges.size(), expectedChanges.size());
- for (int i = 0; i < actualChanges.size(); ++i) {
- auto expectedChange = expectedChanges[i];
- auto actualChange
- = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(actualChanges[i]);
-
- QCOMPARE(actualChange->subjectId(), expectedChange->subjectId());
- QCOMPARE(actualChange->deliveryFlags(), expectedChange->deliveryFlags());
- QCOMPARE(actualChange->propertyName(), expectedChange->propertyName());
- QCOMPARE(actualChange->value(), expectedChange->value());
+ QCOMPARE(actualChanges.targetChanges.size(), expectedChanges.targetChanges.size());
+ for (int i = 0; i < actualChanges.targetChanges.size(); ++i) {
+ const auto &expectedChange = expectedChanges.targetChanges[i];
+ const auto &actualChange = actualChanges.targetChanges[i];
+
+ QCOMPARE(actualChange.targetId, expectedChange.targetId);
+ QCOMPARE(actualChange.propertyName, expectedChange.propertyName);
+ QCOMPARE(actualChange.value, expectedChange.value);
}
}