OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/math_util.h" | 5 #include "cc/math_util.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "cc/test/geometry_test_utils.h" | 9 #include "cc/test/geometry_test_utils.h" |
10 #include "testing/gmock/include/gmock/gmock.h" | 10 #include "testing/gmock/include/gmock/gmock.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
12 #include "ui/gfx/rect.h" | 12 #include "ui/gfx/rect.h" |
13 #include "ui/gfx/rect_f.h" | 13 #include "ui/gfx/rect_f.h" |
14 #include "ui/gfx/transform.h" | 14 #include "ui/gfx/transform.h" |
15 | 15 |
16 namespace cc { | 16 namespace cc { |
17 namespace { | 17 namespace { |
18 | 18 |
19 TEST(MathUtilTest, verifyBackfaceVisibilityBasicCases) | |
20 { | |
21 gfx::Transform transform; | |
22 | |
23 transform.MakeIdentity(); | |
24 EXPECT_FALSE(transform.IsBackFaceVisible()); | |
25 | |
26 transform.MakeIdentity(); | |
27 MathUtil::rotateEulerAngles(&transform, 0, 80, 0); | |
28 EXPECT_FALSE(transform.IsBackFaceVisible()); | |
29 | |
30 transform.MakeIdentity(); | |
31 MathUtil::rotateEulerAngles(&transform, 0, 100, 0); | |
32 EXPECT_TRUE(transform.IsBackFaceVisible()); | |
33 | |
34 // Edge case, 90 degree rotation should return false. | |
35 transform.MakeIdentity(); | |
36 MathUtil::rotateEulerAngles(&transform, 0, 90, 0); | |
37 EXPECT_FALSE(transform.IsBackFaceVisible()); | |
38 } | |
39 | |
40 TEST(MathUtilTest, verifyBackfaceVisibilityForPerspective) | |
41 { | |
42 gfx::Transform layerSpaceToProjectionPlane; | |
43 | |
44 // This tests if IsBackFaceVisible works properly under perspective transfor
ms. | |
45 // Specifically, layers that may have their back face visible in orthographi
c | |
46 // projection, may not actually have back face visible under perspective pro
jection. | |
47 | |
48 // Case 1: Layer is rotated by slightly more than 90 degrees, at the center
of the | |
49 // prespective projection. In this case, the layer's back-side is vi
sible to | |
50 // the camera. | |
51 layerSpaceToProjectionPlane.MakeIdentity(); | |
52 layerSpaceToProjectionPlane.ApplyPerspectiveDepth(1); | |
53 layerSpaceToProjectionPlane.Translate3d(0, 0, 0); | |
54 MathUtil::rotateEulerAngles(&layerSpaceToProjectionPlane, 0, 100, 0); | |
55 EXPECT_TRUE(layerSpaceToProjectionPlane.IsBackFaceVisible()); | |
56 | |
57 // Case 2: Layer is rotated by slightly more than 90 degrees, but shifted of
f to the | |
58 // side of the camera. Because of the wide field-of-view, the layer'
s front | |
59 // side is still visible. | |
60 // | |
61 // |<-- front side of layer is visible to perspective
camera | |
62 // \ | / | |
63 // \ | / | |
64 // \| / | |
65 // | / | |
66 // |\ /<-- camera field of view | |
67 // | \ / | |
68 // back side of layer -->| \ / | |
69 // \./ <-- camera origin | |
70 // | |
71 layerSpaceToProjectionPlane.MakeIdentity(); | |
72 layerSpaceToProjectionPlane.ApplyPerspectiveDepth(1); | |
73 layerSpaceToProjectionPlane.Translate3d(-10, 0, 0); | |
74 MathUtil::rotateEulerAngles(&layerSpaceToProjectionPlane, 0, 100, 0); | |
75 EXPECT_FALSE(layerSpaceToProjectionPlane.IsBackFaceVisible()); | |
76 | |
77 // Case 3: Additionally rotating the layer by 180 degrees should of course s
how the | |
78 // opposite result of case 2. | |
79 MathUtil::rotateEulerAngles(&layerSpaceToProjectionPlane, 0, 180, 0); | |
80 EXPECT_TRUE(layerSpaceToProjectionPlane.IsBackFaceVisible()); | |
81 } | |
82 | |
83 TEST(MathUtilTest, verifyProjectionOfPerpendicularPlane) | 19 TEST(MathUtilTest, verifyProjectionOfPerpendicularPlane) |
84 { | 20 { |
85 // In this case, the m33() element of the transform becomes zero, which coul
d cause a | 21 // In this case, the m33() element of the transform becomes zero, which coul
d cause a |
86 // divide-by-zero when projecting points/quads. | 22 // divide-by-zero when projecting points/quads. |
87 | 23 |
88 gfx::Transform transform; | 24 gfx::Transform transform; |
89 transform.MakeIdentity(); | 25 transform.MakeIdentity(); |
90 transform.matrix().setDouble(2, 2, 0); | 26 transform.matrix().setDouble(2, 2, 0); |
91 | 27 |
92 gfx::RectF rect = gfx::RectF(0, 0, 1, 1); | 28 gfx::RectF rect = gfx::RectF(0, 0, 1, 1); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, testVector.y()), MathUtil::projectVector(
testVector, y)); | 107 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, testVector.y()), MathUtil::projectVector(
testVector, y)); |
172 | 108 |
173 // Finally check than an arbitrary vector projected to another one gives a v
ector parallel to | 109 // Finally check than an arbitrary vector projected to another one gives a v
ector parallel to |
174 // the second vector. | 110 // the second vector. |
175 gfx::Vector2dF targetVector(0.5, 0.2f); | 111 gfx::Vector2dF targetVector(0.5, 0.2f); |
176 gfx::Vector2dF projectedVector = MathUtil::projectVector(testVector, targetV
ector); | 112 gfx::Vector2dF projectedVector = MathUtil::projectVector(testVector, targetV
ector); |
177 EXPECT_EQ(projectedVector.x() / targetVector.x(), | 113 EXPECT_EQ(projectedVector.x() / targetVector.x(), |
178 projectedVector.y() / targetVector.y()); | 114 projectedVector.y() / targetVector.y()); |
179 } | 115 } |
180 | 116 |
181 // TODO(shawnsingh): these macros are redundant with those from | |
182 // web_transformation_matrix_unittests, but for now they | |
183 // are different enough to be appropriate here. | |
184 | |
185 #define EXPECT_ROW1_EQ(a, b, c, d, transform) \ | |
186 EXPECT_FLOAT_EQ((a), (transform).matrix().getDouble(0, 0)); \ | |
187 EXPECT_FLOAT_EQ((b), (transform).matrix().getDouble(0, 1)); \ | |
188 EXPECT_FLOAT_EQ((c), (transform).matrix().getDouble(0, 2)); \ | |
189 EXPECT_FLOAT_EQ((d), (transform).matrix().getDouble(0, 3)); | |
190 | |
191 #define EXPECT_ROW2_EQ(a, b, c, d, transform) \ | |
192 EXPECT_FLOAT_EQ((a), (transform).matrix().getDouble(1, 0)); \ | |
193 EXPECT_FLOAT_EQ((b), (transform).matrix().getDouble(1, 1)); \ | |
194 EXPECT_FLOAT_EQ((c), (transform).matrix().getDouble(1, 2)); \ | |
195 EXPECT_FLOAT_EQ((d), (transform).matrix().getDouble(1, 3)); | |
196 | |
197 #define EXPECT_ROW3_EQ(a, b, c, d, transform) \ | |
198 EXPECT_FLOAT_EQ((a), (transform).matrix().getDouble(2, 0)); \ | |
199 EXPECT_FLOAT_EQ((b), (transform).matrix().getDouble(2, 1)); \ | |
200 EXPECT_FLOAT_EQ((c), (transform).matrix().getDouble(2, 2)); \ | |
201 EXPECT_FLOAT_EQ((d), (transform).matrix().getDouble(2, 3)); | |
202 | |
203 #define EXPECT_ROW4_EQ(a, b, c, d, transform) \ | |
204 EXPECT_FLOAT_EQ((a), (transform).matrix().getDouble(3, 0)); \ | |
205 EXPECT_FLOAT_EQ((b), (transform).matrix().getDouble(3, 1)); \ | |
206 EXPECT_FLOAT_EQ((c), (transform).matrix().getDouble(3, 2)); \ | |
207 EXPECT_FLOAT_EQ((d), (transform).matrix().getDouble(3, 3)); | |
208 | |
209 // Checking float values for equality close to zero is not robust using EXPECT_F
LOAT_EQ | |
210 // (see gtest documentation). So, to verify rotation matrices, we must use a loo
ser | |
211 // absolute error threshold in some places. | |
212 #define EXPECT_ROW1_NEAR(a, b, c, d, transform, errorThreshold) \ | |
213 EXPECT_NEAR((a), (transform).matrix().getDouble(0, 0), (errorThreshold));
\ | |
214 EXPECT_NEAR((b), (transform).matrix().getDouble(0, 1), (errorThreshold));
\ | |
215 EXPECT_NEAR((c), (transform).matrix().getDouble(0, 2), (errorThreshold));
\ | |
216 EXPECT_NEAR((d), (transform).matrix().getDouble(0, 3), (errorThreshold)); | |
217 | |
218 #define EXPECT_ROW2_NEAR(a, b, c, d, transform, errorThreshold) \ | |
219 EXPECT_NEAR((a), (transform).matrix().getDouble(1, 0), (errorThreshold));
\ | |
220 EXPECT_NEAR((b), (transform).matrix().getDouble(1, 1), (errorThreshold));
\ | |
221 EXPECT_NEAR((c), (transform).matrix().getDouble(1, 2), (errorThreshold));
\ | |
222 EXPECT_NEAR((d), (transform).matrix().getDouble(1, 3), (errorThreshold)); | |
223 | |
224 #define EXPECT_ROW3_NEAR(a, b, c, d, transform, errorThreshold) \ | |
225 EXPECT_NEAR((a), (transform).matrix().getDouble(2, 0), (errorThreshold));
\ | |
226 EXPECT_NEAR((b), (transform).matrix().getDouble(2, 1), (errorThreshold));
\ | |
227 EXPECT_NEAR((c), (transform).matrix().getDouble(2, 2), (errorThreshold));
\ | |
228 EXPECT_NEAR((d), (transform).matrix().getDouble(2, 3), (errorThreshold)); | |
229 | |
230 #define ERROR_THRESHOLD 1e-14 | |
231 #define LOOSE_ERROR_THRESHOLD 1e-7 | |
232 | |
233 static void initializeTestMatrix(gfx::Transform* transform) | |
234 { | |
235 SkMatrix44& matrix = transform->matrix(); | |
236 matrix.setDouble(0, 0, 10); | |
237 matrix.setDouble(1, 0, 11); | |
238 matrix.setDouble(2, 0, 12); | |
239 matrix.setDouble(3, 0, 13); | |
240 matrix.setDouble(0, 1, 14); | |
241 matrix.setDouble(1, 1, 15); | |
242 matrix.setDouble(2, 1, 16); | |
243 matrix.setDouble(3, 1, 17); | |
244 matrix.setDouble(0, 2, 18); | |
245 matrix.setDouble(1, 2, 19); | |
246 matrix.setDouble(2, 2, 20); | |
247 matrix.setDouble(3, 2, 21); | |
248 matrix.setDouble(0, 3, 22); | |
249 matrix.setDouble(1, 3, 23); | |
250 matrix.setDouble(2, 3, 24); | |
251 matrix.setDouble(3, 3, 25); | |
252 | |
253 // Sanity check | |
254 EXPECT_ROW1_EQ(10, 14, 18, 22, (*transform)); | |
255 EXPECT_ROW2_EQ(11, 15, 19, 23, (*transform)); | |
256 EXPECT_ROW3_EQ(12, 16, 20, 24, (*transform)); | |
257 EXPECT_ROW4_EQ(13, 17, 21, 25, (*transform)); | |
258 } | |
259 | |
260 static void initializeTestMatrix2(gfx::Transform* transform) | |
261 { | |
262 SkMatrix44& matrix = transform->matrix(); | |
263 matrix.setDouble(0, 0, 30); | |
264 matrix.setDouble(1, 0, 31); | |
265 matrix.setDouble(2, 0, 32); | |
266 matrix.setDouble(3, 0, 33); | |
267 matrix.setDouble(0, 1, 34); | |
268 matrix.setDouble(1, 1, 35); | |
269 matrix.setDouble(2, 1, 36); | |
270 matrix.setDouble(3, 1, 37); | |
271 matrix.setDouble(0, 2, 38); | |
272 matrix.setDouble(1, 2, 39); | |
273 matrix.setDouble(2, 2, 40); | |
274 matrix.setDouble(3, 2, 41); | |
275 matrix.setDouble(0, 3, 42); | |
276 matrix.setDouble(1, 3, 43); | |
277 matrix.setDouble(2, 3, 44); | |
278 matrix.setDouble(3, 3, 45); | |
279 | |
280 // Sanity check | |
281 EXPECT_ROW1_EQ(30, 34, 38, 42, (*transform)); | |
282 EXPECT_ROW2_EQ(31, 35, 39, 43, (*transform)); | |
283 EXPECT_ROW3_EQ(32, 36, 40, 44, (*transform)); | |
284 EXPECT_ROW4_EQ(33, 37, 41, 45, (*transform)); | |
285 } | |
286 | |
287 TEST(MathUtilGfxTransformTest, verifyDefaultConstructorCreatesIdentityMatrix) | |
288 { | |
289 gfx::Transform A; | |
290 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
291 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
292 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
293 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
294 EXPECT_TRUE(A.IsIdentity()); | |
295 } | |
296 | |
297 TEST(MathUtilGfxTransformTest, verifyCreateGfxTransformFor2dElements) | |
298 { | |
299 gfx::Transform A = MathUtil::createGfxTransform(1, 2, 3, 4, 5, 6); | |
300 EXPECT_ROW1_EQ(1, 3, 0, 5, A); | |
301 EXPECT_ROW2_EQ(2, 4, 0, 6, A); | |
302 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
303 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
304 } | |
305 | |
306 TEST(MathUtilGfxTransformTest, verifyCreateGfxTransformForAllElements) | |
307 { | |
308 gfx::Transform A = MathUtil::createGfxTransform(1, 2, 3, 4, 5, 6, 7, 8, 9, 1
0, 11, 12, 13, 14, 15, 16); | |
309 EXPECT_ROW1_EQ(1, 5, 9, 13, A); | |
310 EXPECT_ROW2_EQ(2, 6, 10, 14, A); | |
311 EXPECT_ROW3_EQ(3, 7, 11, 15, A); | |
312 EXPECT_ROW4_EQ(4, 8, 12, 16, A); | |
313 } | |
314 | |
315 TEST(MathUtilGfxTransformTest, verifyCopyConstructor) | |
316 { | |
317 gfx::Transform A; | |
318 initializeTestMatrix(&A); | |
319 | |
320 // Copy constructor should produce exact same elements as matrix A. | |
321 gfx::Transform B(A); | |
322 EXPECT_ROW1_EQ(10, 14, 18, 22, B); | |
323 EXPECT_ROW2_EQ(11, 15, 19, 23, B); | |
324 EXPECT_ROW3_EQ(12, 16, 20, 24, B); | |
325 EXPECT_ROW4_EQ(13, 17, 21, 25, B); | |
326 } | |
327 | |
328 TEST(MathUtilGfxTransformTest, verifyTo2DTransform) | |
329 { | |
330 gfx::Transform A; | |
331 initializeTestMatrix(&A); | |
332 | |
333 gfx::Transform B = MathUtil::to2dTransform(A); | |
334 | |
335 EXPECT_ROW1_EQ(10, 14, 0, 22, B); | |
336 EXPECT_ROW2_EQ(11, 15, 0, 23, B); | |
337 EXPECT_ROW3_EQ(0, 0, 1, 0, B); | |
338 EXPECT_ROW4_EQ(13, 17, 0, 25, B); | |
339 | |
340 // Note that to2DTransform should not have changed the original matrix. | |
341 EXPECT_ROW1_EQ(10, 14, 18, 22, A); | |
342 EXPECT_ROW2_EQ(11, 15, 19, 23, A); | |
343 EXPECT_ROW3_EQ(12, 16, 20, 24, A); | |
344 EXPECT_ROW4_EQ(13, 17, 21, 25, A); | |
345 } | |
346 | |
347 TEST(MathUtilGfxTransformTest, verifyAssignmentOperator) | |
348 { | |
349 gfx::Transform A; | |
350 initializeTestMatrix(&A); | |
351 gfx::Transform B; | |
352 initializeTestMatrix2(&B); | |
353 gfx::Transform C; | |
354 initializeTestMatrix2(&C); | |
355 C = B = A; | |
356 | |
357 // Both B and C should now have been re-assigned to the value of A. | |
358 EXPECT_ROW1_EQ(10, 14, 18, 22, B); | |
359 EXPECT_ROW2_EQ(11, 15, 19, 23, B); | |
360 EXPECT_ROW3_EQ(12, 16, 20, 24, B); | |
361 EXPECT_ROW4_EQ(13, 17, 21, 25, B); | |
362 | |
363 EXPECT_ROW1_EQ(10, 14, 18, 22, C); | |
364 EXPECT_ROW2_EQ(11, 15, 19, 23, C); | |
365 EXPECT_ROW3_EQ(12, 16, 20, 24, C); | |
366 EXPECT_ROW4_EQ(13, 17, 21, 25, C); | |
367 } | |
368 | |
369 TEST(MathUtilGfxTransformTest, verifyEqualsBooleanOperator) | |
370 { | |
371 gfx::Transform A; | |
372 initializeTestMatrix(&A); | |
373 | |
374 gfx::Transform B; | |
375 initializeTestMatrix(&B); | |
376 EXPECT_TRUE(A == B); | |
377 | |
378 // Modifying multiple elements should cause equals operator to return false. | |
379 gfx::Transform C; | |
380 initializeTestMatrix2(&C); | |
381 EXPECT_FALSE(A == C); | |
382 | |
383 // Modifying any one individual element should cause equals operator to retu
rn false. | |
384 gfx::Transform D; | |
385 D = A; | |
386 D.matrix().setDouble(0, 0, 0); | |
387 EXPECT_FALSE(A == D); | |
388 | |
389 D = A; | |
390 D.matrix().setDouble(1, 0, 0); | |
391 EXPECT_FALSE(A == D); | |
392 | |
393 D = A; | |
394 D.matrix().setDouble(2, 0, 0); | |
395 EXPECT_FALSE(A == D); | |
396 | |
397 D = A; | |
398 D.matrix().setDouble(3, 0, 0); | |
399 EXPECT_FALSE(A == D); | |
400 | |
401 D = A; | |
402 D.matrix().setDouble(0, 1, 0); | |
403 EXPECT_FALSE(A == D); | |
404 | |
405 D = A; | |
406 D.matrix().setDouble(1, 1, 0); | |
407 EXPECT_FALSE(A == D); | |
408 | |
409 D = A; | |
410 D.matrix().setDouble(2, 1, 0); | |
411 EXPECT_FALSE(A == D); | |
412 | |
413 D = A; | |
414 D.matrix().setDouble(3, 1, 0); | |
415 EXPECT_FALSE(A == D); | |
416 | |
417 D = A; | |
418 D.matrix().setDouble(0, 2, 0); | |
419 EXPECT_FALSE(A == D); | |
420 | |
421 D = A; | |
422 D.matrix().setDouble(1, 2, 0); | |
423 EXPECT_FALSE(A == D); | |
424 | |
425 D = A; | |
426 D.matrix().setDouble(2, 2, 0); | |
427 EXPECT_FALSE(A == D); | |
428 | |
429 D = A; | |
430 D.matrix().setDouble(3, 2, 0); | |
431 EXPECT_FALSE(A == D); | |
432 | |
433 D = A; | |
434 D.matrix().setDouble(0, 3, 0); | |
435 EXPECT_FALSE(A == D); | |
436 | |
437 D = A; | |
438 D.matrix().setDouble(1, 3, 0); | |
439 EXPECT_FALSE(A == D); | |
440 | |
441 D = A; | |
442 D.matrix().setDouble(2, 3, 0); | |
443 EXPECT_FALSE(A == D); | |
444 | |
445 D = A; | |
446 D.matrix().setDouble(3, 3, 0); | |
447 EXPECT_FALSE(A == D); | |
448 } | |
449 | |
450 TEST(MathUtilGfxTransformTest, verifyMultiplyOperator) | |
451 { | |
452 gfx::Transform A; | |
453 initializeTestMatrix(&A); | |
454 | |
455 gfx::Transform B; | |
456 initializeTestMatrix2(&B); | |
457 | |
458 gfx::Transform C = A * B; | |
459 EXPECT_ROW1_EQ(2036, 2292, 2548, 2804, C); | |
460 EXPECT_ROW2_EQ(2162, 2434, 2706, 2978, C); | |
461 EXPECT_ROW3_EQ(2288, 2576, 2864, 3152, C); | |
462 EXPECT_ROW4_EQ(2414, 2718, 3022, 3326, C); | |
463 | |
464 // Just an additional sanity check; matrix multiplication is not commutative
. | |
465 EXPECT_FALSE(A * B == B * A); | |
466 } | |
467 | |
468 TEST(MathUtilGfxTransformTest, verifyMultiplyAndAssignOperator) | |
469 { | |
470 gfx::Transform A; | |
471 initializeTestMatrix(&A); | |
472 | |
473 gfx::Transform B; | |
474 initializeTestMatrix2(&B); | |
475 | |
476 A *= B; | |
477 EXPECT_ROW1_EQ(2036, 2292, 2548, 2804, A); | |
478 EXPECT_ROW2_EQ(2162, 2434, 2706, 2978, A); | |
479 EXPECT_ROW3_EQ(2288, 2576, 2864, 3152, A); | |
480 EXPECT_ROW4_EQ(2414, 2718, 3022, 3326, A); | |
481 | |
482 // Just an additional sanity check; matrix multiplication is not commutative
. | |
483 gfx::Transform C = A; | |
484 C *= B; | |
485 gfx::Transform D = B; | |
486 D *= A; | |
487 EXPECT_FALSE(C == D); | |
488 } | |
489 | |
490 TEST(MathUtilGfxTransformTest, verifyMatrixMultiplication) | |
491 { | |
492 gfx::Transform A; | |
493 initializeTestMatrix(&A); | |
494 | |
495 gfx::Transform B; | |
496 initializeTestMatrix2(&B); | |
497 | |
498 A.PreconcatTransform(B); | |
499 EXPECT_ROW1_EQ(2036, 2292, 2548, 2804, A); | |
500 EXPECT_ROW2_EQ(2162, 2434, 2706, 2978, A); | |
501 EXPECT_ROW3_EQ(2288, 2576, 2864, 3152, A); | |
502 EXPECT_ROW4_EQ(2414, 2718, 3022, 3326, A); | |
503 } | |
504 | |
505 TEST(MathUtilGfxTransformTest, verifyMakeIdentiy) | |
506 { | |
507 gfx::Transform A; | |
508 initializeTestMatrix(&A); | |
509 A.MakeIdentity(); | |
510 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
511 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
512 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
513 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
514 EXPECT_TRUE(A.IsIdentity()); | |
515 } | |
516 | |
517 TEST(MathUtilGfxTransformTest, verifyTranslate) | |
518 { | |
519 gfx::Transform A; | |
520 A.Translate(2, 3); | |
521 EXPECT_ROW1_EQ(1, 0, 0, 2, A); | |
522 EXPECT_ROW2_EQ(0, 1, 0, 3, A); | |
523 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
524 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
525 | |
526 // Verify that Translate() post-multiplies the existing matrix. | |
527 A.MakeIdentity(); | |
528 A.Scale(5, 5); | |
529 A.Translate(2, 3); | |
530 EXPECT_ROW1_EQ(5, 0, 0, 10, A); | |
531 EXPECT_ROW2_EQ(0, 5, 0, 15, A); | |
532 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
533 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
534 } | |
535 | |
536 TEST(MathUtilGfxTransformTest, verifyTranslate3d) | |
537 { | |
538 gfx::Transform A; | |
539 A.Translate3d(2, 3, 4); | |
540 EXPECT_ROW1_EQ(1, 0, 0, 2, A); | |
541 EXPECT_ROW2_EQ(0, 1, 0, 3, A); | |
542 EXPECT_ROW3_EQ(0, 0, 1, 4, A); | |
543 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
544 | |
545 // Verify that Translate3d() post-multiplies the existing matrix. | |
546 A.MakeIdentity(); | |
547 A.Scale3d(6, 7, 8); | |
548 A.Translate3d(2, 3, 4); | |
549 EXPECT_ROW1_EQ(6, 0, 0, 12, A); | |
550 EXPECT_ROW2_EQ(0, 7, 0, 21, A); | |
551 EXPECT_ROW3_EQ(0, 0, 8, 32, A); | |
552 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
553 } | |
554 | |
555 TEST(MathUtilGfxTransformTest, verifyScale) | |
556 { | |
557 gfx::Transform A; | |
558 A.Scale(6, 7); | |
559 EXPECT_ROW1_EQ(6, 0, 0, 0, A); | |
560 EXPECT_ROW2_EQ(0, 7, 0, 0, A); | |
561 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
562 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
563 | |
564 // Verify that Scale() post-multiplies the existing matrix. | |
565 A.MakeIdentity(); | |
566 A.Translate3d(2, 3, 4); | |
567 A.Scale(6, 7); | |
568 EXPECT_ROW1_EQ(6, 0, 0, 2, A); | |
569 EXPECT_ROW2_EQ(0, 7, 0, 3, A); | |
570 EXPECT_ROW3_EQ(0, 0, 1, 4, A); | |
571 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
572 } | |
573 | |
574 TEST(MathUtilGfxTransformTest, verifyScale3d) | |
575 { | |
576 gfx::Transform A; | |
577 A.Scale3d(6, 7, 8); | |
578 EXPECT_ROW1_EQ(6, 0, 0, 0, A); | |
579 EXPECT_ROW2_EQ(0, 7, 0, 0, A); | |
580 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
581 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
582 | |
583 // Verify that scale3d() post-multiplies the existing matrix. | |
584 A.MakeIdentity(); | |
585 A.Translate3d(2, 3, 4); | |
586 A.Scale3d(6, 7, 8); | |
587 EXPECT_ROW1_EQ(6, 0, 0, 2, A); | |
588 EXPECT_ROW2_EQ(0, 7, 0, 3, A); | |
589 EXPECT_ROW3_EQ(0, 0, 8, 4, A); | |
590 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
591 } | |
592 | |
593 TEST(MathUtilGfxTransformTest, verifyRotate) | |
594 { | |
595 gfx::Transform A; | |
596 A.Rotate(90); | |
597 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD); | |
598 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD); | |
599 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
600 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
601 | |
602 // Verify that Rotate() post-multiplies the existing matrix. | |
603 A.MakeIdentity(); | |
604 A.Scale3d(6, 7, 8); | |
605 A.Rotate(90); | |
606 EXPECT_ROW1_NEAR(0, -6, 0, 0, A, ERROR_THRESHOLD); | |
607 EXPECT_ROW2_NEAR(7, 0, 0, 0, A, ERROR_THRESHOLD); | |
608 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
609 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
610 } | |
611 | |
612 TEST(MathUtilGfxTransformTest, verifyRotateEulerAngles) | |
613 { | |
614 gfx::Transform A; | |
615 | |
616 // Check rotation about z-axis | |
617 A.MakeIdentity(); | |
618 MathUtil::rotateEulerAngles(&A, 0, 0, 90); | |
619 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD); | |
620 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD); | |
621 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
622 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
623 | |
624 // Check rotation about x-axis | |
625 A.MakeIdentity(); | |
626 MathUtil::rotateEulerAngles(&A, 90, 0, 0); | |
627 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
628 EXPECT_ROW2_NEAR(0, 0, -1, 0, A, ERROR_THRESHOLD); | |
629 EXPECT_ROW3_NEAR(0, 1, 0, 0, A, ERROR_THRESHOLD); | |
630 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
631 | |
632 // Check rotation about y-axis. | |
633 // Note carefully, the expected pattern is inverted compared to rotating abo
ut x axis or z axis. | |
634 A.MakeIdentity(); | |
635 MathUtil::rotateEulerAngles(&A, 0, 90, 0); | |
636 EXPECT_ROW1_NEAR(0, 0, 1, 0, A, ERROR_THRESHOLD); | |
637 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
638 EXPECT_ROW3_NEAR(-1, 0, 0, 0, A, ERROR_THRESHOLD); | |
639 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
640 | |
641 // Verify that rotate3d(rx, ry, rz) post-multiplies the existing matrix. | |
642 A.MakeIdentity(); | |
643 A.Scale3d(6, 7, 8); | |
644 MathUtil::rotateEulerAngles(&A, 0, 0, 90); | |
645 EXPECT_ROW1_NEAR(0, -6, 0, 0, A, ERROR_THRESHOLD); | |
646 EXPECT_ROW2_NEAR(7, 0, 0, 0, A, ERROR_THRESHOLD); | |
647 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
648 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
649 } | |
650 | |
651 TEST(MathUtilGfxTransformTest, verifyRotateEulerAnglesOrderOfCompositeRotations) | |
652 { | |
653 // Rotate3d(degreesX, degreesY, degreesZ) is actually composite transform co
nsiting of | |
654 // three primitive rotations. This test verifies that the ordering of those
three | |
655 // transforms is the intended ordering. | |
656 // | |
657 // The correct ordering for this test case should be: | |
658 // 1. rotate by 30 degrees about z-axis | |
659 // 2. rotate by 20 degrees about y-axis | |
660 // 3. rotate by 10 degrees about x-axis | |
661 // | |
662 // Note: there are 6 possible orderings of 3 transforms. For the specific tr
ansforms | |
663 // used in this test, all 6 combinations produce a unique matrix that is dif
ferent | |
664 // from the other orderings. That way, this test verifies the exact ordering
. | |
665 | |
666 gfx::Transform A; | |
667 A.MakeIdentity(); | |
668 MathUtil::rotateEulerAngles(&A, 10, 20, 30); | |
669 | |
670 EXPECT_ROW1_NEAR(0.8137976813493738026394908, | |
671 -0.4409696105298823720630708, | |
672 0.3785223063697923939763257, | |
673 0, A, ERROR_THRESHOLD); | |
674 EXPECT_ROW2_NEAR(0.4698463103929541584413698, | |
675 0.8825641192593856043657752, | |
676 0.0180283112362972230968694, | |
677 0, A, ERROR_THRESHOLD); | |
678 EXPECT_ROW3_NEAR(-0.3420201433256686573969318, | |
679 0.1631759111665348205288950, | |
680 0.9254165783983233639631294, | |
681 0, A, ERROR_THRESHOLD); | |
682 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
683 } | |
684 | |
685 TEST(MathUtilGfxTransformTest, verifyRotateAboutXAxis) | |
686 { | |
687 gfx::Transform A; | |
688 double sin45 = 0.5 * sqrt(2.0); | |
689 double cos45 = sin45; | |
690 | |
691 A.MakeIdentity(); | |
692 A.RotateAboutXAxis(90); | |
693 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
694 EXPECT_ROW2_NEAR(0, 0, -1, 0, A, ERROR_THRESHOLD); | |
695 EXPECT_ROW3_NEAR(0, 1, 0, 0, A, ERROR_THRESHOLD); | |
696 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
697 | |
698 A.MakeIdentity(); | |
699 A.RotateAboutXAxis(45); | |
700 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
701 EXPECT_ROW2_NEAR(0, cos45, -sin45, 0, A, ERROR_THRESHOLD); | |
702 EXPECT_ROW3_NEAR(0, sin45, cos45, 0, A, ERROR_THRESHOLD); | |
703 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
704 | |
705 // Verify that rotateAboutXAxis(angle) post-multiplies the existing matrix. | |
706 A.MakeIdentity(); | |
707 A.Scale3d(6, 7, 8); | |
708 A.RotateAboutXAxis(90); | |
709 EXPECT_ROW1_NEAR(6, 0, 0, 0, A, ERROR_THRESHOLD); | |
710 EXPECT_ROW2_NEAR(0, 0, -7, 0, A, ERROR_THRESHOLD); | |
711 EXPECT_ROW3_NEAR(0, 8, 0, 0, A, ERROR_THRESHOLD); | |
712 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
713 } | |
714 | |
715 TEST(MathUtilGfxTransformTest, verifyRotateAboutYAxis) | |
716 { | |
717 gfx::Transform A; | |
718 double sin45 = 0.5 * sqrt(2.0); | |
719 double cos45 = sin45; | |
720 | |
721 // Note carefully, the expected pattern is inverted compared to rotating abo
ut x axis or z axis. | |
722 A.MakeIdentity(); | |
723 A.RotateAboutYAxis(90); | |
724 EXPECT_ROW1_NEAR(0, 0, 1, 0, A, ERROR_THRESHOLD); | |
725 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
726 EXPECT_ROW3_NEAR(-1, 0, 0, 0, A, ERROR_THRESHOLD); | |
727 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
728 | |
729 A.MakeIdentity(); | |
730 A.RotateAboutYAxis(45); | |
731 EXPECT_ROW1_NEAR(cos45, 0, sin45, 0, A, ERROR_THRESHOLD); | |
732 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
733 EXPECT_ROW3_NEAR(-sin45, 0, cos45, 0, A, ERROR_THRESHOLD); | |
734 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
735 | |
736 // Verify that rotateAboutYAxis(angle) post-multiplies the existing matrix. | |
737 A.MakeIdentity(); | |
738 A.Scale3d(6, 7, 8); | |
739 A.RotateAboutYAxis(90); | |
740 EXPECT_ROW1_NEAR(0, 0, 6, 0, A, ERROR_THRESHOLD); | |
741 EXPECT_ROW2_NEAR(0, 7, 0, 0, A, ERROR_THRESHOLD); | |
742 EXPECT_ROW3_NEAR(-8, 0, 0, 0, A, ERROR_THRESHOLD); | |
743 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
744 } | |
745 | |
746 TEST(MathUtilGfxTransformTest, verifyRotateAboutZAxis) | |
747 { | |
748 gfx::Transform A; | |
749 double sin45 = 0.5 * sqrt(2.0); | |
750 double cos45 = sin45; | |
751 | |
752 A.MakeIdentity(); | |
753 A.RotateAboutZAxis(90); | |
754 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD); | |
755 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD); | |
756 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
757 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
758 | |
759 A.MakeIdentity(); | |
760 A.RotateAboutZAxis(45); | |
761 EXPECT_ROW1_NEAR(cos45, -sin45, 0, 0, A, ERROR_THRESHOLD); | |
762 EXPECT_ROW2_NEAR(sin45, cos45, 0, 0, A, ERROR_THRESHOLD); | |
763 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
764 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
765 | |
766 // Verify that rotateAboutZAxis(angle) post-multiplies the existing matrix. | |
767 A.MakeIdentity(); | |
768 A.Scale3d(6, 7, 8); | |
769 A.RotateAboutZAxis(90); | |
770 EXPECT_ROW1_NEAR(0, -6, 0, 0, A, ERROR_THRESHOLD); | |
771 EXPECT_ROW2_NEAR(7, 0, 0, 0, A, ERROR_THRESHOLD); | |
772 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
773 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
774 } | |
775 | |
776 TEST(MathUtilGfxTransformTest, verifyRotateAboutForAlignedAxes) | |
777 { | |
778 gfx::Transform A; | |
779 | |
780 // Check rotation about z-axis | |
781 A.MakeIdentity(); | |
782 A.RotateAbout(gfx::Vector3dF(0, 0, 1), 90); | |
783 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD); | |
784 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD); | |
785 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
786 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
787 | |
788 // Check rotation about x-axis | |
789 A.MakeIdentity(); | |
790 A.RotateAbout(gfx::Vector3dF(1, 0, 0), 90); | |
791 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
792 EXPECT_ROW2_NEAR(0, 0, -1, 0, A, ERROR_THRESHOLD); | |
793 EXPECT_ROW3_NEAR(0, 1, 0, 0, A, ERROR_THRESHOLD); | |
794 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
795 | |
796 // Check rotation about y-axis. | |
797 // Note carefully, the expected pattern is inverted compared to rotating abo
ut x axis or z axis. | |
798 A.MakeIdentity(); | |
799 A.RotateAbout(gfx::Vector3dF(0, 1, 0), 90); | |
800 EXPECT_ROW1_NEAR(0, 0, 1, 0, A, ERROR_THRESHOLD); | |
801 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
802 EXPECT_ROW3_NEAR(-1, 0, 0, 0, A, ERROR_THRESHOLD); | |
803 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
804 | |
805 // Verify that rotate3d(axis, angle) post-multiplies the existing matrix. | |
806 A.MakeIdentity(); | |
807 A.Scale3d(6, 7, 8); | |
808 A.RotateAboutZAxis(90); | |
809 EXPECT_ROW1_NEAR(0, -6, 0, 0, A, ERROR_THRESHOLD); | |
810 EXPECT_ROW2_NEAR(7, 0, 0, 0, A, ERROR_THRESHOLD); | |
811 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
812 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
813 } | |
814 | |
815 TEST(MathUtilGfxTransformTest, verifyRotateAboutForArbitraryAxis) | |
816 { | |
817 // Check rotation about an arbitrary non-axis-aligned vector. | |
818 gfx::Transform A; | |
819 A.RotateAbout(gfx::Vector3dF(1, 1, 1), 90); | |
820 EXPECT_ROW1_NEAR(0.3333333333333334258519187, | |
821 -0.2440169358562924717404030, | |
822 0.9106836025229592124219380, | |
823 0, A, ERROR_THRESHOLD); | |
824 EXPECT_ROW2_NEAR(0.9106836025229592124219380, | |
825 0.3333333333333334258519187, | |
826 -0.2440169358562924717404030, | |
827 0, A, ERROR_THRESHOLD); | |
828 EXPECT_ROW3_NEAR(-0.2440169358562924717404030, | |
829 0.9106836025229592124219380, | |
830 0.3333333333333334258519187, | |
831 0, A, ERROR_THRESHOLD); | |
832 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
833 } | |
834 | |
835 TEST(MathUtilGfxTransformTest, verifyRotateAboutForDegenerateAxis) | |
836 { | |
837 // Check rotation about a degenerate zero vector. | |
838 // It is expected to skip applying the rotation. | |
839 gfx::Transform A; | |
840 | |
841 A.RotateAbout(gfx::Vector3dF(0, 0, 0), 45); | |
842 // Verify that A remains unchanged. | |
843 EXPECT_TRUE(A.IsIdentity()); | |
844 | |
845 initializeTestMatrix(&A); | |
846 A.RotateAbout(gfx::Vector3dF(0, 0, 0), 35); | |
847 | |
848 // Verify that A remains unchanged. | |
849 EXPECT_ROW1_EQ(10, 14, 18, 22, A); | |
850 EXPECT_ROW2_EQ(11, 15, 19, 23, A); | |
851 EXPECT_ROW3_EQ(12, 16, 20, 24, A); | |
852 EXPECT_ROW4_EQ(13, 17, 21, 25, A); | |
853 } | |
854 | |
855 TEST(MathUtilGfxTransformTest, verifySkewX) | |
856 { | |
857 gfx::Transform A; | |
858 A.SkewX(45); | |
859 EXPECT_ROW1_EQ(1, 1, 0, 0, A); | |
860 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
861 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
862 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
863 | |
864 // Verify that skewX() post-multiplies the existing matrix. | |
865 // Row 1, column 2, would incorrectly have value "7" if the matrix is pre-mu
ltiplied instead of post-multiplied. | |
866 A.MakeIdentity(); | |
867 A.Scale3d(6, 7, 8); | |
868 A.SkewX(45); | |
869 EXPECT_ROW1_EQ(6, 6, 0, 0, A); | |
870 EXPECT_ROW2_EQ(0, 7, 0, 0, A); | |
871 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
872 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
873 } | |
874 | |
875 TEST(MathUtilGfxTransformTest, verifySkewY) | |
876 { | |
877 gfx::Transform A; | |
878 A.SkewY(45); | |
879 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
880 EXPECT_ROW2_EQ(1, 1, 0, 0, A); | |
881 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
882 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
883 | |
884 // Verify that skewY() post-multiplies the existing matrix. | |
885 // Row 2, column 1, would incorrectly have value "6" if the matrix is pre-mu
ltiplied instead of post-multiplied. | |
886 A.MakeIdentity(); | |
887 A.Scale3d(6, 7, 8); | |
888 A.SkewY(45); | |
889 EXPECT_ROW1_EQ(6, 0, 0, 0, A); | |
890 EXPECT_ROW2_EQ(7, 7, 0, 0, A); | |
891 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
892 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
893 } | |
894 | |
895 TEST(MathUtilGfxTransformTest, verifyPerspectiveDepth) | |
896 { | |
897 gfx::Transform A; | |
898 A.ApplyPerspectiveDepth(1); | |
899 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
900 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
901 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
902 EXPECT_ROW4_EQ(0, 0, -1, 1, A); | |
903 | |
904 // Verify that PerspectiveDepth() post-multiplies the existing matrix. | |
905 A.MakeIdentity(); | |
906 A.Translate3d(2, 3, 4); | |
907 A.ApplyPerspectiveDepth(1); | |
908 EXPECT_ROW1_EQ(1, 0, -2, 2, A); | |
909 EXPECT_ROW2_EQ(0, 1, -3, 3, A); | |
910 EXPECT_ROW3_EQ(0, 0, -3, 4, A); | |
911 EXPECT_ROW4_EQ(0, 0, -1, 1, A); | |
912 } | |
913 | |
914 TEST(MathUtilGfxTransformTest, verifyHasPerspective) | |
915 { | |
916 gfx::Transform A; | |
917 A.ApplyPerspectiveDepth(1); | |
918 EXPECT_TRUE(A.HasPerspective()); | |
919 | |
920 A.MakeIdentity(); | |
921 A.ApplyPerspectiveDepth(0); | |
922 EXPECT_FALSE(A.HasPerspective()); | |
923 | |
924 A.MakeIdentity(); | |
925 A.matrix().setDouble(3, 0, -1); | |
926 EXPECT_TRUE(A.HasPerspective()); | |
927 | |
928 A.MakeIdentity(); | |
929 A.matrix().setDouble(3, 1, -1); | |
930 EXPECT_TRUE(A.HasPerspective()); | |
931 | |
932 A.MakeIdentity(); | |
933 A.matrix().setDouble(3, 2, -0.3); | |
934 EXPECT_TRUE(A.HasPerspective()); | |
935 | |
936 A.MakeIdentity(); | |
937 A.matrix().setDouble(3, 3, 0.5); | |
938 EXPECT_TRUE(A.HasPerspective()); | |
939 | |
940 A.MakeIdentity(); | |
941 A.matrix().setDouble(3, 3, 0); | |
942 EXPECT_TRUE(A.HasPerspective()); | |
943 } | |
944 | |
945 TEST(MathUtilGfxTransformTest, verifyIsInvertible) | |
946 { | |
947 gfx::Transform A; | |
948 | |
949 // Translations, rotations, scales, skews and arbitrary combinations of them
are invertible. | |
950 A.MakeIdentity(); | |
951 EXPECT_TRUE(A.IsInvertible()); | |
952 | |
953 A.MakeIdentity(); | |
954 A.Translate3d(2, 3, 4); | |
955 EXPECT_TRUE(A.IsInvertible()); | |
956 | |
957 A.MakeIdentity(); | |
958 A.Scale3d(6, 7, 8); | |
959 EXPECT_TRUE(A.IsInvertible()); | |
960 | |
961 A.MakeIdentity(); | |
962 MathUtil::rotateEulerAngles(&A, 10, 20, 30); | |
963 EXPECT_TRUE(A.IsInvertible()); | |
964 | |
965 A.MakeIdentity(); | |
966 A.SkewX(45); | |
967 EXPECT_TRUE(A.IsInvertible()); | |
968 | |
969 // A perspective matrix (projection plane at z=0) is invertible. The intuiti
ve | |
970 // explanation is that perspective is eqivalent to a skew of the w-axis; ske
ws are | |
971 // invertible. | |
972 A.MakeIdentity(); | |
973 A.ApplyPerspectiveDepth(1); | |
974 EXPECT_TRUE(A.IsInvertible()); | |
975 | |
976 // A "pure" perspective matrix derived by similar triangles, with m44() set
to zero | |
977 // (i.e. camera positioned at the origin), is not invertible. | |
978 A.MakeIdentity(); | |
979 A.ApplyPerspectiveDepth(1); | |
980 A.matrix().setDouble(3, 3, 0); | |
981 EXPECT_FALSE(A.IsInvertible()); | |
982 | |
983 // Adding more to a non-invertible matrix will not make it invertible in the
general case. | |
984 A.MakeIdentity(); | |
985 A.ApplyPerspectiveDepth(1); | |
986 A.matrix().setDouble(3, 3, 0); | |
987 A.Scale3d(6, 7, 8); | |
988 MathUtil::rotateEulerAngles(&A, 10, 20, 30); | |
989 A.Translate3d(6, 7, 8); | |
990 EXPECT_FALSE(A.IsInvertible()); | |
991 | |
992 // A degenerate matrix of all zeros is not invertible. | |
993 A.MakeIdentity(); | |
994 A.matrix().setDouble(0, 0, 0); | |
995 A.matrix().setDouble(1, 1, 0); | |
996 A.matrix().setDouble(2, 2, 0); | |
997 A.matrix().setDouble(3, 3, 0); | |
998 EXPECT_FALSE(A.IsInvertible()); | |
999 } | |
1000 | |
1001 TEST(MathUtilGfxTransformTest, verifyIsIdentity) | |
1002 { | |
1003 gfx::Transform A; | |
1004 | |
1005 initializeTestMatrix(&A); | |
1006 EXPECT_FALSE(A.IsIdentity()); | |
1007 | |
1008 A.MakeIdentity(); | |
1009 EXPECT_TRUE(A.IsIdentity()); | |
1010 | |
1011 // Modifying any one individual element should cause the matrix to no longer
be identity. | |
1012 A.MakeIdentity(); | |
1013 A.matrix().setDouble(0, 0, 2); | |
1014 EXPECT_FALSE(A.IsIdentity()); | |
1015 | |
1016 A.MakeIdentity(); | |
1017 A.matrix().setDouble(1, 0, 2); | |
1018 EXPECT_FALSE(A.IsIdentity()); | |
1019 | |
1020 A.MakeIdentity(); | |
1021 A.matrix().setDouble(2, 0, 2); | |
1022 EXPECT_FALSE(A.IsIdentity()); | |
1023 | |
1024 A.MakeIdentity(); | |
1025 A.matrix().setDouble(3, 0, 2); | |
1026 EXPECT_FALSE(A.IsIdentity()); | |
1027 | |
1028 A.MakeIdentity(); | |
1029 A.matrix().setDouble(0, 1, 2); | |
1030 EXPECT_FALSE(A.IsIdentity()); | |
1031 | |
1032 A.MakeIdentity(); | |
1033 A.matrix().setDouble(1, 1, 2); | |
1034 EXPECT_FALSE(A.IsIdentity()); | |
1035 | |
1036 A.MakeIdentity(); | |
1037 A.matrix().setDouble(2, 1, 2); | |
1038 EXPECT_FALSE(A.IsIdentity()); | |
1039 | |
1040 A.MakeIdentity(); | |
1041 A.matrix().setDouble(3, 1, 2); | |
1042 EXPECT_FALSE(A.IsIdentity()); | |
1043 | |
1044 A.MakeIdentity(); | |
1045 A.matrix().setDouble(0, 2, 2); | |
1046 EXPECT_FALSE(A.IsIdentity()); | |
1047 | |
1048 A.MakeIdentity(); | |
1049 A.matrix().setDouble(1, 2, 2); | |
1050 EXPECT_FALSE(A.IsIdentity()); | |
1051 | |
1052 A.MakeIdentity(); | |
1053 A.matrix().setDouble(2, 2, 2); | |
1054 EXPECT_FALSE(A.IsIdentity()); | |
1055 | |
1056 A.MakeIdentity(); | |
1057 A.matrix().setDouble(3, 2, 2); | |
1058 EXPECT_FALSE(A.IsIdentity()); | |
1059 | |
1060 A.MakeIdentity(); | |
1061 A.matrix().setDouble(0, 3, 2); | |
1062 EXPECT_FALSE(A.IsIdentity()); | |
1063 | |
1064 A.MakeIdentity(); | |
1065 A.matrix().setDouble(1, 3, 2); | |
1066 EXPECT_FALSE(A.IsIdentity()); | |
1067 | |
1068 A.MakeIdentity(); | |
1069 A.matrix().setDouble(2, 3, 2); | |
1070 EXPECT_FALSE(A.IsIdentity()); | |
1071 | |
1072 A.MakeIdentity(); | |
1073 A.matrix().setDouble(3, 3, 2); | |
1074 EXPECT_FALSE(A.IsIdentity()); | |
1075 } | |
1076 | |
1077 TEST(MathUtilGfxTransformTest, verifyIsIdentityOrTranslation) | |
1078 { | |
1079 gfx::Transform A; | |
1080 | |
1081 initializeTestMatrix(&A); | |
1082 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1083 | |
1084 A.MakeIdentity(); | |
1085 EXPECT_TRUE(A.IsIdentityOrTranslation()); | |
1086 | |
1087 // Modifying any non-translation components should cause IsIdentityOrTransla
tion() to | |
1088 // return false. NOTE: (0, 3), (1, 3), and (2, 3) are the translation compon
ents, so | |
1089 // modifying them should still return true. | |
1090 A.MakeIdentity(); | |
1091 A.matrix().setDouble(0, 0, 2); | |
1092 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1093 | |
1094 A.MakeIdentity(); | |
1095 A.matrix().setDouble(1, 0, 2); | |
1096 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1097 | |
1098 A.MakeIdentity(); | |
1099 A.matrix().setDouble(2, 0, 2); | |
1100 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1101 | |
1102 A.MakeIdentity(); | |
1103 A.matrix().setDouble(3, 0, 2); | |
1104 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1105 | |
1106 A.MakeIdentity(); | |
1107 A.matrix().setDouble(0, 1, 2); | |
1108 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1109 | |
1110 A.MakeIdentity(); | |
1111 A.matrix().setDouble(1, 1, 2); | |
1112 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1113 | |
1114 A.MakeIdentity(); | |
1115 A.matrix().setDouble(2, 1, 2); | |
1116 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1117 | |
1118 A.MakeIdentity(); | |
1119 A.matrix().setDouble(3, 1, 2); | |
1120 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1121 | |
1122 A.MakeIdentity(); | |
1123 A.matrix().setDouble(0, 2, 2); | |
1124 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1125 | |
1126 A.MakeIdentity(); | |
1127 A.matrix().setDouble(1, 2, 2); | |
1128 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1129 | |
1130 A.MakeIdentity(); | |
1131 A.matrix().setDouble(2, 2, 2); | |
1132 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1133 | |
1134 A.MakeIdentity(); | |
1135 A.matrix().setDouble(3, 2, 2); | |
1136 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1137 | |
1138 // Note carefully - expecting true here. | |
1139 A.MakeIdentity(); | |
1140 A.matrix().setDouble(0, 3, 2); | |
1141 EXPECT_TRUE(A.IsIdentityOrTranslation()); | |
1142 | |
1143 // Note carefully - expecting true here. | |
1144 A.MakeIdentity(); | |
1145 A.matrix().setDouble(1, 3, 2); | |
1146 EXPECT_TRUE(A.IsIdentityOrTranslation()); | |
1147 | |
1148 // Note carefully - expecting true here. | |
1149 A.MakeIdentity(); | |
1150 A.matrix().setDouble(2, 3, 2); | |
1151 EXPECT_TRUE(A.IsIdentityOrTranslation()); | |
1152 | |
1153 A.MakeIdentity(); | |
1154 A.matrix().setDouble(3, 3, 2); | |
1155 EXPECT_FALSE(A.IsIdentityOrTranslation()); | |
1156 } | |
1157 | |
1158 TEST(MathUtilGfxTransformTest, verifyIsScaleOrTranslation) | |
1159 { | |
1160 gfx::Transform A; | |
1161 | |
1162 initializeTestMatrix(&A); | |
1163 EXPECT_FALSE(A.IsScaleOrTranslation()); | |
1164 | |
1165 A.MakeIdentity(); | |
1166 EXPECT_TRUE(A.IsScaleOrTranslation()); | |
1167 | |
1168 // Modifying any non-scale or non-translation components should cause | |
1169 // IsScaleOrTranslation() to return false. (0, 0), (1, 1), (2, 2), (0, 3), | |
1170 // (1, 3), and (2, 3) are the scale and translation components, so | |
1171 // modifying them should still return true. | |
1172 | |
1173 // Note carefully - expecting true here. | |
1174 A.MakeIdentity(); | |
1175 A.matrix().setDouble(0, 0, 2); | |
1176 EXPECT_TRUE(A.IsScaleOrTranslation()); | |
1177 | |
1178 A.MakeIdentity(); | |
1179 A.matrix().setDouble(1, 0, 2); | |
1180 EXPECT_FALSE(A.IsScaleOrTranslation()); | |
1181 | |
1182 A.MakeIdentity(); | |
1183 A.matrix().setDouble(2, 0, 2); | |
1184 EXPECT_FALSE(A.IsScaleOrTranslation()); | |
1185 | |
1186 A.MakeIdentity(); | |
1187 A.matrix().setDouble(3, 0, 2); | |
1188 EXPECT_FALSE(A.IsScaleOrTranslation()); | |
1189 | |
1190 A.MakeIdentity(); | |
1191 A.matrix().setDouble(0, 1, 2); | |
1192 EXPECT_FALSE(A.IsScaleOrTranslation()); | |
1193 | |
1194 // Note carefully - expecting true here. | |
1195 A.MakeIdentity(); | |
1196 A.matrix().setDouble(1, 1, 2); | |
1197 EXPECT_TRUE(A.IsScaleOrTranslation()); | |
1198 | |
1199 A.MakeIdentity(); | |
1200 A.matrix().setDouble(2, 1, 2); | |
1201 EXPECT_FALSE(A.IsScaleOrTranslation()); | |
1202 | |
1203 A.MakeIdentity(); | |
1204 A.matrix().setDouble(3, 1, 2); | |
1205 EXPECT_FALSE(A.IsScaleOrTranslation()); | |
1206 | |
1207 A.MakeIdentity(); | |
1208 A.matrix().setDouble(0, 2, 2); | |
1209 EXPECT_FALSE(A.IsScaleOrTranslation()); | |
1210 | |
1211 A.MakeIdentity(); | |
1212 A.matrix().setDouble(1, 2, 2); | |
1213 EXPECT_FALSE(A.IsScaleOrTranslation()); | |
1214 | |
1215 // Note carefully - expecting true here. | |
1216 A.MakeIdentity(); | |
1217 A.matrix().setDouble(2, 2, 2); | |
1218 EXPECT_TRUE(A.IsScaleOrTranslation()); | |
1219 | |
1220 A.MakeIdentity(); | |
1221 A.matrix().setDouble(3, 2, 2); | |
1222 EXPECT_FALSE(A.IsScaleOrTranslation()); | |
1223 | |
1224 // Note carefully - expecting true here. | |
1225 A.MakeIdentity(); | |
1226 A.matrix().setDouble(0, 3, 2); | |
1227 EXPECT_TRUE(A.IsScaleOrTranslation()); | |
1228 | |
1229 // Note carefully - expecting true here. | |
1230 A.MakeIdentity(); | |
1231 A.matrix().setDouble(1, 3, 2); | |
1232 EXPECT_TRUE(A.IsScaleOrTranslation()); | |
1233 | |
1234 // Note carefully - expecting true here. | |
1235 A.MakeIdentity(); | |
1236 A.matrix().setDouble(2, 3, 2); | |
1237 EXPECT_TRUE(A.IsScaleOrTranslation()); | |
1238 | |
1239 A.MakeIdentity(); | |
1240 A.matrix().setDouble(3, 3, 2); | |
1241 EXPECT_FALSE(A.IsScaleOrTranslation()); | |
1242 } | |
1243 | |
1244 } // namespace | 117 } // namespace |
1245 } // namespace cc | 118 } // namespace cc |
OLD | NEW |