transform_operations_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright 2013 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 "base/memory/scoped_vector.h" 6#include "cc/animation/transform_operations.h" 7#include "cc/test/geometry_test_utils.h" 8#include "testing/gtest/include/gtest/gtest.h" 9#include "ui/gfx/vector3d_f.h" 10 11namespace cc { 12namespace { 13 14TEST(TransformOperationTest, TransformTypesAreUnique) { 15 ScopedVector<TransformOperations> transforms; 16 17 TransformOperations* to_add = new TransformOperations(); 18 to_add->AppendTranslate(1, 0, 0); 19 transforms.push_back(to_add); 20 21 to_add = new TransformOperations(); 22 to_add->AppendRotate(0, 0, 1, 2); 23 transforms.push_back(to_add); 24 25 to_add = new TransformOperations(); 26 to_add->AppendScale(2, 2, 2); 27 transforms.push_back(to_add); 28 29 to_add = new TransformOperations(); 30 to_add->AppendSkew(1, 0); 31 transforms.push_back(to_add); 32 33 to_add = new TransformOperations(); 34 to_add->AppendPerspective(800); 35 transforms.push_back(to_add); 36 37 for (size_t i = 0; i < transforms.size(); ++i) { 38 for (size_t j = 0; j < transforms.size(); ++j) { 39 bool matches_type = transforms[i]->MatchesTypes(*transforms[j]); 40 EXPECT_TRUE((i == j && matches_type) || !matches_type); 41 } 42 } 43} 44 45TEST(TransformOperationTest, MatchTypesSameLength) { 46 TransformOperations translates; 47 translates.AppendTranslate(1, 0, 0); 48 translates.AppendTranslate(1, 0, 0); 49 translates.AppendTranslate(1, 0, 0); 50 51 TransformOperations skews; 52 skews.AppendSkew(0, 2); 53 skews.AppendSkew(0, 2); 54 skews.AppendSkew(0, 2); 55 56 TransformOperations translates2; 57 translates2.AppendTranslate(0, 2, 0); 58 translates2.AppendTranslate(0, 2, 0); 59 translates2.AppendTranslate(0, 2, 0); 60 61 TransformOperations translates3 = translates2; 62 63 EXPECT_FALSE(translates.MatchesTypes(skews)); 64 EXPECT_TRUE(translates.MatchesTypes(translates2)); 65 EXPECT_TRUE(translates.MatchesTypes(translates3)); 66} 67 68TEST(TransformOperationTest, MatchTypesDifferentLength) { 69 TransformOperations translates; 70 translates.AppendTranslate(1, 0, 0); 71 translates.AppendTranslate(1, 0, 0); 72 translates.AppendTranslate(1, 0, 0); 73 74 TransformOperations skews; 75 skews.AppendSkew(2, 0); 76 skews.AppendSkew(2, 0); 77 78 TransformOperations translates2; 79 translates2.AppendTranslate(0, 2, 0); 80 translates2.AppendTranslate(0, 2, 0); 81 82 EXPECT_FALSE(translates.MatchesTypes(skews)); 83 EXPECT_FALSE(translates.MatchesTypes(translates2)); 84} 85 86void GetIdentityOperations(ScopedVector<TransformOperations>* operations) { 87 TransformOperations* to_add = new TransformOperations(); 88 operations->push_back(to_add); 89 90 to_add = new TransformOperations(); 91 to_add->AppendTranslate(0, 0, 0); 92 operations->push_back(to_add); 93 94 to_add = new TransformOperations(); 95 to_add->AppendTranslate(0, 0, 0); 96 to_add->AppendTranslate(0, 0, 0); 97 operations->push_back(to_add); 98 99 to_add = new TransformOperations(); 100 to_add->AppendScale(1, 1, 1); 101 operations->push_back(to_add); 102 103 to_add = new TransformOperations(); 104 to_add->AppendScale(1, 1, 1); 105 to_add->AppendScale(1, 1, 1); 106 operations->push_back(to_add); 107 108 to_add = new TransformOperations(); 109 to_add->AppendSkew(0, 0); 110 operations->push_back(to_add); 111 112 to_add = new TransformOperations(); 113 to_add->AppendSkew(0, 0); 114 to_add->AppendSkew(0, 0); 115 operations->push_back(to_add); 116 117 to_add = new TransformOperations(); 118 to_add->AppendRotate(0, 0, 1, 0); 119 operations->push_back(to_add); 120 121 to_add = new TransformOperations(); 122 to_add->AppendRotate(0, 0, 1, 0); 123 to_add->AppendRotate(0, 0, 1, 0); 124 operations->push_back(to_add); 125 126 to_add = new TransformOperations(); 127 to_add->AppendMatrix(gfx::Transform()); 128 operations->push_back(to_add); 129 130 to_add = new TransformOperations(); 131 to_add->AppendMatrix(gfx::Transform()); 132 to_add->AppendMatrix(gfx::Transform()); 133 operations->push_back(to_add); 134} 135 136TEST(TransformOperationTest, IdentityAlwaysMatches) { 137 ScopedVector<TransformOperations> operations; 138 GetIdentityOperations(&operations); 139 140 for (size_t i = 0; i < operations.size(); ++i) { 141 for (size_t j = 0; j < operations.size(); ++j) 142 EXPECT_TRUE(operations[i]->MatchesTypes(*operations[j])); 143 } 144} 145 146TEST(TransformOperationTest, ApplyTranslate) { 147 double x = 1; 148 double y = 2; 149 double z = 3; 150 TransformOperations operations; 151 operations.AppendTranslate(x, y, z); 152 gfx::Transform expected; 153 expected.Translate3d(x, y, z); 154 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply()); 155} 156 157TEST(TransformOperationTest, ApplyRotate) { 158 double x = 1; 159 double y = 2; 160 double z = 3; 161 double degrees = 80; 162 TransformOperations operations; 163 operations.AppendRotate(x, y, z, degrees); 164 gfx::Transform expected; 165 expected.RotateAbout(gfx::Vector3dF(x, y, z), degrees); 166 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply()); 167} 168 169TEST(TransformOperationTest, ApplyScale) { 170 double x = 1; 171 double y = 2; 172 double z = 3; 173 TransformOperations operations; 174 operations.AppendScale(x, y, z); 175 gfx::Transform expected; 176 expected.Scale3d(x, y, z); 177 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply()); 178} 179 180TEST(TransformOperationTest, ApplySkew) { 181 double x = 1; 182 double y = 2; 183 TransformOperations operations; 184 operations.AppendSkew(x, y); 185 gfx::Transform expected; 186 expected.SkewX(x); 187 expected.SkewY(y); 188 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply()); 189} 190 191TEST(TransformOperationTest, ApplyPerspective) { 192 double depth = 800; 193 TransformOperations operations; 194 operations.AppendPerspective(depth); 195 gfx::Transform expected; 196 expected.ApplyPerspectiveDepth(depth); 197 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply()); 198} 199 200TEST(TransformOperationTest, ApplyMatrix) { 201 double dx = 1; 202 double dy = 2; 203 double dz = 3; 204 gfx::Transform expected_matrix; 205 expected_matrix.Translate3d(dx, dy, dz); 206 TransformOperations matrix_transform; 207 matrix_transform.AppendMatrix(expected_matrix); 208 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_matrix, matrix_transform.Apply()); 209} 210 211TEST(TransformOperationTest, ApplyOrder) { 212 double sx = 2; 213 double sy = 4; 214 double sz = 8; 215 216 double dx = 1; 217 double dy = 2; 218 double dz = 3; 219 220 TransformOperations operations; 221 operations.AppendScale(sx, sy, sz); 222 operations.AppendTranslate(dx, dy, dz); 223 224 gfx::Transform expected_scale_matrix; 225 expected_scale_matrix.Scale3d(sx, sy, sz); 226 227 gfx::Transform expected_translate_matrix; 228 expected_translate_matrix.Translate3d(dx, dy, dz); 229 230 gfx::Transform expected_combined_matrix = expected_scale_matrix; 231 expected_combined_matrix.PreconcatTransform(expected_translate_matrix); 232 233 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_combined_matrix, operations.Apply()); 234} 235 236TEST(TransformOperationTest, BlendOrder) { 237 double sx1 = 2; 238 double sy1 = 4; 239 double sz1 = 8; 240 241 double dx1 = 1; 242 double dy1 = 2; 243 double dz1 = 3; 244 245 double sx2 = 4; 246 double sy2 = 8; 247 double sz2 = 16; 248 249 double dx2 = 10; 250 double dy2 = 20; 251 double dz2 = 30; 252 253 TransformOperations operations_from; 254 operations_from.AppendScale(sx1, sy1, sz1); 255 operations_from.AppendTranslate(dx1, dy1, dz1); 256 257 TransformOperations operations_to; 258 operations_to.AppendScale(sx2, sy2, sz2); 259 operations_to.AppendTranslate(dx2, dy2, dz2); 260 261 gfx::Transform scale_from; 262 scale_from.Scale3d(sx1, sy1, sz1); 263 gfx::Transform translate_from; 264 translate_from.Translate3d(dx1, dy1, dz1); 265 266 gfx::Transform scale_to; 267 scale_to.Scale3d(sx2, sy2, sz2); 268 gfx::Transform translate_to; 269 translate_to.Translate3d(dx2, dy2, dz2); 270 271 double progress = 0.25; 272 273 gfx::Transform blended_scale = scale_to; 274 blended_scale.Blend(scale_from, progress); 275 276 gfx::Transform blended_translate = translate_to; 277 blended_translate.Blend(translate_from, progress); 278 279 gfx::Transform expected = blended_scale; 280 expected.PreconcatTransform(blended_translate); 281 282 EXPECT_TRANSFORMATION_MATRIX_EQ( 283 expected, operations_to.Blend(operations_from, progress)); 284} 285 286static void CheckProgress(double progress, 287 const gfx::Transform& from_matrix, 288 const gfx::Transform& to_matrix, 289 const TransformOperations& from_transform, 290 const TransformOperations& to_transform) { 291 gfx::Transform expected_matrix = to_matrix; 292 expected_matrix.Blend(from_matrix, progress); 293 EXPECT_TRANSFORMATION_MATRIX_EQ( 294 expected_matrix, to_transform.Blend(from_transform, progress)); 295} 296 297TEST(TransformOperationTest, BlendProgress) { 298 double sx = 2; 299 double sy = 4; 300 double sz = 8; 301 TransformOperations operations_from; 302 operations_from.AppendScale(sx, sy, sz); 303 304 gfx::Transform matrix_from; 305 matrix_from.Scale3d(sx, sy, sz); 306 307 sx = 4; 308 sy = 8; 309 sz = 16; 310 TransformOperations operations_to; 311 operations_to.AppendScale(sx, sy, sz); 312 313 gfx::Transform matrix_to; 314 matrix_to.Scale3d(sx, sy, sz); 315 316 CheckProgress(-1, matrix_from, matrix_to, operations_from, operations_to); 317 CheckProgress(0, matrix_from, matrix_to, operations_from, operations_to); 318 CheckProgress(0.25, matrix_from, matrix_to, operations_from, operations_to); 319 CheckProgress(0.5, matrix_from, matrix_to, operations_from, operations_to); 320 CheckProgress(1, matrix_from, matrix_to, operations_from, operations_to); 321 CheckProgress(2, matrix_from, matrix_to, operations_from, operations_to); 322} 323 324TEST(TransformOperationTest, BlendWhenTypesDoNotMatch) { 325 double sx1 = 2; 326 double sy1 = 4; 327 double sz1 = 8; 328 329 double dx1 = 1; 330 double dy1 = 2; 331 double dz1 = 3; 332 333 double sx2 = 4; 334 double sy2 = 8; 335 double sz2 = 16; 336 337 double dx2 = 10; 338 double dy2 = 20; 339 double dz2 = 30; 340 341 TransformOperations operations_from; 342 operations_from.AppendScale(sx1, sy1, sz1); 343 operations_from.AppendTranslate(dx1, dy1, dz1); 344 345 TransformOperations operations_to; 346 operations_to.AppendTranslate(dx2, dy2, dz2); 347 operations_to.AppendScale(sx2, sy2, sz2); 348 349 gfx::Transform from; 350 from.Scale3d(sx1, sy1, sz1); 351 from.Translate3d(dx1, dy1, dz1); 352 353 gfx::Transform to; 354 to.Translate3d(dx2, dy2, dz2); 355 to.Scale3d(sx2, sy2, sz2); 356 357 double progress = 0.25; 358 359 gfx::Transform expected = to; 360 expected.Blend(from, progress); 361 362 EXPECT_TRANSFORMATION_MATRIX_EQ( 363 expected, operations_to.Blend(operations_from, progress)); 364} 365 366TEST(TransformOperationTest, LargeRotationsWithSameAxis) { 367 TransformOperations operations_from; 368 operations_from.AppendRotate(0, 0, 1, 0); 369 370 TransformOperations operations_to; 371 operations_to.AppendRotate(0, 0, 2, 360); 372 373 double progress = 0.5; 374 375 gfx::Transform expected; 376 expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180); 377 378 EXPECT_TRANSFORMATION_MATRIX_EQ( 379 expected, operations_to.Blend(operations_from, progress)); 380} 381 382TEST(TransformOperationTest, LargeRotationsWithSameAxisInDifferentDirection) { 383 TransformOperations operations_from; 384 operations_from.AppendRotate(0, 0, 1, 180); 385 386 TransformOperations operations_to; 387 operations_to.AppendRotate(0, 0, -1, 180); 388 389 double progress = 0.5; 390 391 gfx::Transform expected; 392 393 EXPECT_TRANSFORMATION_MATRIX_EQ( 394 expected, operations_to.Blend(operations_from, progress)); 395} 396 397TEST(TransformOperationTest, LargeRotationsWithDifferentAxes) { 398 TransformOperations operations_from; 399 operations_from.AppendRotate(0, 0, 1, 175); 400 401 TransformOperations operations_to; 402 operations_to.AppendRotate(0, 1, 0, 175); 403 404 double progress = 0.5; 405 gfx::Transform matrix_from; 406 matrix_from.RotateAbout(gfx::Vector3dF(0, 0, 1), 175); 407 408 gfx::Transform matrix_to; 409 matrix_to.RotateAbout(gfx::Vector3dF(0, 1, 0), 175); 410 411 gfx::Transform expected = matrix_to; 412 expected.Blend(matrix_from, progress); 413 414 EXPECT_TRANSFORMATION_MATRIX_EQ( 415 expected, operations_to.Blend(operations_from, progress)); 416} 417 418TEST(TransformOperationTest, BlendRotationFromIdentity) { 419 ScopedVector<TransformOperations> identity_operations; 420 GetIdentityOperations(&identity_operations); 421 422 for (size_t i = 0; i < identity_operations.size(); ++i) { 423 TransformOperations operations; 424 operations.AppendRotate(0, 0, 1, 360); 425 426 double progress = 0.5; 427 428 gfx::Transform expected; 429 expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180); 430 431 EXPECT_TRANSFORMATION_MATRIX_EQ( 432 expected, operations.Blend(*identity_operations[i], progress)); 433 } 434} 435 436TEST(TransformOperationTest, BlendTranslationFromIdentity) { 437 ScopedVector<TransformOperations> identity_operations; 438 GetIdentityOperations(&identity_operations); 439 440 for (size_t i = 0; i < identity_operations.size(); ++i) { 441 TransformOperations operations; 442 operations.AppendTranslate(2, 2, 2); 443 444 double progress = 0.5; 445 446 gfx::Transform expected; 447 expected.Translate3d(1, 1, 1); 448 449 EXPECT_TRANSFORMATION_MATRIX_EQ( 450 expected, operations.Blend(*identity_operations[i], progress)); 451 } 452} 453 454TEST(TransformOperationTest, BlendScaleFromIdentity) { 455 ScopedVector<TransformOperations> identity_operations; 456 GetIdentityOperations(&identity_operations); 457 458 for (size_t i = 0; i < identity_operations.size(); ++i) { 459 TransformOperations operations; 460 operations.AppendScale(3, 3, 3); 461 462 double progress = 0.5; 463 464 gfx::Transform expected; 465 expected.Scale3d(2, 2, 2); 466 467 EXPECT_TRANSFORMATION_MATRIX_EQ( 468 expected, operations.Blend(*identity_operations[i], progress)); 469 } 470} 471 472TEST(TransformOperationTest, BlendSkewFromIdentity) { 473 ScopedVector<TransformOperations> identity_operations; 474 GetIdentityOperations(&identity_operations); 475 476 for (size_t i = 0; i < identity_operations.size(); ++i) { 477 TransformOperations operations; 478 operations.AppendSkew(2, 2); 479 480 double progress = 0.5; 481 482 gfx::Transform expected; 483 expected.SkewX(1); 484 expected.SkewY(1); 485 486 EXPECT_TRANSFORMATION_MATRIX_EQ( 487 expected, operations.Blend(*identity_operations[i], progress)); 488 } 489} 490 491TEST(TransformOperationTest, BlendPerspectiveFromIdentity) { 492 ScopedVector<TransformOperations> identity_operations; 493 GetIdentityOperations(&identity_operations); 494 495 for (size_t i = 0; i < identity_operations.size(); ++i) { 496 TransformOperations operations; 497 operations.AppendPerspective(1000); 498 499 double progress = 0.5; 500 501 gfx::Transform expected; 502 expected.ApplyPerspectiveDepth( 503 500 + 0.5 * std::numeric_limits<double>::max()); 504 505 EXPECT_TRANSFORMATION_MATRIX_EQ( 506 expected, operations.Blend(*identity_operations[i], progress)); 507 } 508} 509 510TEST(TransformOperationTest, BlendRotationToIdentity) { 511 ScopedVector<TransformOperations> identity_operations; 512 GetIdentityOperations(&identity_operations); 513 514 for (size_t i = 0; i < identity_operations.size(); ++i) { 515 TransformOperations operations; 516 operations.AppendRotate(0, 0, 1, 360); 517 518 double progress = 0.5; 519 520 gfx::Transform expected; 521 expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180); 522 523 EXPECT_TRANSFORMATION_MATRIX_EQ( 524 expected, identity_operations[i]->Blend(operations, progress)); 525 } 526} 527 528TEST(TransformOperationTest, BlendTranslationToIdentity) { 529 ScopedVector<TransformOperations> identity_operations; 530 GetIdentityOperations(&identity_operations); 531 532 for (size_t i = 0; i < identity_operations.size(); ++i) { 533 TransformOperations operations; 534 operations.AppendTranslate(2, 2, 2); 535 536 double progress = 0.5; 537 538 gfx::Transform expected; 539 expected.Translate3d(1, 1, 1); 540 541 EXPECT_TRANSFORMATION_MATRIX_EQ( 542 expected, identity_operations[i]->Blend(operations, progress)); 543 } 544} 545 546TEST(TransformOperationTest, BlendScaleToIdentity) { 547 ScopedVector<TransformOperations> identity_operations; 548 GetIdentityOperations(&identity_operations); 549 550 for (size_t i = 0; i < identity_operations.size(); ++i) { 551 TransformOperations operations; 552 operations.AppendScale(3, 3, 3); 553 554 double progress = 0.5; 555 556 gfx::Transform expected; 557 expected.Scale3d(2, 2, 2); 558 559 EXPECT_TRANSFORMATION_MATRIX_EQ( 560 expected, identity_operations[i]->Blend(operations, progress)); 561 } 562} 563 564TEST(TransformOperationTest, BlendSkewToIdentity) { 565 ScopedVector<TransformOperations> identity_operations; 566 GetIdentityOperations(&identity_operations); 567 568 for (size_t i = 0; i < identity_operations.size(); ++i) { 569 TransformOperations operations; 570 operations.AppendSkew(2, 2); 571 572 double progress = 0.5; 573 574 gfx::Transform expected; 575 expected.SkewX(1); 576 expected.SkewY(1); 577 578 EXPECT_TRANSFORMATION_MATRIX_EQ( 579 expected, identity_operations[i]->Blend(operations, progress)); 580 } 581} 582 583TEST(TransformOperationTest, BlendPerspectiveToIdentity) { 584 ScopedVector<TransformOperations> identity_operations; 585 GetIdentityOperations(&identity_operations); 586 587 for (size_t i = 0; i < identity_operations.size(); ++i) { 588 TransformOperations operations; 589 operations.AppendPerspective(1000); 590 591 double progress = 0.5; 592 593 gfx::Transform expected; 594 expected.ApplyPerspectiveDepth( 595 500 + 0.5 * std::numeric_limits<double>::max()); 596 597 EXPECT_TRANSFORMATION_MATRIX_EQ( 598 expected, identity_operations[i]->Blend(operations, progress)); 599 } 600} 601 602} // namespace 603} // namespace cc 604