From 383d27f2ec8acb5e3005b07af8739170aaf6a3f9 Mon Sep 17 00:00:00 2001 From: Areloch Date: Thu, 12 May 2016 00:45:16 -0500 Subject: [PATCH 1/2] The class is designed as a general-purpose rotation/orientation class to make it easy to work with rotations and swap between math types as easily as possible. --- Engine/source/console/consoleTypes.h | 2 + Engine/source/gui/editor/inspector/field.cpp | 3 +- Engine/source/math/mRotation.cpp | 299 ++++++++++++ Engine/source/math/mRotation.h | 465 +++++++++++++++++++ Engine/source/math/mathIO.h | 24 + Engine/source/math/mathTypes.cpp | 60 ++- Engine/source/math/mathTypes.h | 5 +- 7 files changed, 853 insertions(+), 5 deletions(-) create mode 100644 Engine/source/math/mRotation.cpp create mode 100644 Engine/source/math/mRotation.h diff --git a/Engine/source/console/consoleTypes.h b/Engine/source/console/consoleTypes.h index c026b8e1a..ab5b97d62 100644 --- a/Engine/source/console/consoleTypes.h +++ b/Engine/source/console/consoleTypes.h @@ -74,6 +74,8 @@ DefineConsoleType( TypeCommand, String ) DefineConsoleType( TypeFilename, const char * ) DefineConsoleType( TypeStringFilename, String ) +DefineConsoleType(TypeRotationF, RotationF) + /// A universally unique identifier. DefineConsoleType( TypeUUID, Torque::UUID ) diff --git a/Engine/source/gui/editor/inspector/field.cpp b/Engine/source/gui/editor/inspector/field.cpp index ac72b2e04..45aa1b2b0 100644 --- a/Engine/source/gui/editor/inspector/field.cpp +++ b/Engine/source/gui/editor/inspector/field.cpp @@ -284,7 +284,8 @@ void GuiInspectorField::setData( const char* data, bool callbacks ) || type == TypeMatrixPosition || type == TypeMatrixRotation || type == TypeBox3F - || type == TypeRectUV ) + || type == TypeRectUV + || type == TypeRotationF) { //TODO: we should actually take strings into account and not chop things up between quotes diff --git a/Engine/source/math/mRotation.cpp b/Engine/source/math/mRotation.cpp new file mode 100644 index 000000000..d915348d6 --- /dev/null +++ b/Engine/source/math/mRotation.cpp @@ -0,0 +1,299 @@ +//----------------------------------------------------------------------------- +// 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. +//----------------------------------------------------------------------------- +#include "math/mRotation.h" + +#ifdef TORQUE_TESTS_ENABLED +#include "testing/unitTesting.h" +#endif + +//==================================================================== +//Eulers setup +//==================================================================== +RotationF::RotationF(EulerF _euler, UnitFormat format) +{ + set(_euler.x, _euler.y, _euler.z, format); +} + +RotationF::RotationF(F32 _x, F32 _y, F32 _z, UnitFormat format) +{ + set(_x, _y, _z, format); +} + +void RotationF::set(EulerF _euler, UnitFormat format) +{ + x = format == Degrees ? mDegToRad(_euler.x) : _euler.x; + y = format == Degrees ? mDegToRad(_euler.y) : _euler.y; + z = format == Degrees ? mDegToRad(_euler.z) : _euler.z; + + mRotationType = Euler; +} + +void RotationF::set(F32 _x, F32 _y, F32 _z, UnitFormat format) +{ + EulerF tempEul; + if (format == Degrees) + { + tempEul.set(mDegToRad(_x), mDegToRad(_y), mDegToRad(_z)); + } + else + { + tempEul.set(_x, _y, _z); + } + + set(tempEul); +} + +//==================================================================== +//AxisAngle setup +//==================================================================== +RotationF::RotationF(AngAxisF _aa, UnitFormat format) +{ + set(_aa, format); +} + +void RotationF::set(AngAxisF _aa, UnitFormat format) +{ + x = _aa.axis.x; + y = _aa.axis.y; + z = _aa.axis.z; + + w = format == Degrees ? mDegToRad(_aa.angle) : _aa.angle; + + mRotationType = AxisAngle; +} + +//==================================================================== +//QuatF setup +//==================================================================== +RotationF::RotationF(QuatF _quat) +{ + set(_quat); +} + +void RotationF::set(QuatF _quat) +{ + AngAxisF tmpAA; + tmpAA.set(_quat); + + set(tmpAA); +} + +//==================================================================== +//MatrixF setup +//==================================================================== +RotationF::RotationF(MatrixF _mat) +{ + set(_mat); +} + +void RotationF::set(MatrixF _mat) +{ + set(_mat.toEuler()); +} + +// +inline F32 RotationF::len() const +{ + return asEulerF().len(); +} + +inline void RotationF::interpolate(const RotationF& _from, const RotationF& _to, F32 _factor) +{ + QuatF tmpQuat; + + tmpQuat.interpolate(_from.asQuatF(), _to.asQuatF(), _factor); + + set(tmpQuat); +} + +void RotationF::lookAt(const Point3F& _origin, const Point3F& _target, const Point3F& _up) +{ + MatrixF mat; + + VectorF newForward = _target - _origin; + newForward.normalize(); + + VectorF up(0.0f, 0.0f, 1.0f); + VectorF axisX; + VectorF axisY = newForward; + VectorF axisZ; + + if (_up != VectorF::Zero) + up = _up; + + // Validate and normalize input: + F32 lenSq; + lenSq = axisY.lenSquared(); + if (lenSq < 0.000001f) + { + //degenerate forward vector + axisY.set(0.0f, 1.0f, 0.0f); + } + else + { + axisY /= mSqrt(lenSq); + } + + + lenSq = up.lenSquared(); + if (lenSq < 0.000001f) + { + //degenerate up vector - too small + up.set(0.0f, 0.0f, 1.0f); + } + else + { + up /= mSqrt(lenSq); + } + + if (fabsf(mDot(up, axisY)) > 0.9999f) + { + //degenerate up vector - same as forward + F32 tmp = up.x; + up.x = -up.y; + up.y = up.z; + up.z = tmp; + } + + // construct the remaining axes: + mCross(axisY, up, &axisX); + mCross(axisX, axisY, &axisZ); + + mat.setColumn(0, axisX); + mat.setColumn(1, axisY); + mat.setColumn(2, axisZ); + + set(mat); +} + +//======================================================== +EulerF RotationF::asEulerF(UnitFormat _format) const +{ + if (mRotationType == Euler) + { + if (_format == Degrees) + { + return EulerF(mRadToDeg(x), mRadToDeg(y), mRadToDeg(z)); + } + else + { + return EulerF(x, y, z); + } + } + else + { + EulerF returnEuler = asMatrixF().toEuler(); + + if (_format == Degrees) + { + returnEuler.x = mRadToDeg(returnEuler.x); + returnEuler.y = mRadToDeg(returnEuler.y); + returnEuler.z = mRadToDeg(returnEuler.z); + } + + return returnEuler; + } +} + +AngAxisF RotationF::asAxisAngle(UnitFormat format) const +{ + AngAxisF returnAA; + + if (mRotationType == Euler) + { + returnAA.set(EulerF(x, y, z)); + } + else + { + returnAA.set(Point3F(x, y, z), w); + } + + if (format == Radians) + { + returnAA.angle = mDegToRad(returnAA.angle); + } + + return returnAA; +} + +MatrixF RotationF::asMatrixF() const +{ + MatrixF returnMat; + if (mRotationType == Euler) + { + returnMat.set(EulerF(x, y, z)); + } + else + { + AngAxisF aa; + aa.set(Point3F(x, y, z), w); + + aa.setMatrix(&returnMat); + } + + return returnMat; +} + +QuatF RotationF::asQuatF() const +{ + QuatF returnQuat; + if (mRotationType == Euler) + { + returnQuat.set(EulerF(x, y, z)); + } + else + { + AngAxisF aa; + aa.set(Point3F(x, y, z), w); + + returnQuat.set(aa); + } + + return returnQuat; +} + +void RotationF::normalize() +{ + if (mRotationType == Euler) + { + EulerF eul = EulerF(x, y, z); + eul.normalize(); + set(eul); + } + else + { + QuatF quat; + quat.set(Point3F(x, y, z), w); + + quat.normalize(); + + set(quat); + } +} + +//Testing +#ifdef TORQUE_TESTS_ENABLED +TEST(Maths, RotationF_Calculations) +{ + //TODO: implement unit test +}; +#endif \ No newline at end of file diff --git a/Engine/source/math/mRotation.h b/Engine/source/math/mRotation.h new file mode 100644 index 000000000..a99510b8c --- /dev/null +++ b/Engine/source/math/mRotation.h @@ -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 diff --git a/Engine/source/math/mathIO.h b/Engine/source/math/mathIO.h index ee2f0dcad..6acbc1b52 100644 --- a/Engine/source/math/mathIO.h +++ b/Engine/source/math/mathIO.h @@ -149,6 +149,20 @@ inline bool mathRead(Stream& stream, EaseF* e) return success; } +inline bool mathRead(Stream& stream, RotationF* e) +{ + bool success = stream.read(&e->x); + success &= stream.read(&e->y); + success &= stream.read(&e->z); + success &= stream.read(&e->w); + + U32 rotType; + success &= stream.read(&rotType); + e->mRotationType = (RotationF::RotationTypes)rotType; + + return success; +} + //------------------------------------------------------------------------------ //-------------------------------------- WRITING // @@ -263,5 +277,15 @@ inline bool mathWrite(Stream& stream, const EaseF& e) return success; } +inline bool mathWrite(Stream& stream, const RotationF& e) +{ + bool success = stream.write(e.x); + success &= stream.write(e.y); + success &= stream.write(e.z); + success &= stream.write(e.w); + success &= stream.write(e.mRotationType); + return success;; +} + #endif //_MATHIO_H_ diff --git a/Engine/source/math/mathTypes.cpp b/Engine/source/math/mathTypes.cpp index 29c500b60..dd018b2a4 100644 --- a/Engine/source/math/mathTypes.cpp +++ b/Engine/source/math/mathTypes.cpp @@ -36,7 +36,7 @@ #include "math/mRandom.h" #include "math/mEase.h" #include "math/mathUtils.h" - +#include "math/mRotation.h" #include "core/strings/stringUnit.h" IMPLEMENT_SCOPE( MathTypes, Math,, "" ); @@ -113,7 +113,14 @@ IMPLEMENT_STRUCT( EaseF, EaseF, MathTypes, "" ) END_IMPLEMENT_STRUCT; - +IMPLEMENT_STRUCT(RotationF, + RotationF, MathTypes, + "") + FIELD(x, x, 1, "X coordinate.") + FIELD(y, y, 1, "Y coordinate.") + FIELD(z, z, 1, "Z coordinate.") + FIELD(w, w, 1, "W coordinate.") +END_IMPLEMENT_STRUCT; //----------------------------------------------------------------------------- // TypePoint2I @@ -572,6 +579,55 @@ ConsoleSetType( TypeEaseF ) } } +//----------------------------------------------------------------------------- +// TypeRotationF +//----------------------------------------------------------------------------- +ConsoleType(RotationF, TypeRotationF, RotationF, "") +//ImplementConsoleTypeCasters( TypeRotationF, RotationF ) + +ConsoleGetType(TypeRotationF) +{ + RotationF *pt = (RotationF *)dptr; + static const U32 bufSize = 256; + char* returnBuffer = Con::getReturnBuffer(bufSize); + + EulerF out = pt->asEulerF(RotationF::Degrees); + dSprintf(returnBuffer, bufSize, "%g %g %g", out.x, out.y, out.z); + + return returnBuffer; +} + +ConsoleSetType(TypeRotationF) +{ + if (argc == 1) + { + U32 elements = StringUnit::getUnitCount(argv[0], " \t\n"); + if (elements == 3) + { + EulerF in; + dSscanf(argv[0], "%g %g %g", &in.x, &in.y, &in.z); + ((RotationF *)dptr)->set(in, RotationF::Degrees); + } + else + { + AngAxisF in; + dSscanf(argv[0], "%g %g %g %g", &in.axis.x, &in.axis.y, &in.axis.z, &in.angle); + ((RotationF *)dptr)->set(in, RotationF::Degrees); + } + } + else if (argc == 3) + { + EulerF in(dAtof(argv[0]), dAtof(argv[1]), dAtof(argv[2])); + ((RotationF *)dptr)->set(in, RotationF::Degrees); + } + else if (argc == 4) + { + AngAxisF in(Point3F(dAtof(argv[0]), dAtof(argv[1]), dAtof(argv[2])), dAtof(argv[3])); + ((RotationF *)dptr)->set(in, RotationF::Degrees); + } + else + Con::printf("RotationF must be set as { x, y, z, w } or \"x y z w\""); +} //----------------------------------------------------------------------------- diff --git a/Engine/source/math/mathTypes.h b/Engine/source/math/mathTypes.h index b17329cf8..043d59e1f 100644 --- a/Engine/source/math/mathTypes.h +++ b/Engine/source/math/mathTypes.h @@ -43,7 +43,7 @@ class Box3F; class EaseF; class AngAxisF; class TransformF; - +class RotationF; DECLARE_SCOPE( MathTypes ); @@ -60,6 +60,7 @@ DECLARE_STRUCT( AngAxisF ); DECLARE_STRUCT( TransformF ); DECLARE_STRUCT( Box3F ); DECLARE_STRUCT( EaseF ); +DECLARE_STRUCT(RotationF); // Legacy console types. @@ -77,6 +78,6 @@ DefineConsoleType( TypeAngAxisF, AngAxisF ) DefineConsoleType( TypeTransformF, TransformF ) DefineConsoleType( TypeBox3F, Box3F ) DefineConsoleType( TypeEaseF, EaseF ) - +DefineConsoleType(TypeRotationF, RotationF) #endif From 1b47bdd972fe83b529dc3d475b1ade7b7266eea1 Mon Sep 17 00:00:00 2001 From: Areloch Date: Thu, 12 May 2016 23:49:06 -0500 Subject: [PATCH 2/2] Git apparently forgot to commit ALL the changes. --- Engine/source/math/mMath.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Engine/source/math/mMath.h b/Engine/source/math/mMath.h index a1e070db7..4710f6bf0 100644 --- a/Engine/source/math/mMath.h +++ b/Engine/source/math/mMath.h @@ -48,5 +48,8 @@ #ifndef _MEASE_H_ #include "math/mEase.h" #endif +#ifndef MROTATION_H +#include "math/mRotation.h" +#endif #endif //_MMATH_H_