blob: 906535872f3c45bc9affe60fffaee4921e5d4d5f [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) {
robertphillips@google.com09042b82012-04-06 20:01:46 +000072 rot.setRotateDegreesAbout(0, 0, -1, SkIntToScalar(common_angles[i]));
reed@google.com6f2b44d2011-06-24 18:13:39 +000073
74 SkMatrix rot3x3 = rot;
75 REPORTER_ASSERT(reporter, rot3x3.rectStaysRect());
76 }
77}
78
reed@google.com80b577e2012-11-09 21:25:06 +000079static void test_concat(skiatest::Reporter* reporter) {
80 int i;
81 SkMatrix44 a, b, c, d;
82
83 a.setTranslate(10, 10, 10);
84 b.setScale(2, 2, 2);
85
86 SkScalar src[8] = {
87 0, 0, 0, 1,
88 1, 1, 1, 1
89 };
90 SkScalar dst[8];
91
92 c.setConcat(a, b);
93
94 d = a;
95 d.preConcat(b);
96 REPORTER_ASSERT(reporter, d == c);
97
reed@google.com1ea95be2012-11-09 21:39:48 +000098 c.mapScalars(src, dst); c.mapScalars(src + 4, dst + 4);
reed@google.com80b577e2012-11-09 21:25:06 +000099 for (i = 0; i < 3; ++i) {
100 REPORTER_ASSERT(reporter, 10 == dst[i]);
101 REPORTER_ASSERT(reporter, 12 == dst[i + 4]);
102 }
103
104 c.setConcat(b, a);
105
106 d = a;
107 d.postConcat(b);
108 REPORTER_ASSERT(reporter, d == c);
109
reed@google.com1ea95be2012-11-09 21:39:48 +0000110 c.mapScalars(src, dst); c.mapScalars(src + 4, dst + 4);
reed@google.com80b577e2012-11-09 21:25:06 +0000111 for (i = 0; i < 3; ++i) {
112 REPORTER_ASSERT(reporter, 20 == dst[i]);
113 REPORTER_ASSERT(reporter, 22 == dst[i + 4]);
114 }
115}
116
caryclark@google.com42639cd2012-06-06 12:03:39 +0000117static void TestMatrix44(skiatest::Reporter* reporter) {
reed@google.comda9fac02011-06-13 14:46:52 +0000118#ifdef SK_SCALAR_IS_FLOAT
reed@google.com125002a2011-06-09 19:13:41 +0000119 SkMatrix44 mat, inverse, iden1, iden2, rot;
120
121 mat.reset();
122 mat.setTranslate(SK_Scalar1, SK_Scalar1, SK_Scalar1);
123 mat.invert(&inverse);
124 iden1.setConcat(mat, inverse);
125 REPORTER_ASSERT(reporter, is_identity(iden1));
126
127 mat.setScale(SkIntToScalar(2), SkIntToScalar(2), SkIntToScalar(2));
128 mat.invert(&inverse);
129 iden1.setConcat(mat, inverse);
130 REPORTER_ASSERT(reporter, is_identity(iden1));
131
132 mat.setScale(SK_Scalar1/2, SK_Scalar1/2, SK_Scalar1/2);
133 mat.invert(&inverse);
134 iden1.setConcat(mat, inverse);
135 REPORTER_ASSERT(reporter, is_identity(iden1));
136
137 mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20));
138 rot.setRotateDegreesAbout(
139 SkIntToScalar(0),
140 SkIntToScalar(0),
141 SkIntToScalar(-1),
142 SkIntToScalar(90));
143 mat.postConcat(rot);
144 REPORTER_ASSERT(reporter, mat.invert(NULL));
145 mat.invert(&inverse);
146 iden1.setConcat(mat, inverse);
147 REPORTER_ASSERT(reporter, is_identity(iden1));
148 iden2.setConcat(inverse, mat);
149 REPORTER_ASSERT(reporter, is_identity(iden2));
reed@google.comda9fac02011-06-13 14:46:52 +0000150
151 // test rol/col Major getters
152 {
153 mat.setTranslate(2, 3, 4);
154 float dataf[16];
155 double datad[16];
rmistry@google.comd6176b02012-08-23 18:14:13 +0000156
reed@google.comda9fac02011-06-13 14:46:52 +0000157 mat.asColMajorf(dataf);
158 assert16<float>(reporter, dataf,
159 1, 0, 0, 0,
160 0, 1, 0, 0,
161 0, 0, 1, 0,
162 2, 3, 4, 1);
163 mat.asColMajord(datad);
164 assert16<double>(reporter, datad, 1, 0, 0, 0,
165 0, 1, 0, 0,
166 0, 0, 1, 0,
167 2, 3, 4, 1);
168 mat.asRowMajorf(dataf);
169 assert16<float>(reporter, dataf, 1, 0, 0, 2,
170 0, 1, 0, 3,
171 0, 0, 1, 4,
172 0, 0, 0, 1);
173 mat.asRowMajord(datad);
174 assert16<double>(reporter, datad, 1, 0, 0, 2,
175 0, 1, 0, 3,
176 0, 0, 1, 4,
177 0, 0, 0, 1);
178 }
reed@google.com6f2b44d2011-06-24 18:13:39 +0000179
reed@google.com80b577e2012-11-09 21:25:06 +0000180 test_concat(reporter);
181
caryclark@google.com42639cd2012-06-06 12:03:39 +0000182 if (false) { // avoid bit rot, suppress warning (working on making this pass)
183 test_common_angles(reporter);
184 }
reed@google.comda9fac02011-06-13 14:46:52 +0000185#endif
reed@google.com125002a2011-06-09 19:13:41 +0000186}
187
188#include "TestClassDef.h"
189DEFINE_TESTCLASS("Matrix44", Matrix44TestClass, TestMatrix44)