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.
7 #include "base/memory/scoped_vector.h"
8 #include "cc/animation/transform_operations.h"
9 #include "cc/test/geometry_test_utils.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/gfx/vector3d_f.h"
16 TEST(TransformOperationTest
, TransformTypesAreUnique
) {
17 ScopedVector
<TransformOperations
> transforms
;
19 TransformOperations
* to_add
= new TransformOperations();
20 to_add
->AppendTranslate(1, 0, 0);
21 transforms
.push_back(to_add
);
23 to_add
= new TransformOperations();
24 to_add
->AppendRotate(0, 0, 1, 2);
25 transforms
.push_back(to_add
);
27 to_add
= new TransformOperations();
28 to_add
->AppendScale(2, 2, 2);
29 transforms
.push_back(to_add
);
31 to_add
= new TransformOperations();
32 to_add
->AppendSkew(1, 0);
33 transforms
.push_back(to_add
);
35 to_add
= new TransformOperations();
36 to_add
->AppendPerspective(800);
37 transforms
.push_back(to_add
);
39 for (size_t i
= 0; i
< transforms
.size(); ++i
) {
40 for (size_t j
= 0; j
< transforms
.size(); ++j
) {
41 bool matches_type
= transforms
[i
]->MatchesTypes(*transforms
[j
]);
42 EXPECT_TRUE((i
== j
&& matches_type
) || !matches_type
);
47 TEST(TransformOperationTest
, MatchTypesSameLength
) {
48 TransformOperations translates
;
49 translates
.AppendTranslate(1, 0, 0);
50 translates
.AppendTranslate(1, 0, 0);
51 translates
.AppendTranslate(1, 0, 0);
53 TransformOperations skews
;
54 skews
.AppendSkew(0, 2);
55 skews
.AppendSkew(0, 2);
56 skews
.AppendSkew(0, 2);
58 TransformOperations translates2
;
59 translates2
.AppendTranslate(0, 2, 0);
60 translates2
.AppendTranslate(0, 2, 0);
61 translates2
.AppendTranslate(0, 2, 0);
63 TransformOperations translates3
= translates2
;
65 EXPECT_FALSE(translates
.MatchesTypes(skews
));
66 EXPECT_TRUE(translates
.MatchesTypes(translates2
));
67 EXPECT_TRUE(translates
.MatchesTypes(translates3
));
70 TEST(TransformOperationTest
, MatchTypesDifferentLength
) {
71 TransformOperations translates
;
72 translates
.AppendTranslate(1, 0, 0);
73 translates
.AppendTranslate(1, 0, 0);
74 translates
.AppendTranslate(1, 0, 0);
76 TransformOperations skews
;
77 skews
.AppendSkew(2, 0);
78 skews
.AppendSkew(2, 0);
80 TransformOperations translates2
;
81 translates2
.AppendTranslate(0, 2, 0);
82 translates2
.AppendTranslate(0, 2, 0);
84 EXPECT_FALSE(translates
.MatchesTypes(skews
));
85 EXPECT_FALSE(translates
.MatchesTypes(translates2
));
88 void GetIdentityOperations(ScopedVector
<TransformOperations
>* operations
) {
89 TransformOperations
* to_add
= new TransformOperations();
90 operations
->push_back(to_add
);
92 to_add
= new TransformOperations();
93 to_add
->AppendTranslate(0, 0, 0);
94 operations
->push_back(to_add
);
96 to_add
= new TransformOperations();
97 to_add
->AppendTranslate(0, 0, 0);
98 to_add
->AppendTranslate(0, 0, 0);
99 operations
->push_back(to_add
);
101 to_add
= new TransformOperations();
102 to_add
->AppendScale(1, 1, 1);
103 operations
->push_back(to_add
);
105 to_add
= new TransformOperations();
106 to_add
->AppendScale(1, 1, 1);
107 to_add
->AppendScale(1, 1, 1);
108 operations
->push_back(to_add
);
110 to_add
= new TransformOperations();
111 to_add
->AppendSkew(0, 0);
112 operations
->push_back(to_add
);
114 to_add
= new TransformOperations();
115 to_add
->AppendSkew(0, 0);
116 to_add
->AppendSkew(0, 0);
117 operations
->push_back(to_add
);
119 to_add
= new TransformOperations();
120 to_add
->AppendRotate(0, 0, 1, 0);
121 operations
->push_back(to_add
);
123 to_add
= new TransformOperations();
124 to_add
->AppendRotate(0, 0, 1, 0);
125 to_add
->AppendRotate(0, 0, 1, 0);
126 operations
->push_back(to_add
);
128 to_add
= new TransformOperations();
129 to_add
->AppendMatrix(gfx::Transform());
130 operations
->push_back(to_add
);
132 to_add
= new TransformOperations();
133 to_add
->AppendMatrix(gfx::Transform());
134 to_add
->AppendMatrix(gfx::Transform());
135 operations
->push_back(to_add
);
138 TEST(TransformOperationTest
, IdentityAlwaysMatches
) {
139 ScopedVector
<TransformOperations
> operations
;
140 GetIdentityOperations(&operations
);
142 for (size_t i
= 0; i
< operations
.size(); ++i
) {
143 for (size_t j
= 0; j
< operations
.size(); ++j
)
144 EXPECT_TRUE(operations
[i
]->MatchesTypes(*operations
[j
]));
148 TEST(TransformOperationTest
, ApplyTranslate
) {
152 TransformOperations operations
;
153 operations
.AppendTranslate(x
, y
, z
);
154 gfx::Transform expected
;
155 expected
.Translate3d(x
, y
, z
);
156 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
159 TEST(TransformOperationTest
, ApplyRotate
) {
164 TransformOperations operations
;
165 operations
.AppendRotate(x
, y
, z
, degrees
);
166 gfx::Transform expected
;
167 expected
.RotateAbout(gfx::Vector3dF(x
, y
, z
), degrees
);
168 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
171 TEST(TransformOperationTest
, ApplyScale
) {
175 TransformOperations operations
;
176 operations
.AppendScale(x
, y
, z
);
177 gfx::Transform expected
;
178 expected
.Scale3d(x
, y
, z
);
179 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
182 TEST(TransformOperationTest
, ApplySkew
) {
185 TransformOperations operations
;
186 operations
.AppendSkew(x
, y
);
187 gfx::Transform expected
;
190 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
193 TEST(TransformOperationTest
, ApplyPerspective
) {
195 TransformOperations operations
;
196 operations
.AppendPerspective(depth
);
197 gfx::Transform expected
;
198 expected
.ApplyPerspectiveDepth(depth
);
199 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
202 TEST(TransformOperationTest
, ApplyMatrix
) {
206 gfx::Transform expected_matrix
;
207 expected_matrix
.Translate3d(dx
, dy
, dz
);
208 TransformOperations matrix_transform
;
209 matrix_transform
.AppendMatrix(expected_matrix
);
210 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_matrix
, matrix_transform
.Apply());
213 TEST(TransformOperationTest
, ApplyOrder
) {
222 TransformOperations operations
;
223 operations
.AppendScale(sx
, sy
, sz
);
224 operations
.AppendTranslate(dx
, dy
, dz
);
226 gfx::Transform expected_scale_matrix
;
227 expected_scale_matrix
.Scale3d(sx
, sy
, sz
);
229 gfx::Transform expected_translate_matrix
;
230 expected_translate_matrix
.Translate3d(dx
, dy
, dz
);
232 gfx::Transform expected_combined_matrix
= expected_scale_matrix
;
233 expected_combined_matrix
.PreconcatTransform(expected_translate_matrix
);
235 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_combined_matrix
, operations
.Apply());
238 TEST(TransformOperationTest
, BlendOrder
) {
255 TransformOperations operations_from
;
256 operations_from
.AppendScale(sx1
, sy1
, sz1
);
257 operations_from
.AppendTranslate(dx1
, dy1
, dz1
);
259 TransformOperations operations_to
;
260 operations_to
.AppendScale(sx2
, sy2
, sz2
);
261 operations_to
.AppendTranslate(dx2
, dy2
, dz2
);
263 gfx::Transform scale_from
;
264 scale_from
.Scale3d(sx1
, sy1
, sz1
);
265 gfx::Transform translate_from
;
266 translate_from
.Translate3d(dx1
, dy1
, dz1
);
268 gfx::Transform scale_to
;
269 scale_to
.Scale3d(sx2
, sy2
, sz2
);
270 gfx::Transform translate_to
;
271 translate_to
.Translate3d(dx2
, dy2
, dz2
);
273 double progress
= 0.25;
275 gfx::Transform blended_scale
= scale_to
;
276 blended_scale
.Blend(scale_from
, progress
);
278 gfx::Transform blended_translate
= translate_to
;
279 blended_translate
.Blend(translate_from
, progress
);
281 gfx::Transform expected
= blended_scale
;
282 expected
.PreconcatTransform(blended_translate
);
284 EXPECT_TRANSFORMATION_MATRIX_EQ(
285 expected
, operations_to
.Blend(operations_from
, progress
));
288 static void CheckProgress(double progress
,
289 const gfx::Transform
& from_matrix
,
290 const gfx::Transform
& to_matrix
,
291 const TransformOperations
& from_transform
,
292 const TransformOperations
& to_transform
) {
293 gfx::Transform expected_matrix
= to_matrix
;
294 expected_matrix
.Blend(from_matrix
, progress
);
295 EXPECT_TRANSFORMATION_MATRIX_EQ(
296 expected_matrix
, to_transform
.Blend(from_transform
, progress
));
299 TEST(TransformOperationTest
, BlendProgress
) {
303 TransformOperations operations_from
;
304 operations_from
.AppendScale(sx
, sy
, sz
);
306 gfx::Transform matrix_from
;
307 matrix_from
.Scale3d(sx
, sy
, sz
);
312 TransformOperations operations_to
;
313 operations_to
.AppendScale(sx
, sy
, sz
);
315 gfx::Transform matrix_to
;
316 matrix_to
.Scale3d(sx
, sy
, sz
);
318 CheckProgress(-1, matrix_from
, matrix_to
, operations_from
, operations_to
);
319 CheckProgress(0, matrix_from
, matrix_to
, operations_from
, operations_to
);
320 CheckProgress(0.25, matrix_from
, matrix_to
, operations_from
, operations_to
);
321 CheckProgress(0.5, matrix_from
, matrix_to
, operations_from
, operations_to
);
322 CheckProgress(1, matrix_from
, matrix_to
, operations_from
, operations_to
);
323 CheckProgress(2, matrix_from
, matrix_to
, operations_from
, operations_to
);
326 TEST(TransformOperationTest
, BlendWhenTypesDoNotMatch
) {
343 TransformOperations operations_from
;
344 operations_from
.AppendScale(sx1
, sy1
, sz1
);
345 operations_from
.AppendTranslate(dx1
, dy1
, dz1
);
347 TransformOperations operations_to
;
348 operations_to
.AppendTranslate(dx2
, dy2
, dz2
);
349 operations_to
.AppendScale(sx2
, sy2
, sz2
);
352 from
.Scale3d(sx1
, sy1
, sz1
);
353 from
.Translate3d(dx1
, dy1
, dz1
);
356 to
.Translate3d(dx2
, dy2
, dz2
);
357 to
.Scale3d(sx2
, sy2
, sz2
);
359 double progress
= 0.25;
361 gfx::Transform expected
= to
;
362 expected
.Blend(from
, progress
);
364 EXPECT_TRANSFORMATION_MATRIX_EQ(
365 expected
, operations_to
.Blend(operations_from
, progress
));
368 TEST(TransformOperationTest
, LargeRotationsWithSameAxis
) {
369 TransformOperations operations_from
;
370 operations_from
.AppendRotate(0, 0, 1, 0);
372 TransformOperations operations_to
;
373 operations_to
.AppendRotate(0, 0, 2, 360);
375 double progress
= 0.5;
377 gfx::Transform expected
;
378 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
380 EXPECT_TRANSFORMATION_MATRIX_EQ(
381 expected
, operations_to
.Blend(operations_from
, progress
));
384 TEST(TransformOperationTest
, LargeRotationsWithSameAxisInDifferentDirection
) {
385 TransformOperations operations_from
;
386 operations_from
.AppendRotate(0, 0, 1, 180);
388 TransformOperations operations_to
;
389 operations_to
.AppendRotate(0, 0, -1, 180);
391 double progress
= 0.5;
393 gfx::Transform expected
;
395 EXPECT_TRANSFORMATION_MATRIX_EQ(
396 expected
, operations_to
.Blend(operations_from
, progress
));
399 TEST(TransformOperationTest
, LargeRotationsWithDifferentAxes
) {
400 TransformOperations operations_from
;
401 operations_from
.AppendRotate(0, 0, 1, 175);
403 TransformOperations operations_to
;
404 operations_to
.AppendRotate(0, 1, 0, 175);
406 double progress
= 0.5;
407 gfx::Transform matrix_from
;
408 matrix_from
.RotateAbout(gfx::Vector3dF(0, 0, 1), 175);
410 gfx::Transform matrix_to
;
411 matrix_to
.RotateAbout(gfx::Vector3dF(0, 1, 0), 175);
413 gfx::Transform expected
= matrix_to
;
414 expected
.Blend(matrix_from
, progress
);
416 EXPECT_TRANSFORMATION_MATRIX_EQ(
417 expected
, operations_to
.Blend(operations_from
, progress
));
420 TEST(TransformOperationTest
, BlendRotationFromIdentity
) {
421 ScopedVector
<TransformOperations
> identity_operations
;
422 GetIdentityOperations(&identity_operations
);
424 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
425 TransformOperations operations
;
426 operations
.AppendRotate(0, 0, 1, 360);
428 double progress
= 0.5;
430 gfx::Transform expected
;
431 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
433 EXPECT_TRANSFORMATION_MATRIX_EQ(
434 expected
, operations
.Blend(*identity_operations
[i
], progress
));
438 TEST(TransformOperationTest
, BlendTranslationFromIdentity
) {
439 ScopedVector
<TransformOperations
> identity_operations
;
440 GetIdentityOperations(&identity_operations
);
442 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
443 TransformOperations operations
;
444 operations
.AppendTranslate(2, 2, 2);
446 double progress
= 0.5;
448 gfx::Transform expected
;
449 expected
.Translate3d(1, 1, 1);
451 EXPECT_TRANSFORMATION_MATRIX_EQ(
452 expected
, operations
.Blend(*identity_operations
[i
], progress
));
456 TEST(TransformOperationTest
, BlendScaleFromIdentity
) {
457 ScopedVector
<TransformOperations
> identity_operations
;
458 GetIdentityOperations(&identity_operations
);
460 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
461 TransformOperations operations
;
462 operations
.AppendScale(3, 3, 3);
464 double progress
= 0.5;
466 gfx::Transform expected
;
467 expected
.Scale3d(2, 2, 2);
469 EXPECT_TRANSFORMATION_MATRIX_EQ(
470 expected
, operations
.Blend(*identity_operations
[i
], progress
));
474 TEST(TransformOperationTest
, BlendSkewFromIdentity
) {
475 ScopedVector
<TransformOperations
> identity_operations
;
476 GetIdentityOperations(&identity_operations
);
478 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
479 TransformOperations operations
;
480 operations
.AppendSkew(2, 2);
482 double progress
= 0.5;
484 gfx::Transform expected
;
488 EXPECT_TRANSFORMATION_MATRIX_EQ(
489 expected
, operations
.Blend(*identity_operations
[i
], progress
));
493 TEST(TransformOperationTest
, BlendPerspectiveFromIdentity
) {
494 ScopedVector
<TransformOperations
> identity_operations
;
495 GetIdentityOperations(&identity_operations
);
497 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
498 TransformOperations operations
;
499 operations
.AppendPerspective(1000);
501 double progress
= 0.5;
503 gfx::Transform expected
;
504 expected
.ApplyPerspectiveDepth(
505 500 + 0.5 * std::numeric_limits
<double>::max());
507 EXPECT_TRANSFORMATION_MATRIX_EQ(
508 expected
, operations
.Blend(*identity_operations
[i
], progress
));
512 TEST(TransformOperationTest
, BlendRotationToIdentity
) {
513 ScopedVector
<TransformOperations
> identity_operations
;
514 GetIdentityOperations(&identity_operations
);
516 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
517 TransformOperations operations
;
518 operations
.AppendRotate(0, 0, 1, 360);
520 double progress
= 0.5;
522 gfx::Transform expected
;
523 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
525 EXPECT_TRANSFORMATION_MATRIX_EQ(
526 expected
, identity_operations
[i
]->Blend(operations
, progress
));
530 TEST(TransformOperationTest
, BlendTranslationToIdentity
) {
531 ScopedVector
<TransformOperations
> identity_operations
;
532 GetIdentityOperations(&identity_operations
);
534 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
535 TransformOperations operations
;
536 operations
.AppendTranslate(2, 2, 2);
538 double progress
= 0.5;
540 gfx::Transform expected
;
541 expected
.Translate3d(1, 1, 1);
543 EXPECT_TRANSFORMATION_MATRIX_EQ(
544 expected
, identity_operations
[i
]->Blend(operations
, progress
));
548 TEST(TransformOperationTest
, BlendScaleToIdentity
) {
549 ScopedVector
<TransformOperations
> identity_operations
;
550 GetIdentityOperations(&identity_operations
);
552 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
553 TransformOperations operations
;
554 operations
.AppendScale(3, 3, 3);
556 double progress
= 0.5;
558 gfx::Transform expected
;
559 expected
.Scale3d(2, 2, 2);
561 EXPECT_TRANSFORMATION_MATRIX_EQ(
562 expected
, identity_operations
[i
]->Blend(operations
, progress
));
566 TEST(TransformOperationTest
, BlendSkewToIdentity
) {
567 ScopedVector
<TransformOperations
> identity_operations
;
568 GetIdentityOperations(&identity_operations
);
570 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
571 TransformOperations operations
;
572 operations
.AppendSkew(2, 2);
574 double progress
= 0.5;
576 gfx::Transform expected
;
580 EXPECT_TRANSFORMATION_MATRIX_EQ(
581 expected
, identity_operations
[i
]->Blend(operations
, progress
));
585 TEST(TransformOperationTest
, BlendPerspectiveToIdentity
) {
586 ScopedVector
<TransformOperations
> identity_operations
;
587 GetIdentityOperations(&identity_operations
);
589 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
590 TransformOperations operations
;
591 operations
.AppendPerspective(1000);
593 double progress
= 0.5;
595 gfx::Transform expected
;
596 expected
.ApplyPerspectiveDepth(
597 500 + 0.5 * std::numeric_limits
<double>::max());
599 EXPECT_TRANSFORMATION_MATRIX_EQ(
600 expected
, identity_operations
[i
]->Blend(operations
, progress
));