QuaternionTests.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "../Tests.h"
  2. #include "core/Generic.h"
  3. #include "core/Utility.h"
  4. #define CV3(a, b, c) (&(Vector3){{a, b, c}})
  5. #define CV30 CV3(0.0f, 0.0f, 0.0f)
  6. static void testInit() {
  7. Quaternion q = UNIT_QUATERNION;
  8. char buffer[128];
  9. toStringQ(&q, buffer, sizeof(buffer));
  10. TEST_STRING("(0.000 i + 0.000 j + 0.000 k + 1.000)", buffer);
  11. }
  12. static void testAxisAndDegreesInit() {
  13. Quaternion q = UNIT_QUATERNION;
  14. axisAngleQ(&q, CV3(1.0f, 2.0f, 3.0f), degreeToRadian(142.0f));
  15. char buffer[128];
  16. toStringQ(&q, buffer, sizeof(buffer));
  17. TEST_STRING("(0.253 i + 0.505 j + 0.758 k + 0.326)", buffer);
  18. }
  19. static void testLerp() {
  20. Quaternion q1 = UNIT_QUATERNION;
  21. axisAngleQ(&q1, CV3(2.0f, 5.0f, 7.0f), degreeToRadian(130.0f));
  22. Quaternion q2 = UNIT_QUATERNION;
  23. axisAngleQ(&q2, CV3(1.0f, 2.0f, 4.0f), degreeToRadian(260.0f));
  24. Quaternion q3;
  25. lerpQ(&q3, &q1, 0.3f, &q2);
  26. char buffer[128];
  27. toStringQ(&q3, buffer, sizeof(buffer));
  28. TEST_STRING("(0.223 i + 0.529 j + 0.810 k + 0.119)", buffer);
  29. }
  30. static void testMulSet() {
  31. Quaternion q1 = UNIT_QUATERNION;
  32. axisAngleQ(&q1, CV3(2.0f, 5.0f, 7.0f), degreeToRadian(50.0f));
  33. Quaternion q2 = UNIT_QUATERNION;
  34. axisAngleQ(&q2, CV3(2.0f, 5.0f, 7.0f), degreeToRadian(60.0f));
  35. Quaternion q3 = UNIT_QUATERNION;
  36. mulSet(&q3, &q1);
  37. char bufferQ1[128];
  38. toStringQ(&q1, bufferQ1, sizeof(bufferQ1));
  39. char bufferQ3[128];
  40. toStringQ(&q3, bufferQ3, sizeof(bufferQ3));
  41. TEST_STRING(bufferQ1, bufferQ3);
  42. mulSet(&q3, &q2);
  43. toStringQ(&q3, bufferQ3, sizeof(bufferQ3));
  44. axisAngleQ(&q1, CV3(2.0f, 5.0f, 7.0f), degreeToRadian(110.0f));
  45. toStringQ(&q1, bufferQ1, sizeof(bufferQ1));
  46. TEST_STRING(bufferQ1, bufferQ3);
  47. }
  48. static void testMul() {
  49. Quaternion q1 = UNIT_QUATERNION;
  50. axisAngleQ(&q1, CV3(2.0f, 5.0f, 7.0f), degreeToRadian(50.0f));
  51. Quaternion q2 = UNIT_QUATERNION;
  52. axisAngleQ(&q2, CV3(2.0f, 5.0f, 7.0f), degreeToRadian(60.0f));
  53. Quaternion q3 = UNIT_QUATERNION;
  54. mul(&q3, &q1, &q2);
  55. char bufferQ3[128];
  56. toStringQ(&q3, bufferQ3, sizeof(bufferQ3));
  57. Quaternion q = UNIT_QUATERNION;
  58. axisAngleQ(&q, CV3(2.0f, 5.0f, 7.0f), degreeToRadian(110.0f));
  59. char bufferQ[128];
  60. toStringQ(&q, bufferQ, sizeof(bufferQ));
  61. TEST_STRING(bufferQ, bufferQ3);
  62. }
  63. static void testMulVector() {
  64. Quaternion q1 = UNIT_QUATERNION;
  65. axisAngleQ(&q1, CV3(1.0f, 0.0f, 0.0f), degreeToRadian(90.0f));
  66. Quaternion q2 = UNIT_QUATERNION;
  67. axisAngleQ(&q2, CV3(0.0f, 1.0f, 0.0f), degreeToRadian(90.0f));
  68. Quaternion q3 = UNIT_QUATERNION;
  69. axisAngleQ(&q3, CV3(0.0f, 0.0f, 1.0f), degreeToRadian(90.0f));
  70. Vector3 v1 = {{1.0f, 0.0f, 0.0f}};
  71. Vector3 v2 = {{0.0f, 1.0f, 0.0f}};
  72. Vector3 v3 = {{0.0f, 0.0f, 1.0f}};
  73. TEST_V3(CV3(1.0f, 0.0f, 0.0f), mul(CV30, &q1, &v1));
  74. TEST_V3(CV3(0.0f, 0.0f, 1.0f), mul(CV30, &q1, &v2));
  75. TEST_V3(CV3(0.0f, -1.0f, 0.0f), mul(CV30, &q1, &v3));
  76. TEST_V3(CV3(0.0f, 0.0f, -1.0f), mul(CV30, &q2, &v1));
  77. TEST_V3(CV3(0.0f, 1.0f, 0.0f), mul(CV30, &q2, &v2));
  78. TEST_V3(CV3(1.0f, 0.0f, 0.0f), mul(CV30, &q2, &v3));
  79. TEST_V3(CV3(0.0f, 1.0f, 0.0f), mul(CV30, &q3, &v1));
  80. TEST_V3(CV3(-1.0f, 0.0f, 0.0f), mul(CV30, &q3, &v2));
  81. TEST_V3(CV3(0.0f, 0.0f, 1.0f), mul(CV30, &q3, &v3));
  82. }
  83. void testQuaternion() {
  84. testInit();
  85. testAxisAndDegreesInit();
  86. testLerp();
  87. testMulSet();
  88. testMul();
  89. testMulVector();
  90. }