mRotation.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 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 MROTATION_H
  23. #define MROTATION_H
  24. #ifndef _MMATHFN_H_
  25. #include "math/mMathFn.h"
  26. #endif
  27. #ifndef _MPOINT3_H_
  28. #include "math/mPoint3.h"
  29. #endif
  30. #ifndef _MQUAT_H_
  31. #include "math/mQuat.h"
  32. #endif
  33. #ifndef _MMATRIX_H_
  34. #include "math/mMatrix.h"
  35. #endif
  36. #ifndef _MANGAXIS_H_
  37. #include "math/mAngAxis.h"
  38. #endif
  39. //------------------------------------------------------------------------------
  40. /// Rotation Interop Utility class
  41. ///
  42. /// Useful for easily handling rotations/orientations in transforms while manipulating or converting between formats.
  43. class RotationF
  44. {
  45. //-------------------------------------- Public data
  46. public:
  47. F32 x; ///< X co-ordinate.
  48. F32 y; ///< Y co-ordinate.
  49. F32 z; ///< Z co-ordinate.
  50. F32 w; ///< W co-ordinate.
  51. enum RotationTypes
  52. {
  53. Euler = 0,
  54. AxisAngle
  55. };
  56. RotationTypes mRotationType;
  57. enum UnitFormat
  58. {
  59. Radians = 0,
  60. Degrees
  61. };
  62. RotationF(); ///< Create an uninitialized point.
  63. RotationF(const RotationF&); ///< Copy constructor.
  64. //
  65. //Eulers
  66. RotationF(EulerF euler, UnitFormat format = Radians);
  67. RotationF(F32 _x, F32 _y, F32 _z, UnitFormat format = Radians);
  68. void set(EulerF euler, UnitFormat format = Radians);
  69. void set(F32 _x, F32 _y, F32 _z, UnitFormat format = Radians);
  70. //As with AxisAngles, we make the assumption here that if not told otherwise, inbound rotations are in Degrees.
  71. RotationF operator=(const EulerF&);
  72. RotationF operator-(const EulerF&) const;
  73. RotationF operator+(const EulerF&) const;
  74. RotationF& operator-=(const EulerF&);
  75. RotationF& operator+=(const EulerF&);
  76. S32 operator==(const EulerF&) const;
  77. S32 operator!=(const EulerF&) const;
  78. //
  79. //AxisAngle
  80. RotationF(AngAxisF aa, UnitFormat format = Radians);
  81. void set(AngAxisF aa, UnitFormat format = Radians);
  82. //As with Eulers, we make the assumption here that if not told otherwise, inbound rotations are in Degrees.
  83. RotationF operator=(const AngAxisF&);
  84. RotationF operator-(const AngAxisF&) const;
  85. RotationF operator+(const AngAxisF&) const;
  86. RotationF& operator-=(const AngAxisF&);
  87. RotationF& operator+=(const AngAxisF&);
  88. S32 operator==(const AngAxisF&) const;
  89. S32 operator!=(const AngAxisF&) const;
  90. //
  91. //Quat
  92. RotationF(QuatF quat);
  93. void set(QuatF _quat);
  94. RotationF operator=(const QuatF&);
  95. RotationF operator-(const QuatF&) const;
  96. RotationF operator+(const QuatF&) const;
  97. RotationF& operator-=(const QuatF&);
  98. RotationF& operator+=(const QuatF&);
  99. S32 operator==(const QuatF&) const;
  100. S32 operator!=(const QuatF&) const;
  101. //
  102. //Matrix
  103. RotationF(MatrixF mat);
  104. void set(MatrixF _mat);
  105. RotationF operator=(const MatrixF&);
  106. RotationF operator-(const MatrixF&) const;
  107. RotationF operator+(const MatrixF&) const;
  108. RotationF& operator-=(const MatrixF&);
  109. RotationF& operator+=(const MatrixF&);
  110. S32 operator==(const MatrixF&) const;
  111. S32 operator!=(const MatrixF&) const;
  112. //
  113. void interpolate(const RotationF& _pt1, const RotationF& _pt2, F32 _factor);
  114. void lookAt(const Point3F& _origin, const Point3F& _target, const Point3F& _up = Point3F(0, 0, 1));
  115. F32 len() const;
  116. void normalize();
  117. //Non-converting operators
  118. S32 operator ==(const RotationF &) const;
  119. S32 operator !=(const RotationF &) const;
  120. RotationF operator+(const RotationF&) const;
  121. RotationF& operator+=(const RotationF&);
  122. RotationF operator-(const RotationF&) const;
  123. RotationF& operator-=(const RotationF&);
  124. RotationF& operator=(const RotationF&);
  125. //Conversion stuffs
  126. EulerF asEulerF(UnitFormat format = Radians) const;
  127. AngAxisF asAxisAngle(UnitFormat format = Radians) const;
  128. MatrixF asMatrixF() const;
  129. QuatF asQuatF() const;
  130. };
  131. inline RotationF::RotationF()
  132. {
  133. x = 0;
  134. y = 0;
  135. z = 0;
  136. w = 0;
  137. mRotationType = AxisAngle;
  138. }
  139. inline RotationF::RotationF(const RotationF& _copy)
  140. : x(_copy.x), y(_copy.y), z(_copy.z), w(_copy.w), mRotationType(_copy.mRotationType)
  141. {}
  142. inline int RotationF::operator ==(const RotationF& _rotation) const
  143. {
  144. return (x == _rotation.x && y == _rotation.y && z == _rotation.z && w == _rotation.w);
  145. }
  146. inline int RotationF::operator !=(const RotationF& _rotation) const
  147. {
  148. return (x != _rotation.x || y != _rotation.y || z != _rotation.z || w != _rotation.w);
  149. }
  150. //When it comes to actually trying to add rotations, we, in fact, actually multiply their data together.
  151. //Since we're specifically operating on usability for RotationF, we'll operate on this, rather than the literal addition of the values
  152. inline RotationF& RotationF::operator +=(const RotationF& _rotation)
  153. {
  154. if (mRotationType == Euler)
  155. {
  156. x += _rotation.x;
  157. y += _rotation.y;
  158. z += _rotation.z;
  159. }
  160. else
  161. {
  162. MatrixF tempMat = asMatrixF();
  163. MatrixF tempMatAdd = _rotation.asMatrixF();
  164. tempMat.mul(tempMatAdd);
  165. this->set(tempMat);
  166. }
  167. return *this;
  168. }
  169. inline RotationF RotationF::operator +(const RotationF& _rotation) const
  170. {
  171. RotationF result = *this;
  172. if (mRotationType == Euler)
  173. {
  174. result.x += _rotation.x;
  175. result.y += _rotation.y;
  176. result.z += _rotation.z;
  177. }
  178. else
  179. {
  180. MatrixF tempMat = asMatrixF();
  181. MatrixF tempMatAdd = _rotation.asMatrixF();
  182. tempMat.mul(tempMatAdd);
  183. result.set(tempMat);
  184. }
  185. return result;
  186. }
  187. //Much like addition, when subtracting, we're not literally subtracting the values, but infact multiplying the inverse.
  188. //This subtracts the rotation angles to get the difference
  189. inline RotationF& RotationF::operator -=(const RotationF& _rotation)
  190. {
  191. if (mRotationType == Euler)
  192. {
  193. x -= _rotation.x;
  194. y -= _rotation.y;
  195. z -= _rotation.z;
  196. }
  197. else
  198. {
  199. MatrixF tempMat = asMatrixF();
  200. MatrixF tempMatAdd = _rotation.asMatrixF();
  201. tempMatAdd.inverse();
  202. tempMat.mul(tempMatAdd);
  203. this->set(tempMat);
  204. }
  205. return *this;
  206. }
  207. inline RotationF RotationF::operator -(const RotationF& _rotation) const
  208. {
  209. RotationF result = *this;
  210. if (mRotationType == Euler)
  211. {
  212. result.x += _rotation.x;
  213. result.y += _rotation.y;
  214. result.z += _rotation.z;
  215. }
  216. else
  217. {
  218. MatrixF tempMat = asMatrixF();
  219. MatrixF tempMatAdd = _rotation.asMatrixF();
  220. tempMatAdd.inverse();
  221. tempMat.mul(tempMatAdd);
  222. result.set(tempMat);
  223. }
  224. return result;
  225. }
  226. inline RotationF& RotationF::operator =(const RotationF& _rotation)
  227. {
  228. x = _rotation.x;
  229. y = _rotation.y;
  230. z = _rotation.z;
  231. w = _rotation.w;
  232. mRotationType = _rotation.mRotationType;
  233. return *this;
  234. }
  235. //====================================================================
  236. // Euler operators
  237. //====================================================================
  238. inline RotationF RotationF::operator=(const EulerF& _euler)
  239. {
  240. return RotationF(_euler, Radians);
  241. }
  242. inline RotationF RotationF::operator-(const EulerF& _euler) const
  243. {
  244. RotationF temp = *this;
  245. temp -= RotationF(_euler, Radians);
  246. return temp;
  247. }
  248. inline RotationF RotationF::operator+(const EulerF& _euler) const
  249. {
  250. RotationF temp = *this;
  251. temp += RotationF(_euler, Radians);
  252. return temp;
  253. }
  254. inline RotationF& RotationF::operator-=(const EulerF& _euler)
  255. {
  256. *this -= RotationF(_euler, Radians);
  257. return *this;
  258. }
  259. inline RotationF& RotationF::operator+=(const EulerF& _euler)
  260. {
  261. *this += RotationF(_euler, Radians);
  262. return *this;
  263. }
  264. inline S32 RotationF::operator==(const EulerF& _euler) const
  265. {
  266. return *this == RotationF(_euler);
  267. }
  268. inline S32 RotationF::operator!=(const EulerF& _euler) const
  269. {
  270. return *this != RotationF(_euler);
  271. }
  272. //====================================================================
  273. // AxisAngle operators
  274. //====================================================================
  275. inline RotationF RotationF::operator=(const AngAxisF& _aa)
  276. {
  277. return RotationF(_aa, Radians);
  278. }
  279. inline RotationF RotationF::operator-(const AngAxisF& _aa) const
  280. {
  281. RotationF temp = *this;
  282. temp -= RotationF(_aa, Radians);
  283. return temp;
  284. }
  285. inline RotationF RotationF::operator+(const AngAxisF& _aa) const
  286. {
  287. RotationF temp = *this;
  288. temp += RotationF(_aa, Radians);
  289. return temp;
  290. }
  291. inline RotationF& RotationF::operator-=(const AngAxisF& _aa)
  292. {
  293. *this -= RotationF(_aa, Radians);
  294. return *this;
  295. }
  296. inline RotationF& RotationF::operator+=(const AngAxisF& _aa)
  297. {
  298. *this += RotationF(_aa, Radians);
  299. return *this;
  300. }
  301. inline S32 RotationF::operator==(const AngAxisF& _aa) const
  302. {
  303. return *this == RotationF(_aa);
  304. }
  305. inline S32 RotationF::operator!=(const AngAxisF& _aa) const
  306. {
  307. return *this != RotationF(_aa);
  308. }
  309. //====================================================================
  310. // QuatF operators
  311. //====================================================================
  312. inline RotationF RotationF::operator=(const QuatF& _quat)
  313. {
  314. return RotationF(_quat);
  315. }
  316. inline RotationF RotationF::operator-(const QuatF& _quat) const
  317. {
  318. RotationF temp = *this;
  319. temp -= RotationF(_quat);
  320. return temp;
  321. }
  322. inline RotationF RotationF::operator+(const QuatF& _quat) const
  323. {
  324. RotationF temp = *this;
  325. temp += RotationF(_quat);
  326. return temp;
  327. }
  328. inline RotationF& RotationF::operator-=(const QuatF& _quat)
  329. {
  330. *this -= RotationF(_quat);
  331. return *this;
  332. }
  333. inline RotationF& RotationF::operator+=(const QuatF& _quat)
  334. {
  335. *this += RotationF(_quat);
  336. return *this;
  337. }
  338. inline S32 RotationF::operator==(const QuatF& _quat) const
  339. {
  340. return *this == RotationF(_quat);
  341. }
  342. inline S32 RotationF::operator!=(const QuatF& _quat) const
  343. {
  344. return *this != RotationF(_quat);
  345. }
  346. //====================================================================
  347. // MatrixF operators
  348. //====================================================================
  349. inline RotationF RotationF::operator=(const MatrixF& _mat)
  350. {
  351. return RotationF(_mat);
  352. }
  353. inline RotationF RotationF::operator-(const MatrixF& _mat) const
  354. {
  355. RotationF temp = *this;
  356. temp -= RotationF(_mat);
  357. return temp;
  358. }
  359. inline RotationF RotationF::operator+(const MatrixF& _mat) const
  360. {
  361. RotationF temp = *this;
  362. temp += RotationF(_mat);
  363. return temp;
  364. }
  365. inline RotationF& RotationF::operator-=(const MatrixF& _mat)
  366. {
  367. *this -= RotationF(_mat);
  368. return *this;
  369. }
  370. inline RotationF& RotationF::operator+=(const MatrixF& _mat)
  371. {
  372. *this += RotationF(_mat);
  373. return *this;
  374. }
  375. inline S32 RotationF::operator==(const MatrixF& _mat) const
  376. {
  377. return *this == RotationF(_mat);
  378. }
  379. inline S32 RotationF::operator!=(const MatrixF& _mat) const
  380. {
  381. return *this != RotationF(_mat);
  382. }
  383. #endif // MROTATION_H