|
@@ -0,0 +1,465 @@
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+// 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));
|
|
|
+
|
|
|
+ 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
|