Quaternion.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #include "core/Quaternion.h"
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include "core/Utility.h"
  5. #define CV30 (&CORE_VECTOR3)
  6. CoreQuaternion* coreAxisAngleQ(CoreQuaternion* q, const CoreVector3* axis,
  7. float angle) {
  8. q->xyz = *axis;
  9. coreNormalizeV3(&q->xyz);
  10. angle = coreDegreeToRadian(angle) * 0.5f;
  11. q->w = cosf(angle);
  12. coreMulSetV3F(&q->xyz, sinf(angle));
  13. return q;
  14. }
  15. CoreQuaternion* coreLerpQ(CoreQuaternion* q, const CoreQuaternion* a, float f,
  16. const CoreQuaternion* b) {
  17. coreAddV3(&q->xyz, coreMulV3F(CV30, &a->xyz, 1.0f - f),
  18. coreMulV3F(CV30, &b->xyz, f));
  19. q->w = a->w * (1.0f - f) + b->w * f;
  20. float iLength = 1.0f / sqrtf(coreSquareLengthV3(&q->xyz) + q->w * q->w);
  21. coreMulSetV3F(&q->xyz, iLength);
  22. q->w *= iLength;
  23. return q;
  24. }
  25. CoreQuaternion* coreMulSetQ(CoreQuaternion* q, const CoreQuaternion* other) {
  26. float dot = coreDotV3(&q->xyz, &other->xyz);
  27. coreAddV3(&q->xyz, coreMulV3F(CV30, &other->xyz, q->w),
  28. coreAddV3(CV30, coreMulV3F(CV30, &q->xyz, other->w),
  29. coreCross(CV30, &q->xyz, &other->xyz)));
  30. q->w = q->w * other->w - dot;
  31. return q;
  32. }
  33. CoreQuaternion* coreMulQ(CoreQuaternion* q, const CoreQuaternion* a,
  34. const CoreQuaternion* b) {
  35. *q = *a;
  36. coreMulSetQ(q, b);
  37. return q;
  38. }
  39. CoreVector3* coreMulQV3(CoreVector3* r, const CoreQuaternion* q,
  40. const CoreVector3* v) {
  41. CoreVector3 qv;
  42. coreAddV3(&qv, coreMulV3F(CV30, v, q->w), coreCross(CV30, &q->xyz, v));
  43. coreAddV3(r, coreMulV3F(CV30, &q->xyz, coreDotV3(&q->xyz, v)),
  44. coreSubV3(CV30, coreMulV3F(CV30, &qv, q->w),
  45. coreCross(CV30, &qv, &q->xyz)));
  46. return r;
  47. }
  48. size_t coreToStringQ(const CoreQuaternion* q, char* buffer, size_t n) {
  49. int w = snprintf(buffer, n, "(%.3f i + %.3f j + %.3f k + %.3f)",
  50. (double)q->xyz.data[0], (double)q->xyz.data[1],
  51. (double)q->xyz.data[2], (double)q->w);
  52. return w < 0 ? 0 : (size_t)w;
  53. }