mQuat.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _MQUAT_H_
  23. #define _MQUAT_H_
  24. #ifndef _MMATH_H_
  25. #include "math/mMath.h"
  26. #endif
  27. class MatrixF;
  28. class QuatF;
  29. inline F32 QuatIsEqual(F32 a,F32 b,F32 epsilon = 0.0001f)
  30. {
  31. return mFabs(a-b) < epsilon;
  32. }
  33. inline F32 QuatIsZero(F32 a,F32 epsilon = 0.0001f)
  34. {
  35. return mFabs(a) < epsilon;
  36. }
  37. //----------------------------------------------------------------------------
  38. // rotation about an arbitrary axis through the origin:
  39. class AngAxisF
  40. {
  41. public:
  42. Point3F axis;
  43. F32 angle;
  44. AngAxisF();
  45. AngAxisF( const Point3F & _axis, F32 _angle );
  46. explicit AngAxisF( const MatrixF &m );
  47. explicit AngAxisF( const QuatF &q );
  48. AngAxisF& set( const Point3F & _axis, F32 _angle );
  49. AngAxisF& set( const MatrixF & m );
  50. AngAxisF& set( const QuatF & q );
  51. int operator ==( const AngAxisF & c ) const;
  52. int operator !=( const AngAxisF & c ) const;
  53. MatrixF * setMatrix( MatrixF * mat ) const;
  54. };
  55. //----------------------------------------------------------------------------
  56. // unit quaternion class:
  57. class QuatF
  58. {
  59. public:
  60. F32 x,y,z,w;
  61. QuatF();
  62. QuatF( F32 _x, F32 _y, F32 _z, F32 w );
  63. QuatF( const MatrixF & m );
  64. QuatF( const AngAxisF & a );
  65. QuatF( const EulerF & e );
  66. QuatF& set( F32 _x, F32 _y, F32 _z, F32 _w );
  67. QuatF& set( const MatrixF & m );
  68. QuatF& set( const AngAxisF & m );
  69. QuatF& set( const EulerF & e );
  70. int operator ==( const QuatF & c ) const;
  71. int operator !=( const QuatF & c ) const;
  72. QuatF& operator *=( const QuatF & c );
  73. QuatF& operator /=( const QuatF & c );
  74. QuatF& operator +=( const QuatF & c );
  75. QuatF& operator -=( const QuatF & c );
  76. QuatF& operator *=( F32 a );
  77. QuatF& operator /=( F32 a );
  78. QuatF& square();
  79. QuatF& neg();
  80. F32 dot( const QuatF &q ) const;
  81. MatrixF* setMatrix( MatrixF * mat ) const;
  82. QuatF& normalize();
  83. QuatF& inverse();
  84. QuatF& identity();
  85. int isIdentity() const;
  86. QuatF& slerp( const QuatF & q, F32 t );
  87. QuatF& extrapolate( const QuatF & q1, const QuatF & q2, F32 t );
  88. QuatF& interpolate( const QuatF & q1, const QuatF & q2, F32 t );
  89. F32 angleBetween( const QuatF & q );
  90. Point3F& mulP(const Point3F& a, Point3F* b); // r = p * this
  91. QuatF& mul(const QuatF& a, const QuatF& b); // This = a * b
  92. };
  93. //----------------------------------------------------------------------------
  94. // AngAxisF implementation:
  95. inline AngAxisF::AngAxisF()
  96. {
  97. }
  98. inline AngAxisF::AngAxisF( const Point3F & _axis, F32 _angle )
  99. {
  100. set(_axis,_angle);
  101. }
  102. inline AngAxisF::AngAxisF( const MatrixF & mat )
  103. {
  104. set(mat);
  105. }
  106. inline AngAxisF::AngAxisF( const QuatF & quat )
  107. {
  108. set(quat);
  109. }
  110. inline AngAxisF& AngAxisF::set( const Point3F & _axis, F32 _angle )
  111. {
  112. axis = _axis;
  113. angle = _angle;
  114. return *this;
  115. }
  116. inline int AngAxisF::operator ==( const AngAxisF & c ) const
  117. {
  118. return QuatIsEqual(angle, c.angle) && (axis == c.axis);
  119. }
  120. inline int AngAxisF::operator !=( const AngAxisF & c ) const
  121. {
  122. return !QuatIsEqual(angle, c.angle) || (axis != c.axis);
  123. }
  124. //----------------------------------------------------------------------------
  125. // quaternion implementation:
  126. inline QuatF::QuatF()
  127. {
  128. }
  129. inline QuatF::QuatF( F32 _x, F32 _y, F32 _z, F32 _w )
  130. {
  131. set( _x, _y, _z, _w );
  132. }
  133. inline QuatF::QuatF( const AngAxisF & a )
  134. {
  135. set( a );
  136. }
  137. inline QuatF::QuatF( const EulerF & e )
  138. {
  139. set(e);
  140. }
  141. inline QuatF& QuatF::set( F32 _x, F32 _y, F32 _z, F32 _w )
  142. {
  143. x = _x;
  144. y = _y;
  145. z = _z;
  146. w = _w;
  147. return *this;
  148. }
  149. inline int QuatF::operator ==( const QuatF & c ) const
  150. {
  151. QuatF a = *this;
  152. QuatF b = c;
  153. a.normalize();
  154. b.normalize();
  155. b.inverse();
  156. a *= b;
  157. return a.isIdentity();
  158. }
  159. inline int QuatF::isIdentity() const
  160. {
  161. return QuatIsZero( x ) && QuatIsZero( y ) && QuatIsZero( z );
  162. }
  163. inline QuatF& QuatF::identity()
  164. {
  165. x = 0.0f;
  166. y = 0.0f;
  167. z = 0.0f;
  168. w = 1.0f;
  169. return *this;
  170. }
  171. inline int QuatF::operator !=( const QuatF & c ) const
  172. {
  173. return ! operator==( c );
  174. }
  175. inline QuatF::QuatF( const MatrixF & m )
  176. {
  177. set( m );
  178. }
  179. inline QuatF& QuatF::neg()
  180. {
  181. x = -x;
  182. y = -y;
  183. z = -z;
  184. w = -w;
  185. return *this;
  186. }
  187. inline F32 QuatF::dot( const QuatF &q ) const
  188. {
  189. return (w*q.w + x*q.x + y*q.y + z*q.z);
  190. }
  191. inline F32 QuatF::angleBetween( const QuatF & q )
  192. {
  193. // angle between to quaternions
  194. return mAcos(x * q.x + y * q.y + z * q.z + w * q.w);
  195. }
  196. //----------------------------------------------------------------------------
  197. // TQuatF classes:
  198. class TQuatF : public QuatF
  199. {
  200. public:
  201. enum
  202. {
  203. Matrix_HasRotation = 1,
  204. Matrix_HasTranslation = 2,
  205. Matrix_HasScale = 4
  206. };
  207. Point3F p;
  208. U32 flags;
  209. TQuatF();
  210. TQuatF( bool ident );
  211. TQuatF( const EulerF & e, const Point3F & p );
  212. TQuatF( const AngAxisF & aa, const Point3F & p );
  213. TQuatF( const QuatF & q, const Point3F & p );
  214. TQuatF& set( const EulerF & euler, const Point3F & p );
  215. TQuatF& set( const AngAxisF & aa, const Point3F & p );
  216. TQuatF& set( const QuatF & quat, const Point3F & p );
  217. TQuatF& inverse( void );
  218. TQuatF& identity( void );
  219. Point3F& mulP(const Point3F& p, Point3F* r); // r = p * this
  220. };
  221. //---------------------------------------------------------------------------
  222. inline TQuatF::TQuatF()
  223. {
  224. // Beware: no initialization is done!
  225. }
  226. inline TQuatF::TQuatF( bool ident )
  227. {
  228. if( ident )
  229. identity();
  230. }
  231. inline TQuatF::TQuatF( const EulerF & euler, const Point3F & p )
  232. {
  233. set( euler, p );
  234. }
  235. inline TQuatF::TQuatF( const AngAxisF & aa, const Point3F & p )
  236. {
  237. set( aa, p );
  238. }
  239. inline TQuatF::TQuatF( const QuatF & quat, const Point3F & p )
  240. {
  241. set( quat, p );
  242. }
  243. inline TQuatF& TQuatF::set( const EulerF & e, const Point3F & t )
  244. {
  245. p = t;
  246. QuatF::set( e );
  247. flags |= Matrix_HasTranslation;
  248. return *this;
  249. }
  250. inline TQuatF& TQuatF::set( const AngAxisF & aa, const Point3F & t )
  251. {
  252. p = t;
  253. QuatF::set( aa );
  254. flags |= Matrix_HasTranslation;
  255. return *this;
  256. }
  257. inline TQuatF& TQuatF::set( const QuatF & q, const Point3F & t )
  258. {
  259. p = t;
  260. QuatF::set( q.x, q.y, q.z, q.w );
  261. flags |= Matrix_HasTranslation;
  262. return *this;
  263. }
  264. inline TQuatF& TQuatF::inverse( void )
  265. {
  266. QuatF::inverse();
  267. if( flags & Matrix_HasTranslation )
  268. {
  269. Point3F p2 = p;
  270. p2.neg();
  271. QuatF::mulP(p2,&p);
  272. }
  273. return *this;
  274. }
  275. inline TQuatF& TQuatF::identity( void )
  276. {
  277. QuatF::identity();
  278. p.set(0,0,0);
  279. flags &= ~U32(Matrix_HasTranslation);
  280. return *this;
  281. }
  282. #endif