1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 Paul Lemire <paul.lemire350@gmail.com> |
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/QtTest> |
30 | #include <Qt3DCore/private/matrix4x4_sse_p.h> |
31 | |
32 | using namespace Qt3DCore; |
33 | |
34 | class tst_Matrix4x4_SSE: public QObject |
35 | { |
36 | Q_OBJECT |
37 | |
38 | private Q_SLOTS: |
39 | |
40 | void defaultConstruction() |
41 | { |
42 | // GIVEN |
43 | Matrix4x4_SSE mat4; |
44 | |
45 | // THEN |
46 | QCOMPARE(mat4.m11(), 1.0f); |
47 | QCOMPARE(mat4.m12(), 0.0f); |
48 | QCOMPARE(mat4.m13(), 0.0f); |
49 | QCOMPARE(mat4.m14(), 0.0f); |
50 | |
51 | QCOMPARE(mat4.m21(), 0.0f); |
52 | QCOMPARE(mat4.m22(), 1.0f); |
53 | QCOMPARE(mat4.m23(), 0.0f); |
54 | QCOMPARE(mat4.m24(), 0.0f); |
55 | |
56 | QCOMPARE(mat4.m31(), 0.0f); |
57 | QCOMPARE(mat4.m32(), 0.0f); |
58 | QCOMPARE(mat4.m33(), 1.0f); |
59 | QCOMPARE(mat4.m34(), 0.0f); |
60 | |
61 | QCOMPARE(mat4.m41(), 0.0f); |
62 | QCOMPARE(mat4.m42(), 0.0f); |
63 | QCOMPARE(mat4.m43(), 0.0f); |
64 | QCOMPARE(mat4.m44(), 1.0f); |
65 | |
66 | } |
67 | |
68 | void checkExplicitConstruction() |
69 | { |
70 | // GIVEN |
71 | Matrix4x4_SSE mat4(11.0f, 12.0f, 13.0f, 14.0f, |
72 | 21.0f, 22.0f, 23.0f, 24.0f, |
73 | 31.0f, 32.0f, 33.0f, 34.0f, |
74 | 41.0f, 42.0f, 43.0f, 44.0f); |
75 | |
76 | // THEN |
77 | QCOMPARE(mat4.m11(), 11.0f); |
78 | QCOMPARE(mat4.m12(), 12.0f); |
79 | QCOMPARE(mat4.m13(), 13.0f); |
80 | QCOMPARE(mat4.m14(), 14.0f); |
81 | |
82 | QCOMPARE(mat4.m21(), 21.0f); |
83 | QCOMPARE(mat4.m22(), 22.0f); |
84 | QCOMPARE(mat4.m23(), 23.0f); |
85 | QCOMPARE(mat4.m24(), 24.0f); |
86 | |
87 | QCOMPARE(mat4.m31(), 31.0f); |
88 | QCOMPARE(mat4.m32(), 32.0f); |
89 | QCOMPARE(mat4.m33(), 33.0f); |
90 | QCOMPARE(mat4.m34(), 34.0f); |
91 | |
92 | QCOMPARE(mat4.m41(), 41.0f); |
93 | QCOMPARE(mat4.m42(), 42.0f); |
94 | QCOMPARE(mat4.m43(), 43.0f); |
95 | QCOMPARE(mat4.m44(), 44.0f); |
96 | } |
97 | |
98 | void checkTransposed() |
99 | { |
100 | // GIVEN |
101 | Matrix4x4_SSE mat4(11.0f, 12.0f, 13.0f, 14.0f, |
102 | 21.0f, 22.0f, 23.0f, 24.0f, |
103 | 31.0f, 32.0f, 33.0f, 34.0f, |
104 | 41.0f, 42.0f, 43.0f, 44.0f); |
105 | |
106 | // WHEN |
107 | mat4 = mat4.transposed(); |
108 | |
109 | // THEN |
110 | QCOMPARE(mat4.m11(), 11.0f); |
111 | QCOMPARE(mat4.m12(), 21.0f); |
112 | QCOMPARE(mat4.m13(), 31.0f); |
113 | QCOMPARE(mat4.m14(), 41.0f); |
114 | |
115 | QCOMPARE(mat4.m21(), 12.0f); |
116 | QCOMPARE(mat4.m22(), 22.0f); |
117 | QCOMPARE(mat4.m23(), 32.0f); |
118 | QCOMPARE(mat4.m24(), 42.0f); |
119 | |
120 | QCOMPARE(mat4.m31(), 13.0f); |
121 | QCOMPARE(mat4.m32(), 23.0f); |
122 | QCOMPARE(mat4.m33(), 33.0f); |
123 | QCOMPARE(mat4.m34(), 43.0f); |
124 | |
125 | QCOMPARE(mat4.m41(), 14.0f); |
126 | QCOMPARE(mat4.m42(), 24.0f); |
127 | QCOMPARE(mat4.m43(), 34.0f); |
128 | QCOMPARE(mat4.m44(), 44.0f); |
129 | } |
130 | |
131 | void checkMultiplication() |
132 | { |
133 | { |
134 | // GIVEN |
135 | QMatrix4x4 mat1; |
136 | QMatrix4x4 mat2; |
137 | |
138 | mat1.rotate(angle: 45.0f, vector: QVector3D(1.0f, 0.0f, 0.0f)); |
139 | mat2.translate(x: 5.0f, y: 12.0f, z: 11.0f); |
140 | |
141 | const Matrix4x4_SSE mat1fast(mat1); |
142 | const Matrix4x4_SSE mat2fast(mat2); |
143 | |
144 | // WHEN |
145 | const Matrix4x4_SSE ret = mat1fast * mat2fast; |
146 | |
147 | // THEN |
148 | QCOMPARE(ret.toQMatrix4x4(), mat1 * mat2); |
149 | } |
150 | { |
151 | // GIVEN |
152 | QMatrix4x4 mat1; |
153 | QMatrix4x4 mat2; |
154 | |
155 | mat1.rotate(angle: 45.0f, vector: QVector3D(1.0f, 0.0f, 0.0f)); |
156 | mat2.translate(x: 5.0f, y: 12.0f, z: 11.0f); |
157 | |
158 | const Matrix4x4_SSE mat1fast(mat1); |
159 | const Matrix4x4_SSE mat2fast(mat2); |
160 | |
161 | // WHEN |
162 | const Matrix4x4_SSE ret = mat2fast * mat1fast; |
163 | |
164 | // THEN |
165 | QCOMPARE(ret.toQMatrix4x4(), mat2 * mat1); |
166 | } |
167 | } |
168 | |
169 | void checkAddition() |
170 | { |
171 | { |
172 | // GIVEN |
173 | QMatrix4x4 mat1; |
174 | QMatrix4x4 mat2; |
175 | |
176 | mat1.rotate(angle: 45.0f, vector: QVector3D(1.0f, 0.0f, 0.0f)); |
177 | mat2.translate(x: 5.0f, y: 12.0f, z: 11.0f); |
178 | |
179 | const Matrix4x4_SSE mat1fast(mat1); |
180 | const Matrix4x4_SSE mat2fast(mat2); |
181 | |
182 | // WHEN |
183 | const Matrix4x4_SSE ret = mat1fast + mat2fast; |
184 | |
185 | // THEN |
186 | QCOMPARE(ret.toQMatrix4x4(), mat1 + mat2); |
187 | } |
188 | { |
189 | // GIVEN |
190 | QMatrix4x4 mat1; |
191 | QMatrix4x4 mat2; |
192 | |
193 | mat1.rotate(angle: 45.0f, vector: QVector3D(1.0f, 0.0f, 0.0f)); |
194 | mat2.translate(x: 5.0f, y: 12.0f, z: 11.0f); |
195 | |
196 | const Matrix4x4_SSE mat1fast(mat1); |
197 | const Matrix4x4_SSE mat2fast(mat2); |
198 | |
199 | // WHEN |
200 | const Matrix4x4_SSE ret = mat2fast + mat1fast; |
201 | |
202 | // THEN |
203 | QCOMPARE(ret.toQMatrix4x4(), mat2 + mat1); |
204 | } |
205 | } |
206 | |
207 | void checkSubstraction() |
208 | { |
209 | { |
210 | // GIVEN |
211 | QMatrix4x4 mat1; |
212 | QMatrix4x4 mat2; |
213 | |
214 | mat1.rotate(angle: 45.0f, vector: QVector3D(1.0f, 0.0f, 0.0f)); |
215 | mat2.translate(x: 5.0f, y: 12.0f, z: 11.0f); |
216 | |
217 | const Matrix4x4_SSE mat1fast(mat1); |
218 | const Matrix4x4_SSE mat2fast(mat2); |
219 | |
220 | // WHEN |
221 | const Matrix4x4_SSE ret = mat1fast - mat2fast; |
222 | |
223 | // THEN |
224 | QCOMPARE(ret.toQMatrix4x4(), mat1 - mat2); |
225 | } |
226 | { |
227 | // GIVEN |
228 | QMatrix4x4 mat1; |
229 | QMatrix4x4 mat2; |
230 | |
231 | mat1.rotate(angle: 45.0f, vector: QVector3D(1.0f, 0.0f, 0.0f)); |
232 | mat2.translate(x: 5.0f, y: 12.0f, z: 11.0f); |
233 | |
234 | const Matrix4x4_SSE mat1fast(mat1); |
235 | const Matrix4x4_SSE mat2fast(mat2); |
236 | |
237 | // WHEN |
238 | const Matrix4x4_SSE ret = mat2fast - mat1fast; |
239 | |
240 | // THEN |
241 | QCOMPARE(ret.toQMatrix4x4(), mat2 - mat1); |
242 | } |
243 | } |
244 | |
245 | void checkEquality() |
246 | { |
247 | { |
248 | // GIVEN |
249 | Matrix4x4_SSE c1; |
250 | Matrix4x4_SSE c2; |
251 | |
252 | // THEN |
253 | QVERIFY(c1 == c2); |
254 | } |
255 | { |
256 | QMatrix4x4 tmp; |
257 | tmp.translate(x: 5.0f, y: 8.0f, z: 14.0f); |
258 | |
259 | // GIVEN |
260 | Matrix4x4_SSE c1(tmp); |
261 | Matrix4x4_SSE c2(tmp); |
262 | |
263 | // THEN |
264 | QVERIFY(c1 == c2); |
265 | } |
266 | { |
267 | QMatrix4x4 tmp; |
268 | tmp.translate(x: 5.0f, y: 8.0f, z: 14.0f); |
269 | |
270 | // GIVEN |
271 | Matrix4x4_SSE c1; |
272 | Matrix4x4_SSE c2(tmp); |
273 | |
274 | // THEN |
275 | QVERIFY(!(c1 == c2)); |
276 | } |
277 | } |
278 | |
279 | void checkInequality() |
280 | { |
281 | { |
282 | // GIVEN |
283 | Matrix4x4_SSE c1; |
284 | Matrix4x4_SSE c2; |
285 | |
286 | // THEN |
287 | QVERIFY(!(c1 != c2)); |
288 | } |
289 | { |
290 | // GIVEN |
291 | QMatrix4x4 tmp; |
292 | tmp.translate(x: 5.0f, y: 8.0f, z: 14.0f); |
293 | |
294 | Matrix4x4_SSE c1(tmp); |
295 | tmp.translate(x: 3.0f, y: 9.0f, z: -4.0f); |
296 | Matrix4x4_SSE c2(tmp); |
297 | |
298 | // THEN |
299 | QVERIFY(c1 != c2); |
300 | } |
301 | } |
302 | |
303 | void checkMatrixVector4DMultiplication() |
304 | { |
305 | |
306 | // GIVEN |
307 | QMatrix4x4 tmpMat; |
308 | QVector4D tmpVec4(1.0f, 2.0f, 3.0f, 4.0f); |
309 | tmpMat.translate(x: 5.0f, y: 8.0f, z: 14.0f); |
310 | |
311 | Matrix4x4_SSE mat(tmpMat); |
312 | Vector4D vec4(tmpVec4); |
313 | |
314 | // WHEN |
315 | const Vector4D resultingVec = mat * vec4; |
316 | |
317 | // THEN |
318 | QCOMPARE(resultingVec.toQVector4D(), tmpMat * tmpVec4); |
319 | } |
320 | |
321 | void checkVector4DMatrixMultiplication() |
322 | { |
323 | |
324 | // GIVEN |
325 | QMatrix4x4 tmpMat; |
326 | QVector4D tmpVec4(1.0f, 2.0f, 3.0f, 4.0f); |
327 | tmpMat.translate(x: 5.0f, y: 8.0f, z: 14.0f); |
328 | |
329 | Matrix4x4_SSE mat(tmpMat); |
330 | Vector4D vec4(tmpVec4); |
331 | |
332 | // WHEN |
333 | const Vector4D resultingVec = vec4 * mat; |
334 | |
335 | // THEN |
336 | QCOMPARE(resultingVec.toQVector4D(), tmpVec4 * tmpMat); |
337 | } |
338 | |
339 | void checkMatrixVector3DMultiplication() |
340 | { |
341 | |
342 | // GIVEN |
343 | QMatrix4x4 tmpMat; |
344 | QVector3D tmpVec3(1.0f, 2.0f, 3.0f); |
345 | tmpMat.translate(x: 5.0f, y: 8.0f, z: 14.0f); |
346 | |
347 | Matrix4x4_SSE mat(tmpMat); |
348 | Vector3D vec3(tmpVec3); |
349 | |
350 | // WHEN |
351 | const Vector3D resultingVec = mat * vec3; |
352 | |
353 | // THEN |
354 | QCOMPARE(resultingVec.toQVector3D(), tmpMat * tmpVec3); |
355 | } |
356 | |
357 | void checkVector3DMatrixMultiplication() |
358 | { |
359 | |
360 | // GIVEN |
361 | QMatrix4x4 tmpMat; |
362 | QVector3D tmpVec3(1.0f, 2.0f, 3.0f); |
363 | tmpMat.translate(x: 5.0f, y: 8.0f, z: 14.0f); |
364 | |
365 | Matrix4x4_SSE mat(tmpMat); |
366 | Vector3D vec3(tmpVec3); |
367 | |
368 | // WHEN |
369 | const Vector3D resultingVec = vec3 * mat; |
370 | |
371 | // THEN |
372 | QCOMPARE(resultingVec.toQVector3D(), tmpVec3 * tmpMat); |
373 | } |
374 | |
375 | void checkRows() |
376 | { |
377 | // GIVEN |
378 | const Matrix4x4_SSE mat4(11.0f, 12.0f, 13.0f, 14.0f, |
379 | 21.0f, 22.0f, 23.0f, 24.0f, |
380 | 31.0f, 32.0f, 33.0f, 34.0f, |
381 | 41.0f, 42.0f, 43.0f, 44.0f); |
382 | |
383 | { |
384 | // WHEN |
385 | const Vector4D row = mat4.row(index: 0); |
386 | |
387 | // THEN |
388 | QCOMPARE(row.x(), 11.0f); |
389 | QCOMPARE(row.y(), 12.0f); |
390 | QCOMPARE(row.z(), 13.0f); |
391 | QCOMPARE(row.w(), 14.0f); |
392 | } |
393 | { |
394 | // WHEN |
395 | const Vector4D row = mat4.row(index: 1); |
396 | |
397 | // THEN |
398 | QCOMPARE(row.x(), 21.0f); |
399 | QCOMPARE(row.y(), 22.0f); |
400 | QCOMPARE(row.z(), 23.0f); |
401 | QCOMPARE(row.w(), 24.0f); |
402 | } |
403 | { |
404 | // WHEN |
405 | const Vector4D row = mat4.row(index: 2); |
406 | |
407 | // THEN |
408 | QCOMPARE(row.x(), 31.0f); |
409 | QCOMPARE(row.y(), 32.0f); |
410 | QCOMPARE(row.z(), 33.0f); |
411 | QCOMPARE(row.w(), 34.0f); |
412 | } |
413 | { |
414 | // WHEN |
415 | const Vector4D row = mat4.row(index: 3); |
416 | |
417 | // THEN |
418 | QCOMPARE(row.x(), 41.0f); |
419 | QCOMPARE(row.y(), 42.0f); |
420 | QCOMPARE(row.z(), 43.0f); |
421 | QCOMPARE(row.w(), 44.0f); |
422 | } |
423 | } |
424 | |
425 | void checkColumns() |
426 | { |
427 | // GIVEN |
428 | const Matrix4x4_SSE mat4(11.0f, 12.0f, 13.0f, 14.0f, |
429 | 21.0f, 22.0f, 23.0f, 24.0f, |
430 | 31.0f, 32.0f, 33.0f, 34.0f, |
431 | 41.0f, 42.0f, 43.0f, 44.0f); |
432 | |
433 | { |
434 | // WHEN |
435 | const Vector4D row = mat4.column(index: 0); |
436 | |
437 | // THEN |
438 | QCOMPARE(row.x(), 11.0f); |
439 | QCOMPARE(row.y(), 21.0f); |
440 | QCOMPARE(row.z(), 31.0f); |
441 | QCOMPARE(row.w(), 41.0f); |
442 | } |
443 | { |
444 | // WHEN |
445 | const Vector4D row = mat4.column(index: 1); |
446 | |
447 | // THEN |
448 | QCOMPARE(row.x(), 12.0f); |
449 | QCOMPARE(row.y(), 22.0f); |
450 | QCOMPARE(row.z(), 32.0f); |
451 | QCOMPARE(row.w(), 42.0f); |
452 | } |
453 | { |
454 | // WHEN |
455 | const Vector4D row = mat4.column(index: 2); |
456 | |
457 | // THEN |
458 | QCOMPARE(row.x(), 13.0f); |
459 | QCOMPARE(row.y(), 23.0f); |
460 | QCOMPARE(row.z(), 33.0f); |
461 | QCOMPARE(row.w(), 43.0f); |
462 | } |
463 | { |
464 | // WHEN |
465 | const Vector4D row = mat4.column(index: 3); |
466 | |
467 | // THEN |
468 | QCOMPARE(row.x(), 14.0f); |
469 | QCOMPARE(row.y(), 24.0f); |
470 | QCOMPARE(row.z(), 34.0f); |
471 | QCOMPARE(row.w(), 44.0f); |
472 | } |
473 | } |
474 | |
475 | void checkVectorMapVector() |
476 | { |
477 | { |
478 | // GIVEN |
479 | QMatrix4x4 tmpMat; |
480 | QVector3D tmpVec3(1.0f, 0.0f, 0.0f); |
481 | tmpMat.rotate(angle: 90.f, x: 0.f, y: 1.f, z: 0.f); |
482 | |
483 | Matrix4x4_SSE mat(tmpMat); |
484 | Vector3D vec3(tmpVec3); |
485 | |
486 | // WHEN |
487 | const Vector3D resultingVec = mat.mapVector(vector: vec3); |
488 | |
489 | // THEN |
490 | QCOMPARE(resultingVec.toQVector3D(), tmpMat.mapVector(tmpVec3)); |
491 | } |
492 | { |
493 | // GIVEN |
494 | QMatrix4x4 tmpMat; |
495 | QVector3D tmpVec3(0.0f, 0.0f, -1.0f); |
496 | tmpMat.rotate(angle: 90.f, x: 0.f, y: 1.f, z: 0.f); |
497 | |
498 | Matrix4x4_SSE mat(tmpMat); |
499 | Vector3D vec3(tmpVec3); |
500 | |
501 | // WHEN |
502 | const Vector3D resultingVec = mat.mapVector(vector: vec3); |
503 | |
504 | // THEN |
505 | QCOMPARE(resultingVec.toQVector3D(), tmpMat.mapVector(tmpVec3)); |
506 | } |
507 | { |
508 | // GIVEN |
509 | QMatrix4x4 tmpMat; |
510 | QVector3D tmpVec3(3.0f, -3.0f, -1.0f); |
511 | tmpMat.rotate(angle: 90.f, x: 0.33f, y: 0.33f, z: 0.33f); |
512 | |
513 | Matrix4x4_SSE mat(tmpMat); |
514 | Vector3D vec3(tmpVec3); |
515 | |
516 | // WHEN |
517 | const Vector3D resultingVec = mat.mapVector(vector: vec3); |
518 | |
519 | // THEN |
520 | QCOMPARE(resultingVec.toQVector3D(), tmpMat.mapVector(tmpVec3)); |
521 | } |
522 | } |
523 | }; |
524 | |
525 | QTEST_MAIN(tst_Matrix4x4_SSE) |
526 | |
527 | #include "tst_matrix4x4_sse.moc" |
528 | |