transform_operations_unittest.cc revision 3551c9c881056c480085172ff9840cab31610854
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <limits>
6
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/box_f.h"
12#include "ui/gfx/vector3d_f.h"
13
14namespace cc {
15namespace {
16
17TEST(TransformOperationTest, TransformTypesAreUnique) {
18  ScopedVector<TransformOperations> transforms;
19
20  TransformOperations* to_add = new TransformOperations();
21  to_add->AppendTranslate(1, 0, 0);
22  transforms.push_back(to_add);
23
24  to_add = new TransformOperations();
25  to_add->AppendRotate(0, 0, 1, 2);
26  transforms.push_back(to_add);
27
28  to_add = new TransformOperations();
29  to_add->AppendScale(2, 2, 2);
30  transforms.push_back(to_add);
31
32  to_add = new TransformOperations();
33  to_add->AppendSkew(1, 0);
34  transforms.push_back(to_add);
35
36  to_add = new TransformOperations();
37  to_add->AppendPerspective(800);
38  transforms.push_back(to_add);
39
40  for (size_t i = 0; i < transforms.size(); ++i) {
41    for (size_t j = 0; j < transforms.size(); ++j) {
42      bool matches_type = transforms[i]->MatchesTypes(*transforms[j]);
43      EXPECT_TRUE((i == j && matches_type) || !matches_type);
44    }
45  }
46}
47
48TEST(TransformOperationTest, MatchTypesSameLength) {
49  TransformOperations translates;
50  translates.AppendTranslate(1, 0, 0);
51  translates.AppendTranslate(1, 0, 0);
52  translates.AppendTranslate(1, 0, 0);
53
54  TransformOperations skews;
55  skews.AppendSkew(0, 2);
56  skews.AppendSkew(0, 2);
57  skews.AppendSkew(0, 2);
58
59  TransformOperations translates2;
60  translates2.AppendTranslate(0, 2, 0);
61  translates2.AppendTranslate(0, 2, 0);
62  translates2.AppendTranslate(0, 2, 0);
63
64  TransformOperations translates3 = translates2;
65
66  EXPECT_FALSE(translates.MatchesTypes(skews));
67  EXPECT_TRUE(translates.MatchesTypes(translates2));
68  EXPECT_TRUE(translates.MatchesTypes(translates3));
69}
70
71TEST(TransformOperationTest, MatchTypesDifferentLength) {
72  TransformOperations translates;
73  translates.AppendTranslate(1, 0, 0);
74  translates.AppendTranslate(1, 0, 0);
75  translates.AppendTranslate(1, 0, 0);
76
77  TransformOperations skews;
78  skews.AppendSkew(2, 0);
79  skews.AppendSkew(2, 0);
80
81  TransformOperations translates2;
82  translates2.AppendTranslate(0, 2, 0);
83  translates2.AppendTranslate(0, 2, 0);
84
85  EXPECT_FALSE(translates.MatchesTypes(skews));
86  EXPECT_FALSE(translates.MatchesTypes(translates2));
87}
88
89void GetIdentityOperations(ScopedVector<TransformOperations>* operations) {
90  TransformOperations* to_add = new TransformOperations();
91  operations->push_back(to_add);
92
93  to_add = new TransformOperations();
94  to_add->AppendTranslate(0, 0, 0);
95  operations->push_back(to_add);
96
97  to_add = new TransformOperations();
98  to_add->AppendTranslate(0, 0, 0);
99  to_add->AppendTranslate(0, 0, 0);
100  operations->push_back(to_add);
101
102  to_add = new TransformOperations();
103  to_add->AppendScale(1, 1, 1);
104  operations->push_back(to_add);
105
106  to_add = new TransformOperations();
107  to_add->AppendScale(1, 1, 1);
108  to_add->AppendScale(1, 1, 1);
109  operations->push_back(to_add);
110
111  to_add = new TransformOperations();
112  to_add->AppendSkew(0, 0);
113  operations->push_back(to_add);
114
115  to_add = new TransformOperations();
116  to_add->AppendSkew(0, 0);
117  to_add->AppendSkew(0, 0);
118  operations->push_back(to_add);
119
120  to_add = new TransformOperations();
121  to_add->AppendRotate(0, 0, 1, 0);
122  operations->push_back(to_add);
123
124  to_add = new TransformOperations();
125  to_add->AppendRotate(0, 0, 1, 0);
126  to_add->AppendRotate(0, 0, 1, 0);
127  operations->push_back(to_add);
128
129  to_add = new TransformOperations();
130  to_add->AppendMatrix(gfx::Transform());
131  operations->push_back(to_add);
132
133  to_add = new TransformOperations();
134  to_add->AppendMatrix(gfx::Transform());
135  to_add->AppendMatrix(gfx::Transform());
136  operations->push_back(to_add);
137}
138
139TEST(TransformOperationTest, IdentityAlwaysMatches) {
140  ScopedVector<TransformOperations> operations;
141  GetIdentityOperations(&operations);
142
143  for (size_t i = 0; i < operations.size(); ++i) {
144    for (size_t j = 0; j < operations.size(); ++j)
145      EXPECT_TRUE(operations[i]->MatchesTypes(*operations[j]));
146  }
147}
148
149TEST(TransformOperationTest, ApplyTranslate) {
150  double x = 1;
151  double y = 2;
152  double z = 3;
153  TransformOperations operations;
154  operations.AppendTranslate(x, y, z);
155  gfx::Transform expected;
156  expected.Translate3d(x, y, z);
157  EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply());
158}
159
160TEST(TransformOperationTest, ApplyRotate) {
161  double x = 1;
162  double y = 2;
163  double z = 3;
164  double degrees = 80;
165  TransformOperations operations;
166  operations.AppendRotate(x, y, z, degrees);
167  gfx::Transform expected;
168  expected.RotateAbout(gfx::Vector3dF(x, y, z), degrees);
169  EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply());
170}
171
172TEST(TransformOperationTest, ApplyScale) {
173  double x = 1;
174  double y = 2;
175  double z = 3;
176  TransformOperations operations;
177  operations.AppendScale(x, y, z);
178  gfx::Transform expected;
179  expected.Scale3d(x, y, z);
180  EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply());
181}
182
183TEST(TransformOperationTest, ApplySkew) {
184  double x = 1;
185  double y = 2;
186  TransformOperations operations;
187  operations.AppendSkew(x, y);
188  gfx::Transform expected;
189  expected.SkewX(x);
190  expected.SkewY(y);
191  EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply());
192}
193
194TEST(TransformOperationTest, ApplyPerspective) {
195  double depth = 800;
196  TransformOperations operations;
197  operations.AppendPerspective(depth);
198  gfx::Transform expected;
199  expected.ApplyPerspectiveDepth(depth);
200  EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply());
201}
202
203TEST(TransformOperationTest, ApplyMatrix) {
204  double dx = 1;
205  double dy = 2;
206  double dz = 3;
207  gfx::Transform expected_matrix;
208  expected_matrix.Translate3d(dx, dy, dz);
209  TransformOperations matrix_transform;
210  matrix_transform.AppendMatrix(expected_matrix);
211  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_matrix, matrix_transform.Apply());
212}
213
214TEST(TransformOperationTest, ApplyOrder) {
215  double sx = 2;
216  double sy = 4;
217  double sz = 8;
218
219  double dx = 1;
220  double dy = 2;
221  double dz = 3;
222
223  TransformOperations operations;
224  operations.AppendScale(sx, sy, sz);
225  operations.AppendTranslate(dx, dy, dz);
226
227  gfx::Transform expected_scale_matrix;
228  expected_scale_matrix.Scale3d(sx, sy, sz);
229
230  gfx::Transform expected_translate_matrix;
231  expected_translate_matrix.Translate3d(dx, dy, dz);
232
233  gfx::Transform expected_combined_matrix = expected_scale_matrix;
234  expected_combined_matrix.PreconcatTransform(expected_translate_matrix);
235
236  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_combined_matrix, operations.Apply());
237}
238
239TEST(TransformOperationTest, BlendOrder) {
240  double sx1 = 2;
241  double sy1 = 4;
242  double sz1 = 8;
243
244  double dx1 = 1;
245  double dy1 = 2;
246  double dz1 = 3;
247
248  double sx2 = 4;
249  double sy2 = 8;
250  double sz2 = 16;
251
252  double dx2 = 10;
253  double dy2 = 20;
254  double dz2 = 30;
255
256  TransformOperations operations_from;
257  operations_from.AppendScale(sx1, sy1, sz1);
258  operations_from.AppendTranslate(dx1, dy1, dz1);
259
260  TransformOperations operations_to;
261  operations_to.AppendScale(sx2, sy2, sz2);
262  operations_to.AppendTranslate(dx2, dy2, dz2);
263
264  gfx::Transform scale_from;
265  scale_from.Scale3d(sx1, sy1, sz1);
266  gfx::Transform translate_from;
267  translate_from.Translate3d(dx1, dy1, dz1);
268
269  gfx::Transform scale_to;
270  scale_to.Scale3d(sx2, sy2, sz2);
271  gfx::Transform translate_to;
272  translate_to.Translate3d(dx2, dy2, dz2);
273
274  double progress = 0.25;
275
276  gfx::Transform blended_scale = scale_to;
277  blended_scale.Blend(scale_from, progress);
278
279  gfx::Transform blended_translate = translate_to;
280  blended_translate.Blend(translate_from, progress);
281
282  gfx::Transform expected = blended_scale;
283  expected.PreconcatTransform(blended_translate);
284
285  EXPECT_TRANSFORMATION_MATRIX_EQ(
286      expected, operations_to.Blend(operations_from, progress));
287}
288
289static void CheckProgress(double progress,
290              const gfx::Transform& from_matrix,
291              const gfx::Transform& to_matrix,
292              const TransformOperations& from_transform,
293              const TransformOperations& to_transform) {
294  gfx::Transform expected_matrix = to_matrix;
295  expected_matrix.Blend(from_matrix, progress);
296  EXPECT_TRANSFORMATION_MATRIX_EQ(
297      expected_matrix, to_transform.Blend(from_transform, progress));
298}
299
300TEST(TransformOperationTest, BlendProgress) {
301  double sx = 2;
302  double sy = 4;
303  double sz = 8;
304  TransformOperations operations_from;
305  operations_from.AppendScale(sx, sy, sz);
306
307  gfx::Transform matrix_from;
308  matrix_from.Scale3d(sx, sy, sz);
309
310  sx = 4;
311  sy = 8;
312  sz = 16;
313  TransformOperations operations_to;
314  operations_to.AppendScale(sx, sy, sz);
315
316  gfx::Transform matrix_to;
317  matrix_to.Scale3d(sx, sy, sz);
318
319  CheckProgress(-1, matrix_from, matrix_to, operations_from, operations_to);
320  CheckProgress(0, matrix_from, matrix_to, operations_from, operations_to);
321  CheckProgress(0.25, matrix_from, matrix_to, operations_from, operations_to);
322  CheckProgress(0.5, matrix_from, matrix_to, operations_from, operations_to);
323  CheckProgress(1, matrix_from, matrix_to, operations_from, operations_to);
324  CheckProgress(2, matrix_from, matrix_to, operations_from, operations_to);
325}
326
327TEST(TransformOperationTest, BlendWhenTypesDoNotMatch) {
328  double sx1 = 2;
329  double sy1 = 4;
330  double sz1 = 8;
331
332  double dx1 = 1;
333  double dy1 = 2;
334  double dz1 = 3;
335
336  double sx2 = 4;
337  double sy2 = 8;
338  double sz2 = 16;
339
340  double dx2 = 10;
341  double dy2 = 20;
342  double dz2 = 30;
343
344  TransformOperations operations_from;
345  operations_from.AppendScale(sx1, sy1, sz1);
346  operations_from.AppendTranslate(dx1, dy1, dz1);
347
348  TransformOperations operations_to;
349  operations_to.AppendTranslate(dx2, dy2, dz2);
350  operations_to.AppendScale(sx2, sy2, sz2);
351
352  gfx::Transform from;
353  from.Scale3d(sx1, sy1, sz1);
354  from.Translate3d(dx1, dy1, dz1);
355
356  gfx::Transform to;
357  to.Translate3d(dx2, dy2, dz2);
358  to.Scale3d(sx2, sy2, sz2);
359
360  double progress = 0.25;
361
362  gfx::Transform expected = to;
363  expected.Blend(from, progress);
364
365  EXPECT_TRANSFORMATION_MATRIX_EQ(
366      expected, operations_to.Blend(operations_from, progress));
367}
368
369TEST(TransformOperationTest, LargeRotationsWithSameAxis) {
370  TransformOperations operations_from;
371  operations_from.AppendRotate(0, 0, 1, 0);
372
373  TransformOperations operations_to;
374  operations_to.AppendRotate(0, 0, 2, 360);
375
376  double progress = 0.5;
377
378  gfx::Transform expected;
379  expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
380
381  EXPECT_TRANSFORMATION_MATRIX_EQ(
382      expected, operations_to.Blend(operations_from, progress));
383}
384
385TEST(TransformOperationTest, LargeRotationsWithSameAxisInDifferentDirection) {
386  TransformOperations operations_from;
387  operations_from.AppendRotate(0, 0, 1, 180);
388
389  TransformOperations operations_to;
390  operations_to.AppendRotate(0, 0, -1, 180);
391
392  double progress = 0.5;
393
394  gfx::Transform expected;
395
396  EXPECT_TRANSFORMATION_MATRIX_EQ(
397      expected, operations_to.Blend(operations_from, progress));
398}
399
400TEST(TransformOperationTest, LargeRotationsWithDifferentAxes) {
401  TransformOperations operations_from;
402  operations_from.AppendRotate(0, 0, 1, 175);
403
404  TransformOperations operations_to;
405  operations_to.AppendRotate(0, 1, 0, 175);
406
407  double progress = 0.5;
408  gfx::Transform matrix_from;
409  matrix_from.RotateAbout(gfx::Vector3dF(0, 0, 1), 175);
410
411  gfx::Transform matrix_to;
412  matrix_to.RotateAbout(gfx::Vector3dF(0, 1, 0), 175);
413
414  gfx::Transform expected = matrix_to;
415  expected.Blend(matrix_from, progress);
416
417  EXPECT_TRANSFORMATION_MATRIX_EQ(
418      expected, operations_to.Blend(operations_from, progress));
419}
420
421TEST(TransformOperationTest, BlendRotationFromIdentity) {
422  ScopedVector<TransformOperations> identity_operations;
423  GetIdentityOperations(&identity_operations);
424
425  for (size_t i = 0; i < identity_operations.size(); ++i) {
426    TransformOperations operations;
427    operations.AppendRotate(0, 0, 1, 360);
428
429    double progress = 0.5;
430
431    gfx::Transform expected;
432    expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
433
434    EXPECT_TRANSFORMATION_MATRIX_EQ(
435        expected, operations.Blend(*identity_operations[i], progress));
436
437    progress = -0.5;
438
439    expected.MakeIdentity();
440    expected.RotateAbout(gfx::Vector3dF(0, 0, 1), -180);
441
442    EXPECT_TRANSFORMATION_MATRIX_EQ(
443        expected, operations.Blend(*identity_operations[i], progress));
444
445    progress = 1.5;
446
447    expected.MakeIdentity();
448    expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 540);
449
450    EXPECT_TRANSFORMATION_MATRIX_EQ(
451        expected, operations.Blend(*identity_operations[i], progress));
452  }
453}
454
455TEST(TransformOperationTest, BlendTranslationFromIdentity) {
456  ScopedVector<TransformOperations> identity_operations;
457  GetIdentityOperations(&identity_operations);
458
459  for (size_t i = 0; i < identity_operations.size(); ++i) {
460    TransformOperations operations;
461    operations.AppendTranslate(2, 2, 2);
462
463    double progress = 0.5;
464
465    gfx::Transform expected;
466    expected.Translate3d(1, 1, 1);
467
468    EXPECT_TRANSFORMATION_MATRIX_EQ(
469        expected, operations.Blend(*identity_operations[i], progress));
470
471    progress = -0.5;
472
473    expected.MakeIdentity();
474    expected.Translate3d(-1, -1, -1);
475
476    EXPECT_TRANSFORMATION_MATRIX_EQ(
477        expected, operations.Blend(*identity_operations[i], progress));
478
479    progress = 1.5;
480
481    expected.MakeIdentity();
482    expected.Translate3d(3, 3, 3);
483
484    EXPECT_TRANSFORMATION_MATRIX_EQ(
485        expected, operations.Blend(*identity_operations[i], progress));
486  }
487}
488
489TEST(TransformOperationTest, BlendScaleFromIdentity) {
490  ScopedVector<TransformOperations> identity_operations;
491  GetIdentityOperations(&identity_operations);
492
493  for (size_t i = 0; i < identity_operations.size(); ++i) {
494    TransformOperations operations;
495    operations.AppendScale(3, 3, 3);
496
497    double progress = 0.5;
498
499    gfx::Transform expected;
500    expected.Scale3d(2, 2, 2);
501
502    EXPECT_TRANSFORMATION_MATRIX_EQ(
503        expected, operations.Blend(*identity_operations[i], progress));
504
505    progress = -0.5;
506
507    expected.MakeIdentity();
508    expected.Scale3d(0, 0, 0);
509
510    EXPECT_TRANSFORMATION_MATRIX_EQ(
511        expected, operations.Blend(*identity_operations[i], progress));
512
513    progress = 1.5;
514
515    expected.MakeIdentity();
516    expected.Scale3d(4, 4, 4);
517
518    EXPECT_TRANSFORMATION_MATRIX_EQ(
519        expected, operations.Blend(*identity_operations[i], progress));
520  }
521}
522
523TEST(TransformOperationTest, BlendSkewFromIdentity) {
524  ScopedVector<TransformOperations> identity_operations;
525  GetIdentityOperations(&identity_operations);
526
527  for (size_t i = 0; i < identity_operations.size(); ++i) {
528    TransformOperations operations;
529    operations.AppendSkew(2, 2);
530
531    double progress = 0.5;
532
533    gfx::Transform expected;
534    expected.SkewX(1);
535    expected.SkewY(1);
536
537    EXPECT_TRANSFORMATION_MATRIX_EQ(
538        expected, operations.Blend(*identity_operations[i], progress));
539
540    progress = -0.5;
541
542    expected.MakeIdentity();
543    expected.SkewX(-1);
544    expected.SkewY(-1);
545
546    EXPECT_TRANSFORMATION_MATRIX_EQ(
547        expected, operations.Blend(*identity_operations[i], progress));
548
549    progress = 1.5;
550
551    expected.MakeIdentity();
552    expected.SkewX(3);
553    expected.SkewY(3);
554
555    EXPECT_TRANSFORMATION_MATRIX_EQ(
556        expected, operations.Blend(*identity_operations[i], progress));
557  }
558}
559
560TEST(TransformOperationTest, BlendPerspectiveFromIdentity) {
561  ScopedVector<TransformOperations> identity_operations;
562  GetIdentityOperations(&identity_operations);
563
564  for (size_t i = 0; i < identity_operations.size(); ++i) {
565    TransformOperations operations;
566    operations.AppendPerspective(1000);
567
568    double progress = 0.5;
569
570    gfx::Transform expected;
571    expected.ApplyPerspectiveDepth(
572        500 + 0.5 * std::numeric_limits<double>::max());
573
574    EXPECT_TRANSFORMATION_MATRIX_EQ(
575        expected, operations.Blend(*identity_operations[i], progress));
576  }
577}
578
579TEST(TransformOperationTest, BlendRotationToIdentity) {
580  ScopedVector<TransformOperations> identity_operations;
581  GetIdentityOperations(&identity_operations);
582
583  for (size_t i = 0; i < identity_operations.size(); ++i) {
584    TransformOperations operations;
585    operations.AppendRotate(0, 0, 1, 360);
586
587    double progress = 0.5;
588
589    gfx::Transform expected;
590    expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
591
592    EXPECT_TRANSFORMATION_MATRIX_EQ(
593        expected, identity_operations[i]->Blend(operations, progress));
594  }
595}
596
597TEST(TransformOperationTest, BlendTranslationToIdentity) {
598  ScopedVector<TransformOperations> identity_operations;
599  GetIdentityOperations(&identity_operations);
600
601  for (size_t i = 0; i < identity_operations.size(); ++i) {
602    TransformOperations operations;
603    operations.AppendTranslate(2, 2, 2);
604
605    double progress = 0.5;
606
607    gfx::Transform expected;
608    expected.Translate3d(1, 1, 1);
609
610    EXPECT_TRANSFORMATION_MATRIX_EQ(
611        expected, identity_operations[i]->Blend(operations, progress));
612  }
613}
614
615TEST(TransformOperationTest, BlendScaleToIdentity) {
616  ScopedVector<TransformOperations> identity_operations;
617  GetIdentityOperations(&identity_operations);
618
619  for (size_t i = 0; i < identity_operations.size(); ++i) {
620    TransformOperations operations;
621    operations.AppendScale(3, 3, 3);
622
623    double progress = 0.5;
624
625    gfx::Transform expected;
626    expected.Scale3d(2, 2, 2);
627
628    EXPECT_TRANSFORMATION_MATRIX_EQ(
629        expected, identity_operations[i]->Blend(operations, progress));
630  }
631}
632
633TEST(TransformOperationTest, BlendSkewToIdentity) {
634  ScopedVector<TransformOperations> identity_operations;
635  GetIdentityOperations(&identity_operations);
636
637  for (size_t i = 0; i < identity_operations.size(); ++i) {
638    TransformOperations operations;
639    operations.AppendSkew(2, 2);
640
641    double progress = 0.5;
642
643    gfx::Transform expected;
644    expected.SkewX(1);
645    expected.SkewY(1);
646
647    EXPECT_TRANSFORMATION_MATRIX_EQ(
648        expected, identity_operations[i]->Blend(operations, progress));
649  }
650}
651
652TEST(TransformOperationTest, BlendPerspectiveToIdentity) {
653  ScopedVector<TransformOperations> identity_operations;
654  GetIdentityOperations(&identity_operations);
655
656  for (size_t i = 0; i < identity_operations.size(); ++i) {
657    TransformOperations operations;
658    operations.AppendPerspective(1000);
659
660    double progress = 0.5;
661
662    gfx::Transform expected;
663    expected.ApplyPerspectiveDepth(
664        500 + 0.5 * std::numeric_limits<double>::max());
665
666    EXPECT_TRANSFORMATION_MATRIX_EQ(
667        expected, identity_operations[i]->Blend(operations, progress));
668  }
669}
670
671TEST(TransformOperationTest, ExtrapolatePerspectiveBlending) {
672  TransformOperations operations1;
673  operations1.AppendPerspective(1000);
674
675  TransformOperations operations2;
676  operations2.AppendPerspective(500);
677
678  gfx::Transform expected;
679  expected.ApplyPerspectiveDepth(250);
680
681  EXPECT_TRANSFORMATION_MATRIX_EQ(
682      expected, operations1.Blend(operations2, -0.5));
683
684  expected.MakeIdentity();
685  expected.ApplyPerspectiveDepth(1250);
686
687  EXPECT_TRANSFORMATION_MATRIX_EQ(
688      expected, operations1.Blend(operations2, 1.5));
689}
690
691TEST(TransformOperationTest, ExtrapolateMatrixBlending) {
692  gfx::Transform transform1;
693  transform1.Translate3d(1, 1, 1);
694  TransformOperations operations1;
695  operations1.AppendMatrix(transform1);
696
697  gfx::Transform transform2;
698  transform2.Translate3d(3, 3, 3);
699  TransformOperations operations2;
700  operations2.AppendMatrix(transform2);
701
702  gfx::Transform expected;
703  EXPECT_TRANSFORMATION_MATRIX_EQ(
704      expected, operations1.Blend(operations2, 1.5));
705
706  expected.Translate3d(4, 4, 4);
707  EXPECT_TRANSFORMATION_MATRIX_EQ(
708      expected, operations1.Blend(operations2, -0.5));
709}
710
711TEST(TransformOperationTest, BlendedBoundsWhenTypesDoNotMatch) {
712  TransformOperations operations_from;
713  operations_from.AppendScale(2.0, 4.0, 8.0);
714  operations_from.AppendTranslate(1.0, 2.0, 3.0);
715
716  TransformOperations operations_to;
717  operations_to.AppendTranslate(10.0, 20.0, 30.0);
718  operations_to.AppendScale(4.0, 8.0, 16.0);
719
720  gfx::BoxF box(1.f, 1.f, 1.f);
721  gfx::BoxF bounds;
722
723  double min_progress = 0.0;
724  double max_progress = 1.0;
725
726  EXPECT_FALSE(operations_to.BlendedBoundsForBox(
727      box, operations_from, min_progress, max_progress, &bounds));
728}
729
730TEST(TransformOperationTest, BlendedBoundsForIdentity) {
731  TransformOperations operations_from;
732  operations_from.AppendIdentity();
733  TransformOperations operations_to;
734  operations_to.AppendIdentity();
735
736  gfx::BoxF box(1.f, 2.f, 3.f);
737  gfx::BoxF bounds;
738
739  double min_progress = 0.0;
740  double max_progress = 1.0;
741
742  EXPECT_TRUE(operations_to.BlendedBoundsForBox(
743      box, operations_from, min_progress, max_progress, &bounds));
744  EXPECT_EQ(box.ToString(), bounds.ToString());
745}
746
747TEST(TransformOperationTest, BlendedBoundsForTranslate) {
748  TransformOperations operations_from;
749  operations_from.AppendTranslate(3.0, -4.0, 2.0);
750  TransformOperations operations_to;
751  operations_to.AppendTranslate(7.0, 4.0, -2.0);
752
753  gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
754  gfx::BoxF bounds;
755
756  double min_progress = -0.5;
757  double max_progress = 1.5;
758  EXPECT_TRUE(operations_to.BlendedBoundsForBox(
759      box, operations_from, min_progress, max_progress, &bounds));
760  EXPECT_EQ(gfx::BoxF(2.f, -6.f, -1.f, 12.f, 20.f, 12.f).ToString(),
761            bounds.ToString());
762
763  min_progress = 0.0;
764  max_progress = 1.0;
765  EXPECT_TRUE(operations_to.BlendedBoundsForBox(
766      box, operations_from, min_progress, max_progress, &bounds));
767  EXPECT_EQ(gfx::BoxF(4.f, -2.f, 1.f, 8.f, 12.f, 8.f).ToString(),
768            bounds.ToString());
769
770  TransformOperations identity;
771  EXPECT_TRUE(operations_to.BlendedBoundsForBox(
772        box, identity, min_progress, max_progress, &bounds));
773  EXPECT_EQ(gfx::BoxF(1.f, 2.f, 1.f, 11.f, 8.f, 6.f).ToString(),
774            bounds.ToString());
775
776  EXPECT_TRUE(identity.BlendedBoundsForBox(
777        box, operations_from, min_progress, max_progress, &bounds));
778  EXPECT_EQ(gfx::BoxF(1.f, -2.f, 3.f, 7.f, 8.f, 6.f).ToString(),
779            bounds.ToString());
780}
781
782TEST(TransformOperationTest, BlendedBoundsForScale) {
783  TransformOperations operations_from;
784  operations_from.AppendScale(3.0, 0.5, 2.0);
785  TransformOperations operations_to;
786  operations_to.AppendScale(7.0, 4.0, -2.0);
787
788  gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
789  gfx::BoxF bounds;
790
791  double min_progress = -0.5;
792  double max_progress = 1.5;
793  EXPECT_TRUE(operations_to.BlendedBoundsForBox(
794      box, operations_from, min_progress, max_progress, &bounds));
795  EXPECT_EQ(gfx::BoxF(1.f, -7.5f, -28.f, 44.f, 42.f, 56.f).ToString(),
796            bounds.ToString());
797
798  min_progress = 0.0;
799  max_progress = 1.0;
800  EXPECT_TRUE(operations_to.BlendedBoundsForBox(
801      box, operations_from, min_progress, max_progress, &bounds));
802  EXPECT_EQ(gfx::BoxF(3.f, 1.f, -14.f, 32.f, 23.f, 28.f).ToString(),
803            bounds.ToString());
804
805  TransformOperations identity;
806  EXPECT_TRUE(operations_to.BlendedBoundsForBox(
807        box, identity, min_progress, max_progress, &bounds));
808  EXPECT_EQ(gfx::BoxF(1.f, 2.f, -14.f, 34.f, 22.f, 21.f).ToString(),
809            bounds.ToString());
810
811  EXPECT_TRUE(identity.BlendedBoundsForBox(
812        box, operations_from, min_progress, max_progress, &bounds));
813  EXPECT_EQ(gfx::BoxF(1.f, 1.f, 3.f, 14.f, 5.f, 11.f).ToString(),
814            bounds.ToString());
815}
816
817TEST(TransformOperationTest, BlendedBoundsWithZeroScale) {
818  TransformOperations zero_scale;
819  zero_scale.AppendScale(0.0, 0.0, 0.0);
820  TransformOperations non_zero_scale;
821  non_zero_scale.AppendScale(2.0, -4.0, 5.0);
822
823  gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
824  gfx::BoxF bounds;
825
826  double min_progress = 0.0;
827  double max_progress = 1.0;
828  EXPECT_TRUE(zero_scale.BlendedBoundsForBox(
829      box, non_zero_scale, min_progress, max_progress, &bounds));
830  EXPECT_EQ(gfx::BoxF(0.f, -24.f, 0.f, 10.f, 24.f, 35.f).ToString(),
831            bounds.ToString());
832
833  EXPECT_TRUE(non_zero_scale.BlendedBoundsForBox(
834      box, zero_scale, min_progress, max_progress, &bounds));
835  EXPECT_EQ(gfx::BoxF(0.f, -24.f, 0.f, 10.f, 24.f, 35.f).ToString(),
836            bounds.ToString());
837
838  EXPECT_TRUE(zero_scale.BlendedBoundsForBox(
839      box, zero_scale, min_progress, max_progress, &bounds));
840  EXPECT_EQ(gfx::BoxF().ToString(), bounds.ToString());
841}
842
843TEST(TransformOperationTest, BlendedBoundsForSequence) {
844  TransformOperations operations_from;
845  operations_from.AppendTranslate(2.0, 4.0, -1.0);
846  operations_from.AppendScale(-1.0, 2.0, 3.0);
847  operations_from.AppendTranslate(1.0, -5.0, 1.0);
848  TransformOperations operations_to;
849  operations_to.AppendTranslate(6.0, -2.0, 3.0);
850  operations_to.AppendScale(-3.0, -2.0, 5.0);
851  operations_to.AppendTranslate(13.0, -1.0, 5.0);
852
853  gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
854  gfx::BoxF bounds;
855
856  double min_progress = -0.5;
857  double max_progress = 1.5;
858  EXPECT_TRUE(operations_to.BlendedBoundsForBox(
859      box, operations_from, min_progress, max_progress, &bounds));
860  EXPECT_EQ(gfx::BoxF(-57.f, -59.f, -1.f, 76.f, 112.f, 80.f).ToString(),
861            bounds.ToString());
862
863  min_progress = 0.0;
864  max_progress = 1.0;
865  EXPECT_TRUE(operations_to.BlendedBoundsForBox(
866      box, operations_from, min_progress, max_progress, &bounds));
867  EXPECT_EQ(gfx::BoxF(-32.f, -25.f, 7.f, 42.f, 44.f, 48.f).ToString(),
868            bounds.ToString());
869
870  TransformOperations identity;
871  EXPECT_TRUE(operations_to.BlendedBoundsForBox(
872        box, identity, min_progress, max_progress, &bounds));
873  EXPECT_EQ(gfx::BoxF(-33.f, -13.f, 3.f, 57.f, 19.f, 52.f).ToString(),
874            bounds.ToString());
875
876  EXPECT_TRUE(identity.BlendedBoundsForBox(
877        box, operations_from, min_progress, max_progress, &bounds));
878  EXPECT_EQ(gfx::BoxF(-7.f, -3.f, 2.f, 15.f, 23.f, 20.f).ToString(),
879            bounds.ToString());
880}
881
882}  // namespace
883}  // namespace cc
884