Okay I uncomment *this = identity(); in scale and in translation.
if I perform
Mat4d m = Mat4d(....);
m.rotateXAxis(180.0);
m.scale(3.0, 3.0, 3.0);
m.translate(-4.5, 3.4, 1.0);
I wanna perform it that way. But calling scale resets the matrix and makes rotateXAxis useless, and when translate gets called it overrides the scale. And that's why I was ponding if I needed to do that. But even if I comment it it will still be overridden the current matrix.
I want try and make it perform that way. And I that was why I was asking if I do mat[0] *= _x;. Since it multiplies the current matrix value with _x then saves it back into it, and returns with *this.
Here's the full matrix class.
#ifndef MATRIX_H_#define MATRIX_H_#include <iostream>#include <tr1/array>#include <cassert>#include <algorithm>#include "Vector.h"#include "Math.h"#define MAT_INLINE __attribute__((always_inline))template<typename _type> class Vec2;template<typename _type> class Vec3;template<typename _type> class Vec4;template<typename _type> class Math;template<typename _type>//! A Matrix 4x4 math classclass Mat4{public: //! Anonymous union union { //! Anonymous struct struct { _type m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44; }; //! Matrix array /*! Holds the matrix data in this array for easy access. Sharing data with the m11 ... m44 variables. */ std::tr1::array<_type, 16> mat; }; //! Explicit default constructor explicit Mat4() { // Set to identity *this = identity(); } //! Explicit constructor /*! Follows the OpenGL matrix style. \f$ \left[\begin{array}{cccc} m11 & m21 & m31 & m41\ m12 & m22 & m32 & m42\ m13 & m23 & m33 & m43\ m14 & m24 & m34 & m44\end{array} \right] \f$ \param m11 mat[0] \param m21 mat[4] \param m31 mat[8] \param m41 mat[12] \param m12 mat[1] \param m22 mat[5] \param m32 mat[9] \param m42 mat[13] \param m13 mat[2] \param m23 mat[6] \param m33 mat[10] \param m34 mat[14] \param m14 mat[3] \param m24 mat[7] \param m34 mat[11] \param m44 mat[15] */ explicit Mat4(_type m11, _type m21, _type m31, _type m41, _type m12, _type m22, _type m32, _type m42, _type m13, _type m23, _type m33, _type m43, _type m14, _type m24, _type m34, _type m44) { mat[0] = m11; mat[4] = m21; mat[8] = m31; mat[12] = m41; mat[1] = m12; mat[5] = m22; mat[9] = m32; mat[13] = m42; mat[2] = m13; mat[6] = m23; mat[10] = m33; mat[14] = m43; mat[3] = m14; mat[7] = m24; mat[11] = m34; mat[15] = m44; } //! Copy constructor /*! \param m A Matrix 4x4 */ Mat4(const Mat4& m) { for(unsigned i = 0; i < mat.size(); ++i) mat = m.mat; } MAT_INLINE Mat4& operator=(const _type* t) { for(unsigned i = 0; i < mat.size(); ++i) mat = t; return *this; } //! Overloaded operator= /*! \param m A Matrix 4x4 \return A Matrix 4x4 */ MAT_INLINE Mat4& operator=(const Mat4& m) { for(unsigned i = 0; i < mat.size(); ++i) mat = m.mat; return *this; } //! Overloaded operator= /*! \param t A Matrix scalar \return A Matrix 4x4 */ MAT_INLINE Mat4& operator=(const _type t) { for(unsigned i = 0; i < mat.size(); ++i) mat = t; return *this; } //! Overloaded operator+ /*! \param m A Matrix 4x4 \return A Matrix 4x4 */ MAT_INLINE Mat4& operator+(const Mat4& m) { for(unsigned i = 0; i < mat.size(); ++i) mat = mat + m.mat; return *this; } //! Overloaded operator+ /*! \param t A Matrix scalar \return A Matrix 4x4 */ MAT_INLINE Mat4& operator+(const _type t) { for(unsigned i = 0; i < mat.size(); ++i) mat = mat + t; return *this; } //! Overloaded operator+= /*! \param m A Matrix 4x4 \return A Matrix 4x4 */ MAT_INLINE Mat4& operator+=(const Mat4& m) { for(unsigned i = 0; i < mat.size(); ++i) mat += m.mat; return *this; } //! Overloaded operator+= /*! \param t A Matrix scalar \return A Matrix 4x4 */ MAT_INLINE Mat4& operator+=(const _type t) { for(unsigned i = 0; i < mat.size(); ++i) mat += t; return *this; } //! Overloaded operator- /*! \param m A Matrix 4x4 \return A Matrix 4x4 */ MAT_INLINE Mat4& operator-(const Mat4& m) { for(unsigned i = 0; i < mat.size(); ++i) mat = mat - m.mat; return *this; } //! Overloaded operator- /*! \param t A Matrix scalar \return A Matrix 4x4 */ MAT_INLINE Mat4& operator-(const _type t) { for(unsigned i = 0; i < mat.size(); ++i) mat = mat - t; return *this; } //! Overloaded operator-= /*! \param m A Matrix 4x4 \return A Matrix 4x4 */ MAT_INLINE Mat4& operator-=(const Mat4& m) { for(unsigned i = 0; i < mat.size(); ++i) mat -= m.mat; return *this; } //! Overloaded operator-= /*! \param t A Matrix scalar \return A Matrix 4x4 */ MAT_INLINE Mat4& operator-=(const _type t) { for(unsigned i = 0; i < mat.size(); ++i) mat -= t; return *this; } //! Overloaded operator* /*! \param m A Matrix 4x4 \return A Matrix 4x4 */ MAT_INLINE Mat4 operator*(const Mat4& m) { return Mat4(mat[0] * m.mat[0] + mat[4] * m.mat[1] + mat[8] * m.mat[2] + mat[12] * m.mat[3], mat[1] * m.mat[0] + mat[5] * m.mat[1] + mat[9] * m.mat[2] + mat[13] * m.mat[3], mat[2] * m.mat[0] + mat[6] * m.mat[1] + mat[10] * m.mat[2] + mat[14] * m.mat[3], mat[3] * m.mat[0] + mat[7] * m.mat[1] + mat[11] * m.mat[2] + mat[15] * m.mat[3], mat[0] * m.mat[4] + mat[4] * m.mat[5] + mat[8] * m.mat[6] + mat[12] * m.mat[7], mat[1] * m.mat[4] + mat[5] * m.mat[5] + mat[9] * m.mat[6] + mat[13] * m.mat[7], mat[2] * m.mat[4] + mat[6] * m.mat[5] + mat[10] * m.mat[6] + mat[14] * m.mat[7], mat[3] * m.mat[4] + mat[7] * m.mat[5] + mat[11] * m.mat[6] + mat[15] * m.mat[7], mat[0] * m.mat[8] + mat[4] * m.mat[9] + mat[8] * m.mat[10] + mat[12] * m.mat[11], mat[1] * m.mat[8] + mat[5] * m.mat[9] + mat[9] * m.mat[10] + mat[13] * m.mat[11], mat[2] * m.mat[8] + mat[6] * m.mat[9] + mat[10] * m.mat[10] + mat[14] * m.mat[11], mat[3] * m.mat[8] + mat[7] * m.mat[9] + mat[11] * m.mat[10] + mat[15] * m.mat[11], mat[0] * m.mat[12] + mat[4] * m.mat[13] + mat[8] * m.mat[14] + mat[12] * m.mat[15], mat[1] * m.mat[12] + mat[5] * m.mat[13] + mat[9] * m.mat[14] + mat[13] * m.mat[15], mat[2] * m.mat[12] + mat[6] * m.mat[13] + mat[10] * m.mat[14] + mat[14] * m.mat[15], mat[3] * m.mat[12] + mat[7] * m.mat[13] + mat[11] * m.mat[14] + mat[15] * m.mat[15]); } //! Overloaded operator* /*! \param t A Matrix scalar \return A Matrix 4x4 */ MAT_INLINE Mat4& operator*(const _type t) { for(unsigned i = 0; i < mat.size(); ++i) mat = mat * t; return *this; } //! Overloaded operator* /*! \param v A Vector 3d \return A Vector 3d */ MAT_INLINE Vec3<_type> operator*(const Vec3<_type>& v) { Vec3<_type> t; t.x = v.x * mat[0] + v.y * mat[4] + v.z * mat[8] + mat[12]; t.y = v.x * mat[1] + v.y * mat[5] + v.z * mat[9] + mat[13]; t.z = v.y * mat[2] + v.y * mat[6] + v.z * mat[10] + mat[14]; return t; } //! Overloaded operator* /*! \param v A Vector 4d \return A Vector 4d */ MAT_INLINE Vec4<_type> operator*(const Vec4<_type>& v) { Vec4<_type> t; t.x = v.x * mat[0] + v.y * mat[4] + v.z * mat[8] + v.w * mat[12]; t.y = v.x * mat[1] + v.y * mat[5] + v.z * mat[9] + v.w * mat[13]; t.z = v.x * mat[2] + v.y * mat[6] + v.z * mat[10] + v.w * mat[14]; t.w = v.x * mat[3] + v.y * mat[7] + v.z * mat[11] + v.w * mat[15]; return t; } //! Overloaded operator*= /*! \param m A Matrix 4x4 \return A Matrix 4x4 */ MAT_INLINE Mat4& operator*=(const Mat4& m) { for(unsigned i = 0; i < mat.size(); ++i) mat *= m.mat; return *this; } //! Overloaded operator*= /*! \param t A Matrix scalar \return A Matrix 4x4 */ MAT_INLINE Mat4& operator*=(const _type t) { for(unsigned i = 0; i < mat.size(); ++i) mat *= t; return *this; } //! Overloaded operator/ /*! \param m A Matrix 4x4 \return A Matrix 4x4 */ MAT_INLINE Mat4 operator/(const Mat4& m) { return Mat4(mat[0] / m.mat[0] + mat[4] / m.mat[1] + mat[8] / m.mat[2] + mat[12] / m.mat[3], mat[1] / m.mat[0] + mat[5] / m.mat[1] + mat[9] / m.mat[2] + mat[13] / m.mat[3], mat[2] / m.mat[0] + mat[6] / m.mat[1] + mat[10] / m.mat[2] + mat[14] / m.mat[3], mat[3] / m.mat[0] + mat[7] / m.mat[1] + mat[11] / m.mat[2] + mat[15] / m.mat[3], mat[0] / m.mat[4] + mat[4] / m.mat[5] + mat[8] / m.mat[6] + mat[12] / m.mat[7], mat[1] / m.mat[4] + mat[5] / m.mat[5] + mat[9] / m.mat[6] + mat[13] / m.mat[7], mat[2] / m.mat[4] + mat[6] / m.mat[5] + mat[10] / m.mat[6] + mat[14] / m.mat[7], mat[3] / m.mat[4] + mat[7] / m.mat[5] + mat[11] / m.mat[6] + mat[15] / m.mat[7], mat[0] / m.mat[8] + mat[4] / m.mat[9] + mat[8] / m.mat[10] + mat[12] / m.mat[11], mat[1] / m.mat[8] + mat[5] / m.mat[9] + mat[9] / m.mat[10] + mat[13] / m.mat[11], mat[2] / m.mat[8] + mat[6] / m.mat[9] + mat[10] / m.mat[10] + mat[14] / m.mat[11], mat[3] / m.mat[8] + mat[7] / m.mat[9] + mat[11] / m.mat[10] + mat[15] / m.mat[11], mat[0] / m.mat[12] + mat[4] / m.mat[13] + mat[8] / m.mat[14] + mat[12] / m.mat[15], mat[1] / m.mat[12] + mat[5] / m.mat[13] + mat[9] / m.mat[14] + mat[13] / m.mat[15], mat[2] / m.mat[12] + mat[6] / m.mat[13] + mat[10] / m.mat[14] + mat[14] / m.mat[15], mat[3] / m.mat[12] + mat[7] / m.mat[13] + mat[11] / m.mat[14] + mat[15] / m.mat[15]); } //! Overloaded operator/ /*! \param t A Matrix scalar \return A Matrix 4x4 */ MAT_INLINE Mat4& operator/(const _type t) { _type tmp; if(t == 0.0) { t = 1.0; } tmp = 1.0 / t; for(unsigned i = 0; i < mat.size(); ++i) mat = mat * tmp; return *this; } //! Overloaded operator/= /*! \param m A Matrix 4x4 \return A Matrix 4x4 */ MAT_INLINE Mat4& operator/=(const Mat4& m) { for(unsigned i = 0; i < mat.size(); ++i) mat /= m.mat; return *this; } //! Overloaded operator/= /*! \param t A Matrix scalar \return A Matrix 4x4 */ MAT_INLINE Mat4& operator/=(const _type t) { for(unsigned i = 0; i < mat.size(); ++i) mat /= t; return *this; } //! Sets the matrix identity /*! \f$ \left[\begin{array}{cccc} 1.0 & 0.0 & 0.0 & 0.0\ 0.0 & 1.0 & 0.0 & 0.0\ 0.0 & 0.0 & 1.0 & 0.0\ 0.0 & 0.0 & 0.0 & 1.0\end{array} \right] \f$ \return A Matrix 4x4 */ MAT_INLINE static Mat4 identity() { return Mat4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); } //! Set the matrix zero /*! \f$ \left[\begin{array}{cccc} 0.0 & 0.0 & 0.0 & 0.0\ 0.0 & 0.0 & 0.0 & 0.0\ 0.0 & 0.0 & 0.0 & 0.0\ 0.0 & 0.0 & 0.0 & 0.0\end{array}\right] \f$ \return A Matrix 4x4 */ MAT_INLINE static Mat4 zero() { return Mat4(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); } //! Transpose a Matrix by swapping its columns and rows MAT_INLINE void transpose() { std::swap(mat[1], mat[4]); std::swap(mat[2], mat[8]); std::swap(mat[3], mat[12]); std::swap(mat[6], mat[9]); std::swap(mat[7], mat[13]); std::swap(mat[11], mat[14]); } //! Rotate the matrix around the X axis /*! \param angle Angle of degrees which to rotate \return A Matrix 4x4 */ MAT_INLINE Mat4& rotateXAxis(_type angle) { _type cos = Math<_type>::Cosine(angle); _type sin = Math<_type>::Sine(angle); mat[5] = cos; mat[6] = -sin; mat[9] = sin; mat[10] = cos; return *this; } //! Rotate the matrix around the Y axis /*! \param angle Angle of degrees which to rotate \return A Matrix 4x4 */ MAT_INLINE Mat4& rotateYAxis(_type angle) { _type cos = Math<_type>::Cosine(angle); _type sin = Math<_type>::Sine(angle); mat[0] = cos; mat[2] = sin; mat[8] = -sin; mat[10] = cos; return *this; } //! Rotate the matrix around the Z axis /*! \param angle Angle of degrees which to rotate \return A Matrix 4x4 */ MAT_INLINE Mat4& rotateZAxis(_type angle) { _type cos = Math<_type>::Cosine(angle); _type sin = Math<_type>::Sine(angle); mat[0] = cos; mat[1] = -sin; mat[4] = sin; mat[5] = cos; return *this; } //! Translate the matrix across the axis' /*! \param _x X axis \param _y Y axis \param _z Z axis \return A Matrix 4x4 */ MAT_INLINE Mat4& translate(const _type _x, const _type _y, const _type _z) { //*this = identity(); mat[12] *= _x; mat[13] *= _y; mat[14] *= _z; return *this; } //! Translate the matrix across the axis' /*! \param v A Vertex 3d to translate \return A Matrix 4x4 */ MAT_INLINE Mat4& translate(const Vec3<_type>& v) { translate(v.x, v.y, v.z); return *this; } //! Scale the matrix /*! \param _x X axis \param _y Y axis \param _z Z axis \return A Matrix 4x4 */ MAT_INLINE Mat4& scale(const _type _x, const _type _y, const _type _z) { //*this = identity(); mat[0] = _x; mat[5] = _y; mat[10] = _z; return *this; } //! Scale the matrix /*! \param v A Vertex 3d \return A Matrix 4x4 */ MAT_INLINE Mat4& scale(const Vec3<_type> v) { scale(v.x, v.y, v.z); return *this; } MAT_INLINE void orthoProjection(const Vec2<_type>& leftRight, const Vec2<_type>& bottomTop, const Vec2<_type>& zNearFar) { *this = zero(); mat[0] = 2.0 / (leftRight.y - leftRight.x); mat[5] = 2.0 / (bottomTop.y - bottomTop.x); mat[10] = -2.0 / (zNearFar.y - zNearFar.x); mat[12] = -((leftRight.y + leftRight.x) / (leftRight.y - leftRight.x)); mat[13] = -((bottomTop.y + bottomTop.x) / (bottomTop.y - bottomTop.x)); mat[14] = -((zNearFar.y + zNearFar.x) / (zNearFar.y - zNearFar.x)); mat[15] = 1.0; } //! Print the Matrix for debugging purposes MAT_INLINE void printMat4() { std::cout << "[ " << m11 << ", " << m21 << ", " << m31 << ", " << m41 << " ]" << std::endl; std::cout << "[ " << m12 << ", " << m22 << ", " << m32 << ", " << m42 << " ]" << std::endl; std::cout << "[ " << m13 << ", " << m23 << ", " << m33 << ", " << m43 << " ]" << std::endl; std::cout << "[ " << m14 << ", " << m24 << ", " << m34 << ", " << m44 << " ]\n" << std::endl; }};typedef Mat4<double> Mat4d;typedef Mat4<float> Mat4f;#endif /*MATRIX_H_*/