mMatrix.h
Classes:
class
4x4 Matrix Class
Public Functions
Detailed Description
Public Functions
mTransformPlane(const MatrixF & mat, const Point3F & scale, const PlaneF & plane, PlaneF * result)
operator*(const MatrixF & m1, const MatrixF & m2)
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 _MMATRIX_H_ 25#define _MMATRIX_H_ 26 27#ifndef _MPLANE_H_ 28#include "math/mPlane.h" 29#endif 30 31#ifndef _MBOX_H_ 32#include "math/mBox.h" 33#endif 34 35#ifndef _MPOINT4_H_ 36#include "math/mPoint4.h" 37#endif 38 39/// 4x4 Matrix Class 40/// 41/// This runs at F32 precision. 42 43class MatrixF 44{ 45private: 46 F32 m[16]; ///< Note: Torque uses row-major matrices 47 48public: 49 /// Create an uninitialized matrix. 50 /// 51 /// @param identity If true, initialize to the identity matrix. 52 explicit MatrixF(bool identity=false); 53 54 /// Create a matrix to rotate about origin by e. 55 /// @see set 56 explicit MatrixF( const EulerF &e); 57 58 /// Create a matrix to rotate about p by e. 59 /// @see set 60 MatrixF( const EulerF &e, const Point3F& p); 61 62 /// Get the index in m to element in column i, row j 63 /// 64 /// This is necessary as we have m as a one dimensional array. 65 /// 66 /// @param i Column desired. 67 /// @param j Row desired. 68 static U32 idx(U32 i, U32 j) { return (i + j*4); } 69 70 /// Initialize matrix to rotate about origin by e. 71 MatrixF& set( const EulerF &e); 72 73 /// Initialize matrix to rotate about p by e. 74 MatrixF& set( const EulerF &e, const Point3F& p); 75 76 /// Initialize matrix with a cross product of p. 77 MatrixF& setCrossProduct( const Point3F &p); 78 79 /// Initialize matrix with a tensor product of p. 80 MatrixF& setTensorProduct( const Point3F &p, const Point3F& q); 81 82 operator F32*() { return (m); } ///< Allow people to get at m. 83 operator const F32*() const { return (F32*)(m); } ///< Allow people to get at m. 84 85 bool isAffine() const; ///< Check to see if this is an affine matrix. 86 bool isIdentity() const; ///< Checks for identity matrix. 87 88 /// Make this an identity matrix. 89 MatrixF& identity(); 90 91 /// Invert m. 92 MatrixF& inverse(); 93 /// Copy the inversion of this into out matrix. 94 void invertTo( MatrixF *out ); 95 96 /// Take inverse of matrix assuming it is affine (rotation, 97 /// scale, sheer, translation only). 98 MatrixF& affineInverse(); 99 100 /// Swap rows and columns. 101 MatrixF& transpose(); 102 103 /// M * Matrix(p) -> M 104 MatrixF& scale( const Point3F &s ); 105 MatrixF& scale( F32 s ) { return scale( Point3F( s, s, s ) ); } 106 107 /// Return scale assuming scale was applied via mat.scale(s). 108 Point3F getScale() const; 109 110 EulerF toEuler() const; 111 112 /// Compute the inverse of the matrix. 113 /// 114 /// Computes inverse of full 4x4 matrix. Returns false and performs no inverse if 115 /// the determinant is 0. 116 /// 117 /// Note: In most cases you want to use the normal inverse function. This method should 118 /// be used if the matrix has something other than (0,0,0,1) in the bottom row. 119 bool fullInverse(); 120 121 /// Swaps rows and columns into matrix. 122 void transposeTo(F32 *matrix) const; 123 124 /// Normalize the matrix. 125 void normalize(); 126 127 /// Copy the requested column into a Point4F. 128 void getColumn(S32 col, Point4F *cptr) const; 129 Point4F getColumn4F(S32 col) const { Point4F ret; getColumn(col,&ret); return ret; } 130 131 /// Copy the requested column into a Point3F. 132 /// 133 /// This drops the bottom-most row. 134 void getColumn(S32 col, Point3F *cptr) const; 135 Point3F getColumn3F(S32 col) const { Point3F ret; getColumn(col,&ret); return ret; } 136 137 /// Set the specified column from a Point4F. 138 void setColumn(S32 col, const Point4F& cptr); 139 140 /// Set the specified column from a Point3F. 141 /// 142 /// The bottom-most row is not set. 143 void setColumn(S32 col, const Point3F& cptr); 144 145 /// Copy the specified row into a Point4F. 146 void getRow(S32 row, Point4F *cptr) const; 147 Point4F getRow4F(S32 row) const { Point4F ret; getRow(row,&ret); return ret; } 148 149 /// Copy the specified row into a Point3F. 150 /// 151 /// Right-most item is dropped. 152 void getRow(S32 row, Point3F *cptr) const; 153 Point3F getRow3F(S32 row) const { Point3F ret; getRow(row,&ret); return ret; } 154 155 /// Set the specified row from a Point4F. 156 void setRow(S32 row, const Point4F& cptr); 157 158 /// Set the specified row from a Point3F. 159 /// 160 /// The right-most item is not set. 161 void setRow(S32 row, const Point3F& cptr); 162 163 /// Get the position of the matrix. 164 /// 165 /// This is the 4th column of the matrix. 166 Point3F getPosition() const; 167 168 /// Set the position of the matrix. 169 /// 170 /// This is the 4th column of the matrix. 171 void setPosition( const Point3F &pos ) { setColumn( 3, pos ); } 172 173 /// Add the passed delta to the matrix position. 174 void displace( const Point3F &delta ); 175 176 /// Get the x axis of the matrix. 177 /// 178 /// This is the 1st column of the matrix and is 179 /// normally considered the right vector. 180 VectorF getRightVector() const; 181 182 /// Get the y axis of the matrix. 183 /// 184 /// This is the 2nd column of the matrix and is 185 /// normally considered the forward vector. 186 VectorF getForwardVector() const; 187 188 /// Get the z axis of the matrix. 189 /// 190 /// This is the 3rd column of the matrix and is 191 /// normally considered the up vector. 192 VectorF getUpVector() const; 193 194 MatrixF& mul(const MatrixF &a); ///< M * a -> M 195 MatrixF& mulL(const MatrixF &a); ///< a * M -> M 196 MatrixF& mul(const MatrixF &a, const MatrixF &b); ///< a * b -> M 197 198 // Scalar multiplies 199 MatrixF& mul(const F32 a); ///< M * a -> M 200 MatrixF& mul(const MatrixF &a, const F32 b); ///< a * b -> M 201 202 203 void mul( Point4F& p ) const; ///< M * p -> p (full [4x4] * [1x4]) 204 void mulP( Point3F& p ) const; ///< M * p -> p (assume w = 1.0f) 205 void mulP( const Point3F &p, Point3F *d) const; ///< M * p -> d (assume w = 1.0f) 206 void mulV( VectorF& p ) const; ///< M * v -> v (assume w = 0.0f) 207 void mulV( const VectorF &p, Point3F *d) const; ///< M * v -> d (assume w = 0.0f) 208 209 void mul(Box3F& b) const; ///< Axial box -> Axial Box 210 211 MatrixF& add( const MatrixF& m ); 212 213 /// Convenience function to allow people to treat this like an array. 214 F32& operator ()(S32 row, S32 col) { return m[idx(col,row)]; } 215 F32 operator ()(S32 row, S32 col) const { return m[idx(col,row)]; } 216 217 void dumpMatrix(const char *caption=<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>) const; 218 219 // Math operator overloads 220 //------------------------------------ 221 friend MatrixF operator *( const MatrixF &m1, const MatrixF &m2 ); 222 MatrixF& operator *=( const MatrixF &m ); 223 224 // Static identity matrix 225 const static MatrixF Identity; 226}; 227 228 229//-------------------------------------- 230// Inline Functions 231 232inline MatrixF::MatrixF(bool _identity) 233{ 234 if (_identity) 235 identity(); 236} 237 238inline MatrixF::MatrixF( const EulerF &e ) 239{ 240 set(e); 241} 242 243inline MatrixF::MatrixF( const EulerF &e, const Point3F& p ) 244{ 245 set(e,p); 246} 247 248inline MatrixF& MatrixF::set( const EulerF &e) 249{ 250 m_matF_set_euler( e, *this ); 251 return (*this); 252} 253 254 255inline MatrixF& MatrixF::set( const EulerF &e, const Point3F& p) 256{ 257 m_matF_set_euler_point( e, p, *this ); 258 return (*this); 259} 260 261inline MatrixF& MatrixF::setCrossProduct( const Point3F &p) 262{ 263 m[1] = -(m[4] = p.z); 264 m[8] = -(m[2] = p.y); 265 m[6] = -(m[9] = p.x); 266 m[0] = m[3] = m[5] = m[7] = m[10] = m[11] = 267 m[12] = m[13] = m[14] = 0.0f; 268 m[15] = 1; 269 return (*this); 270} 271 272inline MatrixF& MatrixF::setTensorProduct( const Point3F &p, const Point3F &q) 273{ 274 m[0] = p.x * q.x; 275 m[1] = p.x * q.y; 276 m[2] = p.x * q.z; 277 m[4] = p.y * q.x; 278 m[5] = p.y * q.y; 279 m[6] = p.y * q.z; 280 m[8] = p.z * q.x; 281 m[9] = p.z * q.y; 282 m[10] = p.z * q.z; 283 m[3] = m[7] = m[11] = m[12] = m[13] = m[14] = 0.0f; 284 m[15] = 1.0f; 285 return (*this); 286} 287 288inline bool MatrixF::isIdentity() const 289{ 290 return 291 m[0] == 1.0f && 292 m[1] == 0.0f && 293 m[2] == 0.0f && 294 m[3] == 0.0f && 295 m[4] == 0.0f && 296 m[5] == 1.0f && 297 m[6] == 0.0f && 298 m[7] == 0.0f && 299 m[8] == 0.0f && 300 m[9] == 0.0f && 301 m[10] == 1.0f && 302 m[11] == 0.0f && 303 m[12] == 0.0f && 304 m[13] == 0.0f && 305 m[14] == 0.0f && 306 m[15] == 1.0f; 307} 308 309inline MatrixF& MatrixF::identity() 310{ 311 m[0] = 1.0f; 312 m[1] = 0.0f; 313 m[2] = 0.0f; 314 m[3] = 0.0f; 315 m[4] = 0.0f; 316 m[5] = 1.0f; 317 m[6] = 0.0f; 318 m[7] = 0.0f; 319 m[8] = 0.0f; 320 m[9] = 0.0f; 321 m[10] = 1.0f; 322 m[11] = 0.0f; 323 m[12] = 0.0f; 324 m[13] = 0.0f; 325 m[14] = 0.0f; 326 m[15] = 1.0f; 327 return (*this); 328} 329 330 331inline MatrixF& MatrixF::inverse() 332{ 333 m_matF_inverse(m); 334 return (*this); 335} 336 337inline void MatrixF::invertTo( MatrixF *out ) 338{ 339 m_matF_invert_to(m,*out); 340} 341 342inline MatrixF& MatrixF::affineInverse() 343{ 344// AssertFatal(isAffine() == true, "Error, this matrix is not an affine transform"); 345 m_matF_affineInverse(m); 346 return (*this); 347} 348 349inline MatrixF& MatrixF::transpose() 350{ 351 m_matF_transpose(m); 352 return (*this); 353} 354 355inline MatrixF& MatrixF::scale(const Point3F& p) 356{ 357 m_matF_scale(m,p); 358 return *this; 359} 360 361inline Point3F MatrixF::getScale() const 362{ 363 Point3F scale; 364 scale.x = mSqrt(m[0]*m[0] + m[4] * m[4] + m[8] * m[8]); 365 scale.y = mSqrt(m[1]*m[1] + m[5] * m[5] + m[9] * m[9]); 366 scale.z = mSqrt(m[2]*m[2] + m[6] * m[6] + m[10] * m[10]); 367 return scale; 368} 369 370inline void MatrixF::normalize() 371{ 372 m_matF_normalize(m); 373} 374 375inline MatrixF& MatrixF::mul( const MatrixF &a ) 376{ // M * a -> M 377 AssertFatal(&a != this, "MatrixF::mul - a.mul(a) is invalid!"); 378 379 MatrixF tempThis(*this); 380 m_matF_x_matF(tempThis, a, *this); 381 return (*this); 382} 383 384inline MatrixF& MatrixF::mulL( const MatrixF &a ) 385{ // a * M -> M 386 AssertFatal(&a != this, "MatrixF::mulL - a.mul(a) is invalid!"); 387 388 MatrixF tempThis(*this); 389 m_matF_x_matF(a, tempThis, *this); 390 return (*this); 391} 392 393inline MatrixF& MatrixF::mul( const MatrixF &a, const MatrixF &b ) 394{ // a * b -> M 395 AssertFatal((&a != this) && (&b != this), "MatrixF::mul - a.mul(a, b) a.mul(b, a) a.mul(a, a) is invalid!"); 396 397 m_matF_x_matF(a, b, *this); 398 return (*this); 399} 400 401 402inline MatrixF& MatrixF::mul(const F32 a) 403{ 404 for (U32 i = 0; i < 16; i++) 405 m[i] *= a; 406 407 return *this; 408} 409 410 411inline MatrixF& MatrixF::mul(const MatrixF &a, const F32 b) 412{ 413 *this = a; 414 mul(b); 415 416 return *this; 417} 418 419inline void MatrixF::mul( Point4F& p ) const 420{ 421 Point4F temp; 422 m_matF_x_point4F(*this, &p.x, &temp.x); 423 p = temp; 424} 425 426inline void MatrixF::mulP( Point3F& p) const 427{ 428 // M * p -> d 429 Point3F d; 430 m_matF_x_point3F(*this, &p.x, &d.x); 431 p = d; 432} 433 434inline void MatrixF::mulP( const Point3F &p, Point3F *d) const 435{ 436 // M * p -> d 437 m_matF_x_point3F(*this, &p.x, &d->x); 438} 439 440inline void MatrixF::mulV( VectorF& v) const 441{ 442 // M * v -> v 443 VectorF temp; 444 m_matF_x_vectorF(*this, &v.x, &temp.x); 445 v = temp; 446} 447 448inline void MatrixF::mulV( const VectorF &v, Point3F *d) const 449{ 450 // M * v -> d 451 m_matF_x_vectorF(*this, &v.x, &d->x); 452} 453 454inline void MatrixF::mul(Box3F& b) const 455{ 456 m_matF_x_box3F(*this, &b.minExtents.x, &b.maxExtents.x); 457} 458 459inline MatrixF& MatrixF::add( const MatrixF& a ) 460{ 461 for( U32 i = 0; i < 16; ++ i ) 462 m[ i ] += a.m[ i ]; 463 464 return *this; 465} 466 467inline void MatrixF::getColumn(S32 col, Point4F *cptr) const 468{ 469 cptr->x = m[col]; 470 cptr->y = m[col+4]; 471 cptr->z = m[col+8]; 472 cptr->w = m[col+12]; 473} 474 475inline void MatrixF::getColumn(S32 col, Point3F *cptr) const 476{ 477 cptr->x = m[col]; 478 cptr->y = m[col+4]; 479 cptr->z = m[col+8]; 480} 481 482inline void MatrixF::setColumn(S32 col, const Point4F &cptr) 483{ 484 m[col] = cptr.x; 485 m[col+4] = cptr.y; 486 m[col+8] = cptr.z; 487 m[col+12]= cptr.w; 488} 489 490inline void MatrixF::setColumn(S32 col, const Point3F &cptr) 491{ 492 m[col] = cptr.x; 493 m[col+4] = cptr.y; 494 m[col+8] = cptr.z; 495} 496 497 498inline void MatrixF::getRow(S32 col, Point4F *cptr) const 499{ 500 col *= 4; 501 cptr->x = m[col++]; 502 cptr->y = m[col++]; 503 cptr->z = m[col++]; 504 cptr->w = m[col]; 505} 506 507inline void MatrixF::getRow(S32 col, Point3F *cptr) const 508{ 509 col *= 4; 510 cptr->x = m[col++]; 511 cptr->y = m[col++]; 512 cptr->z = m[col]; 513} 514 515inline void MatrixF::setRow(S32 col, const Point4F &cptr) 516{ 517 col *= 4; 518 m[col++] = cptr.x; 519 m[col++] = cptr.y; 520 m[col++] = cptr.z; 521 m[col] = cptr.w; 522} 523 524inline void MatrixF::setRow(S32 col, const Point3F &cptr) 525{ 526 col *= 4; 527 m[col++] = cptr.x; 528 m[col++] = cptr.y; 529 m[col] = cptr.z; 530} 531 532inline Point3F MatrixF::getPosition() const 533{ 534 return Point3F( m[3], m[3+4], m[3+8] ); 535} 536 537inline void MatrixF::displace( const Point3F &delta ) 538{ 539 m[3] += delta.x; 540 m[3+4] += delta.y; 541 m[3+8] += delta.z; 542} 543 544inline VectorF MatrixF::getForwardVector() const 545{ 546 VectorF vec; 547 getColumn( 1, &vec ); 548 return vec; 549} 550 551inline VectorF MatrixF::getRightVector() const 552{ 553 VectorF vec; 554 getColumn( 0, &vec ); 555 return vec; 556} 557 558inline VectorF MatrixF::getUpVector() const 559{ 560 VectorF vec; 561 getColumn( 2, &vec ); 562 return vec; 563} 564 565//------------------------------------ 566// Math operator overloads 567//------------------------------------ 568inline MatrixF operator *( const MatrixF &m1, const MatrixF &m2 ) 569{ 570 // temp = m1 * m2 571 MatrixF temp; 572 m_matF_x_matF(m1, m2, temp); 573 return temp; 574} 575 576inline MatrixF& MatrixF::operator *=( const MatrixF &m1 ) 577{ 578 MatrixF tempThis(*this); 579 m_matF_x_matF(tempThis, m1, *this); 580 return (*this); 581} 582 583//------------------------------------ 584// Non-member methods 585//------------------------------------ 586 587inline void mTransformPlane(const MatrixF& mat, const Point3F& scale, const PlaneF& plane, PlaneF * result) 588{ 589 m_matF_x_scale_x_planeF(mat, &scale.x, &plane.x, &result->x); 590} 591 592#endif //_MMATRIX_H_ 593
