mRotation.h
Engine/source/math/mRotation.h
Classes:
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