///////////////////////////////////////////////////////////////////// // Linear Math Matrixes (Column weighted) // © Dan Andersson 2013 ///////////////////////////////////////////////////////////////////// #ifndef LINEARALGEBRA_MATRIX_H #define LINEARALGEBRA_MATRIX_H #include "Vector.h" #include "Utilities.h" namespace LinearAlgebra { template struct Matrix2x2 { public: union { ScalarType m[2][2]; struct{ Vector2 v[2]; }; struct{ ScalarType m11, m21, m12, m22; }; ScalarType element[4]; char byte[sizeof(ScalarType[4])]; }; static const Matrix2x2 identity, null; Matrix2x2( ); Matrix2x2( const ScalarType &m11, const ScalarType &m12, const ScalarType &m21, const ScalarType &m22 ); explicit Matrix2x2( const Vector2 vec[2] ); Matrix2x2( const Vector2 &vec1, const Vector2 &vec2 ); explicit Matrix2x2( const ScalarType element[4] ); Matrix2x2( const Matrix2x2 &matrix ); operator ScalarType* ( ); operator const ScalarType* ( ) const; Matrix2x2 & operator = ( const Vector2 vec[2] ); Matrix2x2 & operator = ( const Matrix2x2 &matrix ); Matrix2x2 & operator += ( const Matrix2x2 &matrix ); Matrix2x2 & operator -= ( const Matrix2x2 &matrix ); Matrix2x2 & operator *= ( const ScalarType &scalar ); Matrix2x2 & operator /= ( const ScalarType &scalar ); Matrix2x2 operator + ( const Matrix2x2 &matrix ) const; Matrix2x2 operator - ( const Matrix2x2 &matrix ) const; Matrix2x2 operator * ( const ScalarType &scalar ) const; Matrix2x2 operator / ( const ScalarType &scalar ) const; Matrix2x2 operator - ( ) const; // unary negation ScalarType GetDeterminant( ) const; Matrix2x2 GetAdjoint( ) const; Matrix2x2 GetTranspose( ) const; Matrix2x2 & Transpose( ); Matrix2x2 GetInverse( ) const; Matrix2x2 GetInverse( ScalarType &determinant ) const; Matrix2x2 & Invert( ); Matrix2x2 & Invert( ScalarType &determinant ); Vector2 GetRowVector( unsigned int rowID ) const; Vector2 GetColumnVector( unsigned int colID ) const; }; template struct Matrix3x3 { public: union { ScalarType m[3][3]; struct{ Vector3 v[3]; }; struct{ ScalarType m11, m21, m31, m12, m22, m32, m13, m23, m33; }; ScalarType element[9]; char byte[sizeof(ScalarType[9])]; }; static const Matrix3x3 identity, null; Matrix3x3( ); Matrix3x3( const ScalarType &m11, const ScalarType &m12, const ScalarType &m13, const ScalarType &m21, const ScalarType &m22, const ScalarType &m23, const ScalarType &m31, const ScalarType &m32, const ScalarType &m33 ); explicit Matrix3x3( const Vector3 vec[3] ); Matrix3x3( const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3 ); explicit Matrix3x3( const ScalarType element[9] ); Matrix3x3( const Matrix3x3 &matrix ); operator ScalarType* ( ); operator const ScalarType* ( ) const; Matrix3x3 & operator = ( const Vector3 vec[3] ); Matrix3x3 & operator = ( const Matrix3x3 &matrix ); Matrix3x3 & operator += ( const Matrix3x3 &matrix ); Matrix3x3 & operator -= ( const Matrix3x3 &matrix ); Matrix3x3 & operator *= ( const ScalarType &scalar ); Matrix3x3 & operator /= ( const ScalarType &scalar ); Matrix3x3 operator + ( const Matrix3x3 &matrix ) const; Matrix3x3 operator - ( const Matrix3x3 &matrix ) const; Matrix3x3 operator * ( const ScalarType &scalar ) const; Matrix3x3 operator / ( const ScalarType &scalar ) const; Matrix3x3 operator - ( ) const; // unary negation ScalarType GetDeterminant( ) const; Matrix3x3 GetAdjoint( ) const; Matrix3x3 GetTranspose( ) const; Matrix3x3 & Transpose( ); Matrix3x3 GetInverse( ) const; Matrix3x3 GetInverse( ScalarType &determinant ) const; Matrix3x3 & Invert( ); Matrix3x3 & Invert( ScalarType &determinant ); Vector3 GetRowVector( unsigned int rowID ) const; Vector3 GetColumnVector( unsigned int colID ) const; }; template struct Matrix4x4 { public: union { ScalarType m[4][4]; struct{ Vector4 v[4]; }; struct{ ScalarType m11, m21, m31, m41, m12, m22, m32, m42, m13, m23, m33, m43, m14, m24, m34, m44; }; ScalarType element[16]; char byte[sizeof(ScalarType[16])]; }; static const Matrix4x4 identity, null; Matrix4x4( ); Matrix4x4( const ScalarType &m11, const ScalarType &m12, const ScalarType &m13, const ScalarType &m14, const ScalarType &m21, const ScalarType &m22, const ScalarType &m23, const ScalarType &m24, const ScalarType &m31, const ScalarType &m32, const ScalarType &m33, const ScalarType &m34, const ScalarType &m41, const ScalarType &m42, const ScalarType &m43, const ScalarType &m44 ); explicit Matrix4x4( const Vector4 vec[4] ); Matrix4x4( const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, const Vector4 &vec4 ); explicit Matrix4x4( const ScalarType element[16] ); Matrix4x4( const Matrix4x4 &matrix ); operator ScalarType* ( ); operator const ScalarType* ( ) const; Matrix4x4 & operator = ( const Vector4 vec[4] ); Matrix4x4 & operator = ( const Matrix4x4 &matrix ); Matrix4x4 & operator += ( const Matrix4x4 &matrix ); Matrix4x4 & operator -= ( const Matrix4x4 &matrix ); Matrix4x4 & operator *= ( const ScalarType &scalar ); Matrix4x4 & operator /= ( const ScalarType &scalar ); Matrix4x4 operator + ( const Matrix4x4 &matrix ) const; Matrix4x4 operator - ( const Matrix4x4 &matrix ) const; Matrix4x4 operator * ( const ScalarType &scalar ) const; Matrix4x4 operator / ( const ScalarType &scalar ) const; Matrix4x4 operator - ( ) const; // unary negation ScalarType GetDeterminant( ) const; Matrix4x4 GetAdjoint( ) const; Matrix4x4 GetTranspose( ) const; Matrix4x4 & Transpose( ); Matrix4x4 GetInverse( ) const; Matrix4x4 GetInverse( ScalarType &determinant ) const; Matrix4x4 & Invert( ); Matrix4x4 & Invert( ScalarType &determinant ); Vector4 GetRowVector( unsigned int rowID ) const; const Vector4 & GetColumnVector( unsigned int colID ) const; }; } template LinearAlgebra::Matrix2x2 operator * ( const ScalarType &left, const LinearAlgebra::Matrix2x2 &right ); template LinearAlgebra::Matrix3x3 operator * ( const ScalarType &left, const LinearAlgebra::Matrix3x3 &right ); template LinearAlgebra::Matrix4x4 operator * ( const ScalarType &left, const LinearAlgebra::Matrix4x4 &right ); /////////////////////////////////////////////////////////////////////////////////// // Body /////////////////////////////////////////////////////////////////////////////////// namespace LinearAlgebra { // Matrix2x2 /////////////////////////////////////// template const Matrix2x2 Matrix2x2::identity = Matrix2x2( 1, 0, 0, 1 ); template const Matrix2x2 Matrix2x2::null = Matrix2x2( 0, 0, 0, 0 ); template Matrix2x2::Matrix2x2( ) : m11(), m21(), m12(), m22() {} template Matrix2x2::Matrix2x2( const ScalarType &_m11, const ScalarType &_m12, const ScalarType &_m21, const ScalarType &_m22 ) { this->m11 = _m11; this->m12 = _m12; this->m21 = _m21; this->m22 = _m22; } template Matrix2x2::Matrix2x2( const Vector2 vec[2] ) { this->v[0] = vec[0]; this->v[1] = vec[1]; } template Matrix2x2::Matrix2x2( const Vector2 &vec1, const Vector2 &vec2 ) { this->v[0] = vec1; this->v[1] = vec2; } template Matrix2x2::Matrix2x2( const ScalarType _element[4] ) { this->m11 = _element[0]; this->m12 = _element[1]; this->m21 = _element[2]; this->m22 = _element[3]; } template Matrix2x2::Matrix2x2( const Matrix2x2 &matrix ) { this->v[0] = matrix.v[0]; this->v[1] = matrix.v[1]; } template inline Matrix2x2::operator ScalarType* ( ) { return this->element; } template inline Matrix2x2::operator const ScalarType* ( ) const { return this->element; } template Matrix2x2 & Matrix2x2::operator = ( const Vector2 vec[2] ) { this->v[0] = vec[0]; this->v[1] = vec[1]; return *this; } template Matrix2x2 & Matrix2x2::operator = ( const Matrix2x2 &matrix ) { this->v[0] = matrix.v[0]; this->v[1] = matrix.v[1]; return *this; } template Matrix2x2 & Matrix2x2::operator += ( const Matrix2x2 &matrix ) { this->v[0] += matrix.v[0]; this->v[1] += matrix.v[1]; return *this; } template Matrix2x2 & Matrix2x2::operator -= ( const Matrix2x2 &matrix ) { this->v[0] -= matrix.v[0]; this->v[1] -= matrix.v[1]; return *this; } template Matrix2x2 & Matrix2x2::operator *= ( const ScalarType &scalar ) { this->v[0] *= scalar; this->v[1] *= scalar; return *this; } template Matrix2x2 & Matrix2x2::operator /= ( const ScalarType &scalar ) { this->v[0] /= scalar; this->v[1] /= scalar; return *this; } template inline Matrix2x2 Matrix2x2::operator + ( const Matrix2x2 &matrix ) const { return Matrix2x2(*this) += matrix; } template inline Matrix2x2 Matrix2x2::operator - ( const Matrix2x2 &matrix ) const { return Matrix2x2(*this) -= matrix; } template inline Matrix2x2 Matrix2x2::operator * ( const ScalarType &scalar ) const { return Matrix2x2(*this) *= scalar; } template inline Matrix2x2 Matrix2x2::operator / ( const ScalarType &scalar ) const { return Matrix2x2(*this) /= scalar; } template inline Matrix2x2 Matrix2x2::operator - ( ) const { return Matrix2x2(-this->v[0], -this->v[1]); } template ScalarType Matrix2x2::GetDeterminant( ) const { ScalarType determinant = (this->m11 * this->m22); return determinant -= (this->m12 * this->m21); } template Matrix2x2 Matrix2x2::GetAdjoint( ) const { return Matrix2x2( this->m22, -this->m21, -this->m12, this->m11 ); } template inline Matrix2x2 Matrix2x2::GetTranspose( ) const { return Matrix2x2( this->element[0], this->element[1], this->element[2], this->element[3] ); } template Matrix2x2 & Matrix2x2::Transpose( ) { ScalarType swapSpace; ::Utility::Element::Swap( this->m12, this->m21, swapSpace ); return *this; } template inline Matrix2x2 Matrix2x2::GetInverse( ) const { return this->GetAdjoint() /= this->GetDeterminant(); } template Matrix2x2 Matrix2x2::GetInverse( ScalarType &determinant ) const { determinant = this->GetDeterminant(); if( determinant != 0 ) return this->GetAdjoint() / determinant; return Matrix2x2::null; } template Matrix2x2 & Matrix2x2::Invert( ) { *this /= this->GetDeterminant(); this->m12 *= -1; this->m21 *= -1; ScalarType swapSpace; Utility::Element::Swap( this->m12, this->m21, swapSpace ); Utility::Element::Swap( this->m11, this->m22, swapSpace ); return *this; } template Matrix2x2 & Matrix2x2::Invert( ScalarType &determinant ) { determinant = this->GetDeterminant(); if( determinant != 0 ) { *this /= determinant; this->m12 *= -1; this->m21 *= -1; ScalarType swapSpace; Utility::Element::Swap( this->m12, this->m21, swapSpace ); Utility::Element::Swap( this->m11, this->m22, swapSpace ); } return *this; } template inline Vector2 Matrix2x2::GetRowVector( unsigned int rowID ) const { return Vector2( this->m[0][rowID], this->m[1][rowID] ); } template inline Vector2 Matrix2x2::GetColumnVector( unsigned int colID ) const { return this->v[colID]; } // Matrix3x3 /////////////////////////////////////// template const Matrix3x3 Matrix3x3::identity = Matrix3x3( 1, 0, 0, 0, 1, 0, 0, 0, 1 ); template const Matrix3x3 Matrix3x3::null = Matrix3x3( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); template Matrix3x3::Matrix3x3( ): m11(), m21(), m31(), m12(), m22(), m32(), m13(), m23(), m33() {} template Matrix3x3::Matrix3x3( const ScalarType &_m11, const ScalarType &_m12, const ScalarType &_m13, const ScalarType &_m21, const ScalarType &_m22, const ScalarType &_m23, const ScalarType &_m31, const ScalarType &_m32, const ScalarType &_m33 ) { this->m11 = _m11; this->m12 = _m12; this->m13 = _m13; this->m21 = _m21; this->m22 = _m22; this->m23 = _m23; this->m31 = _m31; this->m32 = _m32; this->m33 = _m33; } template Matrix3x3::Matrix3x3( const Vector3 vec[3] ) { this->v[0] = vec[0]; this->v[1] = vec[1]; this->v[2] = vec[2]; } template Matrix3x3::Matrix3x3( const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3 ) { this->v[0] = vec1; this->v[1] = vec2; this->v[2] = vec3; } template Matrix3x3::Matrix3x3( const ScalarType _element[9] ) { this->m11 = _element[0]; this->m12 = _element[1]; this->m13 = _element[2]; this->m21 = _element[3]; this->m22 = _element[4]; this->m23 = _element[5]; this->m31 = _element[6]; this->m32 = _element[7]; this->m33 = _element[8]; } template Matrix3x3::Matrix3x3( const Matrix3x3 &matrix ) { this->v[0] = matrix.v[0]; this->v[1] = matrix.v[1]; this->v[2] = matrix.v[2]; } template inline Matrix3x3::operator ScalarType* ( ) { return this->element; } template inline Matrix3x3::operator const ScalarType* ( ) const { return this->element; } template Matrix3x3 & Matrix3x3::operator = ( const Vector3 vec[3] ) { this->v[0] = vec[0]; this->v[1] = vec[1]; this->v[2] = vec[2]; return *this; } template Matrix3x3 & Matrix3x3::operator = ( const Matrix3x3 &matrix ) { this->v[0] = matrix.v[0]; this->v[1] = matrix.v[1]; this->v[2] = matrix.v[2]; return *this; } template Matrix3x3 & Matrix3x3::operator += ( const Matrix3x3 &matrix ) { this->v[0] += matrix.v[0]; this->v[1] += matrix.v[1]; this->v[2] += matrix.v[2]; return *this; } template Matrix3x3 & Matrix3x3::operator -= ( const Matrix3x3 &matrix ) { this->v[0] -= matrix.v[0]; this->v[1] -= matrix.v[1]; this->v[2] -= matrix.v[2]; return *this; } template Matrix3x3 & Matrix3x3::operator *= ( const ScalarType &scalar ) { this->v[0] *= scalar; this->v[1] *= scalar; this->v[2] *= scalar; return *this; } template Matrix3x3 & Matrix3x3::operator /= ( const ScalarType &scalar ) { this->v[0] /= scalar; this->v[1] /= scalar; this->v[2] /= scalar; return *this; } template inline Matrix3x3 Matrix3x3::operator + ( const Matrix3x3 &matrix ) const { return Matrix3x3(*this) += matrix; } template inline Matrix3x3 Matrix3x3::operator - ( const Matrix3x3 &matrix ) const { return Matrix3x3(*this) -= matrix; } template inline Matrix3x3 Matrix3x3::operator * ( const ScalarType &scalar ) const { return Matrix3x3(*this) *= scalar; } template inline Matrix3x3 Matrix3x3::operator / ( const ScalarType &scalar ) const { return Matrix3x3(*this) /= scalar; } template inline Matrix3x3 Matrix3x3::operator - ( ) const { return Matrix3x3(-this->v[0], -this->v[1], -this->v[2]); } template ScalarType Matrix3x3::GetDeterminant( ) const { ScalarType determinant = (this->m11 * this->m22 * this->m33); determinant += (this->m12 * this->m23 * this->m31); determinant += (this->m13 * this->m21 * this->m32); determinant -= (this->m11 * this->m23 * this->m32); determinant -= (this->m12 * this->m21 * this->m33); return determinant -= (this->m13 * this->m22 * this->m31); } template Matrix3x3 Matrix3x3::GetAdjoint( ) const { return Matrix3x3( (this->m22*this->m33 - this->m23*this->m32), (this->m13*this->m32 - this->m12*this->m33), (this->m12*this->m23 - this->m13*this->m22), (this->m23*this->m31 - this->m21*this->m33), (this->m11*this->m33 - this->m13*this->m31), (this->m13*this->m21 - this->m11*this->m23), (this->m21*this->m32 - this->m22*this->m31), (this->m12*this->m31 - this->m11*this->m32), (this->m11*this->m22 - this->m12*this->m21) ); } template inline Matrix3x3 Matrix3x3::GetTranspose( ) const { return Matrix3x3( this->m11, this->m21, this->m31, this->m12, this->m22, this->m32, this->m13, this->m23, this->m33 ); } template Matrix3x3 & Matrix3x3::Transpose( ) { ScalarType swapSpace; Utility::Element::Swap( this->m12, this->m21, swapSpace ); Utility::Element::Swap( this->m13, this->m31, swapSpace ); Utility::Element::Swap( this->m23, this->m32, swapSpace ); return *this; } template Matrix3x3 Matrix3x3::GetInverse( ) const { return this->GetAdjoint() /= this->GetDeterminant(); } template Matrix3x3 Matrix3x3::GetInverse( ScalarType &determinant ) const { determinant = this->GetDeterminant(); if( determinant != 0 ) return this->GetAdjoint() /= determinant; else return Matrix3x3::null; } template Matrix3x3 & Matrix3x3::Invert( ) { return *this = this->GetAdjoint() /= this->GetDeterminant(); } template Matrix3x3 & Matrix3x3::Invert( ScalarType &determinant ) { determinant = this->GetDeterminant(); if( determinant != 0 ) return *this = this->GetAdjoint() /= determinant; return *this; } template inline Vector3 Matrix3x3::GetRowVector( unsigned int rowID ) const { return Vector3( this->m[0][rowID], this->m[1][rowID], this->m[2][rowID] ); } template inline Vector3 Matrix3x3::GetColumnVector( unsigned int colID ) const { return this->v[colID]; } // Matrix4x4 /////////////////////////////////////// template const Matrix4x4 Matrix4x4::identity = Matrix4x4( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); template const Matrix4x4 Matrix4x4::null = Matrix4x4( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); template Matrix4x4::Matrix4x4( ) : m11(), m21(), m31(), m41(), m12(), m22(), m32(), m42(), m13(), m23(), m33(), m43(), m14(), m24(), m34(), m44() {} template Matrix4x4::Matrix4x4( const ScalarType &_m11, const ScalarType &_m12, const ScalarType &_m13, const ScalarType &_m14, const ScalarType &_m21, const ScalarType &_m22, const ScalarType &_m23, const ScalarType &_m24, const ScalarType &_m31, const ScalarType &_m32, const ScalarType &_m33, const ScalarType &_m34, const ScalarType &_m41, const ScalarType &_m42, const ScalarType &_m43, const ScalarType &_m44 ) { this->m11 = _m11; this->m12 = _m12; this->m13 = _m13; this->m14 = _m14; this->m21 = _m21; this->m22 = _m22; this->m23 = _m23; this->m24 = _m24; this->m31 = _m31; this->m32 = _m32; this->m33 = _m33; this->m34 = _m34; this->m41 = _m41; this->m42 = _m42; this->m43 = _m43; this->m44 = _m44; } template Matrix4x4::Matrix4x4( const Vector4 vec[4] ) { this->v[0] = vec[0]; this->v[1] = vec[1]; this->v[2] = vec[2]; this->v[3] = vec[3]; } template Matrix4x4::Matrix4x4( const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, const Vector4 &vec4 ) { this->v[0] = vec1; this->v[1] = vec2; this->v[2] = vec3; this->v[3] = vec4; } template Matrix4x4::Matrix4x4( const ScalarType _element[16] ) { this->m11 = _element[0]; this->m12 = _element[1]; this->m13 = _element[2]; this->m14 = _element[3]; this->m21 = _element[4]; this->m22 = _element[5]; this->m23 = _element[6]; this->m24 = _element[7]; this->m31 = _element[8]; this->m32 = _element[9]; this->m33 = _element[10]; this->m34 = _element[11]; this->m41 = _element[12]; this->m42 = _element[13]; this->m43 = _element[14]; this->m44 = _element[15]; } template Matrix4x4::Matrix4x4( const Matrix4x4 &matrix ) { this->v[0] = matrix.v[0]; this->v[1] = matrix.v[1]; this->v[2] = matrix.v[2]; this->v[3] = matrix.v[3]; } template inline Matrix4x4::operator ScalarType* ( ) { return this->element; } template inline Matrix4x4::operator const ScalarType* ( ) const { return this->element; } template Matrix4x4 & Matrix4x4::operator = ( const Vector4 vec[4] ) { this->v[0] = vec[0]; this->v[1] = vec[1]; this->v[2] = vec[2]; this->v[3] = vec[3]; return *this; } template Matrix4x4 & Matrix4x4::operator = ( const Matrix4x4 &matrix ) { this->v[0] = matrix.v[0]; this->v[1] = matrix.v[1]; this->v[2] = matrix.v[2]; this->v[3] = matrix.v[3]; return *this; } template Matrix4x4 & Matrix4x4::operator += ( const Matrix4x4 &matrix ) { this->v[0] += matrix.v[0]; this->v[1] += matrix.v[1]; this->v[2] += matrix.v[2]; this->v[3] += matrix.v[3]; return *this; } template Matrix4x4 & Matrix4x4::operator -= ( const Matrix4x4 &matrix ) { this->v[0] -= matrix.v[0]; this->v[1] -= matrix.v[1]; this->v[2] -= matrix.v[2]; this->v[3] -= matrix.v[3]; return *this; } template Matrix4x4 & Matrix4x4::operator *= ( const ScalarType &scalar ) { this->v[0] *= scalar; this->v[1] *= scalar; this->v[2] *= scalar; this->v[3] *= scalar; return *this; } template Matrix4x4 & Matrix4x4::operator /= ( const ScalarType &scalar ) { this->v[0] /= scalar; this->v[1] /= scalar; this->v[2] /= scalar; this->v[3] /= scalar; return *this; } template inline Matrix4x4 Matrix4x4::operator + ( const Matrix4x4 &matrix ) const { return Matrix4x4(*this) += matrix; } template inline Matrix4x4 Matrix4x4::operator - ( const Matrix4x4 &matrix ) const { return Matrix4x4(*this) -= matrix; } template inline Matrix4x4 Matrix4x4::operator * ( const ScalarType &scalar ) const { return Matrix4x4(*this) *= scalar; } template inline Matrix4x4 Matrix4x4::operator / ( const ScalarType &scalar ) const { return Matrix4x4(*this) /= scalar; } template inline Matrix4x4 Matrix4x4::operator - ( ) const { return Matrix4x4(-this->v[0], -this->v[1], -this->v[2], -this->v[3]); } template ScalarType Matrix4x4::GetDeterminant( ) const { ScalarType determinant = this->m11 * Matrix3x3(this->m22, this->m23, this->m24, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).GetDeterminant(); determinant -= this->m12 * Matrix3x3(this->m21, this->m23, this->m24, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).GetDeterminant(); determinant += this->m13 * Matrix3x3(this->m21, this->m22, this->m24, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).GetDeterminant(); return determinant -= this->m14 * Matrix3x3(this->m21, this->m22, this->m23, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).GetDeterminant(); } template Matrix4x4 Matrix4x4::GetAdjoint( ) const { return Matrix4x4( Matrix3x3(this->m22, this->m23, this->m24, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).GetDeterminant(), -Matrix3x3(this->m12, this->m13, this->m14, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).GetDeterminant(), Matrix3x3(this->m12, this->m13, this->m14, this->m22, this->m23, this->m24, this->m42, this->m43, this->m44).GetDeterminant(), -Matrix3x3(this->m12, this->m13, this->m14, this->m22, this->m23, this->m24, this->m32, this->m33, this->m34).GetDeterminant(), -Matrix3x3(this->m21, this->m23, this->m24, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).GetDeterminant(), Matrix3x3(this->m11, this->m13, this->m14, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).GetDeterminant(), -Matrix3x3(this->m11, this->m13, this->m14, this->m21, this->m23, this->m24, this->m41, this->m43, this->m44).GetDeterminant(), Matrix3x3(this->m11, this->m13, this->m14, this->m21, this->m23, this->m24, this->m31, this->m33, this->m34).GetDeterminant(), Matrix3x3(this->m21, this->m22, this->m24, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).GetDeterminant(), -Matrix3x3(this->m11, this->m12, this->m14, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).GetDeterminant(), Matrix3x3(this->m11, this->m12, this->m14, this->m21, this->m22, this->m24, this->m41, this->m42, this->m44).GetDeterminant(), -Matrix3x3(this->m11, this->m12, this->m14, this->m21, this->m22, this->m24, this->m31, this->m32, this->m34).GetDeterminant(), -Matrix3x3(this->m21, this->m22, this->m23, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).GetDeterminant(), Matrix3x3(this->m11, this->m12, this->m13, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).GetDeterminant(), -Matrix3x3(this->m11, this->m12, this->m13, this->m21, this->m22, this->m23, this->m41, this->m42, this->m43).GetDeterminant(), Matrix3x3(this->m11, this->m12, this->m13, this->m21, this->m22, this->m23, this->m31, this->m32, this->m33).GetDeterminant() ); } template inline Matrix4x4 Matrix4x4::GetTranspose( ) const { return Matrix4x4( this->m11, this->m21, this->m31, this->m41, this->m12, this->m22, this->m32, this->m42, this->m13, this->m23, this->m33, this->m43, this->m14, this->m24, this->m34, this->m44 ); } template Matrix4x4 & Matrix4x4::Transpose( ) { ScalarType swapSpace; ::Utility::Element::Swap( this->m12, this->m21, swapSpace ); ::Utility::Element::Swap( this->m13, this->m31, swapSpace ); ::Utility::Element::Swap( this->m14, this->m41, swapSpace ); ::Utility::Element::Swap( this->m23, this->m32, swapSpace ); ::Utility::Element::Swap( this->m24, this->m42, swapSpace ); ::Utility::Element::Swap( this->m34, this->m43, swapSpace ); return *this; } template inline Matrix4x4 Matrix4x4::GetInverse( ) const { return this->GetAdjoint() /= this->GetDeterminant() ; } template Matrix4x4 Matrix4x4::GetInverse( ScalarType &determinant ) const { determinant = this->GetDeterminant(); if( determinant != 0.0f ) return this->GetAdjoint() /= determinant; return Matrix4x4::null; } template Matrix4x4 & Matrix4x4::Invert( ) { return *this = this->GetAdjoint() /= this->GetDeterminant(); } template Matrix4x4 & Matrix4x4::Invert( ScalarType &determinant ) { determinant = this->GetDeterminant(); if( determinant != 0.0f ) return *this = this->GetAdjoint() /= determinant; return *this; } template inline Vector4 Matrix4x4::GetRowVector( unsigned int rowID ) const { return Vector4( this->m[0][rowID], this->m[1][rowID], this->m[2][rowID], this->m[3][rowID] ); } template inline const Vector4 & Matrix4x4::GetColumnVector( unsigned int colID ) const { return this->v[colID]; } } template inline LinearAlgebra::Matrix2x2 operator * ( const ScalarType &left, const LinearAlgebra::Matrix2x2 &right ) { return right * left; } template inline LinearAlgebra::Matrix3x3 operator * ( const ScalarType &left, const LinearAlgebra::Matrix3x3 &right ) { return right * left; } template inline LinearAlgebra::Matrix4x4 operator * ( const ScalarType &left, const LinearAlgebra::Matrix4x4 &right ) { return right * left; } #endif