mRotation.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  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. VectorF getDirection();
  116. F32 len() const;
  117. void normalize();
  118. //Non-converting operators
  119. S32 operator ==(const RotationF &) const;
  120. S32 operator !=(const RotationF &) const;
  121. RotationF operator+(const RotationF&) const;
  122. RotationF& operator+=(const RotationF&);
  123. RotationF operator-(const RotationF&) const;
  124. RotationF& operator-=(const RotationF&);
  125. RotationF& operator=(const RotationF&);
  126. //Conversion stuffs
  127. EulerF asEulerF(UnitFormat format = Radians) const;
  128. AngAxisF asAxisAngle(UnitFormat format = Radians) const;
  129. MatrixF asMatrixF() const;
  130. QuatF asQuatF() const;
  131. };
  132. inline RotationF::RotationF()
  133. {
  134. x = 0;
  135. y = 0;
  136. z = 0;
  137. w = 0;
  138. mRotationType = AxisAngle;
  139. }
  140. inline RotationF::RotationF(const RotationF& _copy)
  141. : x(_copy.x), y(_copy.y), z(_copy.z), w(_copy.w), mRotationType(_copy.mRotationType)
  142. {}
  143. inline int RotationF::operator ==(const RotationF& _rotation) const
  144. {
  145. return (x == _rotation.x && y == _rotation.y && z == _rotation.z && w == _rotation.w);
  146. }
  147. inline int RotationF::operator !=(const RotationF& _rotation) const
  148. {
  149. return (x != _rotation.x || y != _rotation.y || z != _rotation.z || w != _rotation.w);
  150. }
  151. //When it comes to actually trying to add rotations, we, in fact, actually multiply their data together.
  152. //Since we're specifically operating on usability for RotationF, we'll operate on this, rather than the literal addition of the values
  153. inline RotationF& RotationF::operator +=(const RotationF& _rotation)
  154. {
  155. if (mRotationType == Euler)
  156. {
  157. x += _rotation.x;
  158. y += _rotation.y;
  159. z += _rotation.z;
  160. }
  161. else
  162. {
  163. MatrixF tempMat = asMatrixF();
  164. MatrixF tempMatAdd = _rotation.asMatrixF();
  165. tempMat.mul(tempMatAdd);
  166. this->set(tempMat);
  167. }
  168. return *this;
  169. }
  170. inline RotationF RotationF::operator +(const RotationF& _rotation) const
  171. {
  172. RotationF result = *this;
  173. if (mRotationType == Euler)
  174. {
  175. result.x += _rotation.x;
  176. result.y += _rotation.y;
  177. result.z += _rotation.z;
  178. }
  179. else
  180. {
  181. MatrixF tempMat = asMatrixF();
  182. MatrixF tempMatAdd = _rotation.asMatrixF();
  183. tempMat.mul(tempMatAdd);
  184. result.set(tempMat);
  185. }
  186. return result;
  187. }
  188. //Much like addition, when subtracting, we're not literally subtracting the values, but infact multiplying the inverse.
  189. //This subtracts the rotation angles to get the difference
  190. inline RotationF& RotationF::operator -=(const RotationF& _rotation)
  191. {
  192. if (mRotationType == Euler)
  193. {
  194. x -= _rotation.x;
  195. y -= _rotation.y;
  196. z -= _rotation.z;
  197. }
  198. else
  199. {
  200. MatrixF tempMat = asMatrixF();
  201. MatrixF tempMatAdd = _rotation.asMatrixF();
  202. tempMatAdd.inverse();
  203. tempMat.mul(tempMatAdd);
  204. this->set(tempMat);
  205. }
  206. return *this;
  207. }
  208. inline RotationF RotationF::operator -(const RotationF& _rotation) const
  209. {
  210. RotationF result = *this;
  211. if (mRotationType == Euler)
  212. {
  213. result.x += _rotation.x;
  214. result.y += _rotation.y;
  215. result.z += _rotation.z;
  216. }
  217. else
  218. {
  219. MatrixF tempMat = asMatrixF();
  220. MatrixF tempMatAdd = _rotation.asMatrixF();
  221. tempMatAdd.inverse();
  222. tempMat.mul(tempMatAdd);
  223. result.set(tempMat);
  224. }
  225. return result;
  226. }
  227. inline RotationF& RotationF::operator =(const RotationF& _rotation)
  228. {
  229. x = _rotation.x;
  230. y = _rotation.y;
  231. z = _rotation.z;
  232. w = _rotation.w;
  233. mRotationType = _rotation.mRotationType;
  234. return *this;
  235. }
  236. //====================================================================
  237. // Euler operators
  238. //====================================================================
  239. inline RotationF RotationF::operator=(const EulerF& _euler)
  240. {
  241. return RotationF(_euler, Radians);
  242. }
  243. inline RotationF RotationF::operator-(const EulerF& _euler) const
  244. {
  245. RotationF temp = *this;
  246. temp -= RotationF(_euler, Radians);
  247. return temp;
  248. }
  249. inline RotationF RotationF::operator+(const EulerF& _euler) const
  250. {
  251. RotationF temp = *this;
  252. temp += RotationF(_euler, Radians);
  253. return temp;
  254. }
  255. inline RotationF& RotationF::operator-=(const EulerF& _euler)
  256. {
  257. *this -= RotationF(_euler, Radians);
  258. return *this;
  259. }
  260. inline RotationF& RotationF::operator+=(const EulerF& _euler)
  261. {
  262. *this += RotationF(_euler, Radians);
  263. return *this;
  264. }
  265. inline S32 RotationF::operator==(const EulerF& _euler) const
  266. {
  267. return *this == RotationF(_euler);
  268. }
  269. inline S32 RotationF::operator!=(const EulerF& _euler) const
  270. {
  271. return *this != RotationF(_euler);
  272. }
  273. //====================================================================
  274. // AxisAngle operators
  275. //====================================================================
  276. inline RotationF RotationF::operator=(const AngAxisF& _aa)
  277. {
  278. return RotationF(_aa, Radians);
  279. }
  280. inline RotationF RotationF::operator-(const AngAxisF& _aa) const
  281. {
  282. RotationF temp = *this;
  283. temp -= RotationF(_aa, Radians);
  284. return temp;
  285. }
  286. inline RotationF RotationF::operator+(const AngAxisF& _aa) const
  287. {
  288. RotationF temp = *this;
  289. temp += RotationF(_aa, Radians);
  290. return temp;
  291. }
  292. inline RotationF& RotationF::operator-=(const AngAxisF& _aa)
  293. {
  294. *this -= RotationF(_aa, Radians);
  295. return *this;
  296. }
  297. inline RotationF& RotationF::operator+=(const AngAxisF& _aa)
  298. {
  299. *this += RotationF(_aa, Radians);
  300. return *this;
  301. }
  302. inline S32 RotationF::operator==(const AngAxisF& _aa) const
  303. {
  304. return *this == RotationF(_aa);
  305. }
  306. inline S32 RotationF::operator!=(const AngAxisF& _aa) const
  307. {
  308. return *this != RotationF(_aa);
  309. }
  310. //====================================================================
  311. // QuatF operators
  312. //====================================================================
  313. inline RotationF RotationF::operator=(const QuatF& _quat)
  314. {
  315. return RotationF(_quat);
  316. }
  317. inline RotationF RotationF::operator-(const QuatF& _quat) const
  318. {
  319. RotationF temp = *this;
  320. temp -= RotationF(_quat);
  321. return temp;
  322. }
  323. inline RotationF RotationF::operator+(const QuatF& _quat) const
  324. {
  325. RotationF temp = *this;
  326. temp += RotationF(_quat);
  327. return temp;
  328. }
  329. inline RotationF& RotationF::operator-=(const QuatF& _quat)
  330. {
  331. *this -= RotationF(_quat);
  332. return *this;
  333. }
  334. inline RotationF& RotationF::operator+=(const QuatF& _quat)
  335. {
  336. *this += RotationF(_quat);
  337. return *this;
  338. }
  339. inline S32 RotationF::operator==(const QuatF& _quat) const
  340. {
  341. return *this == RotationF(_quat);
  342. }
  343. inline S32 RotationF::operator!=(const QuatF& _quat) const
  344. {
  345. return *this != RotationF(_quat);
  346. }
  347. //====================================================================
  348. // MatrixF operators
  349. //====================================================================
  350. inline RotationF RotationF::operator=(const MatrixF& _mat)
  351. {
  352. return RotationF(_mat);
  353. }
  354. inline RotationF RotationF::operator-(const MatrixF& _mat) const
  355. {
  356. RotationF temp = *this;
  357. temp -= RotationF(_mat);
  358. return temp;
  359. }
  360. inline RotationF RotationF::operator+(const MatrixF& _mat) const
  361. {
  362. RotationF temp = *this;
  363. temp += RotationF(_mat);
  364. return temp;
  365. }
  366. inline RotationF& RotationF::operator-=(const MatrixF& _mat)
  367. {
  368. *this -= RotationF(_mat);
  369. return *this;
  370. }
  371. inline RotationF& RotationF::operator+=(const MatrixF& _mat)
  372. {
  373. *this += RotationF(_mat);
  374. return *this;
  375. }
  376. inline S32 RotationF::operator==(const MatrixF& _mat) const
  377. {
  378. return *this == RotationF(_mat);
  379. }
  380. inline S32 RotationF::operator!=(const MatrixF& _mat) const
  381. {
  382. return *this != RotationF(_mat);
  383. }
  384. #endif // MROTATION_H