///////////////////////////////////////////////////////////////////// // 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<typename ScalarType> struct Matrix2x2 { public: union { ScalarType m[2][2]; struct{ Vector2<ScalarType> v[2]; }; struct{ ScalarType m11, m21, m12, m22; }; ScalarType element[4]; char byte[sizeof(ScalarType[4])]; }; static const Matrix2x2<ScalarType> identity, null; Matrix2x2( ); Matrix2x2( const ScalarType &m11, const ScalarType &m12, const ScalarType &m21, const ScalarType &m22 ); explicit Matrix2x2( const Vector2<ScalarType> vec[2] ); Matrix2x2( const Vector2<ScalarType> &vec1, const Vector2<ScalarType> &vec2 ); explicit Matrix2x2( const ScalarType element[4] ); Matrix2x2( const Matrix2x2<ScalarType> &matrix ); operator ScalarType* ( ); operator const ScalarType* ( ) const; Matrix2x2<ScalarType> & operator = ( const Vector2<ScalarType> vec[2] ); Matrix2x2<ScalarType> & operator = ( const Matrix2x2<ScalarType> &matrix ); Matrix2x2<ScalarType> & operator += ( const Matrix2x2<ScalarType> &matrix ); Matrix2x2<ScalarType> & operator -= ( const Matrix2x2<ScalarType> &matrix ); Matrix2x2<ScalarType> & operator *= ( const ScalarType &scalar ); Matrix2x2<ScalarType> & operator /= ( const ScalarType &scalar ); Matrix2x2<ScalarType> operator + ( const Matrix2x2<ScalarType> &matrix ) const; Matrix2x2<ScalarType> operator - ( const Matrix2x2<ScalarType> &matrix ) const; Matrix2x2<ScalarType> operator * ( const ScalarType &scalar ) const; Matrix2x2<ScalarType> operator / ( const ScalarType &scalar ) const; Matrix2x2<ScalarType> operator - ( ) const; // unary negation ScalarType GetDeterminant( ) const; Matrix2x2<ScalarType> GetAdjoint( ) const; Matrix2x2<ScalarType> GetTranspose( ) const; Matrix2x2<ScalarType> & Transpose( ); Matrix2x2<ScalarType> GetInverse( ) const; Matrix2x2<ScalarType> GetInverse( ScalarType &determinant ) const; Matrix2x2<ScalarType> & Invert( ); Matrix2x2<ScalarType> & Invert( ScalarType &determinant ); Vector2<ScalarType> GetRowVector( unsigned int rowID ) const; Vector2<ScalarType> GetColumnVector( unsigned int colID ) const; }; template<typename ScalarType> struct Matrix3x3 { public: union { ScalarType m[3][3]; struct{ Vector3<ScalarType> v[3]; }; struct{ ScalarType m11, m21, m31, m12, m22, m32, m13, m23, m33; }; ScalarType element[9]; char byte[sizeof(ScalarType[9])]; }; static const Matrix3x3<ScalarType> 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<ScalarType> vec[3] ); Matrix3x3( const Vector3<ScalarType> &vec1, const Vector3<ScalarType> &vec2, const Vector3<ScalarType> &vec3 ); explicit Matrix3x3( const ScalarType element[9] ); Matrix3x3( const Matrix3x3<ScalarType> &matrix ); operator ScalarType* ( ); operator const ScalarType* ( ) const; Matrix3x3<ScalarType> & operator = ( const Vector3<ScalarType> vec[3] ); Matrix3x3<ScalarType> & operator = ( const Matrix3x3<ScalarType> &matrix ); Matrix3x3<ScalarType> & operator += ( const Matrix3x3<ScalarType> &matrix ); Matrix3x3<ScalarType> & operator -= ( const Matrix3x3<ScalarType> &matrix ); Matrix3x3<ScalarType> & operator *= ( const ScalarType &scalar ); Matrix3x3<ScalarType> & operator /= ( const ScalarType &scalar ); Matrix3x3<ScalarType> operator + ( const Matrix3x3<ScalarType> &matrix ) const; Matrix3x3<ScalarType> operator - ( const Matrix3x3<ScalarType> &matrix ) const; Matrix3x3<ScalarType> operator * ( const ScalarType &scalar ) const; Matrix3x3<ScalarType> operator / ( const ScalarType &scalar ) const; Matrix3x3<ScalarType> operator - ( ) const; // unary negation ScalarType GetDeterminant( ) const; Matrix3x3<ScalarType> GetAdjoint( ) const; Matrix3x3<ScalarType> GetTranspose( ) const; Matrix3x3<ScalarType> & Transpose( ); Matrix3x3<ScalarType> GetInverse( ) const; Matrix3x3<ScalarType> GetInverse( ScalarType &determinant ) const; Matrix3x3<ScalarType> & Invert( ); Matrix3x3<ScalarType> & Invert( ScalarType &determinant ); Vector3<ScalarType> GetRowVector( unsigned int rowID ) const; Vector3<ScalarType> GetColumnVector( unsigned int colID ) const; }; template<typename ScalarType> struct Matrix4x4 { public: union { ScalarType m[4][4]; struct{ Vector4<ScalarType> 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<ScalarType> 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<ScalarType> vec[4] ); Matrix4x4( const Vector4<ScalarType> &vec1, const Vector4<ScalarType> &vec2, const Vector4<ScalarType> &vec3, const Vector4<ScalarType> &vec4 ); explicit Matrix4x4( const ScalarType element[16] ); Matrix4x4( const Matrix4x4<ScalarType> &matrix ); operator ScalarType* ( ); operator const ScalarType* ( ) const; Matrix4x4<ScalarType> & operator = ( const Vector4<ScalarType> vec[4] ); Matrix4x4<ScalarType> & operator = ( const Matrix4x4<ScalarType> &matrix ); Matrix4x4<ScalarType> & operator += ( const Matrix4x4<ScalarType> &matrix ); Matrix4x4<ScalarType> & operator -= ( const Matrix4x4<ScalarType> &matrix ); Matrix4x4<ScalarType> & operator *= ( const ScalarType &scalar ); Matrix4x4<ScalarType> & operator /= ( const ScalarType &scalar ); Matrix4x4<ScalarType> operator + ( const Matrix4x4<ScalarType> &matrix ) const; Matrix4x4<ScalarType> operator - ( const Matrix4x4<ScalarType> &matrix ) const; Matrix4x4<ScalarType> operator * ( const ScalarType &scalar ) const; Matrix4x4<ScalarType> operator / ( const ScalarType &scalar ) const; Matrix4x4<ScalarType> operator - ( ) const; // unary negation ScalarType GetDeterminant( ) const; Matrix4x4<ScalarType> GetAdjoint( ) const; Matrix4x4<ScalarType> GetTranspose( ) const; Matrix4x4<ScalarType> & Transpose( ); Matrix4x4<ScalarType> GetInverse( ) const; Matrix4x4<ScalarType> GetInverse( ScalarType &determinant ) const; Matrix4x4<ScalarType> & Invert( ); Matrix4x4<ScalarType> & Invert( ScalarType &determinant ); Vector4<ScalarType> GetRowVector( unsigned int rowID ) const; const Vector4<ScalarType> & GetColumnVector( unsigned int colID ) const; }; /////////////////////////////////////////////////////////////////////////////////// // Body /////////////////////////////////////////////////////////////////////////////////// // Matrix2x2<ScalarType> /////////////////////////////////////// template<typename ScalarType> const Matrix2x2<ScalarType> Matrix2x2<ScalarType>::identity = Matrix2x2<ScalarType>( 1, 0, 0, 1 ); template<typename ScalarType> const Matrix2x2<ScalarType> Matrix2x2<ScalarType>::null = Matrix2x2<ScalarType>( 0, 0, 0, 0 ); template<typename ScalarType> Matrix2x2<ScalarType>::Matrix2x2( ) : m11(), m21(), m12(), m22() {} template<typename ScalarType> Matrix2x2<ScalarType>::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<typename ScalarType> Matrix2x2<ScalarType>::Matrix2x2( const Vector2<ScalarType> vec[2] ) { this->v[0] = vec[0]; this->v[1] = vec[1]; } template<typename ScalarType> Matrix2x2<ScalarType>::Matrix2x2( const Vector2<ScalarType> &vec1, const Vector2<ScalarType> &vec2 ) { this->v[0] = vec1; this->v[1] = vec2; } template<typename ScalarType> Matrix2x2<ScalarType>::Matrix2x2( const ScalarType _element[4] ) { this->m11 = _element[0]; this->m12 = _element[1]; this->m21 = _element[2]; this->m22 = _element[3]; } template<typename ScalarType> Matrix2x2<ScalarType>::Matrix2x2( const Matrix2x2<ScalarType> &matrix ) { this->v[0] = matrix.v[0]; this->v[1] = matrix.v[1]; } template<typename ScalarType> inline Matrix2x2<ScalarType>::operator ScalarType* ( ) { return this->element; } template<typename ScalarType> inline Matrix2x2<ScalarType>::operator const ScalarType* ( ) const { return this->element; } template<typename ScalarType> Matrix2x2<ScalarType> & Matrix2x2<ScalarType>::operator = ( const Vector2<ScalarType> vec[2] ) { this->v[0] = vec[0]; this->v[1] = vec[1]; return *this; } template<typename ScalarType> Matrix2x2<ScalarType> & Matrix2x2<ScalarType>::operator = ( const Matrix2x2<ScalarType> &matrix ) { this->v[0] = matrix.v[0]; this->v[1] = matrix.v[1]; return *this; } template<typename ScalarType> Matrix2x2<ScalarType> & Matrix2x2<ScalarType>::operator += ( const Matrix2x2<ScalarType> &matrix ) { this->v[0] += matrix.v[0]; this->v[1] += matrix.v[1]; return *this; } template<typename ScalarType> Matrix2x2<ScalarType> & Matrix2x2<ScalarType>::operator -= ( const Matrix2x2<ScalarType> &matrix ) { this->v[0] -= matrix.v[0]; this->v[1] -= matrix.v[1]; return *this; } template<typename ScalarType> Matrix2x2<ScalarType> & Matrix2x2<ScalarType>::operator *= ( const ScalarType &scalar ) { this->v[0] *= scalar; this->v[1] *= scalar; return *this; } template<typename ScalarType> Matrix2x2<ScalarType> & Matrix2x2<ScalarType>::operator /= ( const ScalarType &scalar ) { this->v[0] /= scalar; this->v[1] /= scalar; return *this; } template<typename ScalarType> inline Matrix2x2<ScalarType> Matrix2x2<ScalarType>::operator + ( const Matrix2x2<ScalarType> &matrix ) const { return Matrix2x2<ScalarType>(*this) += matrix; } template<typename ScalarType> inline Matrix2x2<ScalarType> Matrix2x2<ScalarType>::operator - ( const Matrix2x2<ScalarType> &matrix ) const { return Matrix2x2<ScalarType>(*this) -= matrix; } template<typename ScalarType> inline Matrix2x2<ScalarType> Matrix2x2<ScalarType>::operator * ( const ScalarType &scalar ) const { return Matrix2x2<ScalarType>(*this) *= scalar; } template<typename ScalarType> inline Matrix2x2<ScalarType> Matrix2x2<ScalarType>::operator / ( const ScalarType &scalar ) const { return Matrix2x2<ScalarType>(*this) /= scalar; } template<typename ScalarType> inline Matrix2x2<ScalarType> Matrix2x2<ScalarType>::operator - ( ) const { return Matrix2x2<ScalarType>(-this->v[0], -this->v[1]); } template<typename ScalarType> ScalarType Matrix2x2<ScalarType>::GetDeterminant( ) const { ScalarType determinant = (this->m11 * this->m22); return determinant -= (this->m12 * this->m21); } template<typename ScalarType> Matrix2x2<ScalarType> Matrix2x2<ScalarType>::GetAdjoint( ) const { return Matrix2x2<ScalarType>( this->m22, -this->m21, -this->m12, this->m11 ); } template<typename ScalarType> inline Matrix2x2<ScalarType> Matrix2x2<ScalarType>::GetTranspose( ) const { return Matrix2x2<ScalarType>( this->element[0], this->element[1], this->element[2], this->element[3] ); } template<typename ScalarType> Matrix2x2<ScalarType> & Matrix2x2<ScalarType>::Transpose( ) { ScalarType swapSpace; ::Utility::Element::Swap( this->m12, this->m21, swapSpace ); return *this; } template<typename ScalarType> inline Matrix2x2<ScalarType> Matrix2x2<ScalarType>::GetInverse( ) const { return this->GetAdjoint() /= this->GetDeterminant(); } template<typename ScalarType> Matrix2x2<ScalarType> Matrix2x2<ScalarType>::GetInverse( ScalarType &determinant ) const { determinant = this->GetDeterminant(); if( determinant != 0 ) return this->GetAdjoint() / determinant; return Matrix2x2<ScalarType>::null; } template<typename ScalarType> Matrix2x2<ScalarType> & Matrix2x2<ScalarType>::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<typename ScalarType> Matrix2x2<ScalarType> & Matrix2x2<ScalarType>::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<typename ScalarType> inline Vector2<ScalarType> Matrix2x2<ScalarType>::GetRowVector( unsigned int rowID ) const { return Vector2<ScalarType>( this->m[0][rowID], this->m[1][rowID] ); } template<typename ScalarType> inline Vector2<ScalarType> Matrix2x2<ScalarType>::GetColumnVector( unsigned int colID ) const { return this->v[colID]; } // Matrix3x3<ScalarType> /////////////////////////////////////// template<typename ScalarType> const Matrix3x3<ScalarType> Matrix3x3<ScalarType>::identity = Matrix3x3<ScalarType>( 1, 0, 0, 0, 1, 0, 0, 0, 1 ); template<typename ScalarType> const Matrix3x3<ScalarType> Matrix3x3<ScalarType>::null = Matrix3x3<ScalarType>( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); template<typename ScalarType> Matrix3x3<ScalarType>::Matrix3x3( ): m11(), m21(), m31(), m12(), m22(), m32(), m13(), m23(), m33() {} template<typename ScalarType> Matrix3x3<ScalarType>::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<typename ScalarType> Matrix3x3<ScalarType>::Matrix3x3( const Vector3<ScalarType> vec[3] ) { this->v[0] = vec[0]; this->v[1] = vec[1]; this->v[2] = vec[2]; } template<typename ScalarType> Matrix3x3<ScalarType>::Matrix3x3( const Vector3<ScalarType> &vec1, const Vector3<ScalarType> &vec2, const Vector3<ScalarType> &vec3 ) { this->v[0] = vec1; this->v[1] = vec2; this->v[2] = vec3; } template<typename ScalarType> Matrix3x3<ScalarType>::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<typename ScalarType> Matrix3x3<ScalarType>::Matrix3x3( const Matrix3x3<ScalarType> &matrix ) { this->v[0] = matrix.v[0]; this->v[1] = matrix.v[1]; this->v[2] = matrix.v[2]; } template<typename ScalarType> inline Matrix3x3<ScalarType>::operator ScalarType* ( ) { return this->element; } template<typename ScalarType> inline Matrix3x3<ScalarType>::operator const ScalarType* ( ) const { return this->element; } template<typename ScalarType> Matrix3x3<ScalarType> & Matrix3x3<ScalarType>::operator = ( const Vector3<ScalarType> vec[3] ) { this->v[0] = vec[0]; this->v[1] = vec[1]; this->v[2] = vec[2]; return *this; } template<typename ScalarType> Matrix3x3<ScalarType> & Matrix3x3<ScalarType>::operator = ( const Matrix3x3<ScalarType> &matrix ) { this->v[0] = matrix.v[0]; this->v[1] = matrix.v[1]; this->v[2] = matrix.v[2]; return *this; } template<typename ScalarType> Matrix3x3<ScalarType> & Matrix3x3<ScalarType>::operator += ( const Matrix3x3<ScalarType> &matrix ) { this->v[0] += matrix.v[0]; this->v[1] += matrix.v[1]; this->v[2] += matrix.v[2]; return *this; } template<typename ScalarType> Matrix3x3<ScalarType> & Matrix3x3<ScalarType>::operator -= ( const Matrix3x3<ScalarType> &matrix ) { this->v[0] -= matrix.v[0]; this->v[1] -= matrix.v[1]; this->v[2] -= matrix.v[2]; return *this; } template<typename ScalarType> Matrix3x3<ScalarType> & Matrix3x3<ScalarType>::operator *= ( const ScalarType &scalar ) { this->v[0] *= scalar; this->v[1] *= scalar; this->v[2] *= scalar; return *this; } template<typename ScalarType> Matrix3x3<ScalarType> & Matrix3x3<ScalarType>::operator /= ( const ScalarType &scalar ) { this->v[0] /= scalar; this->v[1] /= scalar; this->v[2] /= scalar; return *this; } template<typename ScalarType> inline Matrix3x3<ScalarType> Matrix3x3<ScalarType>::operator + ( const Matrix3x3<ScalarType> &matrix ) const { return Matrix3x3<ScalarType>(*this) += matrix; } template<typename ScalarType> inline Matrix3x3<ScalarType> Matrix3x3<ScalarType>::operator - ( const Matrix3x3<ScalarType> &matrix ) const { return Matrix3x3<ScalarType>(*this) -= matrix; } template<typename ScalarType> inline Matrix3x3<ScalarType> Matrix3x3<ScalarType>::operator * ( const ScalarType &scalar ) const { return Matrix3x3<ScalarType>(*this) *= scalar; } template<typename ScalarType> inline Matrix3x3<ScalarType> Matrix3x3<ScalarType>::operator / ( const ScalarType &scalar ) const { return Matrix3x3<ScalarType>(*this) /= scalar; } template<typename ScalarType> inline Matrix3x3<ScalarType> Matrix3x3<ScalarType>::operator - ( ) const { return Matrix3x3<ScalarType>(-this->v[0], -this->v[1], -this->v[2]); } template<typename ScalarType> ScalarType Matrix3x3<ScalarType>::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<typename ScalarType> Matrix3x3<ScalarType> Matrix3x3<ScalarType>::GetAdjoint( ) const { return Matrix3x3<ScalarType>( (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<typename ScalarType> inline Matrix3x3<ScalarType> Matrix3x3<ScalarType>::GetTranspose( ) const { return Matrix3x3<ScalarType>( this->m11, this->m21, this->m31, this->m12, this->m22, this->m32, this->m13, this->m23, this->m33 ); } template<typename ScalarType> Matrix3x3<ScalarType> & Matrix3x3<ScalarType>::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<typename ScalarType> Matrix3x3<ScalarType> Matrix3x3<ScalarType>::GetInverse( ) const { return this->GetAdjoint() /= this->GetDeterminant(); } template<typename ScalarType> Matrix3x3<ScalarType> Matrix3x3<ScalarType>::GetInverse( ScalarType &determinant ) const { determinant = this->GetDeterminant(); if( determinant != 0 ) return this->GetAdjoint() /= determinant; else return Matrix3x3<ScalarType>::null; } template<typename ScalarType> Matrix3x3<ScalarType> & Matrix3x3<ScalarType>::Invert( ) { return *this = this->GetAdjoint() /= this->GetDeterminant(); } template<typename ScalarType> Matrix3x3<ScalarType> & Matrix3x3<ScalarType>::Invert( ScalarType &determinant ) { determinant = this->GetDeterminant(); if( determinant != 0 ) return *this = this->GetAdjoint() /= determinant; return *this; } template<typename ScalarType> inline Vector3<ScalarType> Matrix3x3<ScalarType>::GetRowVector( unsigned int rowID ) const { return Vector3<ScalarType>( this->m[0][rowID], this->m[1][rowID], this->m[2][rowID] ); } template<typename ScalarType> inline Vector3<ScalarType> Matrix3x3<ScalarType>::GetColumnVector( unsigned int colID ) const { return this->v[colID]; } // Matrix4x4<ScalarType> /////////////////////////////////////// template<typename ScalarType> const Matrix4x4<ScalarType> Matrix4x4<ScalarType>::identity = Matrix4x4<ScalarType>( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); template<typename ScalarType> const Matrix4x4<ScalarType> Matrix4x4<ScalarType>::null = Matrix4x4<ScalarType>( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); template<typename ScalarType> Matrix4x4<ScalarType>::Matrix4x4( ) : m11(), m21(), m31(), m41(), m12(), m22(), m32(), m42(), m13(), m23(), m33(), m43(), m14(), m24(), m34(), m44() {} template<typename ScalarType> Matrix4x4<ScalarType>::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<typename ScalarType> Matrix4x4<ScalarType>::Matrix4x4( const Vector4<ScalarType> vec[4] ) { this->v[0] = vec[0]; this->v[1] = vec[1]; this->v[2] = vec[2]; this->v[3] = vec[3]; } template<typename ScalarType> Matrix4x4<ScalarType>::Matrix4x4( const Vector4<ScalarType> &vec1, const Vector4<ScalarType> &vec2, const Vector4<ScalarType> &vec3, const Vector4<ScalarType> &vec4 ) { this->v[0] = vec1; this->v[1] = vec2; this->v[2] = vec3; this->v[3] = vec4; } template<typename ScalarType> Matrix4x4<ScalarType>::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<typename ScalarType> Matrix4x4<ScalarType>::Matrix4x4( const Matrix4x4<ScalarType> &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<typename ScalarType> inline Matrix4x4<ScalarType>::operator ScalarType* ( ) { return this->element; } template<typename ScalarType> inline Matrix4x4<ScalarType>::operator const ScalarType* ( ) const { return this->element; } template<typename ScalarType> Matrix4x4<ScalarType> & Matrix4x4<ScalarType>::operator = ( const Vector4<ScalarType> 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<typename ScalarType> Matrix4x4<ScalarType> & Matrix4x4<ScalarType>::operator = ( const Matrix4x4<ScalarType> &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<typename ScalarType> Matrix4x4<ScalarType> & Matrix4x4<ScalarType>::operator += ( const Matrix4x4<ScalarType> &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<typename ScalarType> Matrix4x4<ScalarType> & Matrix4x4<ScalarType>::operator -= ( const Matrix4x4<ScalarType> &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<typename ScalarType> Matrix4x4<ScalarType> & Matrix4x4<ScalarType>::operator *= ( const ScalarType &scalar ) { this->v[0] *= scalar; this->v[1] *= scalar; this->v[2] *= scalar; this->v[3] *= scalar; return *this; } template<typename ScalarType> Matrix4x4<ScalarType> & Matrix4x4<ScalarType>::operator /= ( const ScalarType &scalar ) { this->v[0] /= scalar; this->v[1] /= scalar; this->v[2] /= scalar; this->v[3] /= scalar; return *this; } template<typename ScalarType> inline Matrix4x4<ScalarType> Matrix4x4<ScalarType>::operator + ( const Matrix4x4<ScalarType> &matrix ) const { return Matrix4x4<ScalarType>(*this) += matrix; } template<typename ScalarType> inline Matrix4x4<ScalarType> Matrix4x4<ScalarType>::operator - ( const Matrix4x4<ScalarType> &matrix ) const { return Matrix4x4<ScalarType>(*this) -= matrix; } template<typename ScalarType> inline Matrix4x4<ScalarType> Matrix4x4<ScalarType>::operator * ( const ScalarType &scalar ) const { return Matrix4x4<ScalarType>(*this) *= scalar; } template<typename ScalarType> inline Matrix4x4<ScalarType> Matrix4x4<ScalarType>::operator / ( const ScalarType &scalar ) const { return Matrix4x4<ScalarType>(*this) /= scalar; } template<typename ScalarType> inline Matrix4x4<ScalarType> Matrix4x4<ScalarType>::operator - ( ) const { return Matrix4x4<ScalarType>(-this->v[0], -this->v[1], -this->v[2], -this->v[3]); } template<typename ScalarType> ScalarType Matrix4x4<ScalarType>::GetDeterminant( ) const { ScalarType determinant = this->m11 * Matrix3x3<ScalarType>(this->m22, this->m23, this->m24, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).GetDeterminant(); determinant -= this->m12 * Matrix3x3<ScalarType>(this->m21, this->m23, this->m24, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).GetDeterminant(); determinant += this->m13 * Matrix3x3<ScalarType>(this->m21, this->m22, this->m24, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).GetDeterminant(); return determinant -= this->m14 * Matrix3x3<ScalarType>(this->m21, this->m22, this->m23, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).GetDeterminant(); } template<typename ScalarType> Matrix4x4<ScalarType> Matrix4x4<ScalarType>::GetAdjoint( ) const { return Matrix4x4<ScalarType>( Matrix3x3<ScalarType>(this->m22, this->m23, this->m24, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).GetDeterminant(), -Matrix3x3<ScalarType>(this->m12, this->m13, this->m14, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).GetDeterminant(), Matrix3x3<ScalarType>(this->m12, this->m13, this->m14, this->m22, this->m23, this->m24, this->m42, this->m43, this->m44).GetDeterminant(), -Matrix3x3<ScalarType>(this->m12, this->m13, this->m14, this->m22, this->m23, this->m24, this->m32, this->m33, this->m34).GetDeterminant(), -Matrix3x3<ScalarType>(this->m21, this->m23, this->m24, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).GetDeterminant(), Matrix3x3<ScalarType>(this->m11, this->m13, this->m14, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).GetDeterminant(), -Matrix3x3<ScalarType>(this->m11, this->m13, this->m14, this->m21, this->m23, this->m24, this->m41, this->m43, this->m44).GetDeterminant(), Matrix3x3<ScalarType>(this->m11, this->m13, this->m14, this->m21, this->m23, this->m24, this->m31, this->m33, this->m34).GetDeterminant(), Matrix3x3<ScalarType>(this->m21, this->m22, this->m24, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).GetDeterminant(), -Matrix3x3<ScalarType>(this->m11, this->m12, this->m14, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).GetDeterminant(), Matrix3x3<ScalarType>(this->m11, this->m12, this->m14, this->m21, this->m22, this->m24, this->m41, this->m42, this->m44).GetDeterminant(), -Matrix3x3<ScalarType>(this->m11, this->m12, this->m14, this->m21, this->m22, this->m24, this->m31, this->m32, this->m34).GetDeterminant(), -Matrix3x3<ScalarType>(this->m21, this->m22, this->m23, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).GetDeterminant(), Matrix3x3<ScalarType>(this->m11, this->m12, this->m13, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).GetDeterminant(), -Matrix3x3<ScalarType>(this->m11, this->m12, this->m13, this->m21, this->m22, this->m23, this->m41, this->m42, this->m43).GetDeterminant(), Matrix3x3<ScalarType>(this->m11, this->m12, this->m13, this->m21, this->m22, this->m23, this->m31, this->m32, this->m33).GetDeterminant() ); } template<typename ScalarType> inline Matrix4x4<ScalarType> Matrix4x4<ScalarType>::GetTranspose( ) const { return Matrix4x4<ScalarType>( 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<typename ScalarType> Matrix4x4<ScalarType> & Matrix4x4<ScalarType>::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<typename ScalarType> inline Matrix4x4<ScalarType> Matrix4x4<ScalarType>::GetInverse( ) const { return this->GetAdjoint() /= this->GetDeterminant() ; } template<typename ScalarType> Matrix4x4<ScalarType> Matrix4x4<ScalarType>::GetInverse( ScalarType &determinant ) const { determinant = this->GetDeterminant(); if( determinant != 0.0f ) return this->GetAdjoint() /= determinant; return Matrix4x4<ScalarType>::null; } template<typename ScalarType> Matrix4x4<ScalarType> & Matrix4x4<ScalarType>::Invert( ) { return *this = this->GetAdjoint() /= this->GetDeterminant(); } template<typename ScalarType> Matrix4x4<ScalarType> & Matrix4x4<ScalarType>::Invert( ScalarType &determinant ) { determinant = this->GetDeterminant(); if( determinant != 0.0f ) return *this = this->GetAdjoint() /= determinant; return *this; } template<typename ScalarType> inline Vector4<ScalarType> Matrix4x4<ScalarType>::GetRowVector( unsigned int rowID ) const { return Vector4<ScalarType>( this->m[0][rowID], this->m[1][rowID], this->m[2][rowID], this->m[3][rowID] ); } template<typename ScalarType> inline const Vector4<ScalarType> & Matrix4x4<ScalarType>::GetColumnVector( unsigned int colID ) const { return this->v[colID]; } } #endif