Quaternion.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #include "core/Quaternion.h"
  2. #include <math.h>
  3. #include "core/Utility.h"
  4. #define mulC(a, b) mulV3F(&VECTOR3, (a), (b))
  5. #define crossC(a, b) cross(&VECTOR3, (a), (b))
  6. #define addC(a, b) addV3(&VECTOR3, (a), (b))
  7. #define subC(a, b) subV3(&VECTOR3, (a), (b))
  8. Quaternion* axisAngleQ(Quaternion* q, const Vector3* axis, float angle) {
  9. q->xyz = *axis;
  10. normalizeV3(&q->xyz);
  11. angle = degreeToRadian(angle) * 0.5f;
  12. q->w = cosf(angle);
  13. mulSetV3F(&q->xyz, sinf(angle));
  14. return q;
  15. }
  16. Quaternion* lerpQ(Quaternion* q, const Quaternion* a, float f,
  17. const Quaternion* b) {
  18. addV3(&q->xyz, mulC(&a->xyz, 1.0f - f), mulC(&b->xyz, f));
  19. q->w = a->w * (1.0f - f) + b->w * f;
  20. float iLength = 1.0f / sqrtf(squareLengthV3(&q->xyz) + q->w * q->w);
  21. mulSetV3F(&q->xyz, iLength);
  22. q->w *= iLength;
  23. return q;
  24. }
  25. Quaternion* mulSetQ(Quaternion* q, const Quaternion* o) {
  26. float dot = dotV3(&q->xyz, &o->xyz);
  27. addV3(&q->xyz, mulC(&o->xyz, q->w),
  28. addC(mulC(&q->xyz, o->w), crossC(&q->xyz, &o->xyz)));
  29. q->w = q->w * o->w - dot;
  30. return q;
  31. }
  32. Quaternion* mulQ(Quaternion* q, const Quaternion* a, const Quaternion* b) {
  33. *q = *a;
  34. mulSetQ(q, b);
  35. return q;
  36. }
  37. Vector3* mulQV3(Vector3* r, const Quaternion* q, const Vector3* v) {
  38. Vector3 qv;
  39. addV3(&qv, mulC(v, q->w), crossC(&q->xyz, v));
  40. addV3(r, mulC(&q->xyz, dotV3(&q->xyz, v)),
  41. subC(mulC(&qv, q->w), crossC(&qv, &q->xyz)));
  42. return r;
  43. }
  44. size_t toStringQ(const Quaternion* q, char* buffer, size_t n) {
  45. return toString(buffer, n, "(%.3f i + %.3f j + %.3f k + %.3f)",
  46. (double)q->xyz.data[0], (double)q->xyz.data[1],
  47. (double)q->xyz.data[2], (double)q->w);
  48. }