From e6af555b152d01a561526bc8c5515338cec464fe Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Thu, 13 Dec 2012 22:48:16 +0100 Subject: [PATCH] [DEV] update matrix4 --- etk/math/Matrix4.cpp | 60 ++++++++++++++++++++++++++-- etk/math/Matrix4.h | 93 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 143 insertions(+), 10 deletions(-) diff --git a/etk/math/Matrix4.cpp b/etk/math/Matrix4.cpp index 02b8a58..4760c33 100644 --- a/etk/math/Matrix4.cpp +++ b/etk/math/Matrix4.cpp @@ -11,7 +11,7 @@ #include #include -etk::Matrix4 etk::Matrix4::Perspective(float left, float right, float bottom, float top, float nearVal, float farVal) +etk::Matrix4 etk::matPerspective(float left, float right, float bottom, float top, float nearVal, float farVal) { etk::Matrix4 tmp; for(int32_t iii=0; iii<4*4 ; iii++) { @@ -29,7 +29,7 @@ etk::Matrix4 etk::Matrix4::Perspective(float left, float right, float bottom, fl return tmp; } -etk::Matrix4 etk::Matrix4::Translate(etk::Vector3D vect) +etk::Matrix4 etk::matTranslate(etk::Vector3D vect) { etk::Matrix4 tmp; // set translation : @@ -41,7 +41,7 @@ etk::Matrix4 etk::Matrix4::Translate(etk::Vector3D vect) return tmp; } -etk::Matrix4 etk::Matrix4::Scale(etk::Vector3D vect) +etk::Matrix4 etk::matScale(etk::Vector3D vect) { etk::Matrix4 tmp; // set scale : @@ -53,7 +53,7 @@ etk::Matrix4 etk::Matrix4::Scale(etk::Vector3D vect) return tmp; } -etk::Matrix4 etk::Matrix4::Rotate(etk::Vector3D vect, float angleRad) +etk::Matrix4 etk::matRotate(etk::Vector3D vect, float angleRad) { etk::Matrix4 tmp; float cosVal = cos(angleRad); @@ -74,6 +74,58 @@ etk::Matrix4 etk::Matrix4::Rotate(etk::Vector3D vect, float angleRad) return tmp; } + + +float etk::Matrix4::CoFactor(int32_t row, int32_t col) const +{ + return ( ( m_mat[((row+1)&3)*4 + ((col+1)&3)] * m_mat[((row+2)&3)*4 + ((col+2)&3)] * m_mat[((row+3)&3)*4 + ((col+3)&3)] + + m_mat[((row+1)&3)*4 + ((col+2)&3)] * m_mat[((row+2)&3)*4 + ((col+3)&3)] * m_mat[((row+3)&3)*4 + ((col+1)&3)] + + m_mat[((row+1)&3)*4 + ((col+3)&3)] * m_mat[((row+2)&3)*4 + ((col+1)&3)] * m_mat[((row+3)&3)*4 + ((col+2)&3)] ) + - ( m_mat[((row+3)&3)*4 + ((col+1)&3)] * m_mat[((row+2)&3)*4 + ((col+2)&3)] * m_mat[((row+1)&3)*4 + ((col+3)&3)] + + m_mat[((row+3)&3)*4 + ((col+2)&3)] * m_mat[((row+2)&3)*4 + ((col+3)&3)] * m_mat[((row+1)&3)*4 + ((col+1)&3)] + + m_mat[((row+3)&3)*4 + ((col+3)&3)] * m_mat[((row+2)&3)*4 + ((col+1)&3)] * m_mat[((row+1)&3)*4 + ((col+2)&3)] ) + ) * ((row + col) & 1 ? -1.0f : +1.0f); +} + + +float etk::Matrix4::Determinant() const +{ + return m_mat[0] * CoFactor(0, 0) + + m_mat[1] * CoFactor(0, 1) + + m_mat[2] * CoFactor(0, 2) + + m_mat[3] * CoFactor(0, 3); +} + + +etk::Matrix4 etk::Matrix4::Invert() +{ + float det = Determinant(); + if(fabsf(det) < (1.0e-7f)) { + // The matrix is not invertible! Singular case! + return *this; + } + etk::Matrix4 temp; + float iDet = 1.0f / det; + temp.m_mat[0] = CoFactor(0,0) * iDet; + temp.m_mat[1] = CoFactor(0,1) * iDet; + temp.m_mat[2] = CoFactor(0,2) * iDet; + temp.m_mat[3] = CoFactor(0,3) * iDet; + temp.m_mat[4] = CoFactor(1,0) * iDet; + temp.m_mat[5] = CoFactor(1,1) * iDet; + temp.m_mat[6] = CoFactor(1,2) * iDet; + temp.m_mat[7] = CoFactor(1,3) * iDet; + temp.m_mat[8] = CoFactor(2,0) * iDet; + temp.m_mat[9] = CoFactor(2,1) * iDet; + temp.m_mat[10] = CoFactor(2,2) * iDet; + temp.m_mat[11] = CoFactor(2,3) * iDet; + temp.m_mat[12] = CoFactor(3,0) * iDet; + temp.m_mat[13] = CoFactor(3,1) * iDet; + temp.m_mat[14] = CoFactor(3,2) * iDet; + temp.m_mat[15] = CoFactor(3,3) * iDet; + return temp; +} + + etk::CCout& etk::operator <<(etk::CCout &os, const etk::Matrix4 obj) { os << "matrix4 : ("; diff --git a/etk/math/Matrix4.h b/etk/math/Matrix4.h index e077fc7..b656c60 100644 --- a/etk/math/Matrix4.h +++ b/etk/math/Matrix4.h @@ -174,6 +174,12 @@ namespace etk tmpp *= obj; return tmpp; } + vec3 operator*(const vec3& point) const + { + return vec3( m_mat[0]*point.x + m_mat[1]*point.y + m_mat[2]*point.z + m_mat[3], + m_mat[4]*point.x + m_mat[5]*point.y + m_mat[6]*point.z + m_mat[7], + m_mat[8]*point.x + m_mat[9]*point.y + m_mat[10]*point.z + m_mat[11] ); + } /***************************************************** * other basic function : *****************************************************/ @@ -202,14 +208,89 @@ namespace etk tmpVal = m_mat[11]; m_mat[11] = m_mat[14]; m_mat[14] = tmpVal; - } - public: - static Matrix4 Perspective(float left, float right, float bottom, float top, float nearVal, float farVal); - static Matrix4 Translate(etk::Vector3D vect); - static Matrix4 Scale(etk::Vector3D vect); - static Matrix4 Rotate(etk::Vector3D vect, float angleRad=0.0); + void Scale(const vec3& p) + { + Scale(p.x, p.y, p.z); + } + void Scale(float sx, float sy, float sz) + { + m_mat[0] *= sx; m_mat[1] *= sy; m_mat[2] *= sz; + m_mat[4] *= sx; m_mat[5] *= sy; m_mat[6] *= sz; + m_mat[8] *= sx; m_mat[9] *= sy; m_mat[10] *= sz; + } + #if 0 + /** + * @brief Sets a rotation matrix around the X axis. + * @param[in] angleRad Angle to rotate in radian. + */ + void RotateX(float angleRad) + { + float Cos = cosf(angleRad); + float Sin = sinf(angleRad); + Identity(); + m_mat[5] = m_mat[10] = Cos; + m_mat[9] = -Sin; + m_mat[6] = Sin; + } + /** + * @brief Sets a rotation matrix around the Y axis. + * @param[in] angleRad Angle to rotate in radian. + */ + void RotateY(float angleRad) + { + float Cos = cosf(angleRad); + float Sin = sinf(angleRad); + Identity(); + m_mat[0] = m_mat[10] = Cos; + m_mat[8] = Sin; + m_mat[2] = -Sin; + } + /** + * @brief Sets a rotation matrix around the Z axis. + * @param[in] angleRad Angle to rotate in radian. + */ + void RotateZ(float angleRad) + { + float Cos = cosf(angle); + float Sin = sinf(angle); + Identity(); + m_mat[0] = m_mat[9] = Cos; + m_mat[4] = -Sin; + m_mat[1] = Sin; + } + + /** + * @brief Makes a rotation matrix about an arbitrary axis. + * @param[in] vect vector to apply the angle. + * @param[in] angleRad angle to apply. + */ + void Rotate(etk::Vector3D vect, float angleRad=0.0); +#endif + + /** + * @brief Computes a cofactor. Used for matrix inversion. + * @param[in] row Id of raw. + * @param[in] col Id of colomn. + * @return the coFactorValue. + */ + float CoFactor(int32_t row, int32_t col) const; + /** + * @brief Computes the determinant of the matrix. + * @return The determinent Value. + */ + float Determinant(void) const; + /** + * @brief Inverts the matrix. + * @note The determinant must be != 0, otherwithe the matrix can't be inverted. + * @return The inverted matrix. + */ + Matrix4 Invert(void); }; + Matrix4 matPerspective(float left, float right, float bottom, float top, float nearVal, float farVal); + Matrix4 matTranslate(etk::Vector3D vect); + Matrix4 matScale(etk::Vector3D vect); + Matrix4 matRotate(etk::Vector3D vect, float angleRad=0.0); /** * @brief Debug operator To display the curent element in a Human redeable information */