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/basictypes.h"
8 #include "base/memory/scoped_vector.h"
9 #include "cc/animation/transform_operations.h"
10 #include "cc/test/geometry_test_utils.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/gfx/animation/tween.h"
13 #include "ui/gfx/geometry/box_f.h"
14 #include "ui/gfx/geometry/rect_conversions.h"
15 #include "ui/gfx/geometry/vector3d_f.h"
20 TEST(TransformOperationTest
, TransformTypesAreUnique
) {
21 ScopedVector
<TransformOperations
> transforms
;
23 TransformOperations
* to_add
= new TransformOperations();
24 to_add
->AppendTranslate(1, 0, 0);
25 transforms
.push_back(to_add
);
27 to_add
= new TransformOperations();
28 to_add
->AppendRotate(0, 0, 1, 2);
29 transforms
.push_back(to_add
);
31 to_add
= new TransformOperations();
32 to_add
->AppendScale(2, 2, 2);
33 transforms
.push_back(to_add
);
35 to_add
= new TransformOperations();
36 to_add
->AppendSkew(1, 0);
37 transforms
.push_back(to_add
);
39 to_add
= new TransformOperations();
40 to_add
->AppendPerspective(800);
41 transforms
.push_back(to_add
);
43 for (size_t i
= 0; i
< transforms
.size(); ++i
) {
44 for (size_t j
= 0; j
< transforms
.size(); ++j
) {
45 bool matches_type
= transforms
[i
]->MatchesTypes(*transforms
[j
]);
46 EXPECT_TRUE((i
== j
&& matches_type
) || !matches_type
);
51 TEST(TransformOperationTest
, MatchTypesSameLength
) {
52 TransformOperations translates
;
53 translates
.AppendTranslate(1, 0, 0);
54 translates
.AppendTranslate(1, 0, 0);
55 translates
.AppendTranslate(1, 0, 0);
57 TransformOperations skews
;
58 skews
.AppendSkew(0, 2);
59 skews
.AppendSkew(0, 2);
60 skews
.AppendSkew(0, 2);
62 TransformOperations translates2
;
63 translates2
.AppendTranslate(0, 2, 0);
64 translates2
.AppendTranslate(0, 2, 0);
65 translates2
.AppendTranslate(0, 2, 0);
67 TransformOperations translates3
= translates2
;
69 EXPECT_FALSE(translates
.MatchesTypes(skews
));
70 EXPECT_TRUE(translates
.MatchesTypes(translates2
));
71 EXPECT_TRUE(translates
.MatchesTypes(translates3
));
74 TEST(TransformOperationTest
, MatchTypesDifferentLength
) {
75 TransformOperations translates
;
76 translates
.AppendTranslate(1, 0, 0);
77 translates
.AppendTranslate(1, 0, 0);
78 translates
.AppendTranslate(1, 0, 0);
80 TransformOperations skews
;
81 skews
.AppendSkew(2, 0);
82 skews
.AppendSkew(2, 0);
84 TransformOperations translates2
;
85 translates2
.AppendTranslate(0, 2, 0);
86 translates2
.AppendTranslate(0, 2, 0);
88 EXPECT_FALSE(translates
.MatchesTypes(skews
));
89 EXPECT_FALSE(translates
.MatchesTypes(translates2
));
92 void GetIdentityOperations(ScopedVector
<TransformOperations
>* operations
) {
93 TransformOperations
* to_add
= new TransformOperations();
94 operations
->push_back(to_add
);
96 to_add
= new TransformOperations();
97 to_add
->AppendTranslate(0, 0, 0);
98 operations
->push_back(to_add
);
100 to_add
= new TransformOperations();
101 to_add
->AppendTranslate(0, 0, 0);
102 to_add
->AppendTranslate(0, 0, 0);
103 operations
->push_back(to_add
);
105 to_add
= new TransformOperations();
106 to_add
->AppendScale(1, 1, 1);
107 operations
->push_back(to_add
);
109 to_add
= new TransformOperations();
110 to_add
->AppendScale(1, 1, 1);
111 to_add
->AppendScale(1, 1, 1);
112 operations
->push_back(to_add
);
114 to_add
= new TransformOperations();
115 to_add
->AppendSkew(0, 0);
116 operations
->push_back(to_add
);
118 to_add
= new TransformOperations();
119 to_add
->AppendSkew(0, 0);
120 to_add
->AppendSkew(0, 0);
121 operations
->push_back(to_add
);
123 to_add
= new TransformOperations();
124 to_add
->AppendRotate(0, 0, 1, 0);
125 operations
->push_back(to_add
);
127 to_add
= new TransformOperations();
128 to_add
->AppendRotate(0, 0, 1, 0);
129 to_add
->AppendRotate(0, 0, 1, 0);
130 operations
->push_back(to_add
);
132 to_add
= new TransformOperations();
133 to_add
->AppendMatrix(gfx::Transform());
134 operations
->push_back(to_add
);
136 to_add
= new TransformOperations();
137 to_add
->AppendMatrix(gfx::Transform());
138 to_add
->AppendMatrix(gfx::Transform());
139 operations
->push_back(to_add
);
142 TEST(TransformOperationTest
, MatchTypesOrder
) {
143 TransformOperations mix_order_identity
;
144 mix_order_identity
.AppendTranslate(0, 0, 0);
145 mix_order_identity
.AppendScale(1, 1, 1);
146 mix_order_identity
.AppendTranslate(0, 0, 0);
148 TransformOperations mix_order_one
;
149 mix_order_one
.AppendTranslate(0, 1, 0);
150 mix_order_one
.AppendScale(2, 1, 3);
151 mix_order_one
.AppendTranslate(1, 0, 0);
153 TransformOperations mix_order_two
;
154 mix_order_two
.AppendTranslate(0, 1, 0);
155 mix_order_two
.AppendTranslate(1, 0, 0);
156 mix_order_two
.AppendScale(2, 1, 3);
158 EXPECT_TRUE(mix_order_identity
.MatchesTypes(mix_order_one
));
159 EXPECT_FALSE(mix_order_identity
.MatchesTypes(mix_order_two
));
160 EXPECT_FALSE(mix_order_one
.MatchesTypes(mix_order_two
));
163 TEST(TransformOperationTest
, NoneAlwaysMatches
) {
164 ScopedVector
<TransformOperations
> operations
;
165 GetIdentityOperations(&operations
);
167 TransformOperations none_operation
;
168 for (size_t i
= 0; i
< operations
.size(); ++i
)
169 EXPECT_TRUE(operations
[i
]->MatchesTypes(none_operation
));
172 TEST(TransformOperationTest
, ApplyTranslate
) {
176 TransformOperations operations
;
177 operations
.AppendTranslate(x
, y
, z
);
178 gfx::Transform expected
;
179 expected
.Translate3d(x
, y
, z
);
180 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
183 TEST(TransformOperationTest
, ApplyRotate
) {
187 SkMScalar degrees
= 80;
188 TransformOperations operations
;
189 operations
.AppendRotate(x
, y
, z
, degrees
);
190 gfx::Transform expected
;
191 expected
.RotateAbout(gfx::Vector3dF(x
, y
, z
), degrees
);
192 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
195 TEST(TransformOperationTest
, ApplyScale
) {
199 TransformOperations operations
;
200 operations
.AppendScale(x
, y
, z
);
201 gfx::Transform expected
;
202 expected
.Scale3d(x
, y
, z
);
203 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
206 TEST(TransformOperationTest
, ApplySkew
) {
209 TransformOperations operations
;
210 operations
.AppendSkew(x
, y
);
211 gfx::Transform expected
;
214 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
217 TEST(TransformOperationTest
, ApplyPerspective
) {
218 SkMScalar depth
= 800;
219 TransformOperations operations
;
220 operations
.AppendPerspective(depth
);
221 gfx::Transform expected
;
222 expected
.ApplyPerspectiveDepth(depth
);
223 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
226 TEST(TransformOperationTest
, ApplyMatrix
) {
230 gfx::Transform expected_matrix
;
231 expected_matrix
.Translate3d(dx
, dy
, dz
);
232 TransformOperations matrix_transform
;
233 matrix_transform
.AppendMatrix(expected_matrix
);
234 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_matrix
, matrix_transform
.Apply());
237 TEST(TransformOperationTest
, ApplyOrder
) {
246 TransformOperations operations
;
247 operations
.AppendScale(sx
, sy
, sz
);
248 operations
.AppendTranslate(dx
, dy
, dz
);
250 gfx::Transform expected_scale_matrix
;
251 expected_scale_matrix
.Scale3d(sx
, sy
, sz
);
253 gfx::Transform expected_translate_matrix
;
254 expected_translate_matrix
.Translate3d(dx
, dy
, dz
);
256 gfx::Transform expected_combined_matrix
= expected_scale_matrix
;
257 expected_combined_matrix
.PreconcatTransform(expected_translate_matrix
);
259 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_combined_matrix
, operations
.Apply());
262 TEST(TransformOperationTest
, BlendOrder
) {
279 TransformOperations operations_from
;
280 operations_from
.AppendScale(sx1
, sy1
, sz1
);
281 operations_from
.AppendTranslate(dx1
, dy1
, dz1
);
283 TransformOperations operations_to
;
284 operations_to
.AppendScale(sx2
, sy2
, sz2
);
285 operations_to
.AppendTranslate(dx2
, dy2
, dz2
);
287 gfx::Transform scale_from
;
288 scale_from
.Scale3d(sx1
, sy1
, sz1
);
289 gfx::Transform translate_from
;
290 translate_from
.Translate3d(dx1
, dy1
, dz1
);
292 gfx::Transform scale_to
;
293 scale_to
.Scale3d(sx2
, sy2
, sz2
);
294 gfx::Transform translate_to
;
295 translate_to
.Translate3d(dx2
, dy2
, dz2
);
297 SkMScalar progress
= 0.25f
;
299 gfx::Transform blended_scale
= scale_to
;
300 blended_scale
.Blend(scale_from
, progress
);
302 gfx::Transform blended_translate
= translate_to
;
303 blended_translate
.Blend(translate_from
, progress
);
305 gfx::Transform expected
= blended_scale
;
306 expected
.PreconcatTransform(blended_translate
);
308 EXPECT_TRANSFORMATION_MATRIX_EQ(
309 expected
, operations_to
.Blend(operations_from
, progress
));
312 static void CheckProgress(SkMScalar progress
,
313 const gfx::Transform
& from_matrix
,
314 const gfx::Transform
& to_matrix
,
315 const TransformOperations
& from_transform
,
316 const TransformOperations
& to_transform
) {
317 gfx::Transform expected_matrix
= to_matrix
;
318 expected_matrix
.Blend(from_matrix
, progress
);
319 EXPECT_TRANSFORMATION_MATRIX_EQ(
320 expected_matrix
, to_transform
.Blend(from_transform
, progress
));
323 TEST(TransformOperationTest
, BlendProgress
) {
327 TransformOperations operations_from
;
328 operations_from
.AppendScale(sx
, sy
, sz
);
330 gfx::Transform matrix_from
;
331 matrix_from
.Scale3d(sx
, sy
, sz
);
336 TransformOperations operations_to
;
337 operations_to
.AppendScale(sx
, sy
, sz
);
339 gfx::Transform matrix_to
;
340 matrix_to
.Scale3d(sx
, sy
, sz
);
342 CheckProgress(-1, matrix_from
, matrix_to
, operations_from
, operations_to
);
343 CheckProgress(0, matrix_from
, matrix_to
, operations_from
, operations_to
);
344 CheckProgress(0.25f
, matrix_from
, matrix_to
, operations_from
, operations_to
);
345 CheckProgress(0.5f
, matrix_from
, matrix_to
, operations_from
, operations_to
);
346 CheckProgress(1, matrix_from
, matrix_to
, operations_from
, operations_to
);
347 CheckProgress(2, matrix_from
, matrix_to
, operations_from
, operations_to
);
350 TEST(TransformOperationTest
, BlendWhenTypesDoNotMatch
) {
367 TransformOperations operations_from
;
368 operations_from
.AppendScale(sx1
, sy1
, sz1
);
369 operations_from
.AppendTranslate(dx1
, dy1
, dz1
);
371 TransformOperations operations_to
;
372 operations_to
.AppendTranslate(dx2
, dy2
, dz2
);
373 operations_to
.AppendScale(sx2
, sy2
, sz2
);
376 from
.Scale3d(sx1
, sy1
, sz1
);
377 from
.Translate3d(dx1
, dy1
, dz1
);
380 to
.Translate3d(dx2
, dy2
, dz2
);
381 to
.Scale3d(sx2
, sy2
, sz2
);
383 SkMScalar progress
= 0.25f
;
385 gfx::Transform expected
= to
;
386 expected
.Blend(from
, progress
);
388 EXPECT_TRANSFORMATION_MATRIX_EQ(
389 expected
, operations_to
.Blend(operations_from
, progress
));
392 TEST(TransformOperationTest
, LargeRotationsWithSameAxis
) {
393 TransformOperations operations_from
;
394 operations_from
.AppendRotate(0, 0, 1, 0);
396 TransformOperations operations_to
;
397 operations_to
.AppendRotate(0, 0, 2, 360);
399 SkMScalar progress
= 0.5f
;
401 gfx::Transform expected
;
402 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
404 EXPECT_TRANSFORMATION_MATRIX_EQ(
405 expected
, operations_to
.Blend(operations_from
, progress
));
408 TEST(TransformOperationTest
, LargeRotationsWithSameAxisInDifferentDirection
) {
409 TransformOperations operations_from
;
410 operations_from
.AppendRotate(0, 0, 1, 180);
412 TransformOperations operations_to
;
413 operations_to
.AppendRotate(0, 0, -1, 180);
415 SkMScalar progress
= 0.5f
;
417 gfx::Transform expected
;
419 EXPECT_TRANSFORMATION_MATRIX_EQ(
420 expected
, operations_to
.Blend(operations_from
, progress
));
423 TEST(TransformOperationTest
, LargeRotationsWithDifferentAxes
) {
424 TransformOperations operations_from
;
425 operations_from
.AppendRotate(0, 0, 1, 175);
427 TransformOperations operations_to
;
428 operations_to
.AppendRotate(0, 1, 0, 175);
430 SkMScalar progress
= 0.5f
;
431 gfx::Transform matrix_from
;
432 matrix_from
.RotateAbout(gfx::Vector3dF(0, 0, 1), 175);
434 gfx::Transform matrix_to
;
435 matrix_to
.RotateAbout(gfx::Vector3dF(0, 1, 0), 175);
437 gfx::Transform expected
= matrix_to
;
438 expected
.Blend(matrix_from
, progress
);
440 EXPECT_TRANSFORMATION_MATRIX_EQ(
441 expected
, operations_to
.Blend(operations_from
, progress
));
444 TEST(TransformOperationTest
, BlendRotationFromIdentity
) {
445 ScopedVector
<TransformOperations
> identity_operations
;
446 GetIdentityOperations(&identity_operations
);
448 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
449 TransformOperations operations
;
450 operations
.AppendRotate(0, 0, 1, 90);
452 SkMScalar progress
= 0.5f
;
454 gfx::Transform expected
;
455 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 45);
457 EXPECT_TRANSFORMATION_MATRIX_EQ(
458 expected
, operations
.Blend(*identity_operations
[i
], progress
));
462 expected
.MakeIdentity();
463 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), -45);
465 EXPECT_TRANSFORMATION_MATRIX_EQ(
466 expected
, operations
.Blend(*identity_operations
[i
], progress
));
470 expected
.MakeIdentity();
471 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 135);
473 EXPECT_TRANSFORMATION_MATRIX_EQ(
474 expected
, operations
.Blend(*identity_operations
[i
], progress
));
478 TEST(TransformOperationTest
, BlendTranslationFromIdentity
) {
479 ScopedVector
<TransformOperations
> identity_operations
;
480 GetIdentityOperations(&identity_operations
);
482 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
483 TransformOperations operations
;
484 operations
.AppendTranslate(2, 2, 2);
486 SkMScalar progress
= 0.5f
;
488 gfx::Transform expected
;
489 expected
.Translate3d(1, 1, 1);
491 EXPECT_TRANSFORMATION_MATRIX_EQ(
492 expected
, operations
.Blend(*identity_operations
[i
], progress
));
496 expected
.MakeIdentity();
497 expected
.Translate3d(-1, -1, -1);
499 EXPECT_TRANSFORMATION_MATRIX_EQ(
500 expected
, operations
.Blend(*identity_operations
[i
], progress
));
504 expected
.MakeIdentity();
505 expected
.Translate3d(3, 3, 3);
507 EXPECT_TRANSFORMATION_MATRIX_EQ(
508 expected
, operations
.Blend(*identity_operations
[i
], progress
));
512 TEST(TransformOperationTest
, BlendScaleFromIdentity
) {
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
.AppendScale(3, 3, 3);
520 SkMScalar progress
= 0.5f
;
522 gfx::Transform expected
;
523 expected
.Scale3d(2, 2, 2);
525 EXPECT_TRANSFORMATION_MATRIX_EQ(
526 expected
, operations
.Blend(*identity_operations
[i
], progress
));
530 expected
.MakeIdentity();
531 expected
.Scale3d(0, 0, 0);
533 EXPECT_TRANSFORMATION_MATRIX_EQ(
534 expected
, operations
.Blend(*identity_operations
[i
], progress
));
538 expected
.MakeIdentity();
539 expected
.Scale3d(4, 4, 4);
541 EXPECT_TRANSFORMATION_MATRIX_EQ(
542 expected
, operations
.Blend(*identity_operations
[i
], progress
));
546 TEST(TransformOperationTest
, BlendSkewFromEmpty
) {
547 TransformOperations empty_operation
;
549 TransformOperations operations
;
550 operations
.AppendSkew(2, 2);
552 SkMScalar progress
= 0.5f
;
554 gfx::Transform expected
;
558 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
,
559 operations
.Blend(empty_operation
, progress
));
563 expected
.MakeIdentity();
567 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
,
568 operations
.Blend(empty_operation
, progress
));
572 expected
.MakeIdentity();
576 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
,
577 operations
.Blend(empty_operation
, progress
));
580 TEST(TransformOperationTest
, BlendPerspectiveFromIdentity
) {
581 ScopedVector
<TransformOperations
> identity_operations
;
582 GetIdentityOperations(&identity_operations
);
584 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
585 TransformOperations operations
;
586 operations
.AppendPerspective(1000);
588 SkMScalar progress
= 0.5f
;
590 gfx::Transform expected
;
591 expected
.ApplyPerspectiveDepth(2000);
593 EXPECT_TRANSFORMATION_MATRIX_EQ(
594 expected
, operations
.Blend(*identity_operations
[i
], progress
));
598 TEST(TransformOperationTest
, BlendRotationToIdentity
) {
599 ScopedVector
<TransformOperations
> identity_operations
;
600 GetIdentityOperations(&identity_operations
);
602 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
603 TransformOperations operations
;
604 operations
.AppendRotate(0, 0, 1, 90);
606 SkMScalar progress
= 0.5f
;
608 gfx::Transform expected
;
609 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 45);
611 EXPECT_TRANSFORMATION_MATRIX_EQ(
612 expected
, identity_operations
[i
]->Blend(operations
, progress
));
616 TEST(TransformOperationTest
, BlendTranslationToIdentity
) {
617 ScopedVector
<TransformOperations
> identity_operations
;
618 GetIdentityOperations(&identity_operations
);
620 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
621 TransformOperations operations
;
622 operations
.AppendTranslate(2, 2, 2);
624 SkMScalar progress
= 0.5f
;
626 gfx::Transform expected
;
627 expected
.Translate3d(1, 1, 1);
629 EXPECT_TRANSFORMATION_MATRIX_EQ(
630 expected
, identity_operations
[i
]->Blend(operations
, progress
));
634 TEST(TransformOperationTest
, BlendScaleToIdentity
) {
635 ScopedVector
<TransformOperations
> identity_operations
;
636 GetIdentityOperations(&identity_operations
);
638 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
639 TransformOperations operations
;
640 operations
.AppendScale(3, 3, 3);
642 SkMScalar progress
= 0.5f
;
644 gfx::Transform expected
;
645 expected
.Scale3d(2, 2, 2);
647 EXPECT_TRANSFORMATION_MATRIX_EQ(
648 expected
, identity_operations
[i
]->Blend(operations
, progress
));
652 TEST(TransformOperationTest
, BlendSkewToEmpty
) {
653 TransformOperations empty_operation
;
655 TransformOperations operations
;
656 operations
.AppendSkew(2, 2);
658 SkMScalar progress
= 0.5f
;
660 gfx::Transform expected
;
664 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
,
665 empty_operation
.Blend(operations
, progress
));
668 TEST(TransformOperationTest
, BlendPerspectiveToIdentity
) {
669 ScopedVector
<TransformOperations
> identity_operations
;
670 GetIdentityOperations(&identity_operations
);
672 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
673 TransformOperations operations
;
674 operations
.AppendPerspective(1000);
676 SkMScalar progress
= 0.5f
;
678 gfx::Transform expected
;
679 expected
.ApplyPerspectiveDepth(2000);
681 EXPECT_TRANSFORMATION_MATRIX_EQ(
682 expected
, identity_operations
[i
]->Blend(operations
, progress
));
686 TEST(TransformOperationTest
, ExtrapolatePerspectiveBlending
) {
687 TransformOperations operations1
;
688 operations1
.AppendPerspective(1000);
690 TransformOperations operations2
;
691 operations2
.AppendPerspective(500);
693 gfx::Transform expected
;
694 expected
.ApplyPerspectiveDepth(400);
696 EXPECT_TRANSFORMATION_MATRIX_EQ(
697 expected
, operations1
.Blend(operations2
, -0.5));
699 expected
.MakeIdentity();
700 expected
.ApplyPerspectiveDepth(2000);
702 EXPECT_TRANSFORMATION_MATRIX_EQ(
703 expected
, operations1
.Blend(operations2
, 1.5));
706 TEST(TransformOperationTest
, ExtrapolateMatrixBlending
) {
707 gfx::Transform transform1
;
708 transform1
.Translate3d(1, 1, 1);
709 TransformOperations operations1
;
710 operations1
.AppendMatrix(transform1
);
712 gfx::Transform transform2
;
713 transform2
.Translate3d(3, 3, 3);
714 TransformOperations operations2
;
715 operations2
.AppendMatrix(transform2
);
717 gfx::Transform expected
;
718 EXPECT_TRANSFORMATION_MATRIX_EQ(
719 expected
, operations1
.Blend(operations2
, 1.5));
721 expected
.Translate3d(4, 4, 4);
722 EXPECT_TRANSFORMATION_MATRIX_EQ(
723 expected
, operations1
.Blend(operations2
, -0.5));
726 TEST(TransformOperationTest
, BlendedBoundsWhenTypesDoNotMatch
) {
727 TransformOperations operations_from
;
728 operations_from
.AppendScale(2.0, 4.0, 8.0);
729 operations_from
.AppendTranslate(1.0, 2.0, 3.0);
731 TransformOperations operations_to
;
732 operations_to
.AppendTranslate(10.0, 20.0, 30.0);
733 operations_to
.AppendScale(4.0, 8.0, 16.0);
735 gfx::BoxF
box(1.f
, 1.f
, 1.f
);
738 SkMScalar min_progress
= 0.f
;
739 SkMScalar max_progress
= 1.f
;
741 EXPECT_FALSE(operations_to
.BlendedBoundsForBox(
742 box
, operations_from
, min_progress
, max_progress
, &bounds
));
745 TEST(TransformOperationTest
, BlendedBoundsForIdentity
) {
746 TransformOperations operations_from
;
747 operations_from
.AppendIdentity();
748 TransformOperations operations_to
;
749 operations_to
.AppendIdentity();
751 gfx::BoxF
box(1.f
, 2.f
, 3.f
);
754 SkMScalar min_progress
= 0.f
;
755 SkMScalar max_progress
= 1.f
;
757 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
758 box
, operations_from
, min_progress
, max_progress
, &bounds
));
759 EXPECT_EQ(box
.ToString(), bounds
.ToString());
762 TEST(TransformOperationTest
, BlendedBoundsForTranslate
) {
763 TransformOperations operations_from
;
764 operations_from
.AppendTranslate(3.0, -4.0, 2.0);
765 TransformOperations operations_to
;
766 operations_to
.AppendTranslate(7.0, 4.0, -2.0);
768 gfx::BoxF
box(1.f
, 2.f
, 3.f
, 4.f
, 4.f
, 4.f
);
771 SkMScalar min_progress
= -0.5f
;
772 SkMScalar max_progress
= 1.5f
;
773 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
774 box
, operations_from
, min_progress
, max_progress
, &bounds
));
775 EXPECT_EQ(gfx::BoxF(2.f
, -6.f
, -1.f
, 12.f
, 20.f
, 12.f
).ToString(),
780 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
781 box
, operations_from
, min_progress
, max_progress
, &bounds
));
782 EXPECT_EQ(gfx::BoxF(4.f
, -2.f
, 1.f
, 8.f
, 12.f
, 8.f
).ToString(),
785 TransformOperations identity
;
786 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
787 box
, identity
, min_progress
, max_progress
, &bounds
));
788 EXPECT_EQ(gfx::BoxF(1.f
, 2.f
, 1.f
, 11.f
, 8.f
, 6.f
).ToString(),
791 EXPECT_TRUE(identity
.BlendedBoundsForBox(
792 box
, operations_from
, min_progress
, max_progress
, &bounds
));
793 EXPECT_EQ(gfx::BoxF(1.f
, -2.f
, 3.f
, 7.f
, 8.f
, 6.f
).ToString(),
797 TEST(TransformOperationTest
, BlendedBoundsForScale
) {
798 TransformOperations operations_from
;
799 operations_from
.AppendScale(3.0, 0.5, 2.0);
800 TransformOperations operations_to
;
801 operations_to
.AppendScale(7.0, 4.0, -2.0);
803 gfx::BoxF
box(1.f
, 2.f
, 3.f
, 4.f
, 4.f
, 4.f
);
806 SkMScalar min_progress
= -0.5f
;
807 SkMScalar max_progress
= 1.5f
;
808 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
809 box
, operations_from
, min_progress
, max_progress
, &bounds
));
810 EXPECT_EQ(gfx::BoxF(1.f
, -7.5f
, -28.f
, 44.f
, 42.f
, 56.f
).ToString(),
815 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
816 box
, operations_from
, min_progress
, max_progress
, &bounds
));
817 EXPECT_EQ(gfx::BoxF(3.f
, 1.f
, -14.f
, 32.f
, 23.f
, 28.f
).ToString(),
820 TransformOperations identity
;
821 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
822 box
, identity
, min_progress
, max_progress
, &bounds
));
823 EXPECT_EQ(gfx::BoxF(1.f
, 2.f
, -14.f
, 34.f
, 22.f
, 21.f
).ToString(),
826 EXPECT_TRUE(identity
.BlendedBoundsForBox(
827 box
, operations_from
, min_progress
, max_progress
, &bounds
));
828 EXPECT_EQ(gfx::BoxF(1.f
, 1.f
, 3.f
, 14.f
, 5.f
, 11.f
).ToString(),
832 TEST(TransformOperationTest
, BlendedBoundsWithZeroScale
) {
833 TransformOperations zero_scale
;
834 zero_scale
.AppendScale(0.0, 0.0, 0.0);
835 TransformOperations non_zero_scale
;
836 non_zero_scale
.AppendScale(2.0, -4.0, 5.0);
838 gfx::BoxF
box(1.f
, 2.f
, 3.f
, 4.f
, 4.f
, 4.f
);
841 SkMScalar min_progress
= 0.f
;
842 SkMScalar max_progress
= 1.f
;
843 EXPECT_TRUE(zero_scale
.BlendedBoundsForBox(
844 box
, non_zero_scale
, min_progress
, max_progress
, &bounds
));
845 EXPECT_EQ(gfx::BoxF(0.f
, -24.f
, 0.f
, 10.f
, 24.f
, 35.f
).ToString(),
848 EXPECT_TRUE(non_zero_scale
.BlendedBoundsForBox(
849 box
, zero_scale
, min_progress
, max_progress
, &bounds
));
850 EXPECT_EQ(gfx::BoxF(0.f
, -24.f
, 0.f
, 10.f
, 24.f
, 35.f
).ToString(),
853 EXPECT_TRUE(zero_scale
.BlendedBoundsForBox(
854 box
, zero_scale
, min_progress
, max_progress
, &bounds
));
855 EXPECT_EQ(gfx::BoxF().ToString(), bounds
.ToString());
858 TEST(TransformOperationTest
, BlendedBoundsForRotationTrivial
) {
859 TransformOperations operations_from
;
860 operations_from
.AppendRotate(0.f
, 0.f
, 1.f
, 0.f
);
861 TransformOperations operations_to
;
862 operations_to
.AppendRotate(0.f
, 0.f
, 1.f
, 360.f
);
864 float sqrt_2
= sqrt(2.f
);
866 -sqrt_2
, -sqrt_2
, 0.f
, sqrt_2
, sqrt_2
, 0.f
);
869 // Since we're rotating 360 degrees, any box with dimensions between 0 and
870 // 2 * sqrt(2) should give the same result.
871 float sizes
[] = { 0.f
, 0.1f
, sqrt_2
, 2.f
* sqrt_2
};
872 for (size_t i
= 0; i
< arraysize(sizes
); ++i
) {
873 box
.set_size(sizes
[i
], sizes
[i
], 0.f
);
874 SkMScalar min_progress
= 0.f
;
875 SkMScalar max_progress
= 1.f
;
876 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
877 box
, operations_from
, min_progress
, max_progress
, &bounds
));
878 EXPECT_EQ(gfx::BoxF(-2.f
, -2.f
, 0.f
, 4.f
, 4.f
, 0.f
).ToString(),
883 TEST(TransformOperationTest
, BlendedBoundsForRotationAllExtrema
) {
884 // If the normal is out of the plane, we can have up to 6 extrema (a min/max
885 // in each dimension) between the endpoints of the arc. This test ensures that
886 // we consider all 6.
887 TransformOperations operations_from
;
888 operations_from
.AppendRotate(1.f
, 1.f
, 1.f
, 30.f
);
889 TransformOperations operations_to
;
890 operations_to
.AppendRotate(1.f
, 1.f
, 1.f
, 390.f
);
892 gfx::BoxF
box(1.f
, 0.f
, 0.f
, 0.f
, 0.f
, 0.f
);
895 float min
= -1.f
/ 3.f
;
897 float size
= max
- min
;
898 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
899 box
, operations_from
, 0.f
, 1.f
, &bounds
));
900 EXPECT_EQ(gfx::BoxF(min
, min
, min
, size
, size
, size
).ToString(),
904 TEST(TransformOperationTest
, BlendedBoundsForRotationDifferentAxes
) {
905 // We can handle rotations about a single axis. If the axes are different,
906 // we revert to matrix interpolation for which inflated bounds cannot be
908 TransformOperations operations_from
;
909 operations_from
.AppendRotate(1.f
, 1.f
, 1.f
, 30.f
);
910 TransformOperations operations_to_same
;
911 operations_to_same
.AppendRotate(1.f
, 1.f
, 1.f
, 390.f
);
912 TransformOperations operations_to_opposite
;
913 operations_to_opposite
.AppendRotate(-1.f
, -1.f
, -1.f
, 390.f
);
914 TransformOperations operations_to_different
;
915 operations_to_different
.AppendRotate(1.f
, 3.f
, 1.f
, 390.f
);
917 gfx::BoxF
box(1.f
, 0.f
, 0.f
, 0.f
, 0.f
, 0.f
);
920 EXPECT_TRUE(operations_to_same
.BlendedBoundsForBox(
921 box
, operations_from
, 0.f
, 1.f
, &bounds
));
922 EXPECT_TRUE(operations_to_opposite
.BlendedBoundsForBox(
923 box
, operations_from
, 0.f
, 1.f
, &bounds
));
924 EXPECT_FALSE(operations_to_different
.BlendedBoundsForBox(
925 box
, operations_from
, 0.f
, 1.f
, &bounds
));
928 TEST(TransformOperationTest
, BlendedBoundsForRotationPointOnAxis
) {
929 // Checks that if the point to rotate is sitting on the axis of rotation, that
930 // it does not get affected.
931 TransformOperations operations_from
;
932 operations_from
.AppendRotate(1.f
, 1.f
, 1.f
, 30.f
);
933 TransformOperations operations_to
;
934 operations_to
.AppendRotate(1.f
, 1.f
, 1.f
, 390.f
);
936 gfx::BoxF
box(1.f
, 1.f
, 1.f
, 0.f
, 0.f
, 0.f
);
939 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
940 box
, operations_from
, 0.f
, 1.f
, &bounds
));
941 EXPECT_EQ(box
.ToString(), bounds
.ToString());
944 TEST(TransformOperationTest
, BlendedBoundsForRotationProblematicAxes
) {
945 // Zeros in the components of the axis of rotation turned out to be tricky to
946 // deal with in practice. This function tests some potentially problematic
947 // axes to ensure sane behavior.
949 // Some common values used in the expected boxes.
950 float dim1
= 0.292893f
;
951 float dim2
= sqrt(2.f
);
952 float dim3
= 2.f
* dim2
;
959 } tests
[] = {{0.f
, 0.f
, 0.f
, gfx::BoxF(1.f
, 1.f
, 1.f
, 0.f
, 0.f
, 0.f
)},
960 {1.f
, 0.f
, 0.f
, gfx::BoxF(1.f
, -dim2
, -dim2
, 0.f
, dim3
, dim3
)},
961 {0.f
, 1.f
, 0.f
, gfx::BoxF(-dim2
, 1.f
, -dim2
, dim3
, 0.f
, dim3
)},
962 {0.f
, 0.f
, 1.f
, gfx::BoxF(-dim2
, -dim2
, 1.f
, dim3
, dim3
, 0.f
)},
963 {1.f
, 1.f
, 0.f
, gfx::BoxF(dim1
, dim1
, -1.f
, dim2
, dim2
, 2.f
)},
964 {0.f
, 1.f
, 1.f
, gfx::BoxF(-1.f
, dim1
, dim1
, 2.f
, dim2
, dim2
)},
965 {1.f
, 0.f
, 1.f
, gfx::BoxF(dim1
, -1.f
, dim1
, dim2
, 2.f
, dim2
)}};
967 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
968 float x
= tests
[i
].x
;
969 float y
= tests
[i
].y
;
970 float z
= tests
[i
].z
;
971 TransformOperations operations_from
;
972 operations_from
.AppendRotate(x
, y
, z
, 0.f
);
973 TransformOperations operations_to
;
974 operations_to
.AppendRotate(x
, y
, z
, 360.f
);
975 gfx::BoxF
box(1.f
, 1.f
, 1.f
, 0.f
, 0.f
, 0.f
);
978 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
979 box
, operations_from
, 0.f
, 1.f
, &bounds
));
980 EXPECT_EQ(tests
[i
].expected
.ToString(), bounds
.ToString());
984 static void ExpectBoxesApproximatelyEqual(const gfx::BoxF
& lhs
,
985 const gfx::BoxF
& rhs
,
987 EXPECT_NEAR(lhs
.x(), rhs
.x(), tolerance
);
988 EXPECT_NEAR(lhs
.y(), rhs
.y(), tolerance
);
989 EXPECT_NEAR(lhs
.z(), rhs
.z(), tolerance
);
990 EXPECT_NEAR(lhs
.width(), rhs
.width(), tolerance
);
991 EXPECT_NEAR(lhs
.height(), rhs
.height(), tolerance
);
992 EXPECT_NEAR(lhs
.depth(), rhs
.depth(), tolerance
);
995 static void EmpiricallyTestBounds(const TransformOperations
& from
,
996 const TransformOperations
& to
,
997 SkMScalar min_progress
,
998 SkMScalar max_progress
,
999 bool test_containment_only
) {
1000 gfx::BoxF
box(200.f
, 500.f
, 100.f
, 100.f
, 300.f
, 200.f
);
1003 to
.BlendedBoundsForBox(box
, from
, min_progress
, max_progress
, &bounds
));
1005 bool first_time
= true;
1006 gfx::BoxF empirical_bounds
;
1007 static const size_t kNumSteps
= 10;
1008 for (size_t step
= 0; step
< kNumSteps
; ++step
) {
1009 float t
= step
/ (kNumSteps
- 1.f
);
1010 t
= gfx::Tween::FloatValueBetween(t
, min_progress
, max_progress
);
1011 gfx::Transform partial_transform
= to
.Blend(from
, t
);
1012 gfx::BoxF transformed
= box
;
1013 partial_transform
.TransformBox(&transformed
);
1016 empirical_bounds
= transformed
;
1019 empirical_bounds
.Union(transformed
);
1023 if (test_containment_only
) {
1024 gfx::BoxF unified_bounds
= bounds
;
1025 unified_bounds
.Union(empirical_bounds
);
1026 // Convert to the screen space rects these boxes represent.
1027 gfx::Rect bounds_rect
= ToEnclosingRect(
1028 gfx::RectF(bounds
.x(), bounds
.y(), bounds
.width(), bounds
.height()));
1029 gfx::Rect unified_bounds_rect
=
1030 ToEnclosingRect(gfx::RectF(unified_bounds
.x(),
1032 unified_bounds
.width(),
1033 unified_bounds
.height()));
1034 EXPECT_EQ(bounds_rect
.ToString(), unified_bounds_rect
.ToString());
1036 // Our empirical estimate will be a little rough since we're only doing
1038 static const float kTolerance
= 1e-2f
;
1039 ExpectBoxesApproximatelyEqual(empirical_bounds
, bounds
, kTolerance
);
1043 static void EmpiricallyTestBoundsEquality(const TransformOperations
& from
,
1044 const TransformOperations
& to
,
1045 SkMScalar min_progress
,
1046 SkMScalar max_progress
) {
1047 EmpiricallyTestBounds(from
, to
, min_progress
, max_progress
, false);
1050 static void EmpiricallyTestBoundsContainment(const TransformOperations
& from
,
1051 const TransformOperations
& to
,
1052 SkMScalar min_progress
,
1053 SkMScalar max_progress
) {
1054 EmpiricallyTestBounds(from
, to
, min_progress
, max_progress
, true);
1057 TEST(TransformOperationTest
, BlendedBoundsForRotationEmpiricalTests
) {
1058 // Sets up various axis angle combinations, computes the bounding box and
1059 // empirically tests that the transformed bounds are indeed contained by the
1060 // computed bounding box.
1066 } axes
[] = {{1.f
, 1.f
, 1.f
},
1088 } angles
[] = {{5.f
, 10.f
},
1096 // We can go beyond the range [0, 1] (the bezier might slide out of this range
1097 // at either end), but since the first and last knots are at (0, 0) and (1, 1)
1098 // we will never go within it, so these tests are sufficient.
1103 {0.f
, 1.f
}, {-.25f
, 1.25f
},
1106 for (size_t i
= 0; i
< arraysize(axes
); ++i
) {
1107 for (size_t j
= 0; j
< arraysize(angles
); ++j
) {
1108 for (size_t k
= 0; k
< arraysize(progress
); ++k
) {
1109 float x
= axes
[i
].x
;
1110 float y
= axes
[i
].y
;
1111 float z
= axes
[i
].z
;
1112 TransformOperations operations_from
;
1113 operations_from
.AppendRotate(x
, y
, z
, angles
[j
].theta_from
);
1114 TransformOperations operations_to
;
1115 operations_to
.AppendRotate(x
, y
, z
, angles
[j
].theta_to
);
1116 EmpiricallyTestBoundsContainment(operations_from
,
1118 progress
[k
].min_progress
,
1119 progress
[k
].max_progress
);
1125 TEST(TransformOperationTest
, PerspectiveMatrixAndTransformBlendingEquivalency
) {
1126 TransformOperations from_operations
;
1127 from_operations
.AppendPerspective(200);
1129 TransformOperations to_operations
;
1130 to_operations
.AppendPerspective(1000);
1132 gfx::Transform from_transform
;
1133 from_transform
.ApplyPerspectiveDepth(200);
1135 gfx::Transform to_transform
;
1136 to_transform
.ApplyPerspectiveDepth(1000);
1138 static const int steps
= 20;
1139 for (int i
= 0; i
< steps
; ++i
) {
1140 double progress
= static_cast<double>(i
) / (steps
- 1);
1142 gfx::Transform blended_matrix
= to_transform
;
1143 EXPECT_TRUE(blended_matrix
.Blend(from_transform
, progress
));
1145 gfx::Transform blended_transform
=
1146 to_operations
.Blend(from_operations
, progress
);
1148 EXPECT_TRANSFORMATION_MATRIX_EQ(blended_matrix
, blended_transform
);
1152 TEST(TransformOperationTest
, BlendedBoundsForPerspective
) {
1156 } perspective_depths
[] = {
1159 {800.f
, std::numeric_limits
<float>::infinity()},
1166 {0.f
, 1.f
}, {-0.1f
, 1.1f
},
1169 for (size_t i
= 0; i
< arraysize(perspective_depths
); ++i
) {
1170 for (size_t j
= 0; j
< arraysize(progress
); ++j
) {
1171 TransformOperations operations_from
;
1172 operations_from
.AppendPerspective(perspective_depths
[i
].from_depth
);
1173 TransformOperations operations_to
;
1174 operations_to
.AppendPerspective(perspective_depths
[i
].to_depth
);
1175 EmpiricallyTestBoundsEquality(operations_from
,
1177 progress
[j
].min_progress
,
1178 progress
[j
].max_progress
);
1183 TEST(TransformOperationTest
, BlendedBoundsForSkew
) {
1190 {1.f
, 0.5f
, 0.5f
, 1.f
}, {2.f
, 1.f
, 0.5f
, 0.5f
},
1197 {0.f
, 1.f
}, {-0.1f
, 1.1f
},
1200 for (size_t i
= 0; i
< arraysize(skews
); ++i
) {
1201 for (size_t j
= 0; j
< arraysize(progress
); ++j
) {
1202 TransformOperations operations_from
;
1203 operations_from
.AppendSkew(skews
[i
].from_x
, skews
[i
].from_y
);
1204 TransformOperations operations_to
;
1205 operations_to
.AppendSkew(skews
[i
].to_x
, skews
[i
].to_y
);
1206 EmpiricallyTestBoundsEquality(operations_from
,
1208 progress
[j
].min_progress
,
1209 progress
[j
].max_progress
);
1214 TEST(TransformOperationTest
, NonCommutativeRotations
) {
1215 TransformOperations operations_from
;
1216 operations_from
.AppendRotate(1.0, 0.0, 0.0, 0.0);
1217 operations_from
.AppendRotate(0.0, 1.0, 0.0, 0.0);
1218 TransformOperations operations_to
;
1219 operations_to
.AppendRotate(1.0, 0.0, 0.0, 45.0);
1220 operations_to
.AppendRotate(0.0, 1.0, 0.0, 135.0);
1222 gfx::BoxF
box(0, 0, 0, 1, 1, 1);
1225 SkMScalar min_progress
= 0.0f
;
1226 SkMScalar max_progress
= 1.0f
;
1227 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
1228 box
, operations_from
, min_progress
, max_progress
, &bounds
));
1229 gfx::Transform blended_transform
=
1230 operations_to
.Blend(operations_from
, max_progress
);
1231 gfx::Point3F
blended_point(0.9f
, 0.9f
, 0.0f
);
1232 blended_transform
.TransformPoint(&blended_point
);
1233 gfx::BoxF expanded_bounds
= bounds
;
1234 expanded_bounds
.ExpandTo(blended_point
);
1235 EXPECT_EQ(bounds
.ToString(), expanded_bounds
.ToString());
1238 TEST(TransformOperationTest
, BlendedBoundsForSequence
) {
1239 TransformOperations operations_from
;
1240 operations_from
.AppendTranslate(1.0, -5.0, 1.0);
1241 operations_from
.AppendScale(-1.0, 2.0, 3.0);
1242 operations_from
.AppendTranslate(2.0, 4.0, -1.0);
1243 TransformOperations operations_to
;
1244 operations_to
.AppendTranslate(13.0, -1.0, 5.0);
1245 operations_to
.AppendScale(-3.0, -2.0, 5.0);
1246 operations_to
.AppendTranslate(6.0, -2.0, 3.0);
1248 gfx::BoxF
box(1.f
, 2.f
, 3.f
, 4.f
, 4.f
, 4.f
);
1251 SkMScalar min_progress
= -0.5f
;
1252 SkMScalar max_progress
= 1.5f
;
1253 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
1254 box
, operations_from
, min_progress
, max_progress
, &bounds
));
1255 EXPECT_EQ(gfx::BoxF(-57.f
, -59.f
, -1.f
, 76.f
, 112.f
, 80.f
).ToString(),
1260 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
1261 box
, operations_from
, min_progress
, max_progress
, &bounds
));
1262 EXPECT_EQ(gfx::BoxF(-32.f
, -25.f
, 7.f
, 42.f
, 44.f
, 48.f
).ToString(),
1265 TransformOperations identity
;
1266 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
1267 box
, identity
, min_progress
, max_progress
, &bounds
));
1268 EXPECT_EQ(gfx::BoxF(-33.f
, -13.f
, 3.f
, 57.f
, 19.f
, 52.f
).ToString(),
1271 EXPECT_TRUE(identity
.BlendedBoundsForBox(
1272 box
, operations_from
, min_progress
, max_progress
, &bounds
));
1273 EXPECT_EQ(gfx::BoxF(-7.f
, -3.f
, 2.f
, 15.f
, 23.f
, 20.f
).ToString(),
1277 TEST(TransformOperationTest
, AffectsScaleWithSingleOperation
) {
1278 TransformOperations empty_operations
;
1279 EXPECT_FALSE(empty_operations
.AffectsScale());
1281 TransformOperations identity
;
1282 identity
.AppendIdentity();
1283 EXPECT_FALSE(identity
.AffectsScale());
1285 TransformOperations translate
;
1286 translate
.AppendTranslate(1.f
, 2.f
, 3.f
);
1287 EXPECT_FALSE(translate
.AffectsScale());
1289 TransformOperations rotate
;
1290 rotate
.AppendRotate(1.f
, 2.f
, 3.f
, 4.f
);
1291 EXPECT_FALSE(rotate
.AffectsScale());
1293 TransformOperations scale
;
1294 scale
.AppendScale(1.f
, 2.f
, 3.f
);
1295 EXPECT_TRUE(scale
.AffectsScale());
1297 TransformOperations skew
;
1298 skew
.AppendSkew(1.f
, 2.f
);
1299 EXPECT_FALSE(skew
.AffectsScale());
1301 TransformOperations perspective
;
1302 perspective
.AppendPerspective(1.f
);
1303 EXPECT_FALSE(perspective
.AffectsScale());
1305 TransformOperations identity_matrix
;
1306 identity_matrix
.AppendMatrix(gfx::Transform());
1307 EXPECT_FALSE(identity_matrix
.AffectsScale());
1309 TransformOperations translation_matrix
;
1310 gfx::Transform translation_transform
;
1311 translation_transform
.Translate3d(1.f
, 2.f
, 3.f
);
1312 translation_matrix
.AppendMatrix(translation_transform
);
1313 EXPECT_FALSE(translation_matrix
.AffectsScale());
1315 TransformOperations scaling_matrix
;
1316 gfx::Transform scaling_transform
;
1317 scaling_transform
.Scale(2.f
, 2.f
);
1318 scaling_matrix
.AppendMatrix(scaling_transform
);
1319 EXPECT_TRUE(scaling_matrix
.AffectsScale());
1322 TEST(TransformOperationTest
, AffectsScaleWithMultipleOperations
) {
1323 TransformOperations operations1
;
1324 operations1
.AppendSkew(1.f
, 2.f
);
1325 operations1
.AppendTranslate(1.f
, 2.f
, 3.f
);
1326 operations1
.AppendIdentity();
1327 EXPECT_FALSE(operations1
.AffectsScale());
1329 TransformOperations operations2
;
1330 operations2
.AppendPerspective(2.f
);
1331 operations2
.AppendScale(1.f
, 2.f
, 3.f
);
1332 operations2
.AppendTranslate(3.f
, 2.f
, 1.f
);
1333 EXPECT_TRUE(operations2
.AffectsScale());
1336 TEST(TransformOperationTest
, IsTranslationWithSingleOperation
) {
1337 TransformOperations empty_operations
;
1338 EXPECT_TRUE(empty_operations
.IsTranslation());
1340 TransformOperations identity
;
1341 identity
.AppendIdentity();
1342 EXPECT_TRUE(identity
.IsTranslation());
1344 TransformOperations translate
;
1345 translate
.AppendTranslate(1.f
, 2.f
, 3.f
);
1346 EXPECT_TRUE(translate
.IsTranslation());
1348 TransformOperations rotate
;
1349 rotate
.AppendRotate(1.f
, 2.f
, 3.f
, 4.f
);
1350 EXPECT_FALSE(rotate
.IsTranslation());
1352 TransformOperations scale
;
1353 scale
.AppendScale(1.f
, 2.f
, 3.f
);
1354 EXPECT_FALSE(scale
.IsTranslation());
1356 TransformOperations skew
;
1357 skew
.AppendSkew(1.f
, 2.f
);
1358 EXPECT_FALSE(skew
.IsTranslation());
1360 TransformOperations perspective
;
1361 perspective
.AppendPerspective(1.f
);
1362 EXPECT_FALSE(perspective
.IsTranslation());
1364 TransformOperations identity_matrix
;
1365 identity_matrix
.AppendMatrix(gfx::Transform());
1366 EXPECT_TRUE(identity_matrix
.IsTranslation());
1368 TransformOperations translation_matrix
;
1369 gfx::Transform translation_transform
;
1370 translation_transform
.Translate3d(1.f
, 2.f
, 3.f
);
1371 translation_matrix
.AppendMatrix(translation_transform
);
1372 EXPECT_TRUE(translation_matrix
.IsTranslation());
1374 TransformOperations scaling_matrix
;
1375 gfx::Transform scaling_transform
;
1376 scaling_transform
.Scale(2.f
, 2.f
);
1377 scaling_matrix
.AppendMatrix(scaling_transform
);
1378 EXPECT_FALSE(scaling_matrix
.IsTranslation());
1381 TEST(TransformOperationTest
, IsTranslationWithMultipleOperations
) {
1382 TransformOperations operations1
;
1383 operations1
.AppendSkew(1.f
, 2.f
);
1384 operations1
.AppendTranslate(1.f
, 2.f
, 3.f
);
1385 operations1
.AppendIdentity();
1386 EXPECT_FALSE(operations1
.IsTranslation());
1388 TransformOperations operations2
;
1389 operations2
.AppendIdentity();
1390 operations2
.AppendTranslate(3.f
, 2.f
, 1.f
);
1391 gfx::Transform translation_transform
;
1392 translation_transform
.Translate3d(1.f
, 2.f
, 3.f
);
1393 operations2
.AppendMatrix(translation_transform
);
1394 EXPECT_TRUE(operations2
.IsTranslation());
1397 TEST(TransformOperationTest
, ScaleComponent
) {
1398 gfx::Vector3dF scale
;
1401 TransformOperations operations1
;
1402 operations1
.AppendScale(-3.f
, 2.f
, 5.f
);
1403 EXPECT_TRUE(operations1
.ScaleComponent(&scale
));
1404 EXPECT_EQ(gfx::Vector3dF(-3.f
, 2.f
, 5.f
), scale
);
1406 // Translate + Scale.
1407 TransformOperations operations5
;
1408 operations5
.AppendTranslate(1.f
, 2.f
, 3.f
);
1409 operations5
.AppendScale(2.f
, 5.f
, 4.f
);
1410 EXPECT_TRUE(operations5
.ScaleComponent(&scale
));
1411 EXPECT_EQ(gfx::Vector3dF(2.f
, 5.f
, 4.f
), scale
);
1413 // Translate + Scale + Matrix with translate.
1414 gfx::Transform translation_transform
;
1415 translation_transform
.Translate3d(1.f
, 2.f
, 3.f
);
1416 operations5
.AppendMatrix(translation_transform
);
1417 EXPECT_TRUE(operations5
.ScaleComponent(&scale
));
1418 EXPECT_EQ(gfx::Vector3dF(2.f
, 5.f
, 4.f
), scale
);
1421 TEST(TransformOperationTest
, ScaleComponentCannotBeComputed
) {
1422 gfx::Vector3dF scale
;
1425 TransformOperations operations1
;
1426 operations1
.AppendScale(2.f
, 2.f
, 2.f
);
1427 EXPECT_TRUE(operations1
.ScaleComponent(&scale
));
1428 EXPECT_EQ(gfx::Vector3dF(2.f
, 2.f
, 2.f
), scale
);
1431 TransformOperations operations2
;
1432 operations2
.AppendTranslate(1.f
, 2.f
, 3.f
);
1433 EXPECT_TRUE(operations2
.ScaleComponent(&scale
));
1434 EXPECT_EQ(gfx::Vector3dF(1.f
, 1.f
, 1.f
), scale
);
1436 // Scale + translate can.
1437 TransformOperations operations3
;
1438 operations3
.AppendScale(2.f
, 3.f
, 2.f
);
1439 operations3
.AppendTranslate(1.f
, 2.f
, 3.f
);
1440 EXPECT_TRUE(operations3
.ScaleComponent(&scale
));
1441 EXPECT_EQ(gfx::Vector3dF(2.f
, 3.f
, 2.f
), scale
);
1443 // Two Scales can't.
1444 TransformOperations operations4
;
1445 operations4
.AppendScale(2.f
, 3.f
, 2.f
);
1446 operations4
.AppendScale(3.f
, 2.f
, 3.f
);
1447 EXPECT_FALSE(operations4
.ScaleComponent(&scale
));
1450 TransformOperations operations5
;
1451 operations5
.AppendScale(2.f
, 2.f
, 2.f
);
1452 gfx::Transform scaling_transform
;
1453 scaling_transform
.Scale(2.f
, 2.f
);
1454 operations5
.AppendMatrix(scaling_transform
);
1455 EXPECT_FALSE(operations5
.ScaleComponent(&scale
));
1457 // Scale + Rotate can't.
1458 TransformOperations operations7
;
1459 operations7
.AppendScale(2.f
, 2.f
, 2.f
);
1460 operations7
.AppendRotate(1.f
, 2.f
, 3.f
, 4.f
);
1461 EXPECT_FALSE(operations7
.ScaleComponent(&scale
));
1463 // Scale + Skew can't.
1464 TransformOperations operations9
;
1465 operations9
.AppendScale(2.f
, 2.f
, 2.f
);
1466 operations9
.AppendSkew(1.f
, 2.f
);
1467 EXPECT_FALSE(operations9
.ScaleComponent(&scale
));
1469 // Scale + Perspective can't.
1470 TransformOperations operations11
;
1471 operations11
.AppendScale(2.f
, 2.f
, 2.f
);
1472 operations11
.AppendPerspective(1.f
);
1473 EXPECT_FALSE(operations11
.ScaleComponent(&scale
));