diff --git a/Engine/source/math/mMatrix.cpp b/Engine/source/math/mMatrix.cpp index 9c75d740b..0a152ad6c 100644 --- a/Engine/source/math/mMatrix.cpp +++ b/Engine/source/math/mMatrix.cpp @@ -372,9 +372,9 @@ Matrix& Matrix::inverse() } } - // Early out if pivot is 0, return a new empty matrix. + // Early out if pivot is 0, return identity matrix. if (augmentedMatrix(i, i) == static_cast(0)) { - return Matrix(); + return Matrix(true); } DATA_TYPE pivotVal = augmentedMatrix(i, i); @@ -550,6 +550,27 @@ bool Matrix::isAffine() const return true; } +template +Matrix& Matrix::affineInverse() +{ + AssertFatal(rows >= 4 && cols >= 4, "affineInverse requires at least 4x4"); + Matrix subMatrix; + + for (U32 i = 0; i < 3; i++) { + for (U32 j = 0; j < 3; j++) { + subMatrix(i, j) = (*this)(i, j); + } + } + + subMatrix.transpose(); + + Point3F pos = getPosition(); + (*this)(0, 3) = mDot(subMatrix.getColumn3F(0), pos); + (*this)(1, 3) = mDot(subMatrix.getColumn3F(1), pos); + (*this)(2, 3) = mDot(subMatrix.getColumn3F(2), pos); + + return *this; +} template EulerF Matrix::toEuler() const diff --git a/Engine/source/math/mMatrix.h b/Engine/source/math/mMatrix.h index 98785dd54..fe715298e 100644 --- a/Engine/source/math/mMatrix.h +++ b/Engine/source/math/mMatrix.h @@ -653,6 +653,8 @@ public: /// Make this an identity matrix. Matrix& identity(); + void normalize(); + Matrix& set(const EulerF& e); Matrix(const EulerF& e, const Point3F p); @@ -730,8 +732,14 @@ public: void mul(Box3F& box) const; // ------ Getters ------ + // col * rows + row + // static U32 idx(U32 i, U32 j) { return (i * rows + j); } bool isAffine() const; bool isIdentity() const; + /// Take inverse of matrix assuming it is affine (rotation, + /// scale, sheer, translation only). + Matrix& affineInverse(); + Point3F getScale() const; EulerF toEuler() const; @@ -906,6 +914,26 @@ inline Matrix& Matrix::identity() return (*this); } +template +inline void Matrix::normalize() +{ + AssertFatal(rows >= 3 && cols >= 3, "Normalize can only be applied 3x3 or more"); + Point3F col0, col1, col2; + getColumn(0, &col0); + getColumn(1, &col1); + + mCross(col0, col1, &col2); + mCross(col2, col0, &col1); + + col0.normalize(); + col1.normalize(); + col2.normalize(); + + setColumn(0, col0); + setColumn(1, col1); + setColumn(2, col2); +} + template inline Matrix& Matrix::scale(const Point3F& s) {