1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/qtest.h>
30#include <Qt3DAnimation/qmorphinganimation.h>
31#include <qobject.h>
32#include <qsignalspy.h>
33
34class tst_QMorphingAnimation : public QObject
35{
36 Q_OBJECT
37
38 bool verifyAttribute(Qt3DRender::QGeometry *geometry, QString name,
39 Qt3DRender::QAttribute *attribute)
40 {
41 const QVector<Qt3DRender::QAttribute *> attributes = geometry->attributes();
42 for (const Qt3DRender::QAttribute *attr : attributes) {
43 if (attr->name() == name) {
44 if (attr == attribute)
45 return true;
46 return false;
47 }
48 }
49 return false;
50 }
51
52private Q_SLOTS:
53
54 void initTestCase()
55 {
56 qRegisterMetaType<Qt3DAnimation::QMorphingAnimation::Method>(typeName: "QMorphingAnimation::Method");
57 }
58
59 void checkDefaultConstruction()
60 {
61 // GIVEN
62 Qt3DAnimation::QMorphingAnimation morphingAnimation;
63
64 // THEN
65 QCOMPARE(morphingAnimation.interpolator(), 0.0f);
66 QCOMPARE(morphingAnimation.target(), nullptr);
67 QCOMPARE(morphingAnimation.targetName(), QString());
68 QCOMPARE(morphingAnimation.method(), Qt3DAnimation::QMorphingAnimation::Relative);
69 QCOMPARE(morphingAnimation.easing(), QEasingCurve());
70 }
71
72 void checkPropertyChanges()
73 {
74 // GIVEN
75 Qt3DAnimation::QMorphingAnimation morphingAnimation;
76
77 {
78 // WHEN
79 QScopedPointer<Qt3DRender::QGeometryRenderer> gr(new Qt3DRender::QGeometryRenderer);
80 QSignalSpy spy(&morphingAnimation,
81 SIGNAL(targetChanged(Qt3DRender::QGeometryRenderer *)));
82 Qt3DRender::QGeometryRenderer *newValue = gr.data();
83 morphingAnimation.setTarget(newValue);
84
85 // THEN
86 QCOMPARE(morphingAnimation.target(), newValue);
87 QCOMPARE(spy.count(), 1);
88
89 // WHEN
90 spy.clear();
91 morphingAnimation.setTarget(newValue);
92
93 // THEN
94 QCOMPARE(morphingAnimation.target(), newValue);
95 QCOMPARE(spy.count(), 0);
96
97 }
98 {
99 // WHEN
100 QSignalSpy spy(&morphingAnimation, SIGNAL(targetNameChanged(QString)));
101 const QString newValue = QString("target");
102 morphingAnimation.setTargetName(newValue);
103
104 // THEN
105 QCOMPARE(morphingAnimation.targetName(), newValue);
106 QCOMPARE(spy.count(), 1);
107
108 // WHEN
109 spy.clear();
110 morphingAnimation.setTargetName(newValue);
111
112 // THEN
113 QCOMPARE(morphingAnimation.targetName(), newValue);
114 QCOMPARE(spy.count(), 0);
115
116 }
117 {
118 // WHEN
119 QSignalSpy spy(&morphingAnimation, SIGNAL(methodChanged(QMorphingAnimation::Method)));
120 const Qt3DAnimation::QMorphingAnimation::Method newValue
121 = Qt3DAnimation::QMorphingAnimation::Normalized;
122 morphingAnimation.setMethod(newValue);
123
124 // THEN
125 QCOMPARE(morphingAnimation.method(), newValue);
126 QCOMPARE(spy.count(), 1);
127
128 // WHEN
129 spy.clear();
130 morphingAnimation.setMethod(newValue);
131
132 // THEN
133 QCOMPARE(morphingAnimation.method(), newValue);
134 QCOMPARE(spy.count(), 0);
135
136 }
137 {
138 // WHEN
139 QSignalSpy spy(&morphingAnimation, SIGNAL(easingChanged(QEasingCurve)));
140 const QEasingCurve newValue = QEasingCurve(QEasingCurve::InBounce);
141 morphingAnimation.setEasing(newValue);
142
143 // THEN
144 QCOMPARE(morphingAnimation.easing(), newValue);
145 QCOMPARE(spy.count(), 1);
146
147 // WHEN
148 spy.clear();
149 morphingAnimation.setEasing(newValue);
150
151 // THEN
152 QCOMPARE(morphingAnimation.easing(), newValue);
153 QCOMPARE(spy.count(), 0);
154
155 }
156 }
157
158 void testAnimation()
159 {
160 // GIVEN
161 const QString baseName("position");
162 const QString targetName("positionTarget");
163 Qt3DAnimation::QMorphingAnimation morphingAnimation;
164 Qt3DRender::QAttribute *base = new Qt3DRender::QAttribute;
165
166 Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry;
167 Qt3DAnimation::QMorphTarget *mt1 = new Qt3DAnimation::QMorphTarget(&morphingAnimation);
168 Qt3DAnimation::QMorphTarget *mt2 = new Qt3DAnimation::QMorphTarget(&morphingAnimation);
169 Qt3DAnimation::QMorphTarget *mt3 = new Qt3DAnimation::QMorphTarget(&morphingAnimation);
170 Qt3DRender::QAttribute *a1 = new Qt3DRender::QAttribute(geometry);
171 Qt3DRender::QAttribute *a2 = new Qt3DRender::QAttribute(geometry);
172 Qt3DRender::QAttribute *a3 = new Qt3DRender::QAttribute(geometry);
173 Qt3DRender::QGeometryRenderer gr;
174
175 base->setName(baseName);
176 geometry->addAttribute(attribute: base);
177 gr.setGeometry(geometry);
178 morphingAnimation.setTarget(&gr);
179 a1->setName(baseName);
180 a2->setName(baseName);
181 a3->setName(baseName);
182 mt1->addAttribute(attribute: a1);
183 mt2->addAttribute(attribute: a2);
184 mt3->addAttribute(attribute: a3);
185 morphingAnimation.addMorphTarget(target: mt1);
186 morphingAnimation.addMorphTarget(target: mt2);
187 morphingAnimation.addMorphTarget(target: mt3);
188
189 QVector<float> positions;
190 QVector<float> weights;
191 positions.push_back(t: 0.0f);
192 positions.push_back(t: 1.0f);
193 positions.push_back(t: 2.0f);
194 positions.push_back(t: 3.0f);
195 positions.push_back(t: 4.0f);
196 morphingAnimation.setTargetPositions(positions);
197
198 weights.resize(asize: 3);
199
200 weights[0] = 1.0f;
201 weights[1] = 0.0f;
202 weights[2] = 0.0f;
203 morphingAnimation.setWeights(positionIndex: 0, weights);
204 weights[0] = 0.0f;
205 weights[1] = 0.0f;
206 weights[2] = 0.0f;
207 morphingAnimation.setWeights(positionIndex: 1, weights);
208 weights[0] = 0.0f;
209 weights[1] = 1.0f;
210 weights[2] = 0.0f;
211 morphingAnimation.setWeights(positionIndex: 2, weights);
212 weights[0] = 0.0f;
213 weights[1] = 0.0f;
214 weights[2] = 0.0f;
215 morphingAnimation.setWeights(positionIndex: 3, weights);
216 weights[0] = 0.0f;
217 weights[1] = 0.0f;
218 weights[2] = 1.0f;
219 morphingAnimation.setWeights(positionIndex: 4, weights);
220
221 morphingAnimation.setMethod(Qt3DAnimation::QMorphingAnimation::Relative);
222 {
223 // WHEN
224 morphingAnimation.setPosition(0.0f);
225
226 // THEN
227 QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), -1.0f));
228 QVERIFY(verifyAttribute(geometry, baseName, base));
229 QVERIFY(verifyAttribute(geometry, targetName, a1));
230
231 // WHEN
232 morphingAnimation.setPosition(0.5f);
233
234 // THEN
235 QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), -0.5f));
236 QVERIFY(verifyAttribute(geometry, baseName, base));
237 QVERIFY(verifyAttribute(geometry, targetName, a1));
238
239 // WHEN
240 morphingAnimation.setPosition(1.0f);
241
242 // THEN
243 QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), -0.0f));
244 QVERIFY(verifyAttribute(geometry, baseName, base));
245
246 // WHEN
247 morphingAnimation.setPosition(1.5f);
248
249 // THEN
250 QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), -0.5f));
251 QVERIFY(verifyAttribute(geometry, baseName, base));
252 QVERIFY(verifyAttribute(geometry, targetName, a2));
253
254 // WHEN
255 morphingAnimation.setPosition(4.0f);
256
257 // THEN
258 QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), -1.0f));
259 QVERIFY(verifyAttribute(geometry, baseName, base));
260 QVERIFY(verifyAttribute(geometry, targetName, a3));
261 }
262
263 morphingAnimation.setMethod(Qt3DAnimation::QMorphingAnimation::Normalized);
264 {
265 // WHEN
266 morphingAnimation.setPosition(0.0f);
267
268 // THEN
269 QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), 1.0f));
270 QVERIFY(verifyAttribute(geometry, baseName, base));
271 QVERIFY(verifyAttribute(geometry, targetName, a1));
272
273 // WHEN
274 morphingAnimation.setPosition(0.5f);
275
276 // THEN
277 QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), 0.5f));
278 QVERIFY(verifyAttribute(geometry, baseName, base));
279 QVERIFY(verifyAttribute(geometry, targetName, a1));
280
281 // WHEN
282 morphingAnimation.setPosition(1.0f);
283
284 // THEN
285 QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), 0.0f));
286 QVERIFY(verifyAttribute(geometry, baseName, base));
287
288 // WHEN
289 morphingAnimation.setPosition(1.5f);
290
291 // THEN
292 QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), 0.5f));
293 QVERIFY(verifyAttribute(geometry, baseName, base));
294 QVERIFY(verifyAttribute(geometry, targetName, a2));
295
296 // WHEN
297 morphingAnimation.setPosition(4.0f);
298
299 // THEN
300 QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), 1.0f));
301 QVERIFY(verifyAttribute(geometry, baseName, base));
302 QVERIFY(verifyAttribute(geometry, targetName, a3));
303 }
304 }
305};
306
307QTEST_APPLESS_MAIN(tst_QMorphingAnimation)
308
309#include "tst_qmorphinganimation.moc"
310

source code of qt3d/tests/auto/animation/qmorphinganimation/tst_qmorphinganimation.cpp