MatrixTests.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "../Tests.h"
  2. #include "core/Generic.h"
  3. #include "core/ToString.h"
  4. typedef CoreVector3 V3;
  5. #define CV3(a, b, c) (&(V3){{a, b, c}})
  6. #define CV30 CV3(0.0f, 0.0f, 0.0f)
  7. static void testInit() {
  8. Matrix m = UNIT_MATRIX;
  9. const float* data = (float*)&m;
  10. for(int i = 0; i < 16; i++) {
  11. int x = i % 4;
  12. int y = i / 4;
  13. TEST_FLOAT(x == y, data[i], 0.0f);
  14. }
  15. }
  16. static void testTranspose() {
  17. Matrix m;
  18. float* data = (float*)&m;
  19. for(int i = 0; i < 16; i++) {
  20. data[i] = (float)(i + 1);
  21. }
  22. Matrix t = m;
  23. transposeMatrix(&t);
  24. Matrix m2 = t;
  25. transposeMatrix(&m2);
  26. const float* mp = (float*)&m;
  27. const float* tp = (float*)&t;
  28. for(int x = 0; x < 4; x++) {
  29. for(int y = 0; y < 4; y++) {
  30. TEST_FLOAT(mp[y * 4 + x], tp[x * 4 + y], 0.0f);
  31. }
  32. }
  33. const float* mp2 = (float*)&m2;
  34. for(int i = 0; i < 16; i++) {
  35. TEST_FLOAT(mp[i], mp2[i], 0.0f);
  36. }
  37. }
  38. static void testScale() {
  39. Matrix m = UNIT_MATRIX;
  40. scaleMatrix(&m, CV3(2.0f, 3.0f, 4.0f));
  41. TEST_V3(CV3(-8.0f, 18.0f, 28.0f), mul(CV30, &m, CV3(-4.0f, 6.0f, 7.0f)));
  42. }
  43. static void testUniformScale() {
  44. Matrix m = UNIT_MATRIX;
  45. scaleMatrixF(&m, 2.0f);
  46. TEST_V3(CV3(-8.0f, 12.0f, 14.0f), mul(CV30, &m, CV3(-4.0f, 6.0f, 7.0f)));
  47. }
  48. static void testTranslateX() {
  49. Matrix m = UNIT_MATRIX;
  50. translateMatrixX(&m, 5.0f);
  51. TEST_V3(CV3(1.0f, 6.0f, 7.0f), mul(CV30, &m, CV3(-4.0f, 6.0f, 7.0f)));
  52. }
  53. static void testTranslateY() {
  54. Matrix m = UNIT_MATRIX;
  55. translateMatrixY(&m, 6.0f);
  56. TEST_V3(CV3(-4.0f, 12.0f, 7.0f), mul(CV30, &m, CV3(-4.0f, 6.0f, 7.0f)));
  57. }
  58. static void testTranslateZ() {
  59. Matrix m = UNIT_MATRIX;
  60. translateMatrixZ(&m, 7.0f);
  61. TEST_V3(CV3(-4.0f, 6.0f, 14.0f), mul(CV30, &m, CV3(-4.0f, 6.0f, 7.0f)));
  62. }
  63. static void testTranslate() {
  64. Matrix m = UNIT_MATRIX;
  65. translateMatrix(&m, CV3(1.0f, 2.0f, 3.0f));
  66. TEST_V3(CV3(-3.0f, 8.0f, 10.0f), mul(CV30, &m, CV3(-4.0f, 6.0f, 7.0f)));
  67. }
  68. static void testTranslateTo() {
  69. char buffer[1024];
  70. Matrix m;
  71. for(int i = 0; i < 16; i++) {
  72. ((float*)&m)[i] = (float)i + 1.0f;
  73. }
  74. translateMatrixTo(&m, CV3(6.0f, 8.0f, 9.0f));
  75. toStringMatrix(&m, buffer, sizeof(buffer));
  76. TEST_STRING("[[1.000, 0.000, 0.000, 6.000], [0.000, 1.000, 0.000, 8.000], "
  77. "[0.000, 0.000, 1.000, 9.000], [0.000, 0.000, 0.000, 1.000]]",
  78. buffer);
  79. }
  80. static void testCombination() {
  81. Matrix m = UNIT_MATRIX;
  82. scaleMatrixF(&m, 2.0f);
  83. translateMatrixX(&m, 1.0f);
  84. translateMatrixY(&m, 2.0f);
  85. translateMatrixZ(&m, 3.0f);
  86. translateMatrix(&m, CV3(-4.0f, 2.0f, 3.0f));
  87. scaleMatrix(&m, CV3(2.0f, 3.0f, 4.0f));
  88. scaleMatrixF(&m, 0.5f);
  89. TEST_V3(CV3(-1.0f, 9.0f, 16.0f), mul(CV30, &m, CV3(1.0f, 1.0f, 1.0f)));
  90. }
  91. static void testMatrixCombination() {
  92. Matrix a = UNIT_MATRIX;
  93. scaleMatrixF(&a, 2.0f);
  94. translateMatrix(&a, CV3(1.0f, 2.0f, 3.0f));
  95. Matrix b = UNIT_MATRIX;
  96. scaleMatrixF(&b, 3.0f);
  97. translateMatrix(&b, CV3(1.0f, 1.0f, 1.0f));
  98. Matrix c = UNIT_MATRIX;
  99. translateMatrix(&c, CV3(-1.0f, -2.0f, -3.0f));
  100. mulSet(&c, mul(&ZERO_MATRIX, &b, &a));
  101. TEST_V3(CV3(9.0f, 11.0f, 13.0f), mul(CV30, &c, CV3(1.0f, 1.0f, 1.0f)));
  102. }
  103. static void testRotateX() {
  104. Matrix m = UNIT_MATRIX;
  105. rotateMatrixX(&m, 90.0f);
  106. TEST_V3(CV3(1.0f, 0.0f, 0.0f), mul(CV30, &m, CV3(1.0f, 0.0f, 0.0f)));
  107. TEST_V3(CV3(0.0f, 0.0f, 1.0f), mul(CV30, &m, CV3(0.0f, 1.0f, 0.0f)));
  108. TEST_V3(CV3(0.0f, -1.0f, 0.0f), mul(CV30, &m, CV3(0.0f, 0.0f, 1.0f)));
  109. }
  110. static void testRotateY() {
  111. Matrix m = UNIT_MATRIX;
  112. rotateMatrixY(&m, 90.0f);
  113. TEST_V3(CV3(0.0f, 0.0f, -1.0f), mul(CV30, &m, CV3(1.0f, 0.0f, 0.0f)));
  114. TEST_V3(CV3(0.0f, 1.0f, 0.0f), mul(CV30, &m, CV3(0.0f, 1.0f, 0.0f)));
  115. TEST_V3(CV3(1.0f, 0.0f, 0.0f), mul(CV30, &m, CV3(0.0f, 0.0f, 1.0f)));
  116. }
  117. static void testRotateZ() {
  118. Matrix m = UNIT_MATRIX;
  119. rotateMatrixZ(&m, 90.0f);
  120. TEST_V3(CV3(0.0f, 1.0f, 0.0f), mul(CV30, &m, CV3(1.0f, 0.0f, 0.0f)));
  121. TEST_V3(CV3(-1.0f, 0.0f, 0.0f), mul(CV30, &m, CV3(0.0f, 1.0f, 0.0f)));
  122. TEST_V3(CV3(0.0f, 0.0f, 1.0f), mul(CV30, &m, CV3(0.0f, 0.0f, 1.0f)));
  123. }
  124. static void testQuaternionMatrix() {
  125. Quaternion q1 = UNIT_QUATERNION;
  126. axisAngleQ(&q1, CV3(1.0f, 0.0f, 0.0f), 48.0f);
  127. Quaternion q2 = UNIT_QUATERNION;
  128. axisAngleQ(&q2, CV3(0.0f, 1.0f, 0.0f), 52.0f);
  129. Quaternion q3 = UNIT_QUATERNION;
  130. axisAngleQ(&q3, CV3(0.0f, 0.0f, 1.0f), 60.0f);
  131. Matrix m = UNIT_MATRIX;
  132. translateMatrix(&m, CV3(1.0f, 2.0f, 3.0f));
  133. rotateMatrix(&m, &q1);
  134. rotateMatrix(&m, &q2);
  135. rotateMatrix(&m, &q3);
  136. translateMatrix(&m, CV3(1.0f, 2.0f, 3.0f));
  137. Matrix check = UNIT_MATRIX;
  138. translateMatrix(&check, CV3(1.0f, 2.0f, 3.0f));
  139. rotateMatrixX(&check, 48.0f);
  140. rotateMatrixY(&check, 52.0f);
  141. rotateMatrixZ(&check, 60.0f);
  142. translateMatrix(&check, CV3(1.0f, 2.0f, 3.0f));
  143. for(int i = 0; i < 16; i++) {
  144. TEST_FLOAT(((float*)&check)[i], ((float*)&m)[i], 0.0001f);
  145. }
  146. }
  147. static void testToString() {
  148. Matrix m;
  149. for(int i = 0; i < 16; i++) {
  150. ((float*)&m)[i] = (float)i + 1.0f;
  151. }
  152. char buffer[1024];
  153. size_t n = toStringMatrix(&m, buffer, sizeof(buffer));
  154. TEST_SIZE(127, n);
  155. TEST_STRING(
  156. "[[1.000, 2.000, 3.000, 4.000], [5.000, 6.000, 7.000, 8.000], "
  157. "[9.000, 10.000, 11.000, 12.000], [13.000, 14.000, 15.000, 16.000]]",
  158. buffer);
  159. n = toStringMatrix(&m, buffer, 20);
  160. TEST_SIZE(127, n);
  161. TEST_STRING("[[1.000, 2.000, 3.0", buffer);
  162. }
  163. void testMatrix() {
  164. testInit();
  165. testTranspose();
  166. testScale();
  167. testUniformScale();
  168. testTranslateX();
  169. testTranslateY();
  170. testTranslateZ();
  171. testTranslate();
  172. testTranslateTo();
  173. testCombination();
  174. testMatrixCombination();
  175. testRotateX();
  176. testRotateY();
  177. testRotateZ();
  178. testQuaternionMatrix();
  179. testToString();
  180. }