Quaternion.cpp 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #include <cmath>
  2. #include "client/math/Quaternion.h"
  3. Quaternion::Quaternion(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {
  4. }
  5. Quaternion::Quaternion(Vector unitAxis, float angle) {
  6. float sin;
  7. sincosf(angle * (M_PI / 360.0f), &sin, &w);
  8. x = unitAxis.getX() * sin;
  9. y = unitAxis.getY() * sin;
  10. z = unitAxis.getZ() * sin;
  11. }
  12. Quaternion Quaternion::lerp(float f, const Quaternion& other) const {
  13. Quaternion q = interpolate(1 - f, f, other);
  14. q.normalize();
  15. return q;
  16. }
  17. Quaternion Quaternion::slerp(float f, const Quaternion& other) const {
  18. float arccos = acosf(x * other.x + y * other.y + z * other.z + w * other.w);
  19. float sin = 1.0f / sinf(arccos);
  20. return interpolate(sinf((1 - f) * arccos) * sin, sinf(f * arccos) * sin, other);
  21. }
  22. Quaternion Quaternion::interpolate(float a, float b, const Quaternion& other) const {
  23. return Quaternion(x * a + other.x * b, y * a + other.y * b, z * a + other.z * b, w * a + other.w * b);
  24. }
  25. void Quaternion::normalize() {
  26. float f = 1.0f / sqrtf(x * x + y * y + z * z + w * w);
  27. x *= f;
  28. y *= f;
  29. z *= f;
  30. w *= f;
  31. }
  32. Matrix Quaternion::toMatrix() const {
  33. float x2 = 2 * x * x;
  34. float y2 = 2 * y * y;
  35. float z2 = 2 * z * z;
  36. float xy = 2 * x * y;
  37. float xz = 2 * x * z;
  38. float xw = 2 * x * w;
  39. float zw = 2 * z * w;
  40. float yz = 2 * y * z;
  41. float yw = 2 * y * w;
  42. Matrix m;
  43. m.set(0, 1 - y2 - z2).set(1, xy - zw).set(2, xz + yw);
  44. m.set(4, xy + zw).set(5, 1 - x2 - z2).set(6, yz - xw);
  45. m.set(8, xz - yw).set(9, yz + xw).set(10, 1 - x2 - y2);
  46. return m;
  47. }