aiQuaternion.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /** @file Quaternion structure, including operators when compiling in C++ */
  2. #ifndef AI_QUATERNION_H_INC
  3. #define AI_QUATERNION_H_INC
  4. #include <math.h>
  5. #include "aiTypes.h"
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. // ---------------------------------------------------------------------------
  10. /** Represents a quaternion in a 4D vector. */
  11. typedef struct aiQuaternion
  12. {
  13. #ifdef __cplusplus
  14. aiQuaternion() : w(0.0f), x(0.0f), y(0.0f), z(0.0f) {}
  15. aiQuaternion(float _w, float _x, float _y, float _z) : w(_w), x(_x), y(_y), z(_z) {}
  16. /** Construct from rotation matrix. Result is undefined if the matrix is not orthonormal. */
  17. aiQuaternion( const aiMatrix3x3& pRotMatrix);
  18. /** Returns a matrix representation of the quaternion */
  19. aiMatrix3x3 GetMatrix() const;
  20. #endif // __cplusplus
  21. float w, x, y, z;
  22. } aiQuaternion_t;
  23. #ifdef __cplusplus
  24. // ---------------------------------------------------------------------------
  25. // Constructs a quaternion from a rotation matrix
  26. inline aiQuaternion::aiQuaternion( const aiMatrix3x3 &pRotMatrix)
  27. {
  28. float t = 1 + pRotMatrix.a1 + pRotMatrix.b2 + pRotMatrix.c3;
  29. // large enough
  30. if( t > 0.00001f)
  31. {
  32. float s = sqrt( t) * 2.0f;
  33. x = (pRotMatrix.b3 - pRotMatrix.c2) / s;
  34. y = (pRotMatrix.c1 - pRotMatrix.a3) / s;
  35. z = (pRotMatrix.a2 - pRotMatrix.b1) / s;
  36. w = 0.25f * s;
  37. } // else we have to check several cases
  38. else if( pRotMatrix.a1 > pRotMatrix.b2 && pRotMatrix.a1 > pRotMatrix.c3 )
  39. {
  40. // Column 0:
  41. float s = sqrt( 1.0f + pRotMatrix.a1 - pRotMatrix.b2 - pRotMatrix.c3) * 2.0f;
  42. x = 0.25f * s;
  43. y = (pRotMatrix.a2 + pRotMatrix.b1) / s;
  44. z = (pRotMatrix.c1 + pRotMatrix.a3) / s;
  45. w = (pRotMatrix.b3 - pRotMatrix.c2) / s;
  46. } else
  47. if( pRotMatrix.b2 > pRotMatrix.c3)
  48. {
  49. // Column 1:
  50. float s = sqrt( 1.0f + pRotMatrix.b2 - pRotMatrix.a1 - pRotMatrix.c3) * 2.0f;
  51. x = (pRotMatrix.a2 + pRotMatrix.b1) / s;
  52. y = 0.25f * s;
  53. z = (pRotMatrix.b3 + pRotMatrix.c2) / s;
  54. w = (pRotMatrix.c1 - pRotMatrix.a3) / s;
  55. } else
  56. {
  57. // Column 2:
  58. float s = sqrt( 1.0f + pRotMatrix.c3 - pRotMatrix.a1 - pRotMatrix.b2) * 2.0f;
  59. x = (pRotMatrix.c1 + pRotMatrix.a3) / s;
  60. y = (pRotMatrix.b3 + pRotMatrix.c2) / s;
  61. z = 0.25f * s;
  62. w = (pRotMatrix.a2 - pRotMatrix.b1) / s;
  63. }
  64. }
  65. // ---------------------------------------------------------------------------
  66. // Returns a matrix representation of the quaternion
  67. inline aiMatrix3x3 aiQuaternion::GetMatrix() const
  68. {
  69. aiMatrix3x3 resMatrix;
  70. resMatrix.a1 = 1.0f - 2.0f * (y * y + z * z);
  71. resMatrix.a2 = 2.0f * (x * y + z * w);
  72. resMatrix.a3 = 2.0f * (x * z - y * w);
  73. resMatrix.b1 = 2.0f * (x * y - z * w);
  74. resMatrix.b2 = 1.0f - 2.0f * (x * x + z * z);
  75. resMatrix.b3 = 2.0f * (y * z + x * w);
  76. resMatrix.c1 = 2.0f * (x * z + y * w);
  77. resMatrix.c2 = 2.0f * (y * z - x * w);
  78. resMatrix.c3 = 1.0f - 2.0f * (x * x + y * y);
  79. return resMatrix;
  80. }
  81. } // end extern "C"
  82. #endif // __cplusplus
  83. #endif // AI_QUATERNION_H_INC