Quaternion.cpp 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. #include <math.h>
  2. #include "core/Generic.hpp"
  3. #include "core/ToString.hpp"
  4. typedef Quaternion Q;
  5. Q* axisAngleQ(Q* q, const Vector3* axis, float angle) {
  6. q->v.xyz = *axis;
  7. normalize(&q->v.xyz);
  8. angle *= 0.5f;
  9. q->v.w = cosf(angle);
  10. mulSet(&q->v.xyz, sinf(angle));
  11. return q;
  12. }
  13. Q* lerpQ(Q* q, const Q* a, float f, const Q* b) {
  14. add(&q->v, mul(&a->v, 1.0f - f), mul(&b->v, f));
  15. float iLength = 1.0f / length(&q->v);
  16. mulSet(&q->v, iLength);
  17. return q;
  18. }
  19. Q* mulSetQ(Q* q, const Q* o) {
  20. float dot = dot(&q->v.xyz, &o->v.xyz);
  21. add(&q->v.xyz, mul(&o->v.xyz, q->v.w),
  22. add(mul(&q->v.xyz, o->v.w), cross(&q->v.xyz, &o->v.xyz)));
  23. q->v.w = q->v.w * o->v.w - dot;
  24. return q;
  25. }
  26. Q* mulQ(Q* q, const Q* a, const Q* b) {
  27. *q = *a;
  28. mulSetQ(q, b);
  29. return q;
  30. }
  31. Vector3* mulQV3(Vector3* r, const Q* q, const Vector3* v) {
  32. Vector3 qv;
  33. add(&qv, mul(v, q->v.w), cross(&q->v.xyz, v));
  34. add(r, mul(&q->v.xyz, dot(&q->v.xyz, v)),
  35. sub(mul(&qv, q->v.w), cross(&qv, &q->v.xyz)));
  36. return r;
  37. }
  38. size_t toStringQ(const Q* q, char* buffer, size_t n) {
  39. return toString(
  40. buffer, n, "(%.3f i + %.3f j + %.3f k + %.3f)", (double)q->v.x,
  41. (double)q->v.y, (double)q->v.z, (double)q->v.w);
  42. }