Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(819)

Side by Side Diff: webkit/compositor/WebTransformationMatrixTest.cpp

Issue 10920056: Make cc_unittests and webkit_compositor_unittests executable always (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rename to webkit_compositor_bindings Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/compositor/WebTransformOperationsTest.cpp ('k') | webkit/compositor/WebVideoLayerImpl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2012 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 "config.h"
6
7 #include <public/WebTransformationMatrix.h>
8
9 #include "CCGeometryTestUtils.h"
10 #include <gtest/gtest.h>
11 #include <wtf/MathExtras.h>
12
13 #define EXPECT_ROW1_EQ(a, b, c, d, matrix) \
14 EXPECT_FLOAT_EQ((a), (matrix).m11()); \
15 EXPECT_FLOAT_EQ((b), (matrix).m21()); \
16 EXPECT_FLOAT_EQ((c), (matrix).m31()); \
17 EXPECT_FLOAT_EQ((d), (matrix).m41());
18
19 #define EXPECT_ROW2_EQ(a, b, c, d, matrix) \
20 EXPECT_FLOAT_EQ((a), (matrix).m12()); \
21 EXPECT_FLOAT_EQ((b), (matrix).m22()); \
22 EXPECT_FLOAT_EQ((c), (matrix).m32()); \
23 EXPECT_FLOAT_EQ((d), (matrix).m42());
24
25 #define EXPECT_ROW3_EQ(a, b, c, d, matrix) \
26 EXPECT_FLOAT_EQ((a), (matrix).m13()); \
27 EXPECT_FLOAT_EQ((b), (matrix).m23()); \
28 EXPECT_FLOAT_EQ((c), (matrix).m33()); \
29 EXPECT_FLOAT_EQ((d), (matrix).m43());
30
31 #define EXPECT_ROW4_EQ(a, b, c, d, matrix) \
32 EXPECT_FLOAT_EQ((a), (matrix).m14()); \
33 EXPECT_FLOAT_EQ((b), (matrix).m24()); \
34 EXPECT_FLOAT_EQ((c), (matrix).m34()); \
35 EXPECT_FLOAT_EQ((d), (matrix).m44()); \
36
37 // Checking float values for equality close to zero is not robust using EXPECT_F LOAT_EQ
38 // (see gtest documentation). So, to verify rotation matrices, we must use a loo ser
39 // absolute error threshold in some places.
40 #define EXPECT_ROW1_NEAR(a, b, c, d, matrix, errorThreshold) \
41 EXPECT_NEAR((a), (matrix).m11(), (errorThreshold)); \
42 EXPECT_NEAR((b), (matrix).m21(), (errorThreshold)); \
43 EXPECT_NEAR((c), (matrix).m31(), (errorThreshold)); \
44 EXPECT_NEAR((d), (matrix).m41(), (errorThreshold));
45
46 #define EXPECT_ROW2_NEAR(a, b, c, d, matrix, errorThreshold) \
47 EXPECT_NEAR((a), (matrix).m12(), (errorThreshold)); \
48 EXPECT_NEAR((b), (matrix).m22(), (errorThreshold)); \
49 EXPECT_NEAR((c), (matrix).m32(), (errorThreshold)); \
50 EXPECT_NEAR((d), (matrix).m42(), (errorThreshold));
51
52 #define EXPECT_ROW3_NEAR(a, b, c, d, matrix, errorThreshold) \
53 EXPECT_NEAR((a), (matrix).m13(), (errorThreshold)); \
54 EXPECT_NEAR((b), (matrix).m23(), (errorThreshold)); \
55 EXPECT_NEAR((c), (matrix).m33(), (errorThreshold)); \
56 EXPECT_NEAR((d), (matrix).m43(), (errorThreshold));
57
58 #define ERROR_THRESHOLD 1e-14
59 #define LOOSE_ERROR_THRESHOLD 1e-7
60
61 using namespace WebKit;
62
63 namespace {
64
65 static void initializeTestMatrix(WebTransformationMatrix& transform)
66 {
67 transform.setM11(10);
68 transform.setM12(11);
69 transform.setM13(12);
70 transform.setM14(13);
71 transform.setM21(14);
72 transform.setM22(15);
73 transform.setM23(16);
74 transform.setM24(17);
75 transform.setM31(18);
76 transform.setM32(19);
77 transform.setM33(20);
78 transform.setM34(21);
79 transform.setM41(22);
80 transform.setM42(23);
81 transform.setM43(24);
82 transform.setM44(25);
83
84 // Sanity check
85 EXPECT_ROW1_EQ(10, 14, 18, 22, transform);
86 EXPECT_ROW2_EQ(11, 15, 19, 23, transform);
87 EXPECT_ROW3_EQ(12, 16, 20, 24, transform);
88 EXPECT_ROW4_EQ(13, 17, 21, 25, transform);
89 }
90
91 static void initializeTestMatrix2(WebTransformationMatrix& transform)
92 {
93 transform.setM11(30);
94 transform.setM12(31);
95 transform.setM13(32);
96 transform.setM14(33);
97 transform.setM21(34);
98 transform.setM22(35);
99 transform.setM23(36);
100 transform.setM24(37);
101 transform.setM31(38);
102 transform.setM32(39);
103 transform.setM33(40);
104 transform.setM34(41);
105 transform.setM41(42);
106 transform.setM42(43);
107 transform.setM43(44);
108 transform.setM44(45);
109
110 // Sanity check
111 EXPECT_ROW1_EQ(30, 34, 38, 42, transform);
112 EXPECT_ROW2_EQ(31, 35, 39, 43, transform);
113 EXPECT_ROW3_EQ(32, 36, 40, 44, transform);
114 EXPECT_ROW4_EQ(33, 37, 41, 45, transform);
115 }
116
117 TEST(WebTransformationMatrixTest, verifyDefaultConstructorCreatesIdentityMatrix)
118 {
119 WebTransformationMatrix A;
120 EXPECT_ROW1_EQ(1, 0, 0, 0, A);
121 EXPECT_ROW2_EQ(0, 1, 0, 0, A);
122 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
123 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
124 EXPECT_TRUE(A.isIdentity());
125 }
126
127 TEST(WebTransformationMatrixTest, verifyConstructorFor2dElements)
128 {
129 WebTransformationMatrix A(1, 2, 3, 4, 5, 6);
130 EXPECT_ROW1_EQ(1, 3, 0, 5, A);
131 EXPECT_ROW2_EQ(2, 4, 0, 6, A);
132 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
133 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
134 }
135
136 TEST(WebTransformationMatrixTest, verifyConstructorForAllElements)
137 {
138 WebTransformationMatrix A(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
139 EXPECT_ROW1_EQ(1, 5, 9, 13, A);
140 EXPECT_ROW2_EQ(2, 6, 10, 14, A);
141 EXPECT_ROW3_EQ(3, 7, 11, 15, A);
142 EXPECT_ROW4_EQ(4, 8, 12, 16, A);
143 }
144
145 TEST(WebTransformationMatrixTest, verifyCopyConstructor)
146 {
147 WebTransformationMatrix A;
148 initializeTestMatrix(A);
149
150 // Copy constructor should produce exact same elements as matrix A.
151 WebTransformationMatrix B(A);
152 EXPECT_ROW1_EQ(10, 14, 18, 22, B);
153 EXPECT_ROW2_EQ(11, 15, 19, 23, B);
154 EXPECT_ROW3_EQ(12, 16, 20, 24, B);
155 EXPECT_ROW4_EQ(13, 17, 21, 25, B);
156 }
157
158 TEST(WebTransformationMatrixTest, verifyMatrixInversion)
159 {
160 // Invert a translation
161 WebTransformationMatrix translation;
162 translation.translate3d(2, 3, 4);
163 EXPECT_TRUE(translation.isInvertible());
164
165 WebTransformationMatrix inverseTranslation = translation.inverse();
166 EXPECT_ROW1_EQ(1, 0, 0, -2, inverseTranslation);
167 EXPECT_ROW2_EQ(0, 1, 0, -3, inverseTranslation);
168 EXPECT_ROW3_EQ(0, 0, 1, -4, inverseTranslation);
169 EXPECT_ROW4_EQ(0, 0, 0, 1, inverseTranslation);
170
171 // Note that inversion should not have changed the original matrix.
172 EXPECT_ROW1_EQ(1, 0, 0, 2, translation);
173 EXPECT_ROW2_EQ(0, 1, 0, 3, translation);
174 EXPECT_ROW3_EQ(0, 0, 1, 4, translation);
175 EXPECT_ROW4_EQ(0, 0, 0, 1, translation);
176
177 // Invert a non-uniform scale
178 WebTransformationMatrix scale;
179 scale.scale3d(4, 10, 100);
180 EXPECT_TRUE(scale.isInvertible());
181
182 WebTransformationMatrix inverseScale = scale.inverse();
183 EXPECT_ROW1_EQ(0.25, 0, 0, 0, inverseScale);
184 EXPECT_ROW2_EQ(0, .1f, 0, 0, inverseScale);
185 EXPECT_ROW3_EQ(0, 0, .01f, 0, inverseScale);
186 EXPECT_ROW4_EQ(0, 0, 0, 1, inverseScale);
187
188 // Try to invert a matrix that is not invertible.
189 // The inverse() function should simply return an identity matrix.
190 WebTransformationMatrix notInvertible;
191 notInvertible.setM11(0);
192 notInvertible.setM22(0);
193 notInvertible.setM33(0);
194 notInvertible.setM44(0);
195 EXPECT_FALSE(notInvertible.isInvertible());
196
197 WebTransformationMatrix inverseOfNotInvertible;
198 initializeTestMatrix(inverseOfNotInvertible); // initialize this to somethin g non-identity, to make sure that assignment below actually took place.
199 inverseOfNotInvertible = notInvertible.inverse();
200 EXPECT_TRUE(inverseOfNotInvertible.isIdentity());
201 }
202
203 TEST(WebTransformationMatrixTest, verifyTo2DTransform)
204 {
205 WebTransformationMatrix A;
206 initializeTestMatrix(A);
207
208 WebTransformationMatrix B = A.to2dTransform();
209
210 EXPECT_ROW1_EQ(10, 14, 0, 22, B);
211 EXPECT_ROW2_EQ(11, 15, 0, 23, B);
212 EXPECT_ROW3_EQ(0, 0, 1, 0, B);
213 EXPECT_ROW4_EQ(13, 17, 0, 25, B);
214
215 // Note that to2DTransform should not have changed the original matrix.
216 EXPECT_ROW1_EQ(10, 14, 18, 22, A);
217 EXPECT_ROW2_EQ(11, 15, 19, 23, A);
218 EXPECT_ROW3_EQ(12, 16, 20, 24, A);
219 EXPECT_ROW4_EQ(13, 17, 21, 25, A);
220 }
221
222 TEST(WebTransformationMatrixTest, verifyAssignmentOperator)
223 {
224 WebTransformationMatrix A;
225 initializeTestMatrix(A);
226 WebTransformationMatrix B;
227 initializeTestMatrix2(B);
228 WebTransformationMatrix C;
229 initializeTestMatrix2(C);
230 C = B = A;
231
232 // Both B and C should now have been re-assigned to the value of A.
233 EXPECT_ROW1_EQ(10, 14, 18, 22, B);
234 EXPECT_ROW2_EQ(11, 15, 19, 23, B);
235 EXPECT_ROW3_EQ(12, 16, 20, 24, B);
236 EXPECT_ROW4_EQ(13, 17, 21, 25, B);
237
238 EXPECT_ROW1_EQ(10, 14, 18, 22, C);
239 EXPECT_ROW2_EQ(11, 15, 19, 23, C);
240 EXPECT_ROW3_EQ(12, 16, 20, 24, C);
241 EXPECT_ROW4_EQ(13, 17, 21, 25, C);
242 }
243
244 TEST(WebTransformationMatrixTest, verifyEqualsBooleanOperator)
245 {
246 WebTransformationMatrix A;
247 initializeTestMatrix(A);
248
249 WebTransformationMatrix B;
250 initializeTestMatrix(B);
251 EXPECT_TRUE(A == B);
252
253 // Modifying multiple elements should cause equals operator to return false.
254 WebTransformationMatrix C;
255 initializeTestMatrix2(C);
256 EXPECT_FALSE(A == C);
257
258 // Modifying any one individual element should cause equals operator to retu rn false.
259 WebTransformationMatrix D;
260 D = A;
261 D.setM11(0);
262 EXPECT_FALSE(A == D);
263
264 D = A;
265 D.setM12(0);
266 EXPECT_FALSE(A == D);
267
268 D = A;
269 D.setM13(0);
270 EXPECT_FALSE(A == D);
271
272 D = A;
273 D.setM14(0);
274 EXPECT_FALSE(A == D);
275
276 D = A;
277 D.setM21(0);
278 EXPECT_FALSE(A == D);
279
280 D = A;
281 D.setM22(0);
282 EXPECT_FALSE(A == D);
283
284 D = A;
285 D.setM23(0);
286 EXPECT_FALSE(A == D);
287
288 D = A;
289 D.setM24(0);
290 EXPECT_FALSE(A == D);
291
292 D = A;
293 D.setM31(0);
294 EXPECT_FALSE(A == D);
295
296 D = A;
297 D.setM32(0);
298 EXPECT_FALSE(A == D);
299
300 D = A;
301 D.setM33(0);
302 EXPECT_FALSE(A == D);
303
304 D = A;
305 D.setM34(0);
306 EXPECT_FALSE(A == D);
307
308 D = A;
309 D.setM41(0);
310 EXPECT_FALSE(A == D);
311
312 D = A;
313 D.setM42(0);
314 EXPECT_FALSE(A == D);
315
316 D = A;
317 D.setM43(0);
318 EXPECT_FALSE(A == D);
319
320 D = A;
321 D.setM44(0);
322 EXPECT_FALSE(A == D);
323 }
324
325 TEST(WebTransformationMatrixTest, verifyMultiplyOperator)
326 {
327 WebTransformationMatrix A;
328 initializeTestMatrix(A);
329
330 WebTransformationMatrix B;
331 initializeTestMatrix2(B);
332
333 WebTransformationMatrix C = A * B;
334 EXPECT_ROW1_EQ(2036, 2292, 2548, 2804, C);
335 EXPECT_ROW2_EQ(2162, 2434, 2706, 2978, C);
336 EXPECT_ROW3_EQ(2288, 2576, 2864, 3152, C);
337 EXPECT_ROW4_EQ(2414, 2718, 3022, 3326, C);
338
339 // Just an additional sanity check; matrix multiplication is not commutative .
340 EXPECT_FALSE(A * B == B * A);
341 }
342
343 TEST(WebTransformationMatrixTest, verifyMatrixMultiplication)
344 {
345 WebTransformationMatrix A;
346 initializeTestMatrix(A);
347
348 WebTransformationMatrix B;
349 initializeTestMatrix2(B);
350
351 A.multiply(B);
352 EXPECT_ROW1_EQ(2036, 2292, 2548, 2804, A);
353 EXPECT_ROW2_EQ(2162, 2434, 2706, 2978, A);
354 EXPECT_ROW3_EQ(2288, 2576, 2864, 3152, A);
355 EXPECT_ROW4_EQ(2414, 2718, 3022, 3326, A);
356 }
357
358 TEST(WebTransformationMatrixTest, verifyMakeIdentiy)
359 {
360 WebTransformationMatrix A;
361 initializeTestMatrix(A);
362 A.makeIdentity();
363 EXPECT_ROW1_EQ(1, 0, 0, 0, A);
364 EXPECT_ROW2_EQ(0, 1, 0, 0, A);
365 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
366 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
367 EXPECT_TRUE(A.isIdentity());
368 }
369
370 TEST(WebTransformationMatrixTest, verifyTranslate)
371 {
372 WebTransformationMatrix A;
373 A.translate(2, 3);
374 EXPECT_ROW1_EQ(1, 0, 0, 2, A);
375 EXPECT_ROW2_EQ(0, 1, 0, 3, A);
376 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
377 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
378
379 // Verify that translate() post-multiplies the existing matrix.
380 A.makeIdentity();
381 A.scale(5);
382 A.translate(2, 3);
383 EXPECT_ROW1_EQ(5, 0, 0, 10, A);
384 EXPECT_ROW2_EQ(0, 5, 0, 15, A);
385 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
386 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
387 }
388
389 TEST(WebTransformationMatrixTest, verifyTranslate3d)
390 {
391 WebTransformationMatrix A;
392 A.translate3d(2, 3, 4);
393 EXPECT_ROW1_EQ(1, 0, 0, 2, A);
394 EXPECT_ROW2_EQ(0, 1, 0, 3, A);
395 EXPECT_ROW3_EQ(0, 0, 1, 4, A);
396 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
397
398 // Verify that translate3d() post-multiplies the existing matrix.
399 A.makeIdentity();
400 A.scale3d(6, 7, 8);
401 A.translate3d(2, 3, 4);
402 EXPECT_ROW1_EQ(6, 0, 0, 12, A);
403 EXPECT_ROW2_EQ(0, 7, 0, 21, A);
404 EXPECT_ROW3_EQ(0, 0, 8, 32, A);
405 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
406 }
407
408 TEST(WebTransformationMatrixTest, verifyTranslateRight3d)
409 {
410 WebTransformationMatrix A;
411 A.translateRight3d(2, 3, 4);
412 EXPECT_ROW1_EQ(1, 0, 0, 2, A);
413 EXPECT_ROW2_EQ(0, 1, 0, 3, A);
414 EXPECT_ROW3_EQ(0, 0, 1, 4, A);
415 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
416
417 // Note carefully, all other operations do post-multiply, this one is unique .
418 // Verify that translateRight3d() PRE-multiplies the existing matrix.
419 A.makeIdentity();
420 A.scale3d(6, 7, 8);
421 A.translateRight3d(2, 3, 4);
422 EXPECT_ROW1_EQ(6, 0, 0, 2, A);
423 EXPECT_ROW2_EQ(0, 7, 0, 3, A);
424 EXPECT_ROW3_EQ(0, 0, 8, 4, A);
425 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
426 }
427
428 TEST(WebTransformationMatrixTest, verifyScale)
429 {
430 WebTransformationMatrix A;
431 A.scale(5);
432 EXPECT_ROW1_EQ(5, 0, 0, 0, A);
433 EXPECT_ROW2_EQ(0, 5, 0, 0, A);
434 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
435 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
436
437 // Verify that scale() post-multiplies the existing matrix.
438 A.makeIdentity();
439 A.translate3d(2, 3, 4);
440 A.scale(5);
441 EXPECT_ROW1_EQ(5, 0, 0, 2, A);
442 EXPECT_ROW2_EQ(0, 5, 0, 3, A);
443 EXPECT_ROW3_EQ(0, 0, 1, 4, A);
444 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
445 }
446
447 TEST(WebTransformationMatrixTest, verifyNonUniformScale)
448 {
449 WebTransformationMatrix A;
450 A.scaleNonUniform(6, 7);
451 EXPECT_ROW1_EQ(6, 0, 0, 0, A);
452 EXPECT_ROW2_EQ(0, 7, 0, 0, A);
453 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
454 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
455
456 // Verify that scaleNonUniform() post-multiplies the existing matrix.
457 A.makeIdentity();
458 A.translate3d(2, 3, 4);
459 A.scaleNonUniform(6, 7);
460 EXPECT_ROW1_EQ(6, 0, 0, 2, A);
461 EXPECT_ROW2_EQ(0, 7, 0, 3, A);
462 EXPECT_ROW3_EQ(0, 0, 1, 4, A);
463 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
464 }
465
466 TEST(WebTransformationMatrixTest, verifyScale3d)
467 {
468 WebTransformationMatrix A;
469 A.scale3d(6, 7, 8);
470 EXPECT_ROW1_EQ(6, 0, 0, 0, A);
471 EXPECT_ROW2_EQ(0, 7, 0, 0, A);
472 EXPECT_ROW3_EQ(0, 0, 8, 0, A);
473 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
474
475 // Verify that scale3d() post-multiplies the existing matrix.
476 A.makeIdentity();
477 A.translate3d(2, 3, 4);
478 A.scale3d(6, 7, 8);
479 EXPECT_ROW1_EQ(6, 0, 0, 2, A);
480 EXPECT_ROW2_EQ(0, 7, 0, 3, A);
481 EXPECT_ROW3_EQ(0, 0, 8, 4, A);
482 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
483 }
484
485 TEST(WebTransformationMatrixTest, verifyRotate)
486 {
487 WebTransformationMatrix A;
488 A.rotate(90);
489 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD);
490 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD);
491 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
492 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
493
494 // Verify that rotate() post-multiplies the existing matrix.
495 A.makeIdentity();
496 A.scale3d(6, 7, 8);
497 A.rotate(90);
498 EXPECT_ROW1_NEAR(0, -6, 0, 0, A, ERROR_THRESHOLD);
499 EXPECT_ROW2_NEAR(7, 0, 0, 0, A, ERROR_THRESHOLD);
500 EXPECT_ROW3_EQ(0, 0, 8, 0, A);
501 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
502 }
503
504 TEST(WebTransformationMatrixTest, verifyRotate3d)
505 {
506 WebTransformationMatrix A;
507
508 // Check rotation about z-axis
509 A.makeIdentity();
510 A.rotate3d(0, 0, 90);
511 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD);
512 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD);
513 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
514 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
515
516 // Check rotation about x-axis
517 A.makeIdentity();
518 A.rotate3d(90, 0, 0);
519 EXPECT_ROW1_EQ(1, 0, 0, 0, A);
520 EXPECT_ROW2_NEAR(0, 0, -1, 0, A, ERROR_THRESHOLD);
521 EXPECT_ROW3_NEAR(0, 1, 0, 0, A, ERROR_THRESHOLD);
522 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
523
524 // Check rotation about y-axis.
525 // Note carefully, the expected pattern is inverted compared to rotating abo ut x axis or z axis.
526 A.makeIdentity();
527 A.rotate3d(0, 90, 0);
528 EXPECT_ROW1_NEAR(0, 0, 1, 0, A, ERROR_THRESHOLD);
529 EXPECT_ROW2_EQ(0, 1, 0, 0, A);
530 EXPECT_ROW3_NEAR(-1, 0, 0, 0, A, ERROR_THRESHOLD);
531 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
532
533 // Verify that rotate3d(rx, ry, rz) post-multiplies the existing matrix.
534 A.makeIdentity();
535 A.scale3d(6, 7, 8);
536 A.rotate3d(0, 0, 90);
537 EXPECT_ROW1_NEAR(0, -6, 0, 0, A, ERROR_THRESHOLD);
538 EXPECT_ROW2_NEAR(7, 0, 0, 0, A, ERROR_THRESHOLD);
539 EXPECT_ROW3_EQ(0, 0, 8, 0, A);
540 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
541 }
542
543 TEST(WebTransformationMatrixTest, verifyRotate3dOrderOfCompositeRotations)
544 {
545 // Rotate3d(degreesX, degreesY, degreesZ) is actually composite transform co nsiting of
546 // three primitive rotations. This test verifies that the ordering of those three
547 // transforms is the intended ordering.
548 //
549 // The correct ordering for this test case should be:
550 // 1. rotate by 30 degrees about z-axis
551 // 2. rotate by 20 degrees about y-axis
552 // 3. rotate by 10 degrees about x-axis
553 //
554 // Note: there are 6 possible orderings of 3 transforms. For the specific tr ansforms
555 // used in this test, all 6 combinations produce a unique matrix that is dif ferent
556 // from the other orderings. That way, this test verifies the exact ordering .
557
558 WebTransformationMatrix A;
559 A.makeIdentity();
560 A.rotate3d(10, 20, 30);
561
562 EXPECT_ROW1_NEAR(0.8137976813493738026394908,
563 -0.4409696105298823720630708,
564 0.3785223063697923939763257,
565 0, A, ERROR_THRESHOLD);
566 EXPECT_ROW2_NEAR(0.4698463103929541584413698,
567 0.8825641192593856043657752,
568 0.0180283112362972230968694,
569 0, A, ERROR_THRESHOLD);
570 EXPECT_ROW3_NEAR(-0.3420201433256686573969318,
571 0.1631759111665348205288950,
572 0.9254165783983233639631294,
573 0, A, ERROR_THRESHOLD);
574 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
575 }
576
577 TEST(WebTransformationMatrixTest, verifyRotateAxisAngle3d)
578 {
579 WebTransformationMatrix A;
580
581 // Check rotation about z-axis
582 A.makeIdentity();
583 A.rotate3d(0, 0, 1, 90);
584 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD);
585 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD);
586 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
587 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
588
589 // Check rotation about x-axis
590 A.makeIdentity();
591 A.rotate3d(1, 0, 0, 90);
592 EXPECT_ROW1_EQ(1, 0, 0, 0, A);
593 EXPECT_ROW2_NEAR(0, 0, -1, 0, A, ERROR_THRESHOLD);
594 EXPECT_ROW3_NEAR(0, 1, 0, 0, A, ERROR_THRESHOLD);
595 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
596
597 // Check rotation about y-axis.
598 // Note carefully, the expected pattern is inverted compared to rotating abo ut x axis or z axis.
599 A.makeIdentity();
600 A.rotate3d(0, 1, 0, 90);
601 EXPECT_ROW1_NEAR(0, 0, 1, 0, A, ERROR_THRESHOLD);
602 EXPECT_ROW2_EQ(0, 1, 0, 0, A);
603 EXPECT_ROW3_NEAR(-1, 0, 0, 0, A, ERROR_THRESHOLD);
604 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
605
606 // Verify that rotate3d(axis, angle) post-multiplies the existing matrix.
607 A.makeIdentity();
608 A.scale3d(6, 7, 8);
609 A.rotate3d(0, 0, 1, 90);
610 EXPECT_ROW1_NEAR(0, -6, 0, 0, A, ERROR_THRESHOLD);
611 EXPECT_ROW2_NEAR(7, 0, 0, 0, A, ERROR_THRESHOLD);
612 EXPECT_ROW3_EQ(0, 0, 8, 0, A);
613 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
614 }
615
616 TEST(WebTransformationMatrixTest, verifyRotateAxisAngle3dForArbitraryAxis)
617 {
618 // Check rotation about an arbitrary non-axis-aligned vector.
619 WebTransformationMatrix A;
620 A.rotate3d(1, 1, 1, 90);
621 EXPECT_ROW1_NEAR(0.3333333333333334258519187,
622 -0.2440169358562924717404030,
623 0.9106836025229592124219380,
624 0, A, ERROR_THRESHOLD);
625 EXPECT_ROW2_NEAR(0.9106836025229592124219380,
626 0.3333333333333334258519187,
627 -0.2440169358562924717404030,
628 0, A, ERROR_THRESHOLD);
629 EXPECT_ROW3_NEAR(-0.2440169358562924717404030,
630 0.9106836025229592124219380,
631 0.3333333333333334258519187,
632 0, A, ERROR_THRESHOLD);
633 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
634 }
635
636 TEST(WebTransformationMatrixTest, verifyRotateAxisAngle3dForDegenerateAxis)
637 {
638 // Check rotation about a degenerate zero vector.
639 // It is expected to default to rotation about the z-axis.
640 WebTransformationMatrix A;
641 A.rotate3d(0, 0, 0, 90);
642 EXPECT_ROW1_NEAR(0, -1, 0, 0, A, ERROR_THRESHOLD);
643 EXPECT_ROW2_NEAR(1, 0, 0, 0, A, ERROR_THRESHOLD);
644 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
645 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
646 }
647
648 TEST(WebTransformationMatrixTest, verifySkewX)
649 {
650 WebTransformationMatrix A;
651 A.skewX(45);
652 EXPECT_ROW1_EQ(1, 1, 0, 0, A);
653 EXPECT_ROW2_EQ(0, 1, 0, 0, A);
654 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
655 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
656
657 // Verify that skewX() post-multiplies the existing matrix.
658 // Row 1, column 2, would incorrectly have value "7" if the matrix is pre-mu ltiplied instead of post-multiplied.
659 A.makeIdentity();
660 A.scale3d(6, 7, 8);
661 A.skewX(45);
662 EXPECT_ROW1_EQ(6, 6, 0, 0, A);
663 EXPECT_ROW2_EQ(0, 7, 0, 0, A);
664 EXPECT_ROW3_EQ(0, 0, 8, 0, A);
665 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
666 }
667
668 TEST(WebTransformationMatrixTest, verifySkewY)
669 {
670 WebTransformationMatrix A;
671 A.skewY(45);
672 EXPECT_ROW1_EQ(1, 0, 0, 0, A);
673 EXPECT_ROW2_EQ(1, 1, 0, 0, A);
674 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
675 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
676
677 // Verify that skewY() post-multiplies the existing matrix.
678 // Row 2, column 1, would incorrectly have value "6" if the matrix is pre-mu ltiplied instead of post-multiplied.
679 A.makeIdentity();
680 A.scale3d(6, 7, 8);
681 A.skewY(45);
682 EXPECT_ROW1_EQ(6, 0, 0, 0, A);
683 EXPECT_ROW2_EQ(7, 7, 0, 0, A);
684 EXPECT_ROW3_EQ(0, 0, 8, 0, A);
685 EXPECT_ROW4_EQ(0, 0, 0, 1, A);
686 }
687
688 TEST(WebTransformationMatrixTest, verifyApplyPerspective)
689 {
690 WebTransformationMatrix A;
691 A.applyPerspective(1);
692 EXPECT_ROW1_EQ(1, 0, 0, 0, A);
693 EXPECT_ROW2_EQ(0, 1, 0, 0, A);
694 EXPECT_ROW3_EQ(0, 0, 1, 0, A);
695 EXPECT_ROW4_EQ(0, 0, -1, 1, A);
696
697 // Verify that applyPerspective() post-multiplies the existing matrix.
698 A.makeIdentity();
699 A.translate3d(2, 3, 4);
700 A.applyPerspective(1);
701 EXPECT_ROW1_EQ(1, 0, -2, 2, A);
702 EXPECT_ROW2_EQ(0, 1, -3, 3, A);
703 EXPECT_ROW3_EQ(0, 0, -3, 4, A);
704 EXPECT_ROW4_EQ(0, 0, -1, 1, A);
705 }
706
707 TEST(WebTransformationMatrixTest, verifyHasPerspective)
708 {
709 WebTransformationMatrix A;
710 A.applyPerspective(1);
711 EXPECT_TRUE(A.hasPerspective());
712
713 A.makeIdentity();
714 A.applyPerspective(0);
715 EXPECT_FALSE(A.hasPerspective());
716
717 A.makeIdentity();
718 A.setM34(-0.3);
719 EXPECT_TRUE(A.hasPerspective());
720
721 // FIXME: WebCore only checkes m34() for perspective, but that is probably
722 // wrong. https://bugs.webkit.org/show_bug.cgi?id=83088. For now, thi s test
723 // case expects the exact behavior as implemented by WebCore, but thi s should
724 // probably be changed so that if the entire bottom row is not exactl y
725 // (0, 0, 0, 1), then hasPerspective should return true.
726
727 A.makeIdentity();
728 A.setM14(-1);
729 EXPECT_FALSE(A.hasPerspective());
730
731 A.makeIdentity();
732 A.setM24(-1);
733 EXPECT_FALSE(A.hasPerspective());
734
735 A.makeIdentity();
736 A.setM44(0.5);
737 EXPECT_FALSE(A.hasPerspective());
738 }
739
740 TEST(WebTransformationMatrixTest, verifyIsInvertible)
741 {
742 WebTransformationMatrix A;
743
744 // Translations, rotations, scales, skews and arbitrary combinations of them are invertible.
745 A.makeIdentity();
746 EXPECT_TRUE(A.isInvertible());
747
748 A.makeIdentity();
749 A.translate3d(2, 3, 4);
750 EXPECT_TRUE(A.isInvertible());
751
752 A.makeIdentity();
753 A.scale3d(6, 7, 8);
754 EXPECT_TRUE(A.isInvertible());
755
756 A.makeIdentity();
757 A.rotate3d(10, 20, 30);
758 EXPECT_TRUE(A.isInvertible());
759
760 A.makeIdentity();
761 A.skewX(45);
762 EXPECT_TRUE(A.isInvertible());
763
764 // A perspective matrix (projection plane at z=0) is invertible. The intuiti ve
765 // explanation is that perspective is eqivalent to a skew of the w-axis; ske ws are
766 // invertible.
767 A.makeIdentity();
768 A.applyPerspective(1);
769 EXPECT_TRUE(A.isInvertible());
770
771 // A "pure" perspective matrix derived by similar triangles, with m44() set to zero
772 // (i.e. camera positioned at the origin), is not invertible.
773 A.makeIdentity();
774 A.applyPerspective(1);
775 A.setM44(0);
776 EXPECT_FALSE(A.isInvertible());
777
778 // Adding more to a non-invertible matrix will not make it invertible in the general case.
779 A.makeIdentity();
780 A.applyPerspective(1);
781 A.setM44(0);
782 A.scale3d(6, 7, 8);
783 A.rotate3d(10, 20, 30);
784 A.translate3d(6, 7, 8);
785 EXPECT_FALSE(A.isInvertible());
786
787 // A degenerate matrix of all zeros is not invertible.
788 A.makeIdentity();
789 A.setM11(0);
790 A.setM22(0);
791 A.setM33(0);
792 A.setM44(0);
793 EXPECT_FALSE(A.isInvertible());
794 }
795
796 TEST(WebTransformationMatrixTest, verifyIsIdentity)
797 {
798 WebTransformationMatrix A;
799
800 initializeTestMatrix(A);
801 EXPECT_FALSE(A.isIdentity());
802
803 A.makeIdentity();
804 EXPECT_TRUE(A.isIdentity());
805
806 // Modifying any one individual element should cause the matrix to no longer be identity.
807 A.makeIdentity();
808 A.setM11(2);
809 EXPECT_FALSE(A.isIdentity());
810
811 A.makeIdentity();
812 A.setM12(2);
813 EXPECT_FALSE(A.isIdentity());
814
815 A.makeIdentity();
816 A.setM13(2);
817 EXPECT_FALSE(A.isIdentity());
818
819 A.makeIdentity();
820 A.setM14(2);
821 EXPECT_FALSE(A.isIdentity());
822
823 A.makeIdentity();
824 A.setM21(2);
825 EXPECT_FALSE(A.isIdentity());
826
827 A.makeIdentity();
828 A.setM22(2);
829 EXPECT_FALSE(A.isIdentity());
830
831 A.makeIdentity();
832 A.setM23(2);
833 EXPECT_FALSE(A.isIdentity());
834
835 A.makeIdentity();
836 A.setM24(2);
837 EXPECT_FALSE(A.isIdentity());
838
839 A.makeIdentity();
840 A.setM31(2);
841 EXPECT_FALSE(A.isIdentity());
842
843 A.makeIdentity();
844 A.setM32(2);
845 EXPECT_FALSE(A.isIdentity());
846
847 A.makeIdentity();
848 A.setM33(2);
849 EXPECT_FALSE(A.isIdentity());
850
851 A.makeIdentity();
852 A.setM34(2);
853 EXPECT_FALSE(A.isIdentity());
854
855 A.makeIdentity();
856 A.setM41(2);
857 EXPECT_FALSE(A.isIdentity());
858
859 A.makeIdentity();
860 A.setM42(2);
861 EXPECT_FALSE(A.isIdentity());
862
863 A.makeIdentity();
864 A.setM43(2);
865 EXPECT_FALSE(A.isIdentity());
866
867 A.makeIdentity();
868 A.setM44(2);
869 EXPECT_FALSE(A.isIdentity());
870 }
871
872 TEST(WebTransformationMatrixTest, verifyIsIdentityOrTranslation)
873 {
874 WebTransformationMatrix A;
875
876 initializeTestMatrix(A);
877 EXPECT_FALSE(A.isIdentityOrTranslation());
878
879 A.makeIdentity();
880 EXPECT_TRUE(A.isIdentityOrTranslation());
881
882 // Modifying any non-translation components should cause isIdentityOrTransla tion() to
883 // return false. NOTE: m41(), m42(), and m43() are the translation component s, so
884 // modifying them should still return true for isIdentityOrTranslation().
885 A.makeIdentity();
886 A.setM11(2);
887 EXPECT_FALSE(A.isIdentityOrTranslation());
888
889 A.makeIdentity();
890 A.setM12(2);
891 EXPECT_FALSE(A.isIdentityOrTranslation());
892
893 A.makeIdentity();
894 A.setM13(2);
895 EXPECT_FALSE(A.isIdentityOrTranslation());
896
897 A.makeIdentity();
898 A.setM14(2);
899 EXPECT_FALSE(A.isIdentityOrTranslation());
900
901 A.makeIdentity();
902 A.setM21(2);
903 EXPECT_FALSE(A.isIdentityOrTranslation());
904
905 A.makeIdentity();
906 A.setM22(2);
907 EXPECT_FALSE(A.isIdentityOrTranslation());
908
909 A.makeIdentity();
910 A.setM23(2);
911 EXPECT_FALSE(A.isIdentityOrTranslation());
912
913 A.makeIdentity();
914 A.setM24(2);
915 EXPECT_FALSE(A.isIdentityOrTranslation());
916
917 A.makeIdentity();
918 A.setM31(2);
919 EXPECT_FALSE(A.isIdentityOrTranslation());
920
921 A.makeIdentity();
922 A.setM32(2);
923 EXPECT_FALSE(A.isIdentityOrTranslation());
924
925 A.makeIdentity();
926 A.setM33(2);
927 EXPECT_FALSE(A.isIdentityOrTranslation());
928
929 A.makeIdentity();
930 A.setM34(2);
931 EXPECT_FALSE(A.isIdentityOrTranslation());
932
933 // Note carefully - expecting true here.
934 A.makeIdentity();
935 A.setM41(2);
936 EXPECT_TRUE(A.isIdentityOrTranslation());
937
938 // Note carefully - expecting true here.
939 A.makeIdentity();
940 A.setM42(2);
941 EXPECT_TRUE(A.isIdentityOrTranslation());
942
943 // Note carefully - expecting true here.
944 A.makeIdentity();
945 A.setM43(2);
946 EXPECT_TRUE(A.isIdentityOrTranslation());
947
948 A.makeIdentity();
949 A.setM44(2);
950 EXPECT_FALSE(A.isIdentityOrTranslation());
951 }
952
953 TEST(WebTransformationMatrixTest, verifyIsIntegerTranslation)
954 {
955 WebTransformationMatrix A;
956
957 A.makeIdentity();
958 A.translate(2, 3);
959 EXPECT_TRUE(A.isIntegerTranslation());
960
961 A.makeIdentity();
962 A.translate(2, 3);
963 EXPECT_TRUE(A.isIntegerTranslation());
964
965 A.makeIdentity();
966 A.translate(2.00001, 3);
967 EXPECT_FALSE(A.isIntegerTranslation());
968
969 A.makeIdentity();
970 A.translate(2, 2.99999);
971 EXPECT_FALSE(A.isIntegerTranslation());
972
973 // Stacking many integer translations should ideally not accumulate any prec ision error.
974 A.makeIdentity();
975 for (int i = 0; i < 100000; ++i)
976 A.translate(2, 3);
977 EXPECT_TRUE(A.isIntegerTranslation());
978 }
979
980 TEST(WebTransformationMatrixTest, verifyBlendForTranslation)
981 {
982 WebTransformationMatrix from;
983 from.translate3d(100, 200, 100);
984
985 WebTransformationMatrix to;
986
987 to.makeIdentity();
988 to.translate3d(200, 100, 300);
989 to.blend(from, 0);
990 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
991
992 to.makeIdentity();
993 to.translate3d(200, 100, 300);
994 to.blend(from, 0.25);
995 EXPECT_ROW1_EQ(1, 0, 0, 125, to);
996 EXPECT_ROW2_EQ(0, 1, 0, 175, to);
997 EXPECT_ROW3_EQ(0, 0, 1, 150, to);
998 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
999
1000 to.makeIdentity();
1001 to.translate3d(200, 100, 300);
1002 to.blend(from, 0.5);
1003 EXPECT_ROW1_EQ(1, 0, 0, 150, to);
1004 EXPECT_ROW2_EQ(0, 1, 0, 150, to);
1005 EXPECT_ROW3_EQ(0, 0, 1, 200, to);
1006 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1007
1008 to.makeIdentity();
1009 to.translate3d(200, 100, 300);
1010 to.blend(from, 1);
1011 EXPECT_ROW1_EQ(1, 0, 0, 200, to);
1012 EXPECT_ROW2_EQ(0, 1, 0, 100, to);
1013 EXPECT_ROW3_EQ(0, 0, 1, 300, to);
1014 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1015 }
1016
1017 TEST(WebTransformationMatrixTest, verifyBlendForScale)
1018 {
1019 WebTransformationMatrix from;
1020 from.scale3d(100, 200, 100);
1021
1022 WebTransformationMatrix to;
1023
1024 to.makeIdentity();
1025 to.scale3d(200, 100, 300);
1026 to.blend(from, 0);
1027 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
1028
1029 to.makeIdentity();
1030 to.scale3d(200, 100, 300);
1031 to.blend(from, 0.25);
1032 EXPECT_ROW1_EQ(125, 0, 0, 0, to);
1033 EXPECT_ROW2_EQ(0, 175, 0, 0, to);
1034 EXPECT_ROW3_EQ(0, 0, 150, 0, to);
1035 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1036
1037 to.makeIdentity();
1038 to.scale3d(200, 100, 300);
1039 to.blend(from, 0.5);
1040 EXPECT_ROW1_EQ(150, 0, 0, 0, to);
1041 EXPECT_ROW2_EQ(0, 150, 0, 0, to);
1042 EXPECT_ROW3_EQ(0, 0, 200, 0, to);
1043 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1044
1045 to.makeIdentity();
1046 to.scale3d(200, 100, 300);
1047 to.blend(from, 1);
1048 EXPECT_ROW1_EQ(200, 0, 0, 0, to);
1049 EXPECT_ROW2_EQ(0, 100, 0, 0, to);
1050 EXPECT_ROW3_EQ(0, 0, 300, 0, to);
1051 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1052 }
1053
1054 TEST(WebTransformationMatrixTest, verifyBlendForSkewX)
1055 {
1056 WebTransformationMatrix from;
1057 from.skewX(0);
1058
1059 WebTransformationMatrix to;
1060
1061 to.makeIdentity();
1062 to.skewX(45);
1063 to.blend(from, 0);
1064 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
1065
1066 to.makeIdentity();
1067 to.skewX(45);
1068 to.blend(from, 0.5);
1069 EXPECT_ROW1_EQ(1, 0.5, 0, 0, to);
1070 EXPECT_ROW2_EQ(0, 1, 0, 0, to);
1071 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
1072 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1073
1074 to.makeIdentity();
1075 to.skewX(45);
1076 to.blend(from, 0.25);
1077 EXPECT_ROW1_EQ(1, 0.25, 0, 0, to);
1078 EXPECT_ROW2_EQ(0, 1, 0, 0, to);
1079 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
1080 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1081
1082 to.makeIdentity();
1083 to.skewX(45);
1084 to.blend(from, 1);
1085 EXPECT_ROW1_EQ(1, 1, 0, 0, to);
1086 EXPECT_ROW2_EQ(0, 1, 0, 0, to);
1087 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
1088 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1089 }
1090
1091 TEST(WebTransformationMatrixTest, verifyBlendForSkewY)
1092 {
1093 // NOTE CAREFULLY: Decomposition of skew and rotation terms of the matrix is
1094 // inherently underconstrained, and so it does not always compute the origin ally
1095 // intended skew parameters. The current implementation uses QR decompositio n, which
1096 // decomposes the shear into a rotation + non-uniform scale.
1097 //
1098 // It is unlikely that the decomposition implementation will need to change very
1099 // often, so to get any test coverage, the compromise is to verify the exact matrix
1100 // that the blend() operation produces.
1101 //
1102 // This problem also potentially exists for skewX, but the current QR decomp osition
1103 // implementation just happens to decompose those test matrices intuitively.
1104
1105 WebTransformationMatrix from;
1106 from.skewY(0);
1107
1108 WebTransformationMatrix to;
1109
1110 to.makeIdentity();
1111 to.skewY(45);
1112 to.blend(from, 0);
1113 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
1114
1115 to.makeIdentity();
1116 to.skewY(45);
1117 to.blend(from, 0.25);
1118 EXPECT_ROW1_NEAR(1.0823489449280947471976333, 0.0464370719145053845178239, 0 , 0, to, ERROR_THRESHOLD);
1119 EXPECT_ROW2_NEAR(0.2152925909665224513123150, 0.9541702441750861130032035, 0 , 0, to, ERROR_THRESHOLD);
1120 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
1121 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1122
1123 to.makeIdentity();
1124 to.skewY(45);
1125 to.blend(from, 0.5);
1126 EXPECT_ROW1_NEAR(1.1152212925809066312865525, 0.0676495144007326631996335, 0 , 0, to, ERROR_THRESHOLD);
1127 EXPECT_ROW2_NEAR(0.4619397844342648662419037, 0.9519009045724774464858342, 0 , 0, to, ERROR_THRESHOLD);
1128 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
1129 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1130
1131 // Unfortunately, this case suffers from uncomfortably large precision error .
1132 to.makeIdentity();
1133 to.skewY(45);
1134 to.blend(from, 1);
1135 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, LOOSE_ERROR_THRESHOLD);
1136 EXPECT_ROW2_NEAR(1, 1, 0, 0, to, LOOSE_ERROR_THRESHOLD);
1137 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
1138 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1139 }
1140
1141 TEST(WebTransformationMatrixTest, verifyBlendForRotationAboutX)
1142 {
1143 // Even though blending uses quaternions, axis-aligned rotations should blen d the same
1144 // with quaternions or Euler angles. So we can test rotation blending by com paring
1145 // against manually specified matrices from Euler angles.
1146
1147 WebTransformationMatrix from;
1148 from.rotate3d(1, 0, 0, 0);
1149
1150 WebTransformationMatrix to;
1151
1152 to.makeIdentity();
1153 to.rotate3d(1, 0, 0, 90);
1154 to.blend(from, 0);
1155 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
1156
1157 double expectedRotationAngle = 22.5 * piDouble / 180.0;
1158 to.makeIdentity();
1159 to.rotate3d(1, 0, 0, 90);
1160 to.blend(from, 0.25);
1161 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
1162 EXPECT_ROW2_NEAR(0, cos(expectedRotationAngle), -sin(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
1163 EXPECT_ROW3_NEAR(0, sin(expectedRotationAngle), cos(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
1164 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1165
1166 expectedRotationAngle = 45 * piDouble / 180.0;
1167 to.makeIdentity();
1168 to.rotate3d(1, 0, 0, 90);
1169 to.blend(from, 0.5);
1170 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
1171 EXPECT_ROW2_NEAR(0, cos(expectedRotationAngle), -sin(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
1172 EXPECT_ROW3_NEAR(0, sin(expectedRotationAngle), cos(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
1173 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1174
1175 to.makeIdentity();
1176 to.rotate3d(1, 0, 0, 90);
1177 to.blend(from, 1);
1178 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
1179 EXPECT_ROW2_NEAR(0, 0, -1, 0, to, ERROR_THRESHOLD);
1180 EXPECT_ROW3_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
1181 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1182 }
1183
1184 TEST(WebTransformationMatrixTest, verifyBlendForRotationAboutY)
1185 {
1186 WebTransformationMatrix from;
1187 from.rotate3d(0, 1, 0, 0);
1188
1189 WebTransformationMatrix to;
1190
1191 to.makeIdentity();
1192 to.rotate3d(0, 1, 0, 90);
1193 to.blend(from, 0);
1194 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
1195
1196 double expectedRotationAngle = 22.5 * piDouble / 180.0;
1197 to.makeIdentity();
1198 to.rotate3d(0, 1, 0, 90);
1199 to.blend(from, 0.25);
1200 EXPECT_ROW1_NEAR(cos(expectedRotationAngle), 0, sin(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
1201 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
1202 EXPECT_ROW3_NEAR(-sin(expectedRotationAngle), 0, cos(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
1203 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1204
1205 expectedRotationAngle = 45 * piDouble / 180.0;
1206 to.makeIdentity();
1207 to.rotate3d(0, 1, 0, 90);
1208 to.blend(from, 0.5);
1209 EXPECT_ROW1_NEAR(cos(expectedRotationAngle), 0, sin(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
1210 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
1211 EXPECT_ROW3_NEAR(-sin(expectedRotationAngle), 0, cos(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
1212 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1213
1214 to.makeIdentity();
1215 to.rotate3d(0, 1, 0, 90);
1216 to.blend(from, 1);
1217 EXPECT_ROW1_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
1218 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
1219 EXPECT_ROW3_NEAR(-1, 0, 0, 0, to, ERROR_THRESHOLD);
1220 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1221 }
1222
1223 TEST(WebTransformationMatrixTest, verifyBlendForRotationAboutZ)
1224 {
1225 WebTransformationMatrix from;
1226 from.rotate3d(0, 0, 1, 0);
1227
1228 WebTransformationMatrix to;
1229
1230 to.makeIdentity();
1231 to.rotate3d(0, 0, 1, 90);
1232 to.blend(from, 0);
1233 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
1234
1235 double expectedRotationAngle = 22.5 * piDouble / 180.0;
1236 to.makeIdentity();
1237 to.rotate3d(0, 0, 1, 90);
1238 to.blend(from, 0.25);
1239 EXPECT_ROW1_NEAR(cos(expectedRotationAngle), -sin(expectedRotationAngle), 0, 0, to, ERROR_THRESHOLD);
1240 EXPECT_ROW2_NEAR(sin(expectedRotationAngle), cos(expectedRotationAngle), 0, 0, to, ERROR_THRESHOLD);
1241 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
1242 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1243
1244 expectedRotationAngle = 45 * piDouble / 180.0;
1245 to.makeIdentity();
1246 to.rotate3d(0, 0, 1, 90);
1247 to.blend(from, 0.5);
1248 EXPECT_ROW1_NEAR(cos(expectedRotationAngle), -sin(expectedRotationAngle), 0, 0, to, ERROR_THRESHOLD);
1249 EXPECT_ROW2_NEAR(sin(expectedRotationAngle), cos(expectedRotationAngle), 0, 0, to, ERROR_THRESHOLD);
1250 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
1251 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1252
1253 to.makeIdentity();
1254 to.rotate3d(0, 0, 1, 90);
1255 to.blend(from, 1);
1256 EXPECT_ROW1_NEAR(0, -1, 0, 0, to, ERROR_THRESHOLD);
1257 EXPECT_ROW2_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
1258 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
1259 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1260 }
1261
1262
1263 TEST(WebTransformationMatrixTest, verifyBlendForCompositeTransform)
1264 {
1265 // Verify that the blending was done with a decomposition in correct order b y blending
1266 // a composite transform.
1267 // Using matrix x vector notation (Ax = b, where x is column vector), the or dering should be:
1268 // perspective * translation * rotation * skew * scale
1269 //
1270 // It is not as important (or meaningful) to check intermediate interpolatio ns; order
1271 // of operations will be tested well enough by the end cases that are easier to
1272 // specify.
1273
1274 WebTransformationMatrix from;
1275 WebTransformationMatrix to;
1276
1277 WebTransformationMatrix expectedEndOfAnimation;
1278 expectedEndOfAnimation.applyPerspective(1);
1279 expectedEndOfAnimation.translate3d(10, 20, 30);
1280 expectedEndOfAnimation.rotate3d(0, 0, 1, 25);
1281 expectedEndOfAnimation.skewY(45);
1282 expectedEndOfAnimation.scale3d(6, 7, 8);
1283
1284 to = expectedEndOfAnimation;
1285 to.blend(from, 0);
1286 EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
1287
1288 to = expectedEndOfAnimation;
1289 to.blend(from, 1);
1290
1291 // Recomposing the matrix results in a normalized matrix, so to verify we ne ed to
1292 // normalize the expectedEndOfAnimation before comparing elements. Normalizi ng means
1293 // dividing everything by expectedEndOfAnimation.m44().
1294 WebTransformationMatrix normalizedExpectedEndOfAnimation = expectedEndOfAnim ation;
1295 WebTransformationMatrix normalizationMatrix;
1296 normalizationMatrix.setM11(1 / expectedEndOfAnimation.m44());
1297 normalizationMatrix.setM22(1 / expectedEndOfAnimation.m44());
1298 normalizationMatrix.setM33(1 / expectedEndOfAnimation.m44());
1299 normalizationMatrix.setM44(1 / expectedEndOfAnimation.m44());
1300 normalizedExpectedEndOfAnimation.multiply(normalizationMatrix);
1301
1302 EXPECT_TRANSFORMATION_MATRIX_EQ(normalizedExpectedEndOfAnimation, to);
1303 }
1304
1305 } // namespace
OLDNEW
« no previous file with comments | « webkit/compositor/WebTransformOperationsTest.cpp ('k') | webkit/compositor/WebVideoLayerImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698