MatrixTests.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #include "tests/MatrixTests.h"
  2. #include "math/Matrix.h"
  3. #include "tests/Test.h"
  4. #include "utils/StringBuffer.h"
  5. const float eps = 0.0001f;
  6. template<int N, typename T>
  7. static void compareVectors(Test& test, const Vector<N, T>& wanted,
  8. const Vector<N, T>& actual, const char* text) {
  9. for(int i = 0; i < N; i++) {
  10. test.checkFloat(
  11. wanted[i], actual[i], eps,
  12. StringBuffer<50>(text).append(" (").append(i).append(")"));
  13. }
  14. }
  15. static void testInit(Test& test) {
  16. Matrix m;
  17. const float* data = m.getValues();
  18. for(int i = 0; i < 16; i++) {
  19. int x = i % 4;
  20. int y = i / 4;
  21. test.checkEqual(static_cast<float>(x == y), data[i],
  22. StringBuffer<50>("init ").append(i));
  23. }
  24. }
  25. static void testTranspose(Test& test) {
  26. Matrix m;
  27. m.set(0, Vector4(1.0f, 2.0f, 3.0f, 4.0f));
  28. m.set(1, Vector4(5.0f, 6.0f, 7.0f, 8.0f));
  29. m.set(2, Vector4(9.0f, 10.0f, 11.0f, 12.0f));
  30. m.set(3, Vector4(13.0f, 14.0f, 15.0f, 16.0f));
  31. Matrix t = m.transpose();
  32. Matrix m2 = t.transpose();
  33. const float* mp = m.getValues();
  34. const float* tp = t.getValues();
  35. for(int x = 0; x < 4; x++) {
  36. for(int y = 0; y < 4; y++) {
  37. StringBuffer<50> s("transpose ");
  38. s.append(x).append(" | ").append(y);
  39. test.checkEqual(mp[y * 4 + x], tp[x * 4 + y], s);
  40. }
  41. }
  42. const float* mp2 = m2.getValues();
  43. for(int i = 0; i < 16; i++) {
  44. test.checkEqual(mp[i], mp2[i],
  45. StringBuffer<50>("transpose ").append(i));
  46. }
  47. }
  48. static void testScale(Test& test) {
  49. Matrix m;
  50. m.scale(Vector3(2.0f, 3.0f, 4.0f));
  51. compareVectors(test, Vector3(-8.0f, 18.0f, 28.0f),
  52. m * Vector3(-4.0f, 6.0f, 7.0f), "scale");
  53. }
  54. static void testUniformScale(Test& test) {
  55. Matrix m;
  56. m.scale(2.0f);
  57. compareVectors(test, Vector3(-8.0f, 12.0f, 14.0f),
  58. m * Vector3(-4.0f, 6.0f, 7.0f), "uniform scale");
  59. }
  60. static void testTranslateX(Test& test) {
  61. Matrix m;
  62. m.translateX(5.0f);
  63. compareVectors(test, Vector3(1.0f, 6.0f, 7.0f),
  64. m * Vector3(-4.0f, 6.0f, 7.0f), "translate x");
  65. }
  66. static void testTranslateY(Test& test) {
  67. Matrix m;
  68. m.translateY(6.0f);
  69. compareVectors(test, Vector3(-4.0f, 12.0f, 7.0f),
  70. m * Vector3(-4.0f, 6.0f, 7.0f), "translate y");
  71. }
  72. static void testTranslateZ(Test& test) {
  73. Matrix m;
  74. m.translateZ(7.0f);
  75. compareVectors(test, Vector3(-4.0f, 6.0f, 14.0f),
  76. m * Vector3(-4.0f, 6.0f, 7.0f), "translate z");
  77. }
  78. static void testTranslate(Test& test) {
  79. Matrix m;
  80. m.translate(Vector3(1.0f, 2.0f, 3.0f));
  81. compareVectors(test, Vector3(-3.0f, 8.0f, 10.0f),
  82. m * Vector3(-4.0f, 6.0f, 7.0f), "translate");
  83. }
  84. static void testCombination(Test& test) {
  85. Matrix m;
  86. m.scale(2.0f);
  87. m.translateX(1.0f);
  88. m.translateY(2.0f);
  89. m.translateZ(3.0f);
  90. m.translate(Vector3(-4.0f, 2.0f, 3.0f));
  91. m.scale(Vector3(2.0f, 3.0f, 4.0f));
  92. m.scale(0.5f);
  93. compareVectors(test, Vector3(-1.0f, 9.0f, 16.0f),
  94. m * Vector3(1.0f, 1.0f, 1.0f), "combination");
  95. }
  96. static void testMatrixCombination(Test& test) {
  97. Matrix a;
  98. a.scale(2.0f);
  99. a.translate(Vector3(1.0f, 2.0f, 3.0f));
  100. Matrix b;
  101. b.scale(3.0f);
  102. b.translate(Vector3(1.0f, 1.0f, 1.0f));
  103. Matrix c;
  104. c.translate(Vector3(-1.0f, -2.0f, -3.0f));
  105. c *= b * a;
  106. compareVectors(test, Vector3(9.0f, 11.0f, 13.0f),
  107. c * Vector3(1.0f, 1.0f, 1.0f), "combination");
  108. }
  109. static void testRotateX(Test& test) {
  110. Matrix m;
  111. m.rotateX(90);
  112. compareVectors(test, Vector3(1.0f, 0.0f, 0.0f),
  113. m * Vector3(1.0f, 0.0f, 0.0f), "rotate x 1");
  114. compareVectors(test, Vector3(0.0f, 0.0f, 1.0f),
  115. m * Vector3(0.0f, 1.0f, 0.0f), "rotate x 2");
  116. compareVectors(test, Vector3(0.0f, -1.0f, 0.0f),
  117. m * Vector3(0.0f, 0.0f, 1.0f), "rotate x 3");
  118. }
  119. static void testRotateY(Test& test) {
  120. Matrix m;
  121. m.rotateY(90);
  122. compareVectors(test, Vector3(0.0f, 0.0f, -1.0f),
  123. m * Vector3(1.0f, 0.0f, 0.0f), "rotate y 1");
  124. compareVectors(test, Vector3(0.0f, 1.0f, 0.0f),
  125. m * Vector3(0.0f, 1.0f, 0.0f), "rotate y 2");
  126. compareVectors(test, Vector3(1.0f, 0.0f, 0.0f),
  127. m * Vector3(0.0f, 0.0f, 1.0f), "rotate y 3");
  128. }
  129. static void testRotateZ(Test& test) {
  130. Matrix m;
  131. m.rotateZ(90);
  132. compareVectors(test, Vector3(0.0f, 1.0f, 0.0f),
  133. m * Vector3(1.0f, 0.0f, 0.0f), "rotate z 1");
  134. compareVectors(test, Vector3(-1.0f, 0.0f, 0.0f),
  135. m * Vector3(0.0f, 1.0f, 0.0f), "rotate z 2");
  136. compareVectors(test, Vector3(0.0f, 0.0f, 1.0f),
  137. m * Vector3(0.0f, 0.0f, 1.0f), "rotate z 3");
  138. }
  139. static void testToString(Test& test) {
  140. StringBuffer<200> s;
  141. Matrix m;
  142. m.set(0, Vector4(1.0f, 2.0f, 3.0f, 4.0f));
  143. m.set(1, Vector4(5.0f, 6.0f, 7.0f, 8.0f));
  144. m.set(2, Vector4(9.0f, 10.0f, 11.0f, 12.0f));
  145. m.set(3, Vector4(13.0f, 14.0f, 15.0f, 16.0f));
  146. s.append(m);
  147. test.checkEqual(
  148. StringBuffer<200>(
  149. "[[1.00, 2.00, 3.00, 4.00], [5.00, 6.00, 7.00, 8.00], "
  150. "[9.00, 10.00, 11.00, 12.00], [13.00, 14.00, 15.00, 16.00]]"),
  151. s, "to string");
  152. }
  153. static void testQuaternionMatrix(Test& test) {
  154. Quaternion q1(Vector3(1.0f, 0.0f, 0.0f), 48.0f);
  155. Quaternion q2(Vector3(0.0f, 1.0f, 0.0f), 52.0f);
  156. Quaternion q3(Vector3(0.0f, 0.0f, 1.0f), 60.0f);
  157. Matrix m;
  158. m.translate(Vector3(1.0f, 2.0f, 3.0f));
  159. m.rotate(q1).rotate(q2).rotate(q3);
  160. m.translate(Vector3(1.0f, 2.0f, 3.0f));
  161. Matrix check;
  162. check.translate(Vector3(1.0f, 2.0f, 3.0f));
  163. check.rotateX(48.0f).rotateY(52.0f).rotateZ(60.0f);
  164. check.translate(Vector3(1.0f, 2.0f, 3.0f));
  165. for(int i = 0; i < 16; i++) {
  166. test.checkFloat(check.getValues()[i], m.getValues()[i], eps,
  167. "mul matrix");
  168. }
  169. }
  170. void MatrixTests::test() {
  171. Test test("Matrix");
  172. testInit(test);
  173. testScale(test);
  174. testUniformScale(test);
  175. testTranspose(test);
  176. testTranslateX(test);
  177. testTranslateY(test);
  178. testTranslateZ(test);
  179. testTranslate(test);
  180. testCombination(test);
  181. testMatrixCombination(test);
  182. testRotateX(test);
  183. testRotateY(test);
  184. testRotateZ(test);
  185. testToString(test);
  186. testQuaternionMatrix(test);
  187. test.finalize();
  188. }