blob: 485b38bc49e744a9f582470c94d726e356e4a01f [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
reed@google.com125002a2011-06-09 19:13:41 +00008#include "Test.h"
9#include "SkMatrix44.h"
10
reed@google.comda9fac02011-06-13 14:46:52 +000011static bool nearly_equal_scalar(SkMScalar a, SkMScalar b) {
reed@google.com125002a2011-06-09 19:13:41 +000012 // Note that we get more compounded error for multiple operations when
13 // SK_SCALAR_IS_FIXED.
14#ifdef SK_SCALAR_IS_FLOAT
15 const SkScalar tolerance = SK_Scalar1 / 200000;
16#else
17 const SkScalar tolerance = SK_Scalar1 / 1024;
18#endif
19
20 return SkScalarAbs(a - b) <= tolerance;
21}
22
reed@google.comda9fac02011-06-13 14:46:52 +000023template <typename T> void assert16(skiatest::Reporter* reporter, const T data[],
24 T m0, T m1, T m2, T m3,
25 T m4, T m5, T m6, T m7,
26 T m8, T m9, T m10, T m11,
27 T m12, T m13, T m14, T m15) {
28 REPORTER_ASSERT(reporter, data[0] == m0);
29 REPORTER_ASSERT(reporter, data[1] == m1);
30 REPORTER_ASSERT(reporter, data[2] == m2);
31 REPORTER_ASSERT(reporter, data[3] == m3);
32
33 REPORTER_ASSERT(reporter, data[4] == m4);
34 REPORTER_ASSERT(reporter, data[5] == m5);
35 REPORTER_ASSERT(reporter, data[6] == m6);
36 REPORTER_ASSERT(reporter, data[7] == m7);
37
38 REPORTER_ASSERT(reporter, data[8] == m8);
39 REPORTER_ASSERT(reporter, data[9] == m9);
40 REPORTER_ASSERT(reporter, data[10] == m10);
41 REPORTER_ASSERT(reporter, data[11] == m11);
42
43 REPORTER_ASSERT(reporter, data[12] == m12);
44 REPORTER_ASSERT(reporter, data[13] == m13);
45 REPORTER_ASSERT(reporter, data[14] == m14);
46 REPORTER_ASSERT(reporter, data[15] == m15);
47}
48
reed@google.com125002a2011-06-09 19:13:41 +000049static bool nearly_equal(const SkMatrix44& a, const SkMatrix44& b) {
50 for (int i = 0; i < 4; ++i) {
51 for (int j = 0; j < 4; ++j) {
52 if (!nearly_equal_scalar(a.get(i, j), b.get(i, j))) {
reed@google.comda9fac02011-06-13 14:46:52 +000053 printf("not equal %g %g\n", a.get(i, j), b.get(i, j));
reed@google.com125002a2011-06-09 19:13:41 +000054 return false;
55 }
56 }
57 }
58 return true;
59}
60
61static bool is_identity(const SkMatrix44& m) {
62 SkMatrix44 identity;
63 identity.reset();
64 return nearly_equal(m, identity);
65}
66
reed@google.com6f2b44d2011-06-24 18:13:39 +000067static void test_common_angles(skiatest::Reporter* reporter) {
68 SkMatrix44 rot;
69 // Test precision of rotation in common cases
70 int common_angles[] = { 0, 90, -90, 180, -180, 270, -270, 360, -360 };
71 for (int i = 0; i < 9; ++i) {
72 rot.setRotateDegreesAbout(0, 0, -1, common_angles[i]);
73
74 SkMatrix rot3x3 = rot;
75 REPORTER_ASSERT(reporter, rot3x3.rectStaysRect());
76 }
77}
78
reed@google.com125002a2011-06-09 19:13:41 +000079void TestMatrix44(skiatest::Reporter* reporter) {
reed@google.comda9fac02011-06-13 14:46:52 +000080#ifdef SK_SCALAR_IS_FLOAT
reed@google.com125002a2011-06-09 19:13:41 +000081 SkMatrix44 mat, inverse, iden1, iden2, rot;
82
83 mat.reset();
84 mat.setTranslate(SK_Scalar1, SK_Scalar1, SK_Scalar1);
85 mat.invert(&inverse);
86 iden1.setConcat(mat, inverse);
87 REPORTER_ASSERT(reporter, is_identity(iden1));
88
89 mat.setScale(SkIntToScalar(2), SkIntToScalar(2), SkIntToScalar(2));
90 mat.invert(&inverse);
91 iden1.setConcat(mat, inverse);
92 REPORTER_ASSERT(reporter, is_identity(iden1));
93
94 mat.setScale(SK_Scalar1/2, SK_Scalar1/2, SK_Scalar1/2);
95 mat.invert(&inverse);
96 iden1.setConcat(mat, inverse);
97 REPORTER_ASSERT(reporter, is_identity(iden1));
98
99 mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20));
100 rot.setRotateDegreesAbout(
101 SkIntToScalar(0),
102 SkIntToScalar(0),
103 SkIntToScalar(-1),
104 SkIntToScalar(90));
105 mat.postConcat(rot);
106 REPORTER_ASSERT(reporter, mat.invert(NULL));
107 mat.invert(&inverse);
108 iden1.setConcat(mat, inverse);
109 REPORTER_ASSERT(reporter, is_identity(iden1));
110 iden2.setConcat(inverse, mat);
111 REPORTER_ASSERT(reporter, is_identity(iden2));
reed@google.comda9fac02011-06-13 14:46:52 +0000112
113 // test rol/col Major getters
114 {
115 mat.setTranslate(2, 3, 4);
116 float dataf[16];
117 double datad[16];
118
119 mat.asColMajorf(dataf);
120 assert16<float>(reporter, dataf,
121 1, 0, 0, 0,
122 0, 1, 0, 0,
123 0, 0, 1, 0,
124 2, 3, 4, 1);
125 mat.asColMajord(datad);
126 assert16<double>(reporter, datad, 1, 0, 0, 0,
127 0, 1, 0, 0,
128 0, 0, 1, 0,
129 2, 3, 4, 1);
130 mat.asRowMajorf(dataf);
131 assert16<float>(reporter, dataf, 1, 0, 0, 2,
132 0, 1, 0, 3,
133 0, 0, 1, 4,
134 0, 0, 0, 1);
135 mat.asRowMajord(datad);
136 assert16<double>(reporter, datad, 1, 0, 0, 2,
137 0, 1, 0, 3,
138 0, 0, 1, 4,
139 0, 0, 0, 1);
140 }
reed@google.com6f2b44d2011-06-24 18:13:39 +0000141
142#if 0 // working on making this pass
143 test_common_angles(reporter);
144#endif
reed@google.comda9fac02011-06-13 14:46:52 +0000145#endif
reed@google.com125002a2011-06-09 19:13:41 +0000146}
147
148#include "TestClassDef.h"
149DEFINE_TESTCLASS("Matrix44", Matrix44TestClass, TestMatrix44)