1// Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "abstractevaluateclipanimatorjob_p.h"
5#include <Qt3DCore/private/qaspectjob_p.h>
6#include <Qt3DCore/private/qaspectmanager_p.h>
7#include <Qt3DCore/private/qskeleton_p.h>
8#include <Qt3DAnimation/qabstractclipanimator.h>
9
10QT_BEGIN_NAMESPACE
11
12namespace Qt3DAnimation {
13namespace Animation {
14
15class AbstractEvaluateClipAnimatorJobPrivate : public Qt3DCore::QAspectJobPrivate
16{
17public:
18 AbstractEvaluateClipAnimatorJobPrivate() { }
19 ~AbstractEvaluateClipAnimatorJobPrivate() override { }
20
21 void postFrame(Qt3DCore::QAspectManager *manager) override;
22
23 AnimationRecord m_record;
24 QVector<AnimationCallbackAndValue> m_callbacks;
25};
26
27AbstractEvaluateClipAnimatorJob::AbstractEvaluateClipAnimatorJob()
28 : Qt3DCore::QAspectJob(*new AbstractEvaluateClipAnimatorJobPrivate)
29{
30}
31
32void AbstractEvaluateClipAnimatorJob::setPostFrameData(const AnimationRecord &record, const QVector<AnimationCallbackAndValue> &callbacks)
33{
34 auto mainThreadCB = callbacks;
35 mainThreadCB.erase(abegin: std::remove_if(first: mainThreadCB.begin(), last: mainThreadCB.end(), pred: [](const AnimationCallbackAndValue &callback) {
36 if (callback.flags.testFlag(flag: QAnimationCallback::OnThreadPool)) {
37 // call these now and remove them from the list
38 callback.callback->valueChanged(value: callback.value);
39 return true;
40 }
41 return false;
42 }), aend: mainThreadCB.end());
43 // Should now only have callbacks to be called on main thread
44
45 Q_D(AbstractEvaluateClipAnimatorJob);
46 d->m_record = record;
47 d->m_callbacks = mainThreadCB;
48}
49
50void AbstractEvaluateClipAnimatorJobPrivate::postFrame(Qt3DCore::QAspectManager *manager)
51{
52 if (m_record.animatorId.isNull())
53 return;
54
55 for (auto targetData : std::as_const(t&: m_record.targetChanges)) {
56 Qt3DCore::QNode *node = manager->lookupNode(id: targetData.targetId);
57 if (node)
58 node->setProperty(name: targetData.propertyName, value: targetData.value);
59 }
60
61 for (auto skeletonData : std::as_const(t&: m_record.skeletonChanges)) {
62 Qt3DCore::QAbstractSkeleton *node = qobject_cast<Qt3DCore::QAbstractSkeleton *>(object: manager->lookupNode(id: skeletonData.first));
63 if (node) {
64 auto d = Qt3DCore::QAbstractSkeletonPrivate::get(q: node);
65 d->m_localPoses = skeletonData.second;
66 d->update();
67 }
68 }
69
70 QAbstractClipAnimator *animator = qobject_cast<QAbstractClipAnimator *>(object: manager->lookupNode(id: m_record.animatorId));
71 if (animator) {
72 if (isValidNormalizedTime(t: m_record.normalizedTime))
73 animator->setNormalizedTime(m_record.normalizedTime);
74 if (m_record.finalFrame)
75 animator->setRunning(false);
76 }
77
78 for (const AnimationCallbackAndValue &callback: std::as_const(t&: m_callbacks)) {
79 if (callback.callback)
80 callback.callback->valueChanged(value: callback.value);
81 }
82
83 m_record = {};
84}
85
86} // Animation
87} // Qt3DAnimation
88
89QT_END_NAMESPACE
90

source code of qt3d/src/animation/backend/abstractevaluateclipanimatorjob.cpp