Quaternion.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #pragma once
  2. #include "Common.h"
  3. #include "Matrix4.h"
  4. #include <math.h>
  5. NS_BF_BEGIN;
  6. const float BF_MS_EPSILON = 1e-03f;
  7. class Quaternion
  8. {
  9. public:
  10. float mX, mY, mZ, mW;
  11. public:
  12. Quaternion()
  13. {}
  14. Quaternion(float x, float y, float z, float w) :
  15. mX(x), mY(y), mZ(z), mW(w)
  16. {
  17. }
  18. Matrix4 ToMatrix2() const
  19. {
  20. // source -> http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation#Quaternion_to_Matrix
  21. float x2 = mX * mX;
  22. float y2 = mY * mY;
  23. float z2 = mZ * mZ;
  24. float xy = mX * mY;
  25. float xz = mX * mZ;
  26. float yz = mY * mZ;
  27. float wx = mW * mX;
  28. float wy = mW * mY;
  29. float wz = mW * mZ;
  30. // This calculation would be a lot more complicated for non-unit length quaternions
  31. // Note: The constructor of Matrix4 expects the Matrix in column-major format like expected by
  32. // OpenGL
  33. return Matrix4(
  34. 1.0f - 2.0f * (y2 + z2), 2.0f * (xy - wz), 2.0f * (xz + wy), 0.0f,
  35. 2.0f * (xy + wz), 1.0f - 2.0f * (x2 + z2), 2.0f * (yz - wx), 0.0f,
  36. 2.0f * (xz - wy), 2.0f * (yz + wx), 1.0f - 2.0f * (x2 + y2), 0.0f,
  37. 2.0f * (xz - wy), 2.0f * (yz + wx), 1.0f - 2.0f * (x2 + y2), 0.0f);
  38. }
  39. Matrix4 ToMatrix() const
  40. {
  41. Matrix4 result;
  42. float fTx = mX + mX;
  43. float fTy = mY + mY;
  44. float fTz = mZ + mZ;
  45. float fTwx = fTx*mW;
  46. float fTwy = fTy*mW;
  47. float fTwz = fTz*mW;
  48. float fTxx = fTx*mX;
  49. float fTxy = fTy*mX;
  50. float fTxz = fTz*mX;
  51. float fTyy = fTy*mY;
  52. float fTyz = fTz*mY;
  53. float fTzz = fTz*mZ;
  54. result.m00 = 1.0f - (fTyy + fTzz);
  55. result.m01 = fTxy - fTwz;
  56. result.m02 = fTxz + fTwy;
  57. result.m03 = 0;
  58. result.m10 = fTxy + fTwz;
  59. result.m11 = 1.0f - (fTxx + fTzz);
  60. result.m12 = fTyz - fTwx;
  61. result.m13 = 0;
  62. result.m20 = fTxz - fTwy;
  63. result.m21 = fTyz + fTwx;
  64. result.m22 = 1.0f - (fTxx + fTyy);
  65. result.m23 = 0;
  66. result.m30 = 0;
  67. result.m31 = 0;
  68. result.m32 = 0;
  69. result.m33 = 1.0f;
  70. return result;
  71. }
  72. static float Dot(const Quaternion& rkP, const Quaternion& rkQ)
  73. {
  74. return rkP.mX*rkQ.mX + rkP.mY*rkQ.mY + rkP.mZ*rkQ.mZ + rkP.mW*rkQ.mW;
  75. }
  76. Quaternion operator- () const
  77. {
  78. return Quaternion(-mX, -mY, -mZ, -mW);
  79. }
  80. Quaternion operator* (float fScalar) const
  81. {
  82. return Quaternion(fScalar*mX, fScalar*mY, fScalar*mZ, fScalar*mW);
  83. }
  84. Quaternion operator+ (const Quaternion& rkQ) const
  85. {
  86. return Quaternion(mX + rkQ.mX, mY + rkQ.mY, mZ + rkQ.mZ, mW + rkQ.mW);
  87. }
  88. static Quaternion Slerp(float fT, const Quaternion& rkP, const Quaternion& rkQ, bool shortestPath);
  89. float Norm() const
  90. {
  91. return mX*mX + mY*mY + mZ*mZ + mW*mW;
  92. }
  93. static Quaternion Normalise(const Quaternion& quat)
  94. {
  95. float len = quat.Norm();
  96. float factor = 1.0f / sqrtf(len);
  97. return quat * factor;
  98. }
  99. };
  100. Quaternion operator*(float fScalar, const Quaternion& rkQ);
  101. NS_BF_END;