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 "blendedclipanimator_p.h"
38#include <Qt3DAnimation/qblendedclipanimator.h>
39#include <Qt3DAnimation/private/qblendedclipanimator_p.h>
40#include <Qt3DAnimation/private/qanimationcallbacktrigger_p.h>
41#include <Qt3DCore/qpropertyupdatedchange.h>
42
43QT_BEGIN_NAMESPACE
44
45namespace Qt3DAnimation {
46namespace Animation {
47
48BlendedClipAnimator::BlendedClipAnimator()
49 : BackendNode(ReadWrite)
50 , m_running(false)
51 , m_lastGlobalTimeNS(0)
52 , m_lastLocalTime(0.0)
53 , m_currentLoop(0)
54 , m_loops(1)
55 , m_normalizedLocalTime(-1.0f)
56 , m_lastNormalizedLocalTime(-1.0)
57{
58}
59
60void BlendedClipAnimator::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
61{
62 const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QBlendedClipAnimatorData>>(change);
63 const QBlendedClipAnimatorData &data = typedChange->data;
64 m_blendTreeRootId = data.blendTreeRootId;
65 m_mapperId = data.mapperId;
66 m_clockId = data.clockId;
67 m_running = data.running;
68 m_loops = data.loops;
69 m_normalizedLocalTime = data.normalizedTime;
70 setDirty(Handler::BlendedClipAnimatorDirty);
71}
72
73double BlendedClipAnimator::lastLocalTime() const
74{
75 return m_lastLocalTime;
76}
77
78void BlendedClipAnimator::setLastLocalTime(double lastLocalTime)
79{
80 m_lastLocalTime = lastLocalTime;
81}
82
83void BlendedClipAnimator::setLastNormalizedLocalTime(float normalizedTime)
84{
85 m_lastNormalizedLocalTime = normalizedTime;
86}
87
88void BlendedClipAnimator::setLastGlobalTimeNS(const qint64 &lastGlobalTimeNS)
89{
90 m_lastGlobalTimeNS = lastGlobalTimeNS;
91}
92
93qint64 BlendedClipAnimator::nsSincePreviousFrame(qint64 currentGlobalTimeNS)
94{
95 return currentGlobalTimeNS - m_lastGlobalTimeNS;
96}
97
98void BlendedClipAnimator::cleanup()
99{
100 setEnabled(false);
101 m_handler = nullptr;
102 m_blendTreeRootId = Qt3DCore::QNodeId();
103 m_mapperId = Qt3DCore::QNodeId();
104 m_clockId = Qt3DCore::QNodeId();
105 m_running = false;
106 m_lastGlobalTimeNS = 0;
107 m_lastLocalTime = 0.0;
108 m_currentLoop = 0;
109 m_loops = 1;
110}
111
112void BlendedClipAnimator::setBlendTreeRootId(Qt3DCore::QNodeId blendTreeId)
113{
114 m_blendTreeRootId = blendTreeId;
115 setDirty(Handler::BlendedClipAnimatorDirty);
116}
117
118void BlendedClipAnimator::setMapperId(Qt3DCore::QNodeId mapperId)
119{
120 m_mapperId = mapperId;
121 setDirty(Handler::BlendedClipAnimatorDirty);
122}
123
124void BlendedClipAnimator::setClockId(Qt3DCore::QNodeId clockId)
125{
126 m_clockId = clockId;
127 setDirty(Handler::BlendedClipAnimatorDirty);
128}
129
130void BlendedClipAnimator::setRunning(bool running)
131{
132 m_running = running;
133 setDirty(Handler::BlendedClipAnimatorDirty);
134}
135
136void BlendedClipAnimator::sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes)
137{
138 for (const Qt3DCore::QSceneChangePtr &change : changes)
139 notifyObservers(change);
140}
141
142void BlendedClipAnimator::sendCallbacks(const QVector<AnimationCallbackAndValue> &callbacks)
143{
144 for (const AnimationCallbackAndValue &callback : callbacks) {
145 if (callback.flags.testFlag(QAnimationCallback::OnThreadPool)) {
146 callback.callback->valueChanged(callback.value);
147 } else {
148 auto e = QAnimationCallbackTriggerPtr::create(peerId());
149 e->setCallback(callback.callback);
150 e->setValue(callback.value);
151 e->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
152 notifyObservers(e);
153 }
154 }
155}
156
157
158Qt3DCore::QNodeId BlendedClipAnimator::blendTreeRootId() const
159{
160 return m_blendTreeRootId;
161}
162
163void BlendedClipAnimator::setNormalizedLocalTime(float normalizedTime)
164{
165 m_normalizedLocalTime = normalizedTime;
166 if (isValidNormalizedTime(m_normalizedLocalTime))
167 setDirty(Handler::BlendedClipAnimatorDirty);
168}
169
170void BlendedClipAnimator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
171{
172 switch (e->type()) {
173 case Qt3DCore::PropertyUpdated: {
174 const auto change = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e);
175 if (change->propertyName() == QByteArrayLiteral("blendTree"))
176 setBlendTreeRootId(change->value().value<Qt3DCore::QNodeId>());
177 else if (change->propertyName() == QByteArrayLiteral("channelMapper"))
178 setMapperId(change->value().value<Qt3DCore::QNodeId>());
179 else if (change->propertyName() == QByteArrayLiteral("clock"))
180 setClockId(change->value().value<Qt3DCore::QNodeId>());
181 else if (change->propertyName() == QByteArrayLiteral("running"))
182 setRunning(change->value().toBool());
183 else if (change->propertyName() == QByteArrayLiteral("loops"))
184 m_loops = change->value().toInt();
185 else if (change->propertyName() == QByteArrayLiteral("normalizedTime"))
186 setNormalizedLocalTime(change->value().toFloat());
187 break;
188 }
189
190 default:
191 break;
192 }
193 BackendNode::sceneChangeEvent(e);
194}
195
196} // namespace Animation
197} // namespace Qt3DAnimation
198
199QT_END_NAMESPACE
200