1/****************************************************************************
2**
3** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
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>
30#include <Qt3DRender/private/joint_p.h>
31#include <Qt3DRender/private/nodemanagers_p.h>
32#include <Qt3DCore/qjoint.h>
33#include <Qt3DCore/private/qnode_p.h>
34#include <Qt3DCore/private/qscene_p.h>
35#include <QtGui/qmatrix4x4.h>
36#include <QtGui/qvector3d.h>
37#include <qbackendnodetester.h>
38#include <testpostmanarbiter.h>
39#include <testrenderer.h>
40
41using namespace Qt3DCore;
42using namespace Qt3DRender;
43using namespace Qt3DRender::Render;
44
45class tst_Joint : public Qt3DCore::QBackendNodeTester
46{
47 Q_OBJECT
48
49private Q_SLOTS:
50 void checkPeerPropertyMirroring()
51 {
52 // GIVEN
53 TestRenderer renderer;
54 NodeManagers nodeManagers;
55 renderer.setNodeManagers(&nodeManagers);
56 Joint backendJoint;
57 backendJoint.setRenderer(&renderer);
58 backendJoint.setJointManager(nodeManagers.jointManager());
59 backendJoint.setSkeletonManager(nodeManagers.skeletonManager());
60 QJoint joint;
61
62 joint.setTranslation(QVector3D(1.0f, 2.0f, 3.0f));
63 joint.setScale(QVector3D(1.5f, 2.5f, 3.5));
64 joint.setRotation(QQuaternion::fromAxisAndAngle(x: 1.0f, y: 0.0f, z: 0.0f, angle: 45.0f));
65 QMatrix4x4 inverseBind;
66 inverseBind.rotate(angle: -45.0f, x: 1.0f, y: 0.0, z: 0.0f);
67 joint.setInverseBindMatrix(inverseBind);
68
69 QVector<QJoint *> childJoints;
70 for (int i = 0; i < 10; ++i) {
71 const auto childJoint = new QJoint();
72 joint.addChildJoint(joint: childJoint);
73 childJoints.push_back(t: childJoint);
74 }
75
76 // WHEN
77 simulateInitializationSync(frontend: &joint, backend: &backendJoint);
78
79 // THEN
80 QCOMPARE(backendJoint.peerId(), joint.id());
81 QCOMPARE(backendJoint.isEnabled(), joint.isEnabled());
82 QCOMPARE(backendJoint.translation(), joint.translation());
83 QCOMPARE(backendJoint.rotation(), joint.rotation());
84 QCOMPARE(backendJoint.scale(), joint.scale());
85 QCOMPARE(backendJoint.inverseBindMatrix(), joint.inverseBindMatrix());
86 for (int i = 0; i < childJoints.size(); ++i) {
87 QCOMPARE(backendJoint.childJointIds()[i], childJoints[i]->id());
88 }
89 }
90
91 void checkInitialAndCleanedUpState()
92 {
93 // GIVEN
94 TestRenderer renderer;
95 NodeManagers nodeManagers;
96 renderer.setNodeManagers(&nodeManagers);
97 Joint backendJoint;
98 backendJoint.setRenderer(&renderer);
99 backendJoint.setJointManager(nodeManagers.jointManager());
100 backendJoint.setSkeletonManager(nodeManagers.skeletonManager());
101
102 // THEN
103 QVERIFY(backendJoint.peerId().isNull());
104 QCOMPARE(backendJoint.isEnabled(), false);
105 QCOMPARE(backendJoint.translation(), QVector3D());
106 QCOMPARE(backendJoint.rotation(), QQuaternion());
107 QCOMPARE(backendJoint.scale(), QVector3D(1.0f, 1.0f, 1.0f));
108 QCOMPARE(backendJoint.inverseBindMatrix(), QMatrix4x4());
109 QCOMPARE(backendJoint.childJointIds(), QNodeIdVector());
110 QCOMPARE(backendJoint.owningSkeleton(), HSkeleton());
111
112 // GIVEN
113 QJoint joint;
114 joint.setTranslation(QVector3D(1.0f, 2.0f, 3.0f));
115 joint.setScale(QVector3D(1.5f, 2.5f, 3.5));
116 joint.setRotation(QQuaternion::fromAxisAndAngle(x: 1.0f, y: 0.0f, z: 0.0f, angle: 45.0f));
117 QMatrix4x4 inverseBind;
118 inverseBind.rotate(angle: -45.0f, x: 1.0f, y: 0.0, z: 0.0f);
119 joint.setInverseBindMatrix(inverseBind);
120
121 QVector<QJoint *> childJoints;
122 for (int i = 0; i < 10; ++i) {
123 const auto childJoint = new QJoint();
124 joint.addChildJoint(joint: childJoint);
125 childJoints.push_back(t: childJoint);
126 }
127
128 // WHEN
129 simulateInitializationSync(frontend: &joint, backend: &backendJoint);
130 backendJoint.cleanup();
131
132 // THEN
133 QCOMPARE(backendJoint.isEnabled(), false);
134 QCOMPARE(backendJoint.translation(), QVector3D());
135 QCOMPARE(backendJoint.rotation(), QQuaternion());
136 QCOMPARE(backendJoint.scale(), QVector3D(1.0f, 1.0f, 1.0f));
137 QCOMPARE(backendJoint.inverseBindMatrix(), QMatrix4x4());
138 QCOMPARE(backendJoint.childJointIds(), QNodeIdVector());
139 QCOMPARE(backendJoint.owningSkeleton(), HSkeleton());
140 }
141
142 void checkPropertyChanges()
143 {
144 // GIVEN
145 TestRenderer renderer;
146 NodeManagers nodeManagers;
147 renderer.setNodeManagers(&nodeManagers);
148 Joint backendJoint;
149 backendJoint.setRenderer(&renderer);
150 backendJoint.setJointManager(nodeManagers.jointManager());
151 backendJoint.setSkeletonManager(nodeManagers.skeletonManager());
152 QJoint joint;
153 simulateInitializationSync(frontend: &joint, backend: &backendJoint);
154
155 // WHEN
156 joint.setEnabled(false);
157 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
158
159 // THEN
160 QCOMPARE(backendJoint.isEnabled(), false);
161
162 // WHEN
163 const QVector3D newTranslation = QVector3D(1.0f, 2.0f, 3.0f);
164 joint.setTranslation(newTranslation);
165 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
166
167 // THEN
168 QCOMPARE(backendJoint.translation(), newTranslation);
169
170 // WHEN
171 const QQuaternion newRotation = QQuaternion::fromAxisAndAngle(x: 1.0f, y: 0.0f, z: 0.0f, angle: 45.0f);
172 joint.setRotation(newRotation);
173 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
174
175 // THEN
176 QCOMPARE(backendJoint.rotation(), newRotation);
177
178 // WHEN
179 const QVector3D newScale = QVector3D(1.5f, 2.5f, 3.5f);
180 joint.setScale(newScale);
181 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
182
183 // THEN
184 QCOMPARE(backendJoint.scale(), newScale);
185
186 // WHEN
187 QMatrix4x4 newInverseBind;
188 newInverseBind.scale(factor: 5.4f);
189 joint.setInverseBindMatrix(newInverseBind);
190 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
191
192 // THEN
193 QCOMPARE(backendJoint.inverseBindMatrix(), newInverseBind);
194
195 // WHEN
196 QVector<QJoint *> childJoints;
197 for (int i = 0; i < 10; ++i) {
198 const auto childJoint = new QJoint();
199 childJoints.push_back(t: childJoint);
200 joint.addChildJoint(joint: childJoint);
201 }
202 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
203
204 // THEN
205 for (int i = 0; i < childJoints.size(); ++i)
206 QCOMPARE(backendJoint.childJointIds()[i], childJoints[i]->id());
207
208 for (int i = 0; i < 10; ++i) {
209 // WHEN
210 const auto childJoint = childJoints.takeLast();
211 joint.removeChildJoint(joint: childJoint);
212 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
213
214 // THEN
215 for (int i = 0; i < childJoints.size(); ++i)
216 QCOMPARE(backendJoint.childJointIds()[i], childJoints[i]->id());
217 }
218 }
219
220 void checkDirectPropertyChanges()
221 {
222 // GIVEN
223 TestRenderer renderer;
224 NodeManagers nodeManagers;
225 renderer.setNodeManagers(&nodeManagers);
226 Joint backendJoint;
227 backendJoint.setRenderer(&renderer);
228 backendJoint.setJointManager(nodeManagers.jointManager());
229 backendJoint.setSkeletonManager(nodeManagers.skeletonManager());
230
231 QJoint joint;
232 simulateInitializationSync(frontend: &joint, backend: &backendJoint);
233
234 // WHEN
235 joint.setEnabled(false);
236 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
237
238 // THEN
239 QCOMPARE(backendJoint.isEnabled(), false);
240
241 // WHEN
242 const QVector3D newTranslation = QVector3D(1.0f, 2.0f, 3.0f);
243 joint.setTranslation(newTranslation);
244 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
245
246 // THEN
247 QCOMPARE(backendJoint.translation(), newTranslation);
248
249 // WHEN
250 const QQuaternion newRotation = QQuaternion::fromAxisAndAngle(x: 1.0f, y: 0.0f, z: 0.0f, angle: 45.0f);
251 joint.setRotation(newRotation);
252 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
253
254 // THEN
255 QCOMPARE(backendJoint.rotation(), newRotation);
256
257 // WHEN
258 const QVector3D newScale = QVector3D(1.5f, 2.5f, 3.5f);
259 joint.setScale(newScale);
260 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
261
262 // THEN
263 QCOMPARE(backendJoint.scale(), newScale);
264
265 // WHEN
266 QMatrix4x4 newInverseBind;
267 newInverseBind.scale(factor: 5.4f);
268 joint.setInverseBindMatrix(newInverseBind);
269 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
270
271 // THEN
272 QCOMPARE(backendJoint.inverseBindMatrix(), newInverseBind);
273
274 // WHEN
275 QVector<QJoint *> childJoints;
276 for (int i = 0; i < 10; ++i) {
277 const auto childJoint = new QJoint();
278 joint.addChildJoint(joint: childJoint);
279 childJoints.push_back(t: childJoint);
280 }
281 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
282
283 // THEN
284 for (int i = 0; i < childJoints.size(); ++i) {
285 QCOMPARE(backendJoint.childJointIds()[i], childJoints[i]->id());
286 }
287
288 for (int i = 0; i < 10; ++i) {
289 // WHEN
290 const auto childJoint = childJoints.takeLast();
291
292 joint.removeChildJoint(joint: childJoint);
293 backendJoint.syncFromFrontEnd(frontEnd: &joint, firstTime: false);
294
295 // THEN
296 for (int j = 0; j < childJoints.size(); ++j)
297 QCOMPARE(backendJoint.childJointIds()[j], childJoints[j]->id());
298 }
299 }
300};
301
302QTEST_APPLESS_MAIN(tst_Joint)
303
304#include "tst_joint.moc"
305

source code of qt3d/tests/auto/render/joint/tst_joint.cpp