| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "config.h" | |
| 6 | |
| 7 #define _USE_MATH_DEFINES | |
| 8 #include <math.h> | |
| 9 | |
| 10 #include "cc/test/geometry_test_utils.h" | |
| 11 #include "testing/gtest/include/gtest/gtest.h" | |
| 12 #include "third_party/WebKit/Source/Platform/chromium/public/WebTransformationMa
trix.h" | |
| 13 | |
| 14 #define EXPECT_ROW1_EQ(a, b, c, d, matrix) \ | |
| 15 EXPECT_FLOAT_EQ((a), (matrix).m11()); \ | |
| 16 EXPECT_FLOAT_EQ((b), (matrix).m21()); \ | |
| 17 EXPECT_FLOAT_EQ((c), (matrix).m31()); \ | |
| 18 EXPECT_FLOAT_EQ((d), (matrix).m41()); | |
| 19 | |
| 20 #define EXPECT_ROW2_EQ(a, b, c, d, matrix) \ | |
| 21 EXPECT_FLOAT_EQ((a), (matrix).m12()); \ | |
| 22 EXPECT_FLOAT_EQ((b), (matrix).m22()); \ | |
| 23 EXPECT_FLOAT_EQ((c), (matrix).m32()); \ | |
| 24 EXPECT_FLOAT_EQ((d), (matrix).m42()); | |
| 25 | |
| 26 #define EXPECT_ROW3_EQ(a, b, c, d, matrix) \ | |
| 27 EXPECT_FLOAT_EQ((a), (matrix).m13()); \ | |
| 28 EXPECT_FLOAT_EQ((b), (matrix).m23()); \ | |
| 29 EXPECT_FLOAT_EQ((c), (matrix).m33()); \ | |
| 30 EXPECT_FLOAT_EQ((d), (matrix).m43()); | |
| 31 | |
| 32 #define EXPECT_ROW4_EQ(a, b, c, d, matrix) \ | |
| 33 EXPECT_FLOAT_EQ((a), (matrix).m14()); \ | |
| 34 EXPECT_FLOAT_EQ((b), (matrix).m24()); \ | |
| 35 EXPECT_FLOAT_EQ((c), (matrix).m34()); \ | |
| 36 EXPECT_FLOAT_EQ((d), (matrix).m44()); \ | |
| 37 | |
| 38 // Checking float values for equality close to zero is not robust using EXPECT_F
LOAT_EQ | |
| 39 // (see gtest documentation). So, to verify rotation matrices, we must use a loo
ser | |
| 40 // absolute error threshold in some places. | |
| 41 #define EXPECT_ROW1_NEAR(a, b, c, d, matrix, errorThreshold) \ | |
| 42 EXPECT_NEAR((a), (matrix).m11(), (errorThreshold)); \ | |
| 43 EXPECT_NEAR((b), (matrix).m21(), (errorThreshold)); \ | |
| 44 EXPECT_NEAR((c), (matrix).m31(), (errorThreshold)); \ | |
| 45 EXPECT_NEAR((d), (matrix).m41(), (errorThreshold)); | |
| 46 | |
| 47 #define EXPECT_ROW2_NEAR(a, b, c, d, matrix, errorThreshold) \ | |
| 48 EXPECT_NEAR((a), (matrix).m12(), (errorThreshold)); \ | |
| 49 EXPECT_NEAR((b), (matrix).m22(), (errorThreshold)); \ | |
| 50 EXPECT_NEAR((c), (matrix).m32(), (errorThreshold)); \ | |
| 51 EXPECT_NEAR((d), (matrix).m42(), (errorThreshold)); | |
| 52 | |
| 53 #define EXPECT_ROW3_NEAR(a, b, c, d, matrix, errorThreshold) \ | |
| 54 EXPECT_NEAR((a), (matrix).m13(), (errorThreshold)); \ | |
| 55 EXPECT_NEAR((b), (matrix).m23(), (errorThreshold)); \ | |
| 56 EXPECT_NEAR((c), (matrix).m33(), (errorThreshold)); \ | |
| 57 EXPECT_NEAR((d), (matrix).m43(), (errorThreshold)); | |
| 58 | |
| 59 #define ERROR_THRESHOLD 1e-14 | |
| 60 #define LOOSE_ERROR_THRESHOLD 1e-7 | |
| 61 | |
| 62 using namespace WebKit; | |
| 63 | |
| 64 namespace { | |
| 65 | |
| 66 static void initializeTestMatrix(WebTransformationMatrix& transform) | |
| 67 { | |
| 68 transform.setM11(10); | |
| 69 transform.setM12(11); | |
| 70 transform.setM13(12); | |
| 71 transform.setM14(13); | |
| 72 transform.setM21(14); | |
| 73 transform.setM22(15); | |
| 74 transform.setM23(16); | |
| 75 transform.setM24(17); | |
| 76 transform.setM31(18); | |
| 77 transform.setM32(19); | |
| 78 transform.setM33(20); | |
| 79 transform.setM34(21); | |
| 80 transform.setM41(22); | |
| 81 transform.setM42(23); | |
| 82 transform.setM43(24); | |
| 83 transform.setM44(25); | |
| 84 | |
| 85 // Sanity check | |
| 86 EXPECT_ROW1_EQ(10, 14, 18, 22, transform); | |
| 87 EXPECT_ROW2_EQ(11, 15, 19, 23, transform); | |
| 88 EXPECT_ROW3_EQ(12, 16, 20, 24, transform); | |
| 89 EXPECT_ROW4_EQ(13, 17, 21, 25, transform); | |
| 90 } | |
| 91 | |
| 92 static void initializeTestMatrix2(WebTransformationMatrix& transform) | |
| 93 { | |
| 94 transform.setM11(30); | |
| 95 transform.setM12(31); | |
| 96 transform.setM13(32); | |
| 97 transform.setM14(33); | |
| 98 transform.setM21(34); | |
| 99 transform.setM22(35); | |
| 100 transform.setM23(36); | |
| 101 transform.setM24(37); | |
| 102 transform.setM31(38); | |
| 103 transform.setM32(39); | |
| 104 transform.setM33(40); | |
| 105 transform.setM34(41); | |
| 106 transform.setM41(42); | |
| 107 transform.setM42(43); | |
| 108 transform.setM43(44); | |
| 109 transform.setM44(45); | |
| 110 | |
| 111 // Sanity check | |
| 112 EXPECT_ROW1_EQ(30, 34, 38, 42, transform); | |
| 113 EXPECT_ROW2_EQ(31, 35, 39, 43, transform); | |
| 114 EXPECT_ROW3_EQ(32, 36, 40, 44, transform); | |
| 115 EXPECT_ROW4_EQ(33, 37, 41, 45, transform); | |
| 116 } | |
| 117 | |
| 118 TEST(WebTransformationMatrixTest, verifyDefaultConstructorCreatesIdentityMatrix) | |
| 119 { | |
| 120 WebTransformationMatrix A; | |
| 121 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
| 122 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
| 123 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 124 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 125 EXPECT_TRUE(A.isIdentity()); | |
| 126 } | |
| 127 | |
| 128 TEST(WebTransformationMatrixTest, verifyConstructorFor2dElements) | |
| 129 { | |
| 130 WebTransformationMatrix A(1, 2, 3, 4, 5, 6); | |
| 131 EXPECT_ROW1_EQ(1, 3, 0, 5, A); | |
| 132 EXPECT_ROW2_EQ(2, 4, 0, 6, A); | |
| 133 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 134 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 135 } | |
| 136 | |
| 137 TEST(WebTransformationMatrixTest, verifyConstructorForAllElements) | |
| 138 { | |
| 139 WebTransformationMatrix A(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16); | |
| 140 EXPECT_ROW1_EQ(1, 5, 9, 13, A); | |
| 141 EXPECT_ROW2_EQ(2, 6, 10, 14, A); | |
| 142 EXPECT_ROW3_EQ(3, 7, 11, 15, A); | |
| 143 EXPECT_ROW4_EQ(4, 8, 12, 16, A); | |
| 144 } | |
| 145 | |
| 146 TEST(WebTransformationMatrixTest, verifyCopyConstructor) | |
| 147 { | |
| 148 WebTransformationMatrix A; | |
| 149 initializeTestMatrix(A); | |
| 150 | |
| 151 // Copy constructor should produce exact same elements as matrix A. | |
| 152 WebTransformationMatrix B(A); | |
| 153 EXPECT_ROW1_EQ(10, 14, 18, 22, B); | |
| 154 EXPECT_ROW2_EQ(11, 15, 19, 23, B); | |
| 155 EXPECT_ROW3_EQ(12, 16, 20, 24, B); | |
| 156 EXPECT_ROW4_EQ(13, 17, 21, 25, B); | |
| 157 } | |
| 158 | |
| 159 TEST(WebTransformationMatrixTest, verifyMatrixInversion) | |
| 160 { | |
| 161 // Invert a translation | |
| 162 WebTransformationMatrix translation; | |
| 163 translation.translate3d(2, 3, 4); | |
| 164 EXPECT_TRUE(translation.isInvertible()); | |
| 165 | |
| 166 WebTransformationMatrix inverseTranslation = translation.inverse(); | |
| 167 EXPECT_ROW1_EQ(1, 0, 0, -2, inverseTranslation); | |
| 168 EXPECT_ROW2_EQ(0, 1, 0, -3, inverseTranslation); | |
| 169 EXPECT_ROW3_EQ(0, 0, 1, -4, inverseTranslation); | |
| 170 EXPECT_ROW4_EQ(0, 0, 0, 1, inverseTranslation); | |
| 171 | |
| 172 // Note that inversion should not have changed the original matrix. | |
| 173 EXPECT_ROW1_EQ(1, 0, 0, 2, translation); | |
| 174 EXPECT_ROW2_EQ(0, 1, 0, 3, translation); | |
| 175 EXPECT_ROW3_EQ(0, 0, 1, 4, translation); | |
| 176 EXPECT_ROW4_EQ(0, 0, 0, 1, translation); | |
| 177 | |
| 178 // Invert a non-uniform scale | |
| 179 WebTransformationMatrix scale; | |
| 180 scale.scale3d(4, 10, 100); | |
| 181 EXPECT_TRUE(scale.isInvertible()); | |
| 182 | |
| 183 WebTransformationMatrix inverseScale = scale.inverse(); | |
| 184 EXPECT_ROW1_EQ(0.25, 0, 0, 0, inverseScale); | |
| 185 EXPECT_ROW2_EQ(0, .1f, 0, 0, inverseScale); | |
| 186 EXPECT_ROW3_EQ(0, 0, .01f, 0, inverseScale); | |
| 187 EXPECT_ROW4_EQ(0, 0, 0, 1, inverseScale); | |
| 188 | |
| 189 // Try to invert a matrix that is not invertible. | |
| 190 // The inverse() function should simply return an identity matrix. | |
| 191 WebTransformationMatrix notInvertible; | |
| 192 notInvertible.setM11(0); | |
| 193 notInvertible.setM22(0); | |
| 194 notInvertible.setM33(0); | |
| 195 notInvertible.setM44(0); | |
| 196 EXPECT_FALSE(notInvertible.isInvertible()); | |
| 197 | |
| 198 WebTransformationMatrix inverseOfNotInvertible; | |
| 199 initializeTestMatrix(inverseOfNotInvertible); // initialize this to somethin
g non-identity, to make sure that assignment below actually took place. | |
| 200 inverseOfNotInvertible = notInvertible.inverse(); | |
| 201 EXPECT_TRUE(inverseOfNotInvertible.isIdentity()); | |
| 202 } | |
| 203 | |
| 204 TEST(WebTransformationMatrixTest, verifyTo2DTransform) | |
| 205 { | |
| 206 WebTransformationMatrix A; | |
| 207 initializeTestMatrix(A); | |
| 208 | |
| 209 WebTransformationMatrix B = A.to2dTransform(); | |
| 210 | |
| 211 EXPECT_ROW1_EQ(10, 14, 0, 22, B); | |
| 212 EXPECT_ROW2_EQ(11, 15, 0, 23, B); | |
| 213 EXPECT_ROW3_EQ(0, 0, 1, 0, B); | |
| 214 EXPECT_ROW4_EQ(13, 17, 0, 25, B); | |
| 215 | |
| 216 // Note that to2DTransform should not have changed the original matrix. | |
| 217 EXPECT_ROW1_EQ(10, 14, 18, 22, A); | |
| 218 EXPECT_ROW2_EQ(11, 15, 19, 23, A); | |
| 219 EXPECT_ROW3_EQ(12, 16, 20, 24, A); | |
| 220 EXPECT_ROW4_EQ(13, 17, 21, 25, A); | |
| 221 } | |
| 222 | |
| 223 TEST(WebTransformationMatrixTest, verifyAssignmentOperator) | |
| 224 { | |
| 225 WebTransformationMatrix A; | |
| 226 initializeTestMatrix(A); | |
| 227 WebTransformationMatrix B; | |
| 228 initializeTestMatrix2(B); | |
| 229 WebTransformationMatrix C; | |
| 230 initializeTestMatrix2(C); | |
| 231 C = B = A; | |
| 232 | |
| 233 // Both B and C should now have been re-assigned to the value of A. | |
| 234 EXPECT_ROW1_EQ(10, 14, 18, 22, B); | |
| 235 EXPECT_ROW2_EQ(11, 15, 19, 23, B); | |
| 236 EXPECT_ROW3_EQ(12, 16, 20, 24, B); | |
| 237 EXPECT_ROW4_EQ(13, 17, 21, 25, B); | |
| 238 | |
| 239 EXPECT_ROW1_EQ(10, 14, 18, 22, C); | |
| 240 EXPECT_ROW2_EQ(11, 15, 19, 23, C); | |
| 241 EXPECT_ROW3_EQ(12, 16, 20, 24, C); | |
| 242 EXPECT_ROW4_EQ(13, 17, 21, 25, C); | |
| 243 } | |
| 244 | |
| 245 TEST(WebTransformationMatrixTest, verifyEqualsBooleanOperator) | |
| 246 { | |
| 247 WebTransformationMatrix A; | |
| 248 initializeTestMatrix(A); | |
| 249 | |
| 250 WebTransformationMatrix B; | |
| 251 initializeTestMatrix(B); | |
| 252 EXPECT_TRUE(A == B); | |
| 253 | |
| 254 // Modifying multiple elements should cause equals operator to return false. | |
| 255 WebTransformationMatrix C; | |
| 256 initializeTestMatrix2(C); | |
| 257 EXPECT_FALSE(A == C); | |
| 258 | |
| 259 // Modifying any one individual element should cause equals operator to retu
rn false. | |
| 260 WebTransformationMatrix D; | |
| 261 D = A; | |
| 262 D.setM11(0); | |
| 263 EXPECT_FALSE(A == D); | |
| 264 | |
| 265 D = A; | |
| 266 D.setM12(0); | |
| 267 EXPECT_FALSE(A == D); | |
| 268 | |
| 269 D = A; | |
| 270 D.setM13(0); | |
| 271 EXPECT_FALSE(A == D); | |
| 272 | |
| 273 D = A; | |
| 274 D.setM14(0); | |
| 275 EXPECT_FALSE(A == D); | |
| 276 | |
| 277 D = A; | |
| 278 D.setM21(0); | |
| 279 EXPECT_FALSE(A == D); | |
| 280 | |
| 281 D = A; | |
| 282 D.setM22(0); | |
| 283 EXPECT_FALSE(A == D); | |
| 284 | |
| 285 D = A; | |
| 286 D.setM23(0); | |
| 287 EXPECT_FALSE(A == D); | |
| 288 | |
| 289 D = A; | |
| 290 D.setM24(0); | |
| 291 EXPECT_FALSE(A == D); | |
| 292 | |
| 293 D = A; | |
| 294 D.setM31(0); | |
| 295 EXPECT_FALSE(A == D); | |
| 296 | |
| 297 D = A; | |
| 298 D.setM32(0); | |
| 299 EXPECT_FALSE(A == D); | |
| 300 | |
| 301 D = A; | |
| 302 D.setM33(0); | |
| 303 EXPECT_FALSE(A == D); | |
| 304 | |
| 305 D = A; | |
| 306 D.setM34(0); | |
| 307 EXPECT_FALSE(A == D); | |
| 308 | |
| 309 D = A; | |
| 310 D.setM41(0); | |
| 311 EXPECT_FALSE(A == D); | |
| 312 | |
| 313 D = A; | |
| 314 D.setM42(0); | |
| 315 EXPECT_FALSE(A == D); | |
| 316 | |
| 317 D = A; | |
| 318 D.setM43(0); | |
| 319 EXPECT_FALSE(A == D); | |
| 320 | |
| 321 D = A; | |
| 322 D.setM44(0); | |
| 323 EXPECT_FALSE(A == D); | |
| 324 } | |
| 325 | |
| 326 TEST(WebTransformationMatrixTest, verifyMultiplyOperator) | |
| 327 { | |
| 328 WebTransformationMatrix A; | |
| 329 initializeTestMatrix(A); | |
| 330 | |
| 331 WebTransformationMatrix B; | |
| 332 initializeTestMatrix2(B); | |
| 333 | |
| 334 WebTransformationMatrix C = A * B; | |
| 335 EXPECT_ROW1_EQ(2036, 2292, 2548, 2804, C); | |
| 336 EXPECT_ROW2_EQ(2162, 2434, 2706, 2978, C); | |
| 337 EXPECT_ROW3_EQ(2288, 2576, 2864, 3152, C); | |
| 338 EXPECT_ROW4_EQ(2414, 2718, 3022, 3326, C); | |
| 339 | |
| 340 // Just an additional sanity check; matrix multiplication is not commutative
. | |
| 341 EXPECT_FALSE(A * B == B * A); | |
| 342 } | |
| 343 | |
| 344 TEST(WebTransformationMatrixTest, verifyMatrixMultiplication) | |
| 345 { | |
| 346 WebTransformationMatrix A; | |
| 347 initializeTestMatrix(A); | |
| 348 | |
| 349 WebTransformationMatrix B; | |
| 350 initializeTestMatrix2(B); | |
| 351 | |
| 352 A.multiply(B); | |
| 353 EXPECT_ROW1_EQ(2036, 2292, 2548, 2804, A); | |
| 354 EXPECT_ROW2_EQ(2162, 2434, 2706, 2978, A); | |
| 355 EXPECT_ROW3_EQ(2288, 2576, 2864, 3152, A); | |
| 356 EXPECT_ROW4_EQ(2414, 2718, 3022, 3326, A); | |
| 357 } | |
| 358 | |
| 359 TEST(WebTransformationMatrixTest, verifyMakeIdentiy) | |
| 360 { | |
| 361 WebTransformationMatrix A; | |
| 362 initializeTestMatrix(A); | |
| 363 A.makeIdentity(); | |
| 364 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
| 365 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
| 366 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 367 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 368 EXPECT_TRUE(A.isIdentity()); | |
| 369 } | |
| 370 | |
| 371 TEST(WebTransformationMatrixTest, verifyTranslate) | |
| 372 { | |
| 373 WebTransformationMatrix A; | |
| 374 A.translate(2, 3); | |
| 375 EXPECT_ROW1_EQ(1, 0, 0, 2, A); | |
| 376 EXPECT_ROW2_EQ(0, 1, 0, 3, A); | |
| 377 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 378 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 379 | |
| 380 // Verify that translate() post-multiplies the existing matrix. | |
| 381 A.makeIdentity(); | |
| 382 A.scale(5); | |
| 383 A.translate(2, 3); | |
| 384 EXPECT_ROW1_EQ(5, 0, 0, 10, A); | |
| 385 EXPECT_ROW2_EQ(0, 5, 0, 15, A); | |
| 386 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 387 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 388 } | |
| 389 | |
| 390 TEST(WebTransformationMatrixTest, verifyTranslate3d) | |
| 391 { | |
| 392 WebTransformationMatrix A; | |
| 393 A.translate3d(2, 3, 4); | |
| 394 EXPECT_ROW1_EQ(1, 0, 0, 2, A); | |
| 395 EXPECT_ROW2_EQ(0, 1, 0, 3, A); | |
| 396 EXPECT_ROW3_EQ(0, 0, 1, 4, A); | |
| 397 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 398 | |
| 399 // Verify that translate3d() post-multiplies the existing matrix. | |
| 400 A.makeIdentity(); | |
| 401 A.scale3d(6, 7, 8); | |
| 402 A.translate3d(2, 3, 4); | |
| 403 EXPECT_ROW1_EQ(6, 0, 0, 12, A); | |
| 404 EXPECT_ROW2_EQ(0, 7, 0, 21, A); | |
| 405 EXPECT_ROW3_EQ(0, 0, 8, 32, A); | |
| 406 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 407 } | |
| 408 | |
| 409 TEST(WebTransformationMatrixTest, verifyTranslateRight3d) | |
| 410 { | |
| 411 WebTransformationMatrix A; | |
| 412 A.translateRight3d(2, 3, 4); | |
| 413 EXPECT_ROW1_EQ(1, 0, 0, 2, A); | |
| 414 EXPECT_ROW2_EQ(0, 1, 0, 3, A); | |
| 415 EXPECT_ROW3_EQ(0, 0, 1, 4, A); | |
| 416 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 417 | |
| 418 // Note carefully, all other operations do post-multiply, this one is unique
. | |
| 419 // Verify that translateRight3d() PRE-multiplies the existing matrix. | |
| 420 A.makeIdentity(); | |
| 421 A.scale3d(6, 7, 8); | |
| 422 A.translateRight3d(2, 3, 4); | |
| 423 EXPECT_ROW1_EQ(6, 0, 0, 2, A); | |
| 424 EXPECT_ROW2_EQ(0, 7, 0, 3, A); | |
| 425 EXPECT_ROW3_EQ(0, 0, 8, 4, A); | |
| 426 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 427 } | |
| 428 | |
| 429 TEST(WebTransformationMatrixTest, verifyScale) | |
| 430 { | |
| 431 WebTransformationMatrix A; | |
| 432 A.scale(5); | |
| 433 EXPECT_ROW1_EQ(5, 0, 0, 0, A); | |
| 434 EXPECT_ROW2_EQ(0, 5, 0, 0, A); | |
| 435 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 436 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 437 | |
| 438 // Verify that scale() post-multiplies the existing matrix. | |
| 439 A.makeIdentity(); | |
| 440 A.translate3d(2, 3, 4); | |
| 441 A.scale(5); | |
| 442 EXPECT_ROW1_EQ(5, 0, 0, 2, A); | |
| 443 EXPECT_ROW2_EQ(0, 5, 0, 3, A); | |
| 444 EXPECT_ROW3_EQ(0, 0, 1, 4, A); | |
| 445 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 446 } | |
| 447 | |
| 448 TEST(WebTransformationMatrixTest, verifyNonUniformScale) | |
| 449 { | |
| 450 WebTransformationMatrix A; | |
| 451 A.scaleNonUniform(6, 7); | |
| 452 EXPECT_ROW1_EQ(6, 0, 0, 0, A); | |
| 453 EXPECT_ROW2_EQ(0, 7, 0, 0, A); | |
| 454 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 455 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 456 | |
| 457 // Verify that scaleNonUniform() post-multiplies the existing matrix. | |
| 458 A.makeIdentity(); | |
| 459 A.translate3d(2, 3, 4); | |
| 460 A.scaleNonUniform(6, 7); | |
| 461 EXPECT_ROW1_EQ(6, 0, 0, 2, A); | |
| 462 EXPECT_ROW2_EQ(0, 7, 0, 3, A); | |
| 463 EXPECT_ROW3_EQ(0, 0, 1, 4, A); | |
| 464 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 465 } | |
| 466 | |
| 467 TEST(WebTransformationMatrixTest, verifyScale3d) | |
| 468 { | |
| 469 WebTransformationMatrix A; | |
| 470 A.scale3d(6, 7, 8); | |
| 471 EXPECT_ROW1_EQ(6, 0, 0, 0, A); | |
| 472 EXPECT_ROW2_EQ(0, 7, 0, 0, A); | |
| 473 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
| 474 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 475 | |
| 476 // Verify that scale3d() post-multiplies the existing matrix. | |
| 477 A.makeIdentity(); | |
| 478 A.translate3d(2, 3, 4); | |
| 479 A.scale3d(6, 7, 8); | |
| 480 EXPECT_ROW1_EQ(6, 0, 0, 2, A); | |
| 481 EXPECT_ROW2_EQ(0, 7, 0, 3, A); | |
| 482 EXPECT_ROW3_EQ(0, 0, 8, 4, A); | |
| 483 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 484 } | |
| 485 | |
| 486 TEST(WebTransformationMatrixTest, verifyRotate) | |
| 487 { | |
| 488 WebTransformationMatrix A; | |
| 489 A.rotate(90); | |
| 490 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD); | |
| 491 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD); | |
| 492 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 493 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 494 | |
| 495 // Verify that rotate() post-multiplies the existing matrix. | |
| 496 A.makeIdentity(); | |
| 497 A.scale3d(6, 7, 8); | |
| 498 A.rotate(90); | |
| 499 EXPECT_ROW1_NEAR(0, -6, 0, 0, A, ERROR_THRESHOLD); | |
| 500 EXPECT_ROW2_NEAR(7, 0, 0, 0, A, ERROR_THRESHOLD); | |
| 501 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
| 502 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 503 } | |
| 504 | |
| 505 TEST(WebTransformationMatrixTest, verifyRotate3d) | |
| 506 { | |
| 507 WebTransformationMatrix A; | |
| 508 | |
| 509 // Check rotation about z-axis | |
| 510 A.makeIdentity(); | |
| 511 A.rotate3d(0, 0, 90); | |
| 512 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD); | |
| 513 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD); | |
| 514 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 515 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 516 | |
| 517 // Check rotation about x-axis | |
| 518 A.makeIdentity(); | |
| 519 A.rotate3d(90, 0, 0); | |
| 520 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
| 521 EXPECT_ROW2_NEAR(0, 0, -1, 0, A, ERROR_THRESHOLD); | |
| 522 EXPECT_ROW3_NEAR(0, 1, 0, 0, A, ERROR_THRESHOLD); | |
| 523 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 524 | |
| 525 // Check rotation about y-axis. | |
| 526 // Note carefully, the expected pattern is inverted compared to rotating abo
ut x axis or z axis. | |
| 527 A.makeIdentity(); | |
| 528 A.rotate3d(0, 90, 0); | |
| 529 EXPECT_ROW1_NEAR(0, 0, 1, 0, A, ERROR_THRESHOLD); | |
| 530 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
| 531 EXPECT_ROW3_NEAR(-1, 0, 0, 0, A, ERROR_THRESHOLD); | |
| 532 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 533 | |
| 534 // Verify that rotate3d(rx, ry, rz) post-multiplies the existing matrix. | |
| 535 A.makeIdentity(); | |
| 536 A.scale3d(6, 7, 8); | |
| 537 A.rotate3d(0, 0, 90); | |
| 538 EXPECT_ROW1_NEAR(0, -6, 0, 0, A, ERROR_THRESHOLD); | |
| 539 EXPECT_ROW2_NEAR(7, 0, 0, 0, A, ERROR_THRESHOLD); | |
| 540 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
| 541 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 542 } | |
| 543 | |
| 544 TEST(WebTransformationMatrixTest, verifyRotate3dOrderOfCompositeRotations) | |
| 545 { | |
| 546 // Rotate3d(degreesX, degreesY, degreesZ) is actually composite transform co
nsiting of | |
| 547 // three primitive rotations. This test verifies that the ordering of those
three | |
| 548 // transforms is the intended ordering. | |
| 549 // | |
| 550 // The correct ordering for this test case should be: | |
| 551 // 1. rotate by 30 degrees about z-axis | |
| 552 // 2. rotate by 20 degrees about y-axis | |
| 553 // 3. rotate by 10 degrees about x-axis | |
| 554 // | |
| 555 // Note: there are 6 possible orderings of 3 transforms. For the specific tr
ansforms | |
| 556 // used in this test, all 6 combinations produce a unique matrix that is dif
ferent | |
| 557 // from the other orderings. That way, this test verifies the exact ordering
. | |
| 558 | |
| 559 WebTransformationMatrix A; | |
| 560 A.makeIdentity(); | |
| 561 A.rotate3d(10, 20, 30); | |
| 562 | |
| 563 EXPECT_ROW1_NEAR(0.8137976813493738026394908, | |
| 564 -0.4409696105298823720630708, | |
| 565 0.3785223063697923939763257, | |
| 566 0, A, ERROR_THRESHOLD); | |
| 567 EXPECT_ROW2_NEAR(0.4698463103929541584413698, | |
| 568 0.8825641192593856043657752, | |
| 569 0.0180283112362972230968694, | |
| 570 0, A, ERROR_THRESHOLD); | |
| 571 EXPECT_ROW3_NEAR(-0.3420201433256686573969318, | |
| 572 0.1631759111665348205288950, | |
| 573 0.9254165783983233639631294, | |
| 574 0, A, ERROR_THRESHOLD); | |
| 575 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 576 } | |
| 577 | |
| 578 TEST(WebTransformationMatrixTest, verifyRotateAxisAngle3d) | |
| 579 { | |
| 580 WebTransformationMatrix A; | |
| 581 | |
| 582 // Check rotation about z-axis | |
| 583 A.makeIdentity(); | |
| 584 A.rotate3d(0, 0, 1, 90); | |
| 585 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD); | |
| 586 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD); | |
| 587 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 588 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 589 | |
| 590 // Check rotation about x-axis | |
| 591 A.makeIdentity(); | |
| 592 A.rotate3d(1, 0, 0, 90); | |
| 593 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
| 594 EXPECT_ROW2_NEAR(0, 0, -1, 0, A, ERROR_THRESHOLD); | |
| 595 EXPECT_ROW3_NEAR(0, 1, 0, 0, A, ERROR_THRESHOLD); | |
| 596 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 597 | |
| 598 // Check rotation about y-axis. | |
| 599 // Note carefully, the expected pattern is inverted compared to rotating abo
ut x axis or z axis. | |
| 600 A.makeIdentity(); | |
| 601 A.rotate3d(0, 1, 0, 90); | |
| 602 EXPECT_ROW1_NEAR(0, 0, 1, 0, A, ERROR_THRESHOLD); | |
| 603 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
| 604 EXPECT_ROW3_NEAR(-1, 0, 0, 0, A, ERROR_THRESHOLD); | |
| 605 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 606 | |
| 607 // Verify that rotate3d(axis, angle) post-multiplies the existing matrix. | |
| 608 A.makeIdentity(); | |
| 609 A.scale3d(6, 7, 8); | |
| 610 A.rotate3d(0, 0, 1, 90); | |
| 611 EXPECT_ROW1_NEAR(0, -6, 0, 0, A, ERROR_THRESHOLD); | |
| 612 EXPECT_ROW2_NEAR(7, 0, 0, 0, A, ERROR_THRESHOLD); | |
| 613 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
| 614 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 615 } | |
| 616 | |
| 617 TEST(WebTransformationMatrixTest, verifyRotateAxisAngle3dForArbitraryAxis) | |
| 618 { | |
| 619 // Check rotation about an arbitrary non-axis-aligned vector. | |
| 620 WebTransformationMatrix A; | |
| 621 A.rotate3d(1, 1, 1, 90); | |
| 622 EXPECT_ROW1_NEAR(0.3333333333333334258519187, | |
| 623 -0.2440169358562924717404030, | |
| 624 0.9106836025229592124219380, | |
| 625 0, A, ERROR_THRESHOLD); | |
| 626 EXPECT_ROW2_NEAR(0.9106836025229592124219380, | |
| 627 0.3333333333333334258519187, | |
| 628 -0.2440169358562924717404030, | |
| 629 0, A, ERROR_THRESHOLD); | |
| 630 EXPECT_ROW3_NEAR(-0.2440169358562924717404030, | |
| 631 0.9106836025229592124219380, | |
| 632 0.3333333333333334258519187, | |
| 633 0, A, ERROR_THRESHOLD); | |
| 634 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 635 } | |
| 636 | |
| 637 TEST(WebTransformationMatrixTest, verifyRotateAxisAngle3dForDegenerateAxis) | |
| 638 { | |
| 639 // Check rotation about a degenerate zero vector. | |
| 640 // It is expected to default to rotation about the z-axis. | |
| 641 WebTransformationMatrix A; | |
| 642 A.rotate3d(0, 0, 0, 90); | |
| 643 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD); | |
| 644 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD); | |
| 645 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 646 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 647 } | |
| 648 | |
| 649 TEST(WebTransformationMatrixTest, verifySkewX) | |
| 650 { | |
| 651 WebTransformationMatrix A; | |
| 652 A.skewX(45); | |
| 653 EXPECT_ROW1_EQ(1, 1, 0, 0, A); | |
| 654 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
| 655 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 656 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 657 | |
| 658 // Verify that skewX() post-multiplies the existing matrix. | |
| 659 // Row 1, column 2, would incorrectly have value "7" if the matrix is pre-mu
ltiplied instead of post-multiplied. | |
| 660 A.makeIdentity(); | |
| 661 A.scale3d(6, 7, 8); | |
| 662 A.skewX(45); | |
| 663 EXPECT_ROW1_EQ(6, 6, 0, 0, A); | |
| 664 EXPECT_ROW2_EQ(0, 7, 0, 0, A); | |
| 665 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
| 666 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 667 } | |
| 668 | |
| 669 TEST(WebTransformationMatrixTest, verifySkewY) | |
| 670 { | |
| 671 WebTransformationMatrix A; | |
| 672 A.skewY(45); | |
| 673 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
| 674 EXPECT_ROW2_EQ(1, 1, 0, 0, A); | |
| 675 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 676 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 677 | |
| 678 // Verify that skewY() post-multiplies the existing matrix. | |
| 679 // Row 2, column 1, would incorrectly have value "6" if the matrix is pre-mu
ltiplied instead of post-multiplied. | |
| 680 A.makeIdentity(); | |
| 681 A.scale3d(6, 7, 8); | |
| 682 A.skewY(45); | |
| 683 EXPECT_ROW1_EQ(6, 0, 0, 0, A); | |
| 684 EXPECT_ROW2_EQ(7, 7, 0, 0, A); | |
| 685 EXPECT_ROW3_EQ(0, 0, 8, 0, A); | |
| 686 EXPECT_ROW4_EQ(0, 0, 0, 1, A); | |
| 687 } | |
| 688 | |
| 689 TEST(WebTransformationMatrixTest, verifyApplyPerspective) | |
| 690 { | |
| 691 WebTransformationMatrix A; | |
| 692 A.applyPerspective(1); | |
| 693 EXPECT_ROW1_EQ(1, 0, 0, 0, A); | |
| 694 EXPECT_ROW2_EQ(0, 1, 0, 0, A); | |
| 695 EXPECT_ROW3_EQ(0, 0, 1, 0, A); | |
| 696 EXPECT_ROW4_EQ(0, 0, -1, 1, A); | |
| 697 | |
| 698 // Verify that applyPerspective() post-multiplies the existing matrix. | |
| 699 A.makeIdentity(); | |
| 700 A.translate3d(2, 3, 4); | |
| 701 A.applyPerspective(1); | |
| 702 EXPECT_ROW1_EQ(1, 0, -2, 2, A); | |
| 703 EXPECT_ROW2_EQ(0, 1, -3, 3, A); | |
| 704 EXPECT_ROW3_EQ(0, 0, -3, 4, A); | |
| 705 EXPECT_ROW4_EQ(0, 0, -1, 1, A); | |
| 706 } | |
| 707 | |
| 708 TEST(WebTransformationMatrixTest, verifyHasPerspective) | |
| 709 { | |
| 710 WebTransformationMatrix A; | |
| 711 A.applyPerspective(1); | |
| 712 EXPECT_TRUE(A.hasPerspective()); | |
| 713 | |
| 714 A.makeIdentity(); | |
| 715 A.applyPerspective(0); | |
| 716 EXPECT_FALSE(A.hasPerspective()); | |
| 717 | |
| 718 A.makeIdentity(); | |
| 719 A.setM34(-0.3); | |
| 720 EXPECT_TRUE(A.hasPerspective()); | |
| 721 | |
| 722 // FIXME: WebCore only checkes m34() for perspective, but that is probably | |
| 723 // wrong. https://bugs.webkit.org/show_bug.cgi?id=83088. For now, thi
s test | |
| 724 // case expects the exact behavior as implemented by WebCore, but thi
s should | |
| 725 // probably be changed so that if the entire bottom row is not exactl
y | |
| 726 // (0, 0, 0, 1), then hasPerspective should return true. | |
| 727 | |
| 728 A.makeIdentity(); | |
| 729 A.setM14(-1); | |
| 730 EXPECT_FALSE(A.hasPerspective()); | |
| 731 | |
| 732 A.makeIdentity(); | |
| 733 A.setM24(-1); | |
| 734 EXPECT_FALSE(A.hasPerspective()); | |
| 735 | |
| 736 A.makeIdentity(); | |
| 737 A.setM44(0.5); | |
| 738 EXPECT_FALSE(A.hasPerspective()); | |
| 739 } | |
| 740 | |
| 741 TEST(WebTransformationMatrixTest, verifyIsInvertible) | |
| 742 { | |
| 743 WebTransformationMatrix A; | |
| 744 | |
| 745 // Translations, rotations, scales, skews and arbitrary combinations of them
are invertible. | |
| 746 A.makeIdentity(); | |
| 747 EXPECT_TRUE(A.isInvertible()); | |
| 748 | |
| 749 A.makeIdentity(); | |
| 750 A.translate3d(2, 3, 4); | |
| 751 EXPECT_TRUE(A.isInvertible()); | |
| 752 | |
| 753 A.makeIdentity(); | |
| 754 A.scale3d(6, 7, 8); | |
| 755 EXPECT_TRUE(A.isInvertible()); | |
| 756 | |
| 757 A.makeIdentity(); | |
| 758 A.rotate3d(10, 20, 30); | |
| 759 EXPECT_TRUE(A.isInvertible()); | |
| 760 | |
| 761 A.makeIdentity(); | |
| 762 A.skewX(45); | |
| 763 EXPECT_TRUE(A.isInvertible()); | |
| 764 | |
| 765 // A perspective matrix (projection plane at z=0) is invertible. The intuiti
ve | |
| 766 // explanation is that perspective is eqivalent to a skew of the w-axis; ske
ws are | |
| 767 // invertible. | |
| 768 A.makeIdentity(); | |
| 769 A.applyPerspective(1); | |
| 770 EXPECT_TRUE(A.isInvertible()); | |
| 771 | |
| 772 // A "pure" perspective matrix derived by similar triangles, with m44() set
to zero | |
| 773 // (i.e. camera positioned at the origin), is not invertible. | |
| 774 A.makeIdentity(); | |
| 775 A.applyPerspective(1); | |
| 776 A.setM44(0); | |
| 777 EXPECT_FALSE(A.isInvertible()); | |
| 778 | |
| 779 // Adding more to a non-invertible matrix will not make it invertible in the
general case. | |
| 780 A.makeIdentity(); | |
| 781 A.applyPerspective(1); | |
| 782 A.setM44(0); | |
| 783 A.scale3d(6, 7, 8); | |
| 784 A.rotate3d(10, 20, 30); | |
| 785 A.translate3d(6, 7, 8); | |
| 786 EXPECT_FALSE(A.isInvertible()); | |
| 787 | |
| 788 // A degenerate matrix of all zeros is not invertible. | |
| 789 A.makeIdentity(); | |
| 790 A.setM11(0); | |
| 791 A.setM22(0); | |
| 792 A.setM33(0); | |
| 793 A.setM44(0); | |
| 794 EXPECT_FALSE(A.isInvertible()); | |
| 795 } | |
| 796 | |
| 797 TEST(WebTransformationMatrixTest, verifyIsIdentity) | |
| 798 { | |
| 799 WebTransformationMatrix A; | |
| 800 | |
| 801 initializeTestMatrix(A); | |
| 802 EXPECT_FALSE(A.isIdentity()); | |
| 803 | |
| 804 A.makeIdentity(); | |
| 805 EXPECT_TRUE(A.isIdentity()); | |
| 806 | |
| 807 // Modifying any one individual element should cause the matrix to no longer
be identity. | |
| 808 A.makeIdentity(); | |
| 809 A.setM11(2); | |
| 810 EXPECT_FALSE(A.isIdentity()); | |
| 811 | |
| 812 A.makeIdentity(); | |
| 813 A.setM12(2); | |
| 814 EXPECT_FALSE(A.isIdentity()); | |
| 815 | |
| 816 A.makeIdentity(); | |
| 817 A.setM13(2); | |
| 818 EXPECT_FALSE(A.isIdentity()); | |
| 819 | |
| 820 A.makeIdentity(); | |
| 821 A.setM14(2); | |
| 822 EXPECT_FALSE(A.isIdentity()); | |
| 823 | |
| 824 A.makeIdentity(); | |
| 825 A.setM21(2); | |
| 826 EXPECT_FALSE(A.isIdentity()); | |
| 827 | |
| 828 A.makeIdentity(); | |
| 829 A.setM22(2); | |
| 830 EXPECT_FALSE(A.isIdentity()); | |
| 831 | |
| 832 A.makeIdentity(); | |
| 833 A.setM23(2); | |
| 834 EXPECT_FALSE(A.isIdentity()); | |
| 835 | |
| 836 A.makeIdentity(); | |
| 837 A.setM24(2); | |
| 838 EXPECT_FALSE(A.isIdentity()); | |
| 839 | |
| 840 A.makeIdentity(); | |
| 841 A.setM31(2); | |
| 842 EXPECT_FALSE(A.isIdentity()); | |
| 843 | |
| 844 A.makeIdentity(); | |
| 845 A.setM32(2); | |
| 846 EXPECT_FALSE(A.isIdentity()); | |
| 847 | |
| 848 A.makeIdentity(); | |
| 849 A.setM33(2); | |
| 850 EXPECT_FALSE(A.isIdentity()); | |
| 851 | |
| 852 A.makeIdentity(); | |
| 853 A.setM34(2); | |
| 854 EXPECT_FALSE(A.isIdentity()); | |
| 855 | |
| 856 A.makeIdentity(); | |
| 857 A.setM41(2); | |
| 858 EXPECT_FALSE(A.isIdentity()); | |
| 859 | |
| 860 A.makeIdentity(); | |
| 861 A.setM42(2); | |
| 862 EXPECT_FALSE(A.isIdentity()); | |
| 863 | |
| 864 A.makeIdentity(); | |
| 865 A.setM43(2); | |
| 866 EXPECT_FALSE(A.isIdentity()); | |
| 867 | |
| 868 A.makeIdentity(); | |
| 869 A.setM44(2); | |
| 870 EXPECT_FALSE(A.isIdentity()); | |
| 871 } | |
| 872 | |
| 873 TEST(WebTransformationMatrixTest, verifyIsIdentityOrTranslation) | |
| 874 { | |
| 875 WebTransformationMatrix A; | |
| 876 | |
| 877 initializeTestMatrix(A); | |
| 878 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 879 | |
| 880 A.makeIdentity(); | |
| 881 EXPECT_TRUE(A.isIdentityOrTranslation()); | |
| 882 | |
| 883 // Modifying any non-translation components should cause isIdentityOrTransla
tion() to | |
| 884 // return false. NOTE: m41(), m42(), and m43() are the translation component
s, so | |
| 885 // modifying them should still return true for isIdentityOrTranslation(). | |
| 886 A.makeIdentity(); | |
| 887 A.setM11(2); | |
| 888 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 889 | |
| 890 A.makeIdentity(); | |
| 891 A.setM12(2); | |
| 892 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 893 | |
| 894 A.makeIdentity(); | |
| 895 A.setM13(2); | |
| 896 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 897 | |
| 898 A.makeIdentity(); | |
| 899 A.setM14(2); | |
| 900 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 901 | |
| 902 A.makeIdentity(); | |
| 903 A.setM21(2); | |
| 904 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 905 | |
| 906 A.makeIdentity(); | |
| 907 A.setM22(2); | |
| 908 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 909 | |
| 910 A.makeIdentity(); | |
| 911 A.setM23(2); | |
| 912 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 913 | |
| 914 A.makeIdentity(); | |
| 915 A.setM24(2); | |
| 916 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 917 | |
| 918 A.makeIdentity(); | |
| 919 A.setM31(2); | |
| 920 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 921 | |
| 922 A.makeIdentity(); | |
| 923 A.setM32(2); | |
| 924 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 925 | |
| 926 A.makeIdentity(); | |
| 927 A.setM33(2); | |
| 928 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 929 | |
| 930 A.makeIdentity(); | |
| 931 A.setM34(2); | |
| 932 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 933 | |
| 934 // Note carefully - expecting true here. | |
| 935 A.makeIdentity(); | |
| 936 A.setM41(2); | |
| 937 EXPECT_TRUE(A.isIdentityOrTranslation()); | |
| 938 | |
| 939 // Note carefully - expecting true here. | |
| 940 A.makeIdentity(); | |
| 941 A.setM42(2); | |
| 942 EXPECT_TRUE(A.isIdentityOrTranslation()); | |
| 943 | |
| 944 // Note carefully - expecting true here. | |
| 945 A.makeIdentity(); | |
| 946 A.setM43(2); | |
| 947 EXPECT_TRUE(A.isIdentityOrTranslation()); | |
| 948 | |
| 949 A.makeIdentity(); | |
| 950 A.setM44(2); | |
| 951 EXPECT_FALSE(A.isIdentityOrTranslation()); | |
| 952 } | |
| 953 | |
| 954 TEST(WebTransformationMatrixTest, verifyIsIntegerTranslation) | |
| 955 { | |
| 956 WebTransformationMatrix A; | |
| 957 | |
| 958 A.makeIdentity(); | |
| 959 A.translate(2, 3); | |
| 960 EXPECT_TRUE(A.isIntegerTranslation()); | |
| 961 | |
| 962 A.makeIdentity(); | |
| 963 A.translate(2, 3); | |
| 964 EXPECT_TRUE(A.isIntegerTranslation()); | |
| 965 | |
| 966 A.makeIdentity(); | |
| 967 A.translate(2.00001, 3); | |
| 968 EXPECT_FALSE(A.isIntegerTranslation()); | |
| 969 | |
| 970 A.makeIdentity(); | |
| 971 A.translate(2, 2.99999); | |
| 972 EXPECT_FALSE(A.isIntegerTranslation()); | |
| 973 | |
| 974 // Stacking many integer translations should ideally not accumulate any prec
ision error. | |
| 975 A.makeIdentity(); | |
| 976 for (int i = 0; i < 100000; ++i) | |
| 977 A.translate(2, 3); | |
| 978 EXPECT_TRUE(A.isIntegerTranslation()); | |
| 979 } | |
| 980 | |
| 981 TEST(WebTransformationMatrixTest, verifyBlendForTranslation) | |
| 982 { | |
| 983 WebTransformationMatrix from; | |
| 984 from.translate3d(100, 200, 100); | |
| 985 | |
| 986 WebTransformationMatrix to; | |
| 987 | |
| 988 to.makeIdentity(); | |
| 989 to.translate3d(200, 100, 300); | |
| 990 to.blend(from, 0); | |
| 991 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to); | |
| 992 | |
| 993 to.makeIdentity(); | |
| 994 to.translate3d(200, 100, 300); | |
| 995 to.blend(from, 0.25); | |
| 996 EXPECT_ROW1_EQ(1, 0, 0, 125, to); | |
| 997 EXPECT_ROW2_EQ(0, 1, 0, 175, to); | |
| 998 EXPECT_ROW3_EQ(0, 0, 1, 150, to); | |
| 999 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1000 | |
| 1001 to.makeIdentity(); | |
| 1002 to.translate3d(200, 100, 300); | |
| 1003 to.blend(from, 0.5); | |
| 1004 EXPECT_ROW1_EQ(1, 0, 0, 150, to); | |
| 1005 EXPECT_ROW2_EQ(0, 1, 0, 150, to); | |
| 1006 EXPECT_ROW3_EQ(0, 0, 1, 200, to); | |
| 1007 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1008 | |
| 1009 to.makeIdentity(); | |
| 1010 to.translate3d(200, 100, 300); | |
| 1011 to.blend(from, 1); | |
| 1012 EXPECT_ROW1_EQ(1, 0, 0, 200, to); | |
| 1013 EXPECT_ROW2_EQ(0, 1, 0, 100, to); | |
| 1014 EXPECT_ROW3_EQ(0, 0, 1, 300, to); | |
| 1015 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1016 } | |
| 1017 | |
| 1018 TEST(WebTransformationMatrixTest, verifyBlendForScale) | |
| 1019 { | |
| 1020 WebTransformationMatrix from; | |
| 1021 from.scale3d(100, 200, 100); | |
| 1022 | |
| 1023 WebTransformationMatrix to; | |
| 1024 | |
| 1025 to.makeIdentity(); | |
| 1026 to.scale3d(200, 100, 300); | |
| 1027 to.blend(from, 0); | |
| 1028 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to); | |
| 1029 | |
| 1030 to.makeIdentity(); | |
| 1031 to.scale3d(200, 100, 300); | |
| 1032 to.blend(from, 0.25); | |
| 1033 EXPECT_ROW1_EQ(125, 0, 0, 0, to); | |
| 1034 EXPECT_ROW2_EQ(0, 175, 0, 0, to); | |
| 1035 EXPECT_ROW3_EQ(0, 0, 150, 0, to); | |
| 1036 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1037 | |
| 1038 to.makeIdentity(); | |
| 1039 to.scale3d(200, 100, 300); | |
| 1040 to.blend(from, 0.5); | |
| 1041 EXPECT_ROW1_EQ(150, 0, 0, 0, to); | |
| 1042 EXPECT_ROW2_EQ(0, 150, 0, 0, to); | |
| 1043 EXPECT_ROW3_EQ(0, 0, 200, 0, to); | |
| 1044 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1045 | |
| 1046 to.makeIdentity(); | |
| 1047 to.scale3d(200, 100, 300); | |
| 1048 to.blend(from, 1); | |
| 1049 EXPECT_ROW1_EQ(200, 0, 0, 0, to); | |
| 1050 EXPECT_ROW2_EQ(0, 100, 0, 0, to); | |
| 1051 EXPECT_ROW3_EQ(0, 0, 300, 0, to); | |
| 1052 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1053 } | |
| 1054 | |
| 1055 TEST(WebTransformationMatrixTest, verifyBlendForSkewX) | |
| 1056 { | |
| 1057 WebTransformationMatrix from; | |
| 1058 from.skewX(0); | |
| 1059 | |
| 1060 WebTransformationMatrix to; | |
| 1061 | |
| 1062 to.makeIdentity(); | |
| 1063 to.skewX(45); | |
| 1064 to.blend(from, 0); | |
| 1065 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to); | |
| 1066 | |
| 1067 to.makeIdentity(); | |
| 1068 to.skewX(45); | |
| 1069 to.blend(from, 0.5); | |
| 1070 EXPECT_ROW1_EQ(1, 0.5, 0, 0, to); | |
| 1071 EXPECT_ROW2_EQ(0, 1, 0, 0, to); | |
| 1072 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | |
| 1073 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1074 | |
| 1075 to.makeIdentity(); | |
| 1076 to.skewX(45); | |
| 1077 to.blend(from, 0.25); | |
| 1078 EXPECT_ROW1_EQ(1, 0.25, 0, 0, to); | |
| 1079 EXPECT_ROW2_EQ(0, 1, 0, 0, to); | |
| 1080 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | |
| 1081 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1082 | |
| 1083 to.makeIdentity(); | |
| 1084 to.skewX(45); | |
| 1085 to.blend(from, 1); | |
| 1086 EXPECT_ROW1_EQ(1, 1, 0, 0, to); | |
| 1087 EXPECT_ROW2_EQ(0, 1, 0, 0, to); | |
| 1088 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | |
| 1089 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1090 } | |
| 1091 | |
| 1092 TEST(WebTransformationMatrixTest, verifyBlendForSkewY) | |
| 1093 { | |
| 1094 // NOTE CAREFULLY: Decomposition of skew and rotation terms of the matrix is | |
| 1095 // inherently underconstrained, and so it does not always compute the origin
ally | |
| 1096 // intended skew parameters. The current implementation uses QR decompositio
n, which | |
| 1097 // decomposes the shear into a rotation + non-uniform scale. | |
| 1098 // | |
| 1099 // It is unlikely that the decomposition implementation will need to change
very | |
| 1100 // often, so to get any test coverage, the compromise is to verify the exact
matrix | |
| 1101 // that the blend() operation produces. | |
| 1102 // | |
| 1103 // This problem also potentially exists for skewX, but the current QR decomp
osition | |
| 1104 // implementation just happens to decompose those test matrices intuitively. | |
| 1105 | |
| 1106 WebTransformationMatrix from; | |
| 1107 from.skewY(0); | |
| 1108 | |
| 1109 WebTransformationMatrix to; | |
| 1110 | |
| 1111 to.makeIdentity(); | |
| 1112 to.skewY(45); | |
| 1113 to.blend(from, 0); | |
| 1114 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to); | |
| 1115 | |
| 1116 to.makeIdentity(); | |
| 1117 to.skewY(45); | |
| 1118 to.blend(from, 0.25); | |
| 1119 EXPECT_ROW1_NEAR(1.0823489449280947471976333, 0.0464370719145053845178239, 0
, 0, to, ERROR_THRESHOLD); | |
| 1120 EXPECT_ROW2_NEAR(0.2152925909665224513123150, 0.9541702441750861130032035, 0
, 0, to, ERROR_THRESHOLD); | |
| 1121 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | |
| 1122 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1123 | |
| 1124 to.makeIdentity(); | |
| 1125 to.skewY(45); | |
| 1126 to.blend(from, 0.5); | |
| 1127 EXPECT_ROW1_NEAR(1.1152212925809066312865525, 0.0676495144007326631996335, 0
, 0, to, ERROR_THRESHOLD); | |
| 1128 EXPECT_ROW2_NEAR(0.4619397844342648662419037, 0.9519009045724774464858342, 0
, 0, to, ERROR_THRESHOLD); | |
| 1129 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | |
| 1130 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1131 | |
| 1132 // Unfortunately, this case suffers from uncomfortably large precision error
. | |
| 1133 to.makeIdentity(); | |
| 1134 to.skewY(45); | |
| 1135 to.blend(from, 1); | |
| 1136 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, LOOSE_ERROR_THRESHOLD); | |
| 1137 EXPECT_ROW2_NEAR(1, 1, 0, 0, to, LOOSE_ERROR_THRESHOLD); | |
| 1138 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | |
| 1139 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1140 } | |
| 1141 | |
| 1142 TEST(WebTransformationMatrixTest, verifyBlendForRotationAboutX) | |
| 1143 { | |
| 1144 // Even though blending uses quaternions, axis-aligned rotations should blen
d the same | |
| 1145 // with quaternions or Euler angles. So we can test rotation blending by com
paring | |
| 1146 // against manually specified matrices from Euler angles. | |
| 1147 | |
| 1148 WebTransformationMatrix from; | |
| 1149 from.rotate3d(1, 0, 0, 0); | |
| 1150 | |
| 1151 WebTransformationMatrix to; | |
| 1152 | |
| 1153 to.makeIdentity(); | |
| 1154 to.rotate3d(1, 0, 0, 90); | |
| 1155 to.blend(from, 0); | |
| 1156 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to); | |
| 1157 | |
| 1158 double expectedRotationAngle = 22.5 * M_PI / 180.0; | |
| 1159 to.makeIdentity(); | |
| 1160 to.rotate3d(1, 0, 0, 90); | |
| 1161 to.blend(from, 0.25); | |
| 1162 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); | |
| 1163 EXPECT_ROW2_NEAR(0, cos(expectedRotationAngle), -sin(expectedRotationAngle),
0, to, ERROR_THRESHOLD); | |
| 1164 EXPECT_ROW3_NEAR(0, sin(expectedRotationAngle), cos(expectedRotationAngle),
0, to, ERROR_THRESHOLD); | |
| 1165 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1166 | |
| 1167 expectedRotationAngle = 45 * M_PI / 180.0; | |
| 1168 to.makeIdentity(); | |
| 1169 to.rotate3d(1, 0, 0, 90); | |
| 1170 to.blend(from, 0.5); | |
| 1171 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); | |
| 1172 EXPECT_ROW2_NEAR(0, cos(expectedRotationAngle), -sin(expectedRotationAngle),
0, to, ERROR_THRESHOLD); | |
| 1173 EXPECT_ROW3_NEAR(0, sin(expectedRotationAngle), cos(expectedRotationAngle),
0, to, ERROR_THRESHOLD); | |
| 1174 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1175 | |
| 1176 to.makeIdentity(); | |
| 1177 to.rotate3d(1, 0, 0, 90); | |
| 1178 to.blend(from, 1); | |
| 1179 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); | |
| 1180 EXPECT_ROW2_NEAR(0, 0, -1, 0, to, ERROR_THRESHOLD); | |
| 1181 EXPECT_ROW3_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); | |
| 1182 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1183 } | |
| 1184 | |
| 1185 TEST(WebTransformationMatrixTest, verifyBlendForRotationAboutY) | |
| 1186 { | |
| 1187 WebTransformationMatrix from; | |
| 1188 from.rotate3d(0, 1, 0, 0); | |
| 1189 | |
| 1190 WebTransformationMatrix to; | |
| 1191 | |
| 1192 to.makeIdentity(); | |
| 1193 to.rotate3d(0, 1, 0, 90); | |
| 1194 to.blend(from, 0); | |
| 1195 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to); | |
| 1196 | |
| 1197 double expectedRotationAngle = 22.5 * M_PI / 180.0; | |
| 1198 to.makeIdentity(); | |
| 1199 to.rotate3d(0, 1, 0, 90); | |
| 1200 to.blend(from, 0.25); | |
| 1201 EXPECT_ROW1_NEAR(cos(expectedRotationAngle), 0, sin(expectedRotationAngle),
0, to, ERROR_THRESHOLD); | |
| 1202 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); | |
| 1203 EXPECT_ROW3_NEAR(-sin(expectedRotationAngle), 0, cos(expectedRotationAngle),
0, to, ERROR_THRESHOLD); | |
| 1204 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1205 | |
| 1206 expectedRotationAngle = 45 * M_PI / 180.0; | |
| 1207 to.makeIdentity(); | |
| 1208 to.rotate3d(0, 1, 0, 90); | |
| 1209 to.blend(from, 0.5); | |
| 1210 EXPECT_ROW1_NEAR(cos(expectedRotationAngle), 0, sin(expectedRotationAngle),
0, to, ERROR_THRESHOLD); | |
| 1211 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); | |
| 1212 EXPECT_ROW3_NEAR(-sin(expectedRotationAngle), 0, cos(expectedRotationAngle),
0, to, ERROR_THRESHOLD); | |
| 1213 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1214 | |
| 1215 to.makeIdentity(); | |
| 1216 to.rotate3d(0, 1, 0, 90); | |
| 1217 to.blend(from, 1); | |
| 1218 EXPECT_ROW1_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); | |
| 1219 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); | |
| 1220 EXPECT_ROW3_NEAR(-1, 0, 0, 0, to, ERROR_THRESHOLD); | |
| 1221 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1222 } | |
| 1223 | |
| 1224 TEST(WebTransformationMatrixTest, verifyBlendForRotationAboutZ) | |
| 1225 { | |
| 1226 WebTransformationMatrix from; | |
| 1227 from.rotate3d(0, 0, 1, 0); | |
| 1228 | |
| 1229 WebTransformationMatrix to; | |
| 1230 | |
| 1231 to.makeIdentity(); | |
| 1232 to.rotate3d(0, 0, 1, 90); | |
| 1233 to.blend(from, 0); | |
| 1234 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to); | |
| 1235 | |
| 1236 double expectedRotationAngle = 22.5 * M_PI / 180.0; | |
| 1237 to.makeIdentity(); | |
| 1238 to.rotate3d(0, 0, 1, 90); | |
| 1239 to.blend(from, 0.25); | |
| 1240 EXPECT_ROW1_NEAR(cos(expectedRotationAngle), -sin(expectedRotationAngle), 0,
0, to, ERROR_THRESHOLD); | |
| 1241 EXPECT_ROW2_NEAR(sin(expectedRotationAngle), cos(expectedRotationAngle), 0,
0, to, ERROR_THRESHOLD); | |
| 1242 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); | |
| 1243 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1244 | |
| 1245 expectedRotationAngle = 45 * M_PI / 180.0; | |
| 1246 to.makeIdentity(); | |
| 1247 to.rotate3d(0, 0, 1, 90); | |
| 1248 to.blend(from, 0.5); | |
| 1249 EXPECT_ROW1_NEAR(cos(expectedRotationAngle), -sin(expectedRotationAngle), 0,
0, to, ERROR_THRESHOLD); | |
| 1250 EXPECT_ROW2_NEAR(sin(expectedRotationAngle), cos(expectedRotationAngle), 0,
0, to, ERROR_THRESHOLD); | |
| 1251 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); | |
| 1252 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1253 | |
| 1254 to.makeIdentity(); | |
| 1255 to.rotate3d(0, 0, 1, 90); | |
| 1256 to.blend(from, 1); | |
| 1257 EXPECT_ROW1_NEAR(0, -1, 0, 0, to, ERROR_THRESHOLD); | |
| 1258 EXPECT_ROW2_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); | |
| 1259 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); | |
| 1260 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | |
| 1261 } | |
| 1262 | |
| 1263 | |
| 1264 TEST(WebTransformationMatrixTest, verifyBlendForCompositeTransform) | |
| 1265 { | |
| 1266 // Verify that the blending was done with a decomposition in correct order b
y blending | |
| 1267 // a composite transform. | |
| 1268 // Using matrix x vector notation (Ax = b, where x is column vector), the or
dering should be: | |
| 1269 // perspective * translation * rotation * skew * scale | |
| 1270 // | |
| 1271 // It is not as important (or meaningful) to check intermediate interpolatio
ns; order | |
| 1272 // of operations will be tested well enough by the end cases that are easier
to | |
| 1273 // specify. | |
| 1274 | |
| 1275 WebTransformationMatrix from; | |
| 1276 WebTransformationMatrix to; | |
| 1277 | |
| 1278 WebTransformationMatrix expectedEndOfAnimation; | |
| 1279 expectedEndOfAnimation.applyPerspective(1); | |
| 1280 expectedEndOfAnimation.translate3d(10, 20, 30); | |
| 1281 expectedEndOfAnimation.rotate3d(0, 0, 1, 25); | |
| 1282 expectedEndOfAnimation.skewY(45); | |
| 1283 expectedEndOfAnimation.scale3d(6, 7, 8); | |
| 1284 | |
| 1285 to = expectedEndOfAnimation; | |
| 1286 to.blend(from, 0); | |
| 1287 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to); | |
| 1288 | |
| 1289 to = expectedEndOfAnimation; | |
| 1290 to.blend(from, 1); | |
| 1291 | |
| 1292 // Recomposing the matrix results in a normalized matrix, so to verify we ne
ed to | |
| 1293 // normalize the expectedEndOfAnimation before comparing elements. Normalizi
ng means | |
| 1294 // dividing everything by expectedEndOfAnimation.m44(). | |
| 1295 WebTransformationMatrix normalizedExpectedEndOfAnimation = expectedEndOfAnim
ation; | |
| 1296 WebTransformationMatrix normalizationMatrix; | |
| 1297 normalizationMatrix.setM11(1 / expectedEndOfAnimation.m44()); | |
| 1298 normalizationMatrix.setM22(1 / expectedEndOfAnimation.m44()); | |
| 1299 normalizationMatrix.setM33(1 / expectedEndOfAnimation.m44()); | |
| 1300 normalizationMatrix.setM44(1 / expectedEndOfAnimation.m44()); | |
| 1301 normalizedExpectedEndOfAnimation.multiply(normalizationMatrix); | |
| 1302 | |
| 1303 EXPECT_TRANSFORMATION_MATRIX_EQ(normalizedExpectedEndOfAnimation, to); | |
| 1304 } | |
| 1305 | |
| 1306 } // namespace | |
| OLD | NEW |