blob: 67dc0d252f65dea2f96fffdf8d930a468654046b [file] [log] [blame]
reed@google.com125002a2011-06-09 19:13:41 +00001#include "Test.h"
2#include "SkMatrix44.h"
3
reed@google.comda9fac02011-06-13 14:46:52 +00004static bool nearly_equal_scalar(SkMScalar a, SkMScalar b) {
reed@google.com125002a2011-06-09 19:13:41 +00005 // Note that we get more compounded error for multiple operations when
6 // SK_SCALAR_IS_FIXED.
7#ifdef SK_SCALAR_IS_FLOAT
8 const SkScalar tolerance = SK_Scalar1 / 200000;
9#else
10 const SkScalar tolerance = SK_Scalar1 / 1024;
11#endif
12
13 return SkScalarAbs(a - b) <= tolerance;
14}
15
reed@google.comda9fac02011-06-13 14:46:52 +000016template <typename T> void assert16(skiatest::Reporter* reporter, const T data[],
17 T m0, T m1, T m2, T m3,
18 T m4, T m5, T m6, T m7,
19 T m8, T m9, T m10, T m11,
20 T m12, T m13, T m14, T m15) {
21 REPORTER_ASSERT(reporter, data[0] == m0);
22 REPORTER_ASSERT(reporter, data[1] == m1);
23 REPORTER_ASSERT(reporter, data[2] == m2);
24 REPORTER_ASSERT(reporter, data[3] == m3);
25
26 REPORTER_ASSERT(reporter, data[4] == m4);
27 REPORTER_ASSERT(reporter, data[5] == m5);
28 REPORTER_ASSERT(reporter, data[6] == m6);
29 REPORTER_ASSERT(reporter, data[7] == m7);
30
31 REPORTER_ASSERT(reporter, data[8] == m8);
32 REPORTER_ASSERT(reporter, data[9] == m9);
33 REPORTER_ASSERT(reporter, data[10] == m10);
34 REPORTER_ASSERT(reporter, data[11] == m11);
35
36 REPORTER_ASSERT(reporter, data[12] == m12);
37 REPORTER_ASSERT(reporter, data[13] == m13);
38 REPORTER_ASSERT(reporter, data[14] == m14);
39 REPORTER_ASSERT(reporter, data[15] == m15);
40}
41
reed@google.com125002a2011-06-09 19:13:41 +000042static bool nearly_equal(const SkMatrix44& a, const SkMatrix44& b) {
43 for (int i = 0; i < 4; ++i) {
44 for (int j = 0; j < 4; ++j) {
45 if (!nearly_equal_scalar(a.get(i, j), b.get(i, j))) {
reed@google.comda9fac02011-06-13 14:46:52 +000046 printf("not equal %g %g\n", a.get(i, j), b.get(i, j));
reed@google.com125002a2011-06-09 19:13:41 +000047 return false;
48 }
49 }
50 }
51 return true;
52}
53
54static bool is_identity(const SkMatrix44& m) {
55 SkMatrix44 identity;
56 identity.reset();
57 return nearly_equal(m, identity);
58}
59
reed@google.com6f2b44d2011-06-24 18:13:39 +000060static void test_common_angles(skiatest::Reporter* reporter) {
61 SkMatrix44 rot;
62 // Test precision of rotation in common cases
63 int common_angles[] = { 0, 90, -90, 180, -180, 270, -270, 360, -360 };
64 for (int i = 0; i < 9; ++i) {
65 rot.setRotateDegreesAbout(0, 0, -1, common_angles[i]);
66
67 SkMatrix rot3x3 = rot;
68 REPORTER_ASSERT(reporter, rot3x3.rectStaysRect());
69 }
70}
71
reed@google.com125002a2011-06-09 19:13:41 +000072void TestMatrix44(skiatest::Reporter* reporter) {
reed@google.comda9fac02011-06-13 14:46:52 +000073#ifdef SK_SCALAR_IS_FLOAT
reed@google.com125002a2011-06-09 19:13:41 +000074 SkMatrix44 mat, inverse, iden1, iden2, rot;
75
76 mat.reset();
77 mat.setTranslate(SK_Scalar1, SK_Scalar1, SK_Scalar1);
78 mat.invert(&inverse);
79 iden1.setConcat(mat, inverse);
80 REPORTER_ASSERT(reporter, is_identity(iden1));
81
82 mat.setScale(SkIntToScalar(2), SkIntToScalar(2), SkIntToScalar(2));
83 mat.invert(&inverse);
84 iden1.setConcat(mat, inverse);
85 REPORTER_ASSERT(reporter, is_identity(iden1));
86
87 mat.setScale(SK_Scalar1/2, SK_Scalar1/2, SK_Scalar1/2);
88 mat.invert(&inverse);
89 iden1.setConcat(mat, inverse);
90 REPORTER_ASSERT(reporter, is_identity(iden1));
91
92 mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20));
93 rot.setRotateDegreesAbout(
94 SkIntToScalar(0),
95 SkIntToScalar(0),
96 SkIntToScalar(-1),
97 SkIntToScalar(90));
98 mat.postConcat(rot);
99 REPORTER_ASSERT(reporter, mat.invert(NULL));
100 mat.invert(&inverse);
101 iden1.setConcat(mat, inverse);
102 REPORTER_ASSERT(reporter, is_identity(iden1));
103 iden2.setConcat(inverse, mat);
104 REPORTER_ASSERT(reporter, is_identity(iden2));
reed@google.comda9fac02011-06-13 14:46:52 +0000105
106 // test rol/col Major getters
107 {
108 mat.setTranslate(2, 3, 4);
109 float dataf[16];
110 double datad[16];
111
112 mat.asColMajorf(dataf);
113 assert16<float>(reporter, dataf,
114 1, 0, 0, 0,
115 0, 1, 0, 0,
116 0, 0, 1, 0,
117 2, 3, 4, 1);
118 mat.asColMajord(datad);
119 assert16<double>(reporter, datad, 1, 0, 0, 0,
120 0, 1, 0, 0,
121 0, 0, 1, 0,
122 2, 3, 4, 1);
123 mat.asRowMajorf(dataf);
124 assert16<float>(reporter, dataf, 1, 0, 0, 2,
125 0, 1, 0, 3,
126 0, 0, 1, 4,
127 0, 0, 0, 1);
128 mat.asRowMajord(datad);
129 assert16<double>(reporter, datad, 1, 0, 0, 2,
130 0, 1, 0, 3,
131 0, 0, 1, 4,
132 0, 0, 0, 1);
133 }
reed@google.com6f2b44d2011-06-24 18:13:39 +0000134
135#if 0 // working on making this pass
136 test_common_angles(reporter);
137#endif
reed@google.comda9fac02011-06-13 14:46:52 +0000138#endif
reed@google.com125002a2011-06-09 19:13:41 +0000139}
140
141#include "TestClassDef.h"
142DEFINE_TESTCLASS("Matrix44", Matrix44TestClass, TestMatrix44)