123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #ifndef MROTATION_H
- #define MROTATION_H
- #ifndef _MMATHFN_H_
- #include "math/mMathFn.h"
- #endif
- #ifndef _MPOINT3_H_
- #include "math/mPoint3.h"
- #endif
- #ifndef _MQUAT_H_
- #include "math/mQuat.h"
- #endif
- #ifndef _MMATRIX_H_
- #include "math/mMatrix.h"
- #endif
- #ifndef _MANGAXIS_H_
- #include "math/mAngAxis.h"
- #endif
- //------------------------------------------------------------------------------
- /// Rotation Interop Utility class
- ///
- /// Useful for easily handling rotations/orientations in transforms while manipulating or converting between formats.
- class RotationF
- {
- //-------------------------------------- Public data
- public:
- F32 x; ///< X co-ordinate.
- F32 y; ///< Y co-ordinate.
- F32 z; ///< Z co-ordinate.
- F32 w; ///< W co-ordinate.
- enum RotationTypes
- {
- Euler = 0,
- AxisAngle
- };
- RotationTypes mRotationType;
- enum UnitFormat
- {
- Radians = 0,
- Degrees
- };
- RotationF(); ///< Create an uninitialized point.
- RotationF(const RotationF&); ///< Copy constructor.
- //
- //Eulers
- RotationF(EulerF euler, UnitFormat format = Radians);
- RotationF(F32 _x, F32 _y, F32 _z, UnitFormat format = Radians);
- void set(EulerF euler, UnitFormat format = Radians);
- void set(F32 _x, F32 _y, F32 _z, UnitFormat format = Radians);
- //As with AxisAngles, we make the assumption here that if not told otherwise, inbound rotations are in Degrees.
- RotationF operator=(const EulerF&);
- RotationF operator-(const EulerF&) const;
- RotationF operator+(const EulerF&) const;
- RotationF& operator-=(const EulerF&);
- RotationF& operator+=(const EulerF&);
- S32 operator==(const EulerF&) const;
- S32 operator!=(const EulerF&) const;
- //
- //AxisAngle
- RotationF(AngAxisF aa, UnitFormat format = Radians);
- void set(AngAxisF aa, UnitFormat format = Radians);
- //As with Eulers, we make the assumption here that if not told otherwise, inbound rotations are in Degrees.
- RotationF operator=(const AngAxisF&);
- RotationF operator-(const AngAxisF&) const;
- RotationF operator+(const AngAxisF&) const;
- RotationF& operator-=(const AngAxisF&);
- RotationF& operator+=(const AngAxisF&);
- S32 operator==(const AngAxisF&) const;
- S32 operator!=(const AngAxisF&) const;
- //
- //Quat
- RotationF(QuatF quat);
- void set(QuatF _quat);
- RotationF operator=(const QuatF&);
- RotationF operator-(const QuatF&) const;
- RotationF operator+(const QuatF&) const;
- RotationF& operator-=(const QuatF&);
- RotationF& operator+=(const QuatF&);
- S32 operator==(const QuatF&) const;
- S32 operator!=(const QuatF&) const;
- //
- //Matrix
- RotationF(MatrixF mat);
- void set(MatrixF _mat);
- RotationF operator=(const MatrixF&);
- RotationF operator-(const MatrixF&) const;
- RotationF operator+(const MatrixF&) const;
- RotationF& operator-=(const MatrixF&);
- RotationF& operator+=(const MatrixF&);
- S32 operator==(const MatrixF&) const;
- S32 operator!=(const MatrixF&) const;
- //
- void interpolate(const RotationF& _pt1, const RotationF& _pt2, F32 _factor);
- void lookAt(const Point3F& _origin, const Point3F& _target, const Point3F& _up = Point3F(0, 0, 1));
- VectorF getDirection();
- F32 len() const;
- void normalize();
- //Non-converting operators
- S32 operator ==(const RotationF &) const;
- S32 operator !=(const RotationF &) const;
- RotationF operator+(const RotationF&) const;
- RotationF& operator+=(const RotationF&);
- RotationF operator-(const RotationF&) const;
- RotationF& operator-=(const RotationF&);
- RotationF& operator=(const RotationF&);
- //Conversion stuffs
- EulerF asEulerF(UnitFormat format = Radians) const;
- AngAxisF asAxisAngle(UnitFormat format = Radians) const;
- MatrixF asMatrixF() const;
- QuatF asQuatF() const;
- };
- inline RotationF::RotationF()
- {
- x = 0;
- y = 0;
- z = 0;
- w = 0;
- mRotationType = AxisAngle;
- }
- inline RotationF::RotationF(const RotationF& _copy)
- : x(_copy.x), y(_copy.y), z(_copy.z), w(_copy.w), mRotationType(_copy.mRotationType)
- {}
- inline int RotationF::operator ==(const RotationF& _rotation) const
- {
- return (x == _rotation.x && y == _rotation.y && z == _rotation.z && w == _rotation.w);
- }
- inline int RotationF::operator !=(const RotationF& _rotation) const
- {
- return (x != _rotation.x || y != _rotation.y || z != _rotation.z || w != _rotation.w);
- }
- //When it comes to actually trying to add rotations, we, in fact, actually multiply their data together.
- //Since we're specifically operating on usability for RotationF, we'll operate on this, rather than the literal addition of the values
- inline RotationF& RotationF::operator +=(const RotationF& _rotation)
- {
- if (mRotationType == Euler)
- {
- x += _rotation.x;
- y += _rotation.y;
- z += _rotation.z;
- }
- else
- {
- MatrixF tempMat = asMatrixF();
- MatrixF tempMatAdd = _rotation.asMatrixF();
- tempMat.mul(tempMatAdd);
- this->set(tempMat);
- }
- return *this;
- }
- inline RotationF RotationF::operator +(const RotationF& _rotation) const
- {
- RotationF result = *this;
- if (mRotationType == Euler)
- {
- result.x += _rotation.x;
- result.y += _rotation.y;
- result.z += _rotation.z;
- }
- else
- {
- MatrixF tempMat = asMatrixF();
- MatrixF tempMatAdd = _rotation.asMatrixF();
- tempMat.mul(tempMatAdd);
- result.set(tempMat);
- }
- return result;
- }
- //Much like addition, when subtracting, we're not literally subtracting the values, but infact multiplying the inverse.
- //This subtracts the rotation angles to get the difference
- inline RotationF& RotationF::operator -=(const RotationF& _rotation)
- {
- if (mRotationType == Euler)
- {
- x -= _rotation.x;
- y -= _rotation.y;
- z -= _rotation.z;
- }
- else
- {
- MatrixF tempMat = asMatrixF();
- MatrixF tempMatAdd = _rotation.asMatrixF();
- tempMatAdd.inverse();
- tempMat.mul(tempMatAdd);
- this->set(tempMat);
- }
- return *this;
- }
- inline RotationF RotationF::operator -(const RotationF& _rotation) const
- {
- RotationF result = *this;
- if (mRotationType == Euler)
- {
- result.x += _rotation.x;
- result.y += _rotation.y;
- result.z += _rotation.z;
- }
- else
- {
- MatrixF tempMat = asMatrixF();
- MatrixF tempMatAdd = _rotation.asMatrixF();
- tempMatAdd.inverse();
- tempMat.mul(tempMatAdd);
- result.set(tempMat);
- }
- return result;
- }
- inline RotationF& RotationF::operator =(const RotationF& _rotation)
- {
- x = _rotation.x;
- y = _rotation.y;
- z = _rotation.z;
- w = _rotation.w;
- mRotationType = _rotation.mRotationType;
- return *this;
- }
- //====================================================================
- // Euler operators
- //====================================================================
- inline RotationF RotationF::operator=(const EulerF& _euler)
- {
- return RotationF(_euler, Radians);
- }
- inline RotationF RotationF::operator-(const EulerF& _euler) const
- {
- RotationF temp = *this;
- temp -= RotationF(_euler, Radians);
- return temp;
- }
- inline RotationF RotationF::operator+(const EulerF& _euler) const
- {
- RotationF temp = *this;
- temp += RotationF(_euler, Radians);
- return temp;
- }
- inline RotationF& RotationF::operator-=(const EulerF& _euler)
- {
- *this -= RotationF(_euler, Radians);
- return *this;
- }
- inline RotationF& RotationF::operator+=(const EulerF& _euler)
- {
- *this += RotationF(_euler, Radians);
- return *this;
- }
- inline S32 RotationF::operator==(const EulerF& _euler) const
- {
- return *this == RotationF(_euler);
- }
- inline S32 RotationF::operator!=(const EulerF& _euler) const
- {
- return *this != RotationF(_euler);
- }
- //====================================================================
- // AxisAngle operators
- //====================================================================
- inline RotationF RotationF::operator=(const AngAxisF& _aa)
- {
- return RotationF(_aa, Radians);
- }
- inline RotationF RotationF::operator-(const AngAxisF& _aa) const
- {
- RotationF temp = *this;
- temp -= RotationF(_aa, Radians);
- return temp;
- }
- inline RotationF RotationF::operator+(const AngAxisF& _aa) const
- {
- RotationF temp = *this;
- temp += RotationF(_aa, Radians);
- return temp;
- }
- inline RotationF& RotationF::operator-=(const AngAxisF& _aa)
- {
- *this -= RotationF(_aa, Radians);
- return *this;
- }
- inline RotationF& RotationF::operator+=(const AngAxisF& _aa)
- {
- *this += RotationF(_aa, Radians);
- return *this;
- }
- inline S32 RotationF::operator==(const AngAxisF& _aa) const
- {
- return *this == RotationF(_aa);
- }
- inline S32 RotationF::operator!=(const AngAxisF& _aa) const
- {
- return *this != RotationF(_aa);
- }
- //====================================================================
- // QuatF operators
- //====================================================================
- inline RotationF RotationF::operator=(const QuatF& _quat)
- {
- return RotationF(_quat);
- }
- inline RotationF RotationF::operator-(const QuatF& _quat) const
- {
- RotationF temp = *this;
- temp -= RotationF(_quat);
- return temp;
- }
- inline RotationF RotationF::operator+(const QuatF& _quat) const
- {
- RotationF temp = *this;
- temp += RotationF(_quat);
- return temp;
- }
- inline RotationF& RotationF::operator-=(const QuatF& _quat)
- {
- *this -= RotationF(_quat);
- return *this;
- }
- inline RotationF& RotationF::operator+=(const QuatF& _quat)
- {
- *this += RotationF(_quat);
- return *this;
- }
- inline S32 RotationF::operator==(const QuatF& _quat) const
- {
- return *this == RotationF(_quat);
- }
- inline S32 RotationF::operator!=(const QuatF& _quat) const
- {
- return *this != RotationF(_quat);
- }
- //====================================================================
- // MatrixF operators
- //====================================================================
- inline RotationF RotationF::operator=(const MatrixF& _mat)
- {
- return RotationF(_mat);
- }
- inline RotationF RotationF::operator-(const MatrixF& _mat) const
- {
- RotationF temp = *this;
- temp -= RotationF(_mat);
- return temp;
- }
- inline RotationF RotationF::operator+(const MatrixF& _mat) const
- {
- RotationF temp = *this;
- temp += RotationF(_mat);
- return temp;
- }
- inline RotationF& RotationF::operator-=(const MatrixF& _mat)
- {
- *this -= RotationF(_mat);
- return *this;
- }
- inline RotationF& RotationF::operator+=(const MatrixF& _mat)
- {
- *this += RotationF(_mat);
- return *this;
- }
- inline S32 RotationF::operator==(const MatrixF& _mat) const
- {
- return *this == RotationF(_mat);
- }
- inline S32 RotationF::operator!=(const MatrixF& _mat) const
- {
- return *this != RotationF(_mat);
- }
- #endif // MROTATION_H
|