DMat44Tests.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2022 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include "UnitTestFramework.h"
  5. #include <Jolt/Math/DMat44.h>
  6. #include <Jolt/Core/StringTools.h>
  7. TEST_SUITE("DMat44Tests")
  8. {
  9. TEST_CASE("TestDMat44Zero")
  10. {
  11. DMat44 zero = DMat44::sZero();
  12. CHECK(zero == DMat44(Vec4(0, 0, 0, 0), Vec4(0, 0, 0, 0), Vec4(0, 0, 0, 0), DVec3(0, 0, 0)));
  13. CHECK(zero.GetAxisX() == Vec3::sZero());
  14. CHECK(zero.GetAxisY() == Vec3::sZero());
  15. CHECK(zero.GetAxisZ() == Vec3::sZero());
  16. CHECK(zero.GetTranslation() == DVec3::sZero());
  17. }
  18. TEST_CASE("TestDMat44Identity")
  19. {
  20. DMat44 identity = DMat44::sIdentity();
  21. CHECK(identity == DMat44(Vec4(1, 0, 0, 0), Vec4(0, 1, 0, 0), Vec4(0, 0, 1, 0), DVec3(0, 0, 0)));
  22. // Check non-equality
  23. CHECK(identity != DMat44(Vec4(0, 0, 0, 0), Vec4(0, 1, 0, 0), Vec4(0, 0, 1, 0), DVec3(0, 0, 0)));
  24. CHECK(identity != DMat44(Vec4(1, 0, 0, 0), Vec4(0, 0, 0, 0), Vec4(0, 0, 1, 0), DVec3(0, 0, 0)));
  25. CHECK(identity != DMat44(Vec4(1, 0, 0, 0), Vec4(0, 1, 0, 0), Vec4(0, 0, 0, 0), DVec3(0, 0, 0)));
  26. CHECK(identity != DMat44(Vec4(1, 0, 0, 0), Vec4(0, 1, 0, 0), Vec4(0, 0, 1, 0), DVec3(1, 0, 0)));
  27. }
  28. TEST_CASE("TestDMat44Construct")
  29. {
  30. DMat44 mat(Vec4(1, 2, 3, 4), Vec4(5, 6, 7, 8), Vec4(9, 10, 11, 12), DVec3(13, 14, 15));
  31. CHECK(mat.GetColumn4(0) == Vec4(1, 2, 3, 4));
  32. CHECK(mat.GetColumn4(1) == Vec4(5, 6, 7, 8));
  33. CHECK(mat.GetColumn4(2) == Vec4(9, 10, 11, 12));
  34. CHECK(mat.GetTranslation() == DVec3(13, 14, 15));
  35. DMat44 mat2(mat);
  36. CHECK(mat2.GetColumn4(0) == Vec4(1, 2, 3, 4));
  37. CHECK(mat2.GetColumn4(1) == Vec4(5, 6, 7, 8));
  38. CHECK(mat2.GetColumn4(2) == Vec4(9, 10, 11, 12));
  39. CHECK(mat2.GetTranslation() == DVec3(13, 14, 15));
  40. }
  41. TEST_CASE("TestDMat44Scale")
  42. {
  43. CHECK(DMat44::sScale(Vec3(2, 3, 4)) == DMat44(Vec4(2, 0, 0, 0), Vec4(0, 3, 0, 0), Vec4(0, 0, 4, 0), DVec3(0, 0, 0)));
  44. }
  45. TEST_CASE("TestDMat44Rotation")
  46. {
  47. DMat44 mat(Vec4(1, 2, 3, 4), Vec4(5, 6, 7, 8), Vec4(9, 10, 11, 12), DVec3(13, 14, 15));
  48. CHECK(mat.GetRotation() == Mat44(Vec4(1, 2, 3, 4), Vec4(5, 6, 7, 8), Vec4(9, 10, 11, 12), Vec4(0, 0, 0, 1)));
  49. }
  50. TEST_CASE("TestMat44SetRotation")
  51. {
  52. DMat44 mat(Vec4(1, 2, 3, 4), Vec4(5, 6, 7, 8), Vec4(9, 10, 11, 12), DVec3(13, 14, 15));
  53. Mat44 mat2(Vec4(17, 18, 19, 20), Vec4(21, 22, 23, 24), Vec4(25, 26, 27, 28), Vec4(29, 30, 31, 32));
  54. mat.SetRotation(mat2);
  55. CHECK(mat == DMat44(Vec4(17, 18, 19, 20), Vec4(21, 22, 23, 24), Vec4(25, 26, 27, 28), DVec3(13, 14, 15)));
  56. }
  57. TEST_CASE("TestDMat44Rotation")
  58. {
  59. Quat q = Quat::sRotation(Vec3(1, 1, 1).Normalized(), 0.2f * JPH_PI);
  60. CHECK(DMat44::sRotation(q).ToMat44() == Mat44::sRotation(q));
  61. }
  62. TEST_CASE("TestDMat44Translation")
  63. {
  64. CHECK(DMat44::sTranslation(DVec3(1, 2, 3)) == DMat44(Vec4(1, 0, 0, 0), Vec4(0, 1, 0, 0), Vec4(0, 0, 1, 0), DVec3(1, 2, 3)));
  65. }
  66. TEST_CASE("TestDMat44RotationTranslation")
  67. {
  68. Quat q = Quat::sRotation(Vec3(1, 1, 1).Normalized(), 0.2f * JPH_PI);
  69. CHECK(DMat44::sRotationTranslation(q, DVec3(1, 2, 3)).ToMat44() == Mat44::sRotationTranslation(q, Vec3(1, 2, 3)));
  70. }
  71. TEST_CASE("TestDMat44MultiplyMat44")
  72. {
  73. DMat44 mat(Vec4(1, 2, 3, 0), Vec4(5, 6, 7, 0), Vec4(9, 10, 11, 0), DVec3(13, 14, 15));
  74. Mat44 mat2(Vec4(17, 18, 19, 0), Vec4(21, 22, 23, 0), Vec4(25, 26, 27, 0), Vec4(29, 30, 31, 1));
  75. DMat44 result = mat * mat2;
  76. CHECK(result == DMat44(Vec4(278, 332, 386, 0), Vec4(338, 404, 470, 0), Vec4(398, 476, 554, 0), DVec3(471, 562, 653)));
  77. }
  78. TEST_CASE("TestDMat44MultiplyDMat44")
  79. {
  80. DMat44 mat(Vec4(1, 2, 3, 0), Vec4(5, 6, 7, 0), Vec4(9, 10, 11, 0), DVec3(13, 14, 15));
  81. DMat44 mat2(Vec4(17, 18, 19, 0), Vec4(21, 22, 23, 0), Vec4(25, 26, 27, 0), DVec3(29, 30, 31));
  82. DMat44 result = mat * mat2;
  83. CHECK(result == DMat44(Vec4(278, 332, 386, 0), Vec4(338, 404, 470, 0), Vec4(398, 476, 554, 0), DVec3(471, 562, 653)));
  84. }
  85. TEST_CASE("TestDMat44MultiplyVec3")
  86. {
  87. DMat44 mat(Vec4(1, 2, 3, 4), Vec4(5, 6, 7, 8), Vec4(9, 10, 11, 12), DVec3(13, 14, 15));
  88. Vec3 vec(17, 18, 19);
  89. DVec3 result = mat * DVec3(vec);
  90. CHECK(result == DVec3(291, 346, 401));
  91. DVec3 result2 = mat * vec;
  92. CHECK(result2 == DVec3(291, 346, 401));
  93. Vec3 result3 = mat.Multiply3x3(vec);
  94. CHECK(result3 == Vec3(278, 332, 386));
  95. Vec3 result4 = mat.Multiply3x3Transposed(vec);
  96. CHECK(result4 == Vec3(110, 326, 542));
  97. }
  98. TEST_CASE("TestDMat44Inversed")
  99. {
  100. DMat44 mat(Vec4(1, 16, 2, 0), Vec4(2, 8, 4, 0), Vec4(8, 4, 1, 0), DVec3(4, 2, 8));
  101. DMat44 inverse = mat.Inversed();
  102. DMat44 identity = mat * inverse;
  103. CHECK_APPROX_EQUAL(identity, DMat44::sIdentity());
  104. }
  105. TEST_CASE("TestDMat44InverseRotateTranslate")
  106. {
  107. Quat rot = Quat::sRotation(Vec3(0, 1, 0), 0.2f * JPH_PI);
  108. DVec3 pos(2, 3, 4);
  109. DMat44 m1 = DMat44::sRotationTranslation(rot, pos).Inversed();
  110. DMat44 m2 = DMat44::sInverseRotationTranslation(rot, pos);
  111. CHECK_APPROX_EQUAL(m1, m2);
  112. }
  113. TEST_CASE("TestDMat44InversedRotationTranslation")
  114. {
  115. Quat rot = Quat::sRotation(Vec3(0, 1, 0), 0.2f * JPH_PI);
  116. DVec3 pos(2, 3, 4);
  117. DMat44 m1 = DMat44::sRotationTranslation(rot, pos).InversedRotationTranslation();
  118. DMat44 m2 = DMat44::sInverseRotationTranslation(rot, pos);
  119. CHECK_APPROX_EQUAL(m1, m2);
  120. }
  121. TEST_CASE("TestDMat44PrePostScaled")
  122. {
  123. DMat44 m(Vec4(2, 3, 4, 0), Vec4(5, 6, 7, 0), Vec4(8, 9, 10, 0), DVec3(11, 12, 13));
  124. Vec3 v(14, 15, 16);
  125. CHECK(m.PreScaled(v) == m * DMat44::sScale(v));
  126. CHECK(m.PostScaled(v) == DMat44::sScale(v) * m);
  127. }
  128. TEST_CASE("TestDMat44PrePostTranslated")
  129. {
  130. DMat44 m(Vec4(2, 3, 4, 0), Vec4(5, 6, 7, 0), Vec4(8, 9, 10, 0), DVec3(11, 12, 13));
  131. Vec3 v(14, 15, 16);
  132. CHECK_APPROX_EQUAL(m.PreTranslated(v), m * DMat44::sTranslation(DVec3(v)));
  133. CHECK_APPROX_EQUAL(m.PostTranslated(v), DMat44::sTranslation(DVec3(v)) * m);
  134. }
  135. TEST_CASE("TestDMat44Decompose")
  136. {
  137. // Create a rotation/translation matrix
  138. Quat rot = Quat::sRotation(Vec3(1, 1, 1).Normalized(), 0.2f * JPH_PI);
  139. DVec3 pos(2, 3, 4);
  140. DMat44 rotation_translation = DMat44::sRotationTranslation(rot, pos);
  141. // Scale the matrix
  142. Vec3 scale(2, 1, 3);
  143. DMat44 m1 = rotation_translation * DMat44::sScale(scale);
  144. // Decompose scale
  145. Vec3 scale_out;
  146. DMat44 m2 = m1.Decompose(scale_out);
  147. // Check individual components
  148. CHECK_APPROX_EQUAL(rotation_translation, m2);
  149. CHECK_APPROX_EQUAL(scale, scale_out);
  150. }
  151. TEST_CASE("TestDMat44ToMat44")
  152. {
  153. DMat44 mat(Vec4(1, 2, 3, 4), Vec4(5, 6, 7, 8), Vec4(9, 10, 11, 12), DVec3(13, 14, 15));
  154. CHECK(mat.ToMat44() == Mat44(Vec4(1, 2, 3, 4), Vec4(5, 6, 7, 8), Vec4(9, 10, 11, 12), Vec4(13, 14, 15, 1)));
  155. }
  156. TEST_CASE("TestDMat44Column")
  157. {
  158. DMat44 mat = DMat44::sZero();
  159. mat.SetColumn4(0, Vec4(1, 2, 3, 4));
  160. CHECK(mat.GetColumn4(0) == Vec4(1, 2, 3, 4));
  161. mat.SetColumn3(0, Vec3(5, 6, 7));
  162. CHECK(mat.GetColumn3(0) == Vec3(5, 6, 7));
  163. CHECK(mat.GetColumn4(0) == Vec4(5, 6, 7, 0));
  164. mat.SetAxisX(Vec3(8, 9, 10));
  165. mat.SetAxisY(Vec3(11, 12, 13));
  166. mat.SetAxisZ(Vec3(14, 15, 16));
  167. mat.SetTranslation(DVec3(17, 18, 19));
  168. CHECK(mat.GetAxisX() == Vec3(8, 9, 10));
  169. CHECK(mat.GetAxisY() == Vec3(11, 12, 13));
  170. CHECK(mat.GetAxisZ() == Vec3(14, 15, 16));
  171. CHECK(mat.GetTranslation() == DVec3(17, 18, 19));
  172. }
  173. TEST_CASE("TestDMat44Transposed")
  174. {
  175. DMat44 mat(Vec4(1, 2, 3, 4), Vec4(5, 6, 7, 8), Vec4(9, 10, 11, 12), DVec3(13, 14, 15));
  176. Mat44 result = mat.Transposed3x3();
  177. CHECK(result == Mat44(Vec4(1, 5, 9, 0), Vec4(2, 6, 10, 0), Vec4(3, 7, 11, 0), Vec4(0, 0, 0, 1)));
  178. }
  179. TEST_CASE("TestDMat44GetQuaternion")
  180. {
  181. Quat rot = Quat::sRotation(Vec3(1, 1, 1).Normalized(), 0.2f * JPH_PI);
  182. DMat44 mat = DMat44::sRotation(rot);
  183. CHECK_APPROX_EQUAL(mat.GetQuaternion(), rot);
  184. }
  185. TEST_CASE("TestDMat44PrePostTranslated")
  186. {
  187. DMat44 m(Vec4(2, 3, 4, 0), Vec4(5, 6, 7, 0), Vec4(8, 9, 10, 0), DVec3(11, 12, 13));
  188. DVec3 v(14, 15, 16);
  189. CHECK(m.PreTranslated(v) == m * DMat44::sTranslation(v));
  190. CHECK(m.PostTranslated(v) == DMat44::sTranslation(v) * m);
  191. }
  192. TEST_CASE("TestDMat44ConvertToString")
  193. {
  194. DMat44 v(Vec4(1, 2, 3, 4), Vec4(5, 6, 7, 8), Vec4(9, 10, 11, 12), DVec3(13, 14, 15));
  195. CHECK(ConvertToString(v) == "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15");
  196. }
  197. }