1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the Qt3D module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL3$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see http://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at http://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPLv3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or later as published by the Free |
28 | ** Software Foundation and appearing in the file LICENSE.GPL included in |
29 | ** the packaging of this file. Please review the following information to |
30 | ** ensure the GNU General Public License version 2.0 requirements will be |
31 | ** met: http://www.gnu.org/licenses/gpl-2.0.html. |
32 | ** |
33 | ** $QT_END_LICENSE$ |
34 | ** |
35 | ****************************************************************************/ |
36 | |
37 | #include "clipanimator_p.h" |
38 | #include <Qt3DAnimation/qclipanimator.h> |
39 | #include <Qt3DAnimation/private/qclipanimator_p.h> |
40 | #include <Qt3DAnimation/private/animationclip_p.h> |
41 | #include <Qt3DAnimation/private/managers_p.h> |
42 | #include <Qt3DAnimation/private/animationlogging_p.h> |
43 | #include <Qt3DAnimation/private/qanimationcallbacktrigger_p.h> |
44 | #include <Qt3DCore/qpropertyupdatedchange.h> |
45 | #include <Qt3DCore/private/qpropertyupdatedchangebase_p.h> |
46 | |
47 | QT_BEGIN_NAMESPACE |
48 | |
49 | namespace Qt3DAnimation { |
50 | namespace Animation { |
51 | |
52 | ClipAnimator::ClipAnimator() |
53 | : BackendNode(ReadWrite) |
54 | , m_clipId() |
55 | , m_mapperId() |
56 | , m_clockId() |
57 | , m_running(false) |
58 | , m_loops(1) |
59 | , m_lastGlobalTimeNS(0) |
60 | , m_lastLocalTime(0.0) |
61 | , m_mappingData() |
62 | , m_currentLoop(0) |
63 | , m_normalizedLocalTime(-1.0f) |
64 | , m_lastNormalizedLocalTime(-1.0f) |
65 | { |
66 | } |
67 | |
68 | void ClipAnimator::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) |
69 | { |
70 | const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QClipAnimatorData>>(change); |
71 | const auto &data = typedChange->data; |
72 | m_clipId = data.clipId; |
73 | m_mapperId = data.mapperId; |
74 | m_clockId = data.clockId; |
75 | m_running = data.running; |
76 | m_loops = data.loops; |
77 | m_normalizedLocalTime = data.normalizedTime; |
78 | setDirty(Handler::ClipAnimatorDirty); |
79 | } |
80 | |
81 | void ClipAnimator::setClipId(Qt3DCore::QNodeId clipId) |
82 | { |
83 | m_clipId = clipId; |
84 | setDirty(Handler::ClipAnimatorDirty); |
85 | |
86 | // register at the clip to make sure we are marked dirty when the clip finished loading |
87 | AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipId); |
88 | if (clip) |
89 | clip->addDependingClipAnimator(peerId()); |
90 | } |
91 | |
92 | void ClipAnimator::setMapperId(Qt3DCore::QNodeId mapperId) |
93 | { |
94 | m_mapperId = mapperId; |
95 | setDirty(Handler::ClipAnimatorDirty); |
96 | } |
97 | |
98 | void ClipAnimator::setClockId(Qt3DCore::QNodeId clockId) |
99 | { |
100 | m_clockId = clockId; |
101 | setDirty(Handler::ClipAnimatorDirty); |
102 | } |
103 | |
104 | void ClipAnimator::setRunning(bool running) |
105 | { |
106 | m_running = running; |
107 | if (!running) |
108 | m_currentLoop = 0; |
109 | setDirty(Handler::ClipAnimatorDirty); |
110 | } |
111 | |
112 | void ClipAnimator::setNormalizedLocalTime(float normalizedTime) |
113 | { |
114 | m_normalizedLocalTime = normalizedTime; |
115 | if (isValidNormalizedTime(normalizedTime)) |
116 | setDirty(Handler::ClipAnimatorDirty); |
117 | } |
118 | |
119 | void ClipAnimator::cleanup() |
120 | { |
121 | setEnabled(false); |
122 | m_handler = nullptr; |
123 | m_clipId = Qt3DCore::QNodeId(); |
124 | m_mapperId = Qt3DCore::QNodeId(); |
125 | m_clockId = Qt3DCore::QNodeId(); |
126 | m_running = false; |
127 | m_loops = 1; |
128 | m_clipFormat = ClipFormat(); |
129 | m_normalizedLocalTime = m_lastNormalizedLocalTime = -1.0f; |
130 | } |
131 | |
132 | void ClipAnimator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) |
133 | { |
134 | switch (e->type()) { |
135 | case Qt3DCore::PropertyUpdated: { |
136 | const auto change = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e); |
137 | if (change->propertyName() == QByteArrayLiteral("clip" )) |
138 | setClipId(change->value().value<Qt3DCore::QNodeId>()); |
139 | else if (change->propertyName() == QByteArrayLiteral("channelMapper" )) |
140 | setMapperId(change->value().value<Qt3DCore::QNodeId>()); |
141 | else if (change->propertyName() == QByteArrayLiteral("clock" )) |
142 | setClockId(change->value().value<Qt3DCore::QNodeId>()); |
143 | else if (change->propertyName() == QByteArrayLiteral("running" )) |
144 | setRunning(change->value().toBool()); |
145 | else if (change->propertyName() == QByteArrayLiteral("loops" )) |
146 | m_loops = change->value().toInt(); |
147 | else if (change->propertyName() == QByteArrayLiteral("normalizedTime" )) |
148 | setNormalizedLocalTime(change->value().toFloat()); |
149 | break; |
150 | } |
151 | |
152 | default: |
153 | break; |
154 | } |
155 | QBackendNode::sceneChangeEvent(e); |
156 | } |
157 | |
158 | void ClipAnimator::sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes) |
159 | { |
160 | for (const Qt3DCore::QSceneChangePtr &change : changes) |
161 | notifyObservers(change); |
162 | } |
163 | |
164 | void ClipAnimator::sendCallbacks(const QVector<AnimationCallbackAndValue> &callbacks) |
165 | { |
166 | for (const AnimationCallbackAndValue &callback : callbacks) { |
167 | if (callback.flags.testFlag(QAnimationCallback::OnThreadPool)) { |
168 | callback.callback->valueChanged(callback.value); |
169 | } else { |
170 | auto e = QAnimationCallbackTriggerPtr::create(peerId()); |
171 | e->setCallback(callback.callback); |
172 | e->setValue(callback.value); |
173 | e->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes); |
174 | notifyObservers(e); |
175 | } |
176 | } |
177 | } |
178 | |
179 | qint64 ClipAnimator::nsSincePreviousFrame(qint64 currentGlobalTimeNS) |
180 | { |
181 | return currentGlobalTimeNS - m_lastGlobalTimeNS; |
182 | } |
183 | |
184 | void ClipAnimator::setLastGlobalTimeNS(qint64 lastGlobalTimeNS) |
185 | { |
186 | m_lastGlobalTimeNS = lastGlobalTimeNS; |
187 | } |
188 | |
189 | double ClipAnimator::lastLocalTime() const |
190 | { |
191 | return m_lastLocalTime; |
192 | } |
193 | |
194 | void ClipAnimator::setLastLocalTime(double lastLocalTime) |
195 | { |
196 | m_lastLocalTime = lastLocalTime; |
197 | } |
198 | |
199 | void ClipAnimator::setLastNormalizedLocalTime(float normalizedTime) |
200 | { |
201 | m_lastNormalizedLocalTime = normalizedTime; |
202 | } |
203 | |
204 | } // namespace Animation |
205 | } // namespace Qt3DAnimation |
206 | |
207 | QT_END_NAMESPACE |
208 | |