Revert "Fix for bug where composited rotate3d should SLERP instead of interpolating...
[chromium-blink-merge.git] / cc / animation / transform_operations_unittest.cc
blobc5fb3c6b8160027c9e0672823a2e91c35b323b75
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.
5 #include <limits>
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"
17 namespace cc {
18 namespace {
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) {
173 SkMScalar x = 1;
174 SkMScalar y = 2;
175 SkMScalar z = 3;
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) {
184 SkMScalar x = 1;
185 SkMScalar y = 2;
186 SkMScalar z = 3;
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) {
196 SkMScalar x = 1;
197 SkMScalar y = 2;
198 SkMScalar z = 3;
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) {
207 SkMScalar x = 1;
208 SkMScalar y = 2;
209 TransformOperations operations;
210 operations.AppendSkew(x, y);
211 gfx::Transform expected;
212 expected.SkewX(x);
213 expected.SkewY(y);
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) {
227 SkMScalar dx = 1;
228 SkMScalar dy = 2;
229 SkMScalar dz = 3;
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) {
238 SkMScalar sx = 2;
239 SkMScalar sy = 4;
240 SkMScalar sz = 8;
242 SkMScalar dx = 1;
243 SkMScalar dy = 2;
244 SkMScalar dz = 3;
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) {
263 SkMScalar sx1 = 2;
264 SkMScalar sy1 = 4;
265 SkMScalar sz1 = 8;
267 SkMScalar dx1 = 1;
268 SkMScalar dy1 = 2;
269 SkMScalar dz1 = 3;
271 SkMScalar sx2 = 4;
272 SkMScalar sy2 = 8;
273 SkMScalar sz2 = 16;
275 SkMScalar dx2 = 10;
276 SkMScalar dy2 = 20;
277 SkMScalar dz2 = 30;
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) {
324 SkMScalar sx = 2;
325 SkMScalar sy = 4;
326 SkMScalar sz = 8;
327 TransformOperations operations_from;
328 operations_from.AppendScale(sx, sy, sz);
330 gfx::Transform matrix_from;
331 matrix_from.Scale3d(sx, sy, sz);
333 sx = 4;
334 sy = 8;
335 sz = 16;
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) {
351 SkMScalar sx1 = 2;
352 SkMScalar sy1 = 4;
353 SkMScalar sz1 = 8;
355 SkMScalar dx1 = 1;
356 SkMScalar dy1 = 2;
357 SkMScalar dz1 = 3;
359 SkMScalar sx2 = 4;
360 SkMScalar sy2 = 8;
361 SkMScalar sz2 = 16;
363 SkMScalar dx2 = 10;
364 SkMScalar dy2 = 20;
365 SkMScalar dz2 = 30;
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);
375 gfx::Transform from;
376 from.Scale3d(sx1, sy1, sz1);
377 from.Translate3d(dx1, dy1, dz1);
379 gfx::Transform to;
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));
460 progress = -0.5f;
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));
468 progress = 1.5f;
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));
494 progress = -0.5f;
496 expected.MakeIdentity();
497 expected.Translate3d(-1, -1, -1);
499 EXPECT_TRANSFORMATION_MATRIX_EQ(
500 expected, operations.Blend(*identity_operations[i], progress));
502 progress = 1.5f;
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));
528 progress = -0.5f;
530 expected.MakeIdentity();
531 expected.Scale3d(0, 0, 0);
533 EXPECT_TRANSFORMATION_MATRIX_EQ(
534 expected, operations.Blend(*identity_operations[i], progress));
536 progress = 1.5f;
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;
555 expected.SkewX(1);
556 expected.SkewY(1);
558 EXPECT_TRANSFORMATION_MATRIX_EQ(expected,
559 operations.Blend(empty_operation, progress));
561 progress = -0.5f;
563 expected.MakeIdentity();
564 expected.SkewX(-1);
565 expected.SkewY(-1);
567 EXPECT_TRANSFORMATION_MATRIX_EQ(expected,
568 operations.Blend(empty_operation, progress));
570 progress = 1.5f;
572 expected.MakeIdentity();
573 expected.SkewX(3);
574 expected.SkewY(3);
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;
661 expected.SkewX(1);
662 expected.SkewY(1);
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);
736 gfx::BoxF bounds;
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);
752 gfx::BoxF bounds;
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);
769 gfx::BoxF bounds;
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(),
776 bounds.ToString());
778 min_progress = 0.f;
779 max_progress = 1.f;
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(),
783 bounds.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(),
789 bounds.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(),
794 bounds.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);
804 gfx::BoxF bounds;
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(),
811 bounds.ToString());
813 min_progress = 0.f;
814 max_progress = 1.f;
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(),
818 bounds.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(),
824 bounds.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(),
829 bounds.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);
839 gfx::BoxF bounds;
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(),
846 bounds.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(),
851 bounds.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);
865 gfx::BoxF box(
866 -sqrt_2, -sqrt_2, 0.f, sqrt_2, sqrt_2, 0.f);
867 gfx::BoxF bounds;
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(),
879 bounds.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);
893 gfx::BoxF bounds;
895 float min = -1.f / 3.f;
896 float max = 1.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(),
901 bounds.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
907 // computed.
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);
918 gfx::BoxF bounds;
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);
937 gfx::BoxF bounds;
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;
954 struct {
955 float x;
956 float y;
957 float z;
958 gfx::BoxF expected;
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);
976 gfx::BoxF bounds;
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,
986 float tolerance) {
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);
1001 gfx::BoxF bounds;
1002 EXPECT_TRUE(
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);
1015 if (first_time) {
1016 empirical_bounds = transformed;
1017 first_time = false;
1018 } else {
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(),
1031 unified_bounds.y(),
1032 unified_bounds.width(),
1033 unified_bounds.height()));
1034 EXPECT_EQ(bounds_rect.ToString(), unified_bounds_rect.ToString());
1035 } else {
1036 // Our empirical estimate will be a little rough since we're only doing
1037 // 100 samples.
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.
1062 struct {
1063 float x;
1064 float y;
1065 float z;
1066 } axes[] = {{1.f, 1.f, 1.f},
1067 {-1.f, -1.f, -1.f},
1068 {-1.f, 2.f, 3.f},
1069 {1.f, -2.f, 3.f},
1070 {1.f, 2.f, -3.f},
1071 {0.f, 0.f, 0.f},
1072 {1.f, 0.f, 0.f},
1073 {0.f, 1.f, 0.f},
1074 {0.f, 0.f, 1.f},
1075 {1.f, 1.f, 0.f},
1076 {0.f, 1.f, 1.f},
1077 {1.f, 0.f, 1.f},
1078 {-1.f, 0.f, 0.f},
1079 {0.f, -1.f, 0.f},
1080 {0.f, 0.f, -1.f},
1081 {-1.f, -1.f, 0.f},
1082 {0.f, -1.f, -1.f},
1083 {-1.f, 0.f, -1.f}};
1085 struct {
1086 float theta_from;
1087 float theta_to;
1088 } angles[] = {{5.f, 10.f},
1089 {10.f, 5.f},
1090 {0.f, 360.f},
1091 {20.f, 180.f},
1092 {-20.f, -180.f},
1093 {180.f, -220.f},
1094 {220.f, 320.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.
1099 struct {
1100 float min_progress;
1101 float max_progress;
1102 } progress[] = {
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,
1117 operations_to,
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) {
1153 struct {
1154 float from_depth;
1155 float to_depth;
1156 } perspective_depths[] = {
1157 {600.f, 400.f},
1158 {800.f, 1000.f},
1159 {800.f, std::numeric_limits<float>::infinity()},
1162 struct {
1163 float min_progress;
1164 float max_progress;
1165 } progress[] = {
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,
1176 operations_to,
1177 progress[j].min_progress,
1178 progress[j].max_progress);
1183 TEST(TransformOperationTest, BlendedBoundsForSkew) {
1184 struct {
1185 float from_x;
1186 float from_y;
1187 float to_x;
1188 float to_y;
1189 } skews[] = {
1190 {1.f, 0.5f, 0.5f, 1.f}, {2.f, 1.f, 0.5f, 0.5f},
1193 struct {
1194 float min_progress;
1195 float max_progress;
1196 } progress[] = {
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,
1207 operations_to,
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);
1223 gfx::BoxF bounds;
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);
1249 gfx::BoxF bounds;
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(),
1256 bounds.ToString());
1258 min_progress = 0.f;
1259 max_progress = 1.f;
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(),
1263 bounds.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(),
1269 bounds.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(),
1274 bounds.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;
1400 // 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;
1424 // Scale can.
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);
1430 // Translate can.
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));
1449 // Matrix can't.
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));
1476 } // namespace
1477 } // namespace cc