mRotation.h

Engine/source/math/mRotation.h

More...

Classes:

class

Rotation Interop Utility class.

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef MROTATION_H
 25#define MROTATION_H
 26
 27#ifndef _MMATHFN_H_
 28#include "math/mMathFn.h"
 29#endif
 30
 31#ifndef _MPOINT3_H_
 32#include "math/mPoint3.h"
 33#endif
 34
 35#ifndef _MQUAT_H_
 36#include "math/mQuat.h"
 37#endif
 38
 39#ifndef _MMATRIX_H_
 40#include "math/mMatrix.h"
 41#endif
 42
 43#ifndef _MANGAXIS_H_
 44#include "math/mAngAxis.h"
 45#endif
 46
 47//------------------------------------------------------------------------------
 48/// Rotation Interop Utility class
 49///
 50/// Useful for easily handling rotations/orientations in transforms while manipulating or converting between formats.
 51class RotationF
 52{
 53   //-------------------------------------- Public data
 54public:
 55   F32 x;   ///< X co-ordinate.
 56   F32 y;   ///< Y co-ordinate.
 57   F32 z;   ///< Z co-ordinate.
 58   F32 w;   ///< W co-ordinate.
 59
 60   enum RotationTypes
 61   {
 62      Euler = 0,
 63      AxisAngle
 64   };
 65   RotationTypes mRotationType;
 66
 67   enum UnitFormat
 68   {
 69      Radians = 0,
 70      Degrees
 71   };
 72
 73   RotationF();               ///< Create an uninitialized point.
 74   RotationF(const RotationF&); ///< Copy constructor.
 75
 76   //
 77   //Eulers
 78   RotationF(EulerF euler, UnitFormat format = Radians);
 79   RotationF(F32 _x, F32 _y, F32 _z, UnitFormat format = Radians);
 80
 81   void set(EulerF euler, UnitFormat format = Radians);
 82   void set(F32 _x, F32 _y, F32 _z, UnitFormat format = Radians);
 83
 84   //As with AxisAngles, we make the assumption here that if not told otherwise, inbound rotations are in Degrees.
 85   RotationF operator=(const EulerF&);
 86   RotationF operator-(const EulerF&) const;
 87   RotationF operator+(const EulerF&) const;
 88   RotationF& operator-=(const EulerF&);
 89   RotationF& operator+=(const EulerF&);
 90   S32 operator==(const EulerF&) const;
 91   S32 operator!=(const EulerF&) const;
 92
 93   //
 94   //AxisAngle
 95   RotationF(AngAxisF aa, UnitFormat format = Radians);
 96   void set(AngAxisF aa, UnitFormat format = Radians);
 97
 98   //As with Eulers, we make the assumption here that if not told otherwise, inbound rotations are in Degrees.
 99   RotationF operator=(const AngAxisF&);
100   RotationF operator-(const AngAxisF&) const;
101   RotationF operator+(const AngAxisF&) const;
102   RotationF& operator-=(const AngAxisF&);
103   RotationF& operator+=(const AngAxisF&);
104   S32 operator==(const AngAxisF&) const;
105   S32 operator!=(const AngAxisF&) const;
106
107   //
108   //Quat
109   RotationF(QuatF quat);
110   void set(QuatF _quat);
111
112   RotationF operator=(const QuatF&);
113   RotationF operator-(const QuatF&) const;
114   RotationF operator+(const QuatF&) const;
115   RotationF& operator-=(const QuatF&);
116   RotationF& operator+=(const QuatF&);
117   S32 operator==(const QuatF&) const;
118   S32 operator!=(const QuatF&) const;
119
120   //
121   //Matrix
122   RotationF(MatrixF mat);
123   void set(MatrixF _mat);
124
125   RotationF operator=(const MatrixF&);
126   RotationF operator-(const MatrixF&) const;
127   RotationF operator+(const MatrixF&) const;
128   RotationF& operator-=(const MatrixF&);
129   RotationF& operator+=(const MatrixF&);
130   S32 operator==(const MatrixF&) const;
131   S32 operator!=(const MatrixF&) const;
132
133   //
134   void interpolate(const RotationF& _pt1, const RotationF& _pt2, F32 _factor);
135   void lookAt(const Point3F& _origin, const Point3F& _target, const Point3F& _up = Point3F(0, 0, 1));
136   VectorF getDirection();
137
138   F32 len() const;
139
140   void normalize();
141
142   //Non-converting operators
143   S32 operator==(const RotationF &) const;
144   S32 operator!=(const RotationF &) const;
145
146   RotationF  operator+(const RotationF&) const;
147   RotationF& operator+=(const RotationF&);
148   RotationF  operator-(const RotationF&) const;
149   RotationF&  operator-=(const RotationF&);
150
151   RotationF& operator=(const RotationF&);
152
153   //Conversion stuffs
154   EulerF asEulerF(UnitFormat format = Radians) const;
155   AngAxisF asAxisAngle(UnitFormat format = Radians) const;
156   MatrixF asMatrixF() const;
157   QuatF asQuatF() const;
158};
159
160inline RotationF::RotationF()
161{
162   x = 0;
163   y = 0;
164   z = 0;
165   w = 0;
166
167   mRotationType = AxisAngle;
168}
169
170inline RotationF::RotationF(const RotationF& _copy)
171   : x(_copy.x), y(_copy.y), z(_copy.z), w(_copy.w), mRotationType(_copy.mRotationType)
172{}
173
174inline int RotationF::operator==(const RotationF& _rotation) const
175{
176   return (x == _rotation.x && y == _rotation.y && z == _rotation.z && w == _rotation.w);
177}
178
179inline int RotationF::operator!=(const RotationF& _rotation) const
180{
181   return (x != _rotation.x || y != _rotation.y || z != _rotation.z || w != _rotation.w);
182}
183
184//When it comes to actually trying to add rotations, we, in fact, actually multiply their data together.
185//Since we're specifically operating on usability for RotationF, we'll operate on this, rather than the literal addition of the values
186inline RotationF& RotationF::operator+=(const RotationF& _rotation)
187{
188   if (mRotationType == Euler)
189   {
190      x += _rotation.x;
191      y += _rotation.y;
192      z += _rotation.z;
193   }
194   else
195   {
196      MatrixF tempMat = asMatrixF();
197      MatrixF tempMatAdd = _rotation.asMatrixF();
198
199      tempMat.mul(tempMatAdd);
200
201      this->set(tempMat);
202   }
203
204   return *this;
205}
206
207inline RotationF RotationF::operator+(const RotationF& _rotation) const
208{
209   RotationF result = *this;
210
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
222      tempMat.mul(tempMatAdd);
223
224      result.set(tempMat);
225   }
226
227   return result;
228}
229
230//Much like addition, when subtracting, we're not literally subtracting the values, but infact multiplying the inverse.
231//This subtracts the rotation angles to get the difference
232inline RotationF& RotationF::operator-=(const RotationF& _rotation)
233{
234   if (mRotationType == Euler)
235   {
236      x -= _rotation.x;
237      y -= _rotation.y;
238      z -= _rotation.z;
239   }
240   else
241   {
242      MatrixF tempMat = asMatrixF();
243      MatrixF tempMatAdd = _rotation.asMatrixF();
244
245      tempMatAdd.inverse();
246
247      tempMat.mul(tempMatAdd);
248
249      this->set(tempMat);
250   }
251
252   return *this;
253}
254
255inline RotationF RotationF::operator-(const RotationF& _rotation) const
256{
257   RotationF result = *this;
258
259   if (mRotationType == Euler)
260   {
261      result.x += _rotation.x;
262      result.y += _rotation.y;
263      result.z += _rotation.z;
264   }
265   else
266   {
267      MatrixF tempMat = asMatrixF();
268      MatrixF tempMatAdd = _rotation.asMatrixF();
269      tempMatAdd.inverse();
270
271      tempMat.mul(tempMatAdd);
272
273      result.set(tempMat);
274   }
275
276   return result;
277}
278
279inline RotationF& RotationF::operator=(const RotationF& _rotation)
280{
281   x = _rotation.x;
282   y = _rotation.y;
283   z = _rotation.z;
284   w = _rotation.w;
285
286   mRotationType = _rotation.mRotationType;
287
288   return *this;
289}
290
291//====================================================================
292// Euler operators
293//====================================================================
294inline RotationF RotationF::operator=(const EulerF& _euler)
295{
296   return RotationF(_euler, Radians);
297}
298
299inline RotationF RotationF::operator-(const EulerF& _euler) const
300{
301   RotationF temp = *this;
302   temp -= RotationF(_euler, Radians);
303   return temp;
304}
305
306inline RotationF RotationF::operator+(const EulerF& _euler) const
307{
308   RotationF temp = *this;
309   temp += RotationF(_euler, Radians);
310   return temp;
311}
312
313inline RotationF& RotationF::operator-=(const EulerF& _euler)
314{
315   *this -= RotationF(_euler, Radians);
316   return *this;
317}
318
319inline RotationF& RotationF::operator+=(const EulerF& _euler)
320{
321   *this += RotationF(_euler, Radians);
322   return *this;
323}
324
325inline S32 RotationF::operator==(const EulerF& _euler) const
326{
327   return *this == RotationF(_euler);
328}
329
330inline S32 RotationF::operator!=(const EulerF& _euler) const
331{
332   return *this != RotationF(_euler);
333}
334
335//====================================================================
336// AxisAngle operators
337//====================================================================
338inline RotationF RotationF::operator=(const AngAxisF& _aa)
339{
340   return RotationF(_aa, Radians);
341}
342
343inline RotationF RotationF::operator-(const AngAxisF& _aa) const
344{
345   RotationF temp = *this;
346   temp -= RotationF(_aa, Radians);
347   return temp;
348}
349
350inline RotationF RotationF::operator+(const AngAxisF& _aa) const
351{
352   RotationF temp = *this;
353   temp += RotationF(_aa, Radians);
354   return temp;
355}
356
357inline RotationF& RotationF::operator-=(const AngAxisF& _aa)
358{
359   *this -= RotationF(_aa, Radians);
360   return *this;
361}
362
363inline RotationF& RotationF::operator+=(const AngAxisF& _aa)
364{
365   *this += RotationF(_aa, Radians);
366   return *this;
367}
368
369inline S32 RotationF::operator==(const AngAxisF& _aa) const
370{
371   return *this == RotationF(_aa);
372}
373
374inline S32 RotationF::operator!=(const AngAxisF& _aa) const
375{
376   return *this != RotationF(_aa);
377}
378
379//====================================================================
380// QuatF operators
381//====================================================================
382inline RotationF RotationF::operator=(const QuatF& _quat)
383{
384   return RotationF(_quat);
385}
386
387inline RotationF RotationF::operator-(const QuatF& _quat) const
388{
389   RotationF temp = *this;
390   temp -= RotationF(_quat);
391   return temp;
392}
393
394inline RotationF RotationF::operator+(const QuatF& _quat) const
395{
396   RotationF temp = *this;
397   temp += RotationF(_quat);
398   return temp;
399}
400
401inline RotationF& RotationF::operator-=(const QuatF& _quat)
402{
403   *this -= RotationF(_quat);
404   return *this;
405}
406
407inline RotationF& RotationF::operator+=(const QuatF& _quat)
408{
409   *this += RotationF(_quat);
410   return *this;
411}
412
413inline S32 RotationF::operator==(const QuatF& _quat) const
414{
415   return *this == RotationF(_quat);
416}
417
418inline S32 RotationF::operator!=(const QuatF& _quat) const
419{
420   return *this != RotationF(_quat);
421}
422
423//====================================================================
424// MatrixF operators
425//====================================================================
426inline RotationF RotationF::operator=(const MatrixF& _mat)
427{
428   return RotationF(_mat);
429}
430
431inline RotationF RotationF::operator-(const MatrixF& _mat) const
432{
433   RotationF temp = *this;
434   temp -= RotationF(_mat);
435   return temp;
436}
437
438inline RotationF RotationF::operator+(const MatrixF& _mat) const
439{
440   RotationF temp = *this;
441   temp += RotationF(_mat);
442   return temp;
443}
444
445inline RotationF& RotationF::operator-=(const MatrixF& _mat)
446{
447   *this -= RotationF(_mat);
448   return *this;
449}
450
451inline RotationF& RotationF::operator+=(const MatrixF& _mat)
452{
453   *this += RotationF(_mat);
454   return *this;
455}
456
457inline S32 RotationF::operator==(const MatrixF& _mat) const
458{
459   return *this == RotationF(_mat);
460}
461
462inline S32 RotationF::operator!=(const MatrixF& _mat) const
463{
464   return *this != RotationF(_mat);
465}
466
467#endif // MROTATION_H
468