Matrix44Test.cpp revision 1ea95be560b38a71e3f24749c4e5e3d3564e4c6c
1 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 */ 8#include "Test.h" 9#include "SkMatrix44.h" 10 11static bool nearly_equal_scalar(SkMScalar a, SkMScalar b) { 12 // 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 23template <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 49static 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))) { 53 printf("not equal %g %g\n", a.get(i, j), b.get(i, j)); 54 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 67static 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, SkIntToScalar(common_angles[i])); 73 74 SkMatrix rot3x3 = rot; 75 REPORTER_ASSERT(reporter, rot3x3.rectStaysRect()); 76 } 77} 78 79static 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 98 c.mapScalars(src, dst); c.mapScalars(src + 4, dst + 4); 99 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 110 c.mapScalars(src, dst); c.mapScalars(src + 4, dst + 4); 111 for (i = 0; i < 3; ++i) { 112 REPORTER_ASSERT(reporter, 20 == dst[i]); 113 REPORTER_ASSERT(reporter, 22 == dst[i + 4]); 114 } 115} 116 117static void TestMatrix44(skiatest::Reporter* reporter) { 118#ifdef SK_SCALAR_IS_FLOAT 119 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)); 150 151 // test rol/col Major getters 152 { 153 mat.setTranslate(2, 3, 4); 154 float dataf[16]; 155 double datad[16]; 156 157 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 } 179 180 test_concat(reporter); 181 182 if (false) { // avoid bit rot, suppress warning (working on making this pass) 183 test_common_angles(reporter); 184 } 185#endif 186} 187 188#include "TestClassDef.h" 189DEFINE_TESTCLASS("Matrix44", Matrix44TestClass, TestMatrix44) 190