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, common_angles[i]); 73 74 SkMatrix rot3x3 = rot; 75 REPORTER_ASSERT(reporter, rot3x3.rectStaysRect()); 76 } 77} 78 79void TestMatrix44(skiatest::Reporter* reporter) { 80#ifdef SK_SCALAR_IS_FLOAT 81 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)); 112 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 } 141 142#if 0 // working on making this pass 143 test_common_angles(reporter); 144#endif 145#endif 146} 147 148#include "TestClassDef.h" 149DEFINE_TESTCLASS("Matrix44", Matrix44TestClass, TestMatrix44) 150