diff options
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); } } |