MatrixTests.cpp 7.1 KB

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