diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index d72529d92..211e8eedb 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -26,9 +26,9 @@ namespace Nz public: Matrix4() = default; Matrix4(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44); + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44); //Matrix4(const Matrix3& matrix); Matrix4(const T matrix[16]); template explicit Matrix4(const Matrix4& matrix); @@ -77,9 +77,9 @@ namespace Nz Matrix4& MakeZero(); Matrix4& Set(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44); + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44); Matrix4& Set(const T matrix[16]); //Matrix4(const Matrix3& matrix); Matrix4& Set(const Matrix4& matrix); @@ -96,8 +96,8 @@ namespace Nz Matrix4& Transpose(); - operator T*(); - operator const T*() const; + operator T* (); + operator const T* () const; T& operator()(unsigned int x, unsigned int y); T operator()(unsigned int x, unsigned int y) const; @@ -131,9 +131,9 @@ namespace Nz static Matrix4 Zero(); T m11, m12, m13, m14, - m21, m22, m23, m24, - m31, m32, m33, m34, - m41, m42, m43, m44; + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44; }; typedef Matrix4 Matrix4d; diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 834a3fb70..e2f604aed 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -20,24 +20,50 @@ namespace Nz { + + /*! + * \class Nz::Matrix4 + * \brief Math class that represents a transformation of the four dimensional vector space with the notion of projectivity + * + * \remark Matrix4 is said to be "row-major" and affine if last column is made of (0, 0, 0, 1) + */ + + /*! + * \brief Constructs a Matrix4 object from its components + * + * \param rIJ Matrix components at index(I, J) + */ + template Matrix4::Matrix4(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44) + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44) { Set(r11, r12, r13, r14, - r21, r22, r23, r24, - r31, r32, r33, r34, - r41, r42, r43, r44); + r21, r22, r23, r24, + r31, r32, r33, r34, + r41, r42, r43, r44); } + /*! + * \brief Constructs a Matrix4 object from an array of sixteen elements + * + * \param matrix[16] Matrix components + */ + template Matrix4::Matrix4(const T matrix[16]) { Set(matrix); } + /*! + * \brief Constructs a Matrix4 object from another type of Matrix4 + * + * \param matrix Matrix4 of type U to convert to type T + */ + template template Matrix4::Matrix4(const Matrix4& matrix) @@ -45,12 +71,26 @@ namespace Nz Set(matrix); } + /*! + * \brief Apply the rotation represented by the quaternion to this matrix + * \return A reference to this matrix which has been rotated + * + * \param rotation Quaternion representing a rotation of space + */ + template Matrix4& Matrix4::ApplyRotation(const Quaternion& rotation) { return Concatenate(Matrix4::Rotate(rotation)); } + /*! + * \brief Apply the scale represented by the vector to this matrix + * \return A reference to this matrix which has been scaled + * + * \param scale Vector3 representing the homothety + */ + template Matrix4& Matrix4::ApplyScale(const Vector3& scale) { @@ -69,6 +109,13 @@ namespace Nz return *this; } + /*! + * \brief Apply the translation represented by the vector to this matrix + * \return A reference to this matrix which has been translated + * + * \param translation Vector3 representing the translation + */ + template Matrix4& Matrix4::ApplyTranslation(const Vector3& translation) { @@ -79,6 +126,17 @@ namespace Nz return *this; } + /*! + * \brief Concatenates this matrix to other one + * \return A reference to this matrix which is the product with other one + * + * \param matrix Matrix to multiply with + * + * \remark if NAZARA_MATH_MATRIX4_CHECK_AFFINE is defined, ConcatenateAffine is called + * + * \see ConcatenateAffine + */ + template Matrix4& Matrix4::Concatenate(const Matrix4& matrix) { @@ -88,26 +146,37 @@ namespace Nz #endif return Set(m11*matrix.m11 + m12*matrix.m21 + m13*matrix.m31 + m14*matrix.m41, - m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32 + m14*matrix.m42, - m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33 + m14*matrix.m43, - m11*matrix.m14 + m12*matrix.m24 + m13*matrix.m34 + m14*matrix.m44, + m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32 + m14*matrix.m42, + m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33 + m14*matrix.m43, + m11*matrix.m14 + m12*matrix.m24 + m13*matrix.m34 + m14*matrix.m44, - m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31 + m24*matrix.m41, - m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32 + m24*matrix.m42, - m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33 + m24*matrix.m43, - m21*matrix.m14 + m22*matrix.m24 + m23*matrix.m34 + m24*matrix.m44, + m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31 + m24*matrix.m41, + m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32 + m24*matrix.m42, + m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33 + m24*matrix.m43, + m21*matrix.m14 + m22*matrix.m24 + m23*matrix.m34 + m24*matrix.m44, - m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31 + m34*matrix.m41, - m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32 + m34*matrix.m42, - m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33 + m34*matrix.m43, - m31*matrix.m14 + m32*matrix.m24 + m33*matrix.m34 + m34*matrix.m44, + m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31 + m34*matrix.m41, + m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32 + m34*matrix.m42, + m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33 + m34*matrix.m43, + m31*matrix.m14 + m32*matrix.m24 + m33*matrix.m34 + m34*matrix.m44, - m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + m44*matrix.m41, - m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + m44*matrix.m42, - m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + m44*matrix.m43, - m41*matrix.m14 + m42*matrix.m24 + m43*matrix.m34 + m44*matrix.m44); + m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + m44*matrix.m41, + m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + m44*matrix.m42, + m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + m44*matrix.m43, + m41*matrix.m14 + m42*matrix.m24 + m43*matrix.m34 + m44*matrix.m44); } + /*! + * \brief Concatenates this matrix to other one + * \return A reference to this matrix which is the product with other one + * + * \param matrix Matrix to multiply with + * + * \remark if NAZARA_DEBUG is defined and matrices are not affine, a NazaraWarning is produced and Concatenate is called + * + * \see Concatenate + */ + template Matrix4& Matrix4::ConcatenateAffine(const Matrix4& matrix) { @@ -126,26 +195,36 @@ namespace Nz #endif return Set(m11*matrix.m11 + m12*matrix.m21 + m13*matrix.m31, - m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32, - m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33, - F(0.0), + m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32, + m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33, + F(0.0), - m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31, - m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32, - m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33, - F(0.0), + m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31, + m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32, + m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33, + F(0.0), - m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31, - m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32, - m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33, - F(0.0), + m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31, + m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32, + m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33, + F(0.0), - m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + matrix.m41, - m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + matrix.m42, - m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + matrix.m43, - F(1.0)); + m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + matrix.m41, + m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + matrix.m42, + m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + matrix.m43, + F(1.0)); } + /*! + * \brief Gets the ith column of the matrix + * \return Vector4 which is the transformation of this axis + * + * \param column Index of the column you want + * + * \remark Produce a NazaraError if you try to access index greater than 3 with NAZARA_MATH_SAFE defined + * \throw std::out_of_range if NAZARA_MATH_SAFE is defined and if you try to access index greater than 3 + */ + template Vector4 Matrix4::GetColumn(unsigned int column) const { @@ -154,10 +233,10 @@ namespace Nz #if NAZARA_MATH_SAFE if (column > 3) { - StringStream ss; - ss << "Row out of range: (" << column << ") > 3"; + String error("Column out of range: (" + String::Number(column) + ") > 3"); - throw std::out_of_range(ss.ToString()); + NazaraError(error); + throw std::out_of_range(error); } #endif @@ -165,9 +244,23 @@ namespace Nz return Vector4(ptr); } + /*! + * \brief Calcultes the determinant of this matrix + * \return The value of the determinant + * + * \remark if NAZARA_MATH_MATRIX4_CHECK_AFFINE is defined, GetDeterminantAffine is called + * + * \see GetDeterminantAffine + */ + template T Matrix4::GetDeterminant() const { + #if NAZARA_MATH_MATRIX4_CHECK_AFFINE + if (IsAffine()) + return GetDeterminantAffine(); + #endif + T A = m22*(m33*m44 - m43*m34) - m32*(m23*m44 - m43*m24) + m42*(m23*m34 - m33*m24); T B = m12*(m33*m44 - m43*m34) - m32*(m13*m44 - m43*m14) + m42*(m13*m34 - m33*m14); T C = m12*(m23*m44 - m43*m24) - m22*(m13*m44 - m43*m14) + m42*(m13*m24 - m23*m14); @@ -176,9 +269,26 @@ namespace Nz return m11*A - m21*B + m31*C - m41*D; } + /*! + * \brief Calcultes the determinant of this matrix + * \return The value of the determinant + * + * \remark if NAZARA_DEBUG is defined and matrix is not affine, a NazaraWarning is produced and GetDeterminant is called + * + * \see GetDeterminant + */ + template T Matrix4::GetDeterminantAffine() const { + #ifdef NAZARA_DEBUG + if (!IsAffine()) + { + NazaraWarning("First matrix not affine"); + return GetDeterminant(); + } + #endif + T A = m22*m33 - m32*m23; T B = m12*m33 - m32*m13; T C = m12*m23 - m22*m13; @@ -186,10 +296,27 @@ namespace Nz return m11*A - m21*B + m31*C; } + /*! + * \brief Gets the inverse of this matrix + * \return true if matrix can be inverted + * + * \param dest Matrix to put the result + * + * \remark You can call this method on the same object + * \remark if NAZARA_MATH_MATRIX4_CHECK_AFFINE is defined, GetInverseAffine is called + * \remark if NAZARA_DEBUG is defined, a NazaraError is produced if dest is null and false is returned + * + * \see GetInverseAffine + */ + template bool Matrix4::GetInverse(Matrix4* dest) const { - ///DOC: Il est possible d'appeler cette méthode avec la même matrice en argument qu'en appelant + #if NAZARA_MATH_MATRIX4_CHECK_AFFINE + if (IsAffine()) + return GetInverseAffine(dest); + #endif + #ifdef NAZARA_DEBUG if (!dest) { @@ -204,116 +331,116 @@ namespace Nz // http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix T inv[16]; inv[0] = m22 * m33 * m44 - - m22 * m34 * m43 - - m32 * m23 * m44 + - m32 * m24 * m43 + - m42 * m23 * m34 - - m42 * m24 * m33; + m22 * m34 * m43 - + m32 * m23 * m44 + + m32 * m24 * m43 + + m42 * m23 * m34 - + m42 * m24 * m33; inv[1] = -m12 * m33 * m44 + - m12 * m34 * m43 + - m32 * m13 * m44 - - m32 * m14 * m43 - - m42 * m13 * m34 + - m42 * m14 * m33; + m12 * m34 * m43 + + m32 * m13 * m44 - + m32 * m14 * m43 - + m42 * m13 * m34 + + m42 * m14 * m33; inv[2] = m12 * m23 * m44 - - m12 * m24 * m43 - - m22 * m13 * m44 + - m22 * m14 * m43 + - m42 * m13 * m24 - - m42 * m14 * m23; + m12 * m24 * m43 - + m22 * m13 * m44 + + m22 * m14 * m43 + + m42 * m13 * m24 - + m42 * m14 * m23; inv[3] = -m12 * m23 * m34 + - m12 * m24 * m33 + - m22 * m13 * m34 - - m22 * m14 * m33 - - m32 * m13 * m24 + - m32 * m14 * m23; + m12 * m24 * m33 + + m22 * m13 * m34 - + m22 * m14 * m33 - + m32 * m13 * m24 + + m32 * m14 * m23; inv[4] = -m21 * m33 * m44 + - m21 * m34 * m43 + - m31 * m23 * m44 - - m31 * m24 * m43 - - m41 * m23 * m34 + - m41 * m24 * m33; + m21 * m34 * m43 + + m31 * m23 * m44 - + m31 * m24 * m43 - + m41 * m23 * m34 + + m41 * m24 * m33; inv[5] = m11 * m33 * m44 - - m11 * m34 * m43 - - m31 * m13 * m44 + - m31 * m14 * m43 + - m41 * m13 * m34 - - m41 * m14 * m33; + m11 * m34 * m43 - + m31 * m13 * m44 + + m31 * m14 * m43 + + m41 * m13 * m34 - + m41 * m14 * m33; inv[6] = -m11 * m23 * m44 + - m11 * m24 * m43 + - m21 * m13 * m44 - - m21 * m14 * m43 - - m41 * m13 * m24 + - m41 * m14 * m23; + m11 * m24 * m43 + + m21 * m13 * m44 - + m21 * m14 * m43 - + m41 * m13 * m24 + + m41 * m14 * m23; inv[7] = m11 * m23 * m34 - - m11 * m24 * m33 - - m21 * m13 * m34 + - m21 * m14 * m33 + - m31 * m13 * m24 - - m31 * m14 * m23; + m11 * m24 * m33 - + m21 * m13 * m34 + + m21 * m14 * m33 + + m31 * m13 * m24 - + m31 * m14 * m23; inv[8] = m21 * m32 * m44 - - m21 * m34 * m42 - - m31 * m22 * m44 + - m31 * m24 * m42 + - m41 * m22 * m34 - - m41 * m24 * m32; + m21 * m34 * m42 - + m31 * m22 * m44 + + m31 * m24 * m42 + + m41 * m22 * m34 - + m41 * m24 * m32; inv[9] = -m11 * m32 * m44 + - m11 * m34 * m42 + - m31 * m12 * m44 - - m31 * m14 * m42 - - m41 * m12 * m34 + - m41 * m14 * m32; + m11 * m34 * m42 + + m31 * m12 * m44 - + m31 * m14 * m42 - + m41 * m12 * m34 + + m41 * m14 * m32; inv[10] = m11 * m22 * m44 - - m11 * m24 * m42 - - m21 * m12 * m44 + - m21 * m14 * m42 + - m41 * m12 * m24 - - m41 * m14 * m22; + m11 * m24 * m42 - + m21 * m12 * m44 + + m21 * m14 * m42 + + m41 * m12 * m24 - + m41 * m14 * m22; inv[11] = -m11 * m22 * m34 + - m11 * m24 * m32 + - m21 * m12 * m34 - - m21 * m14 * m32 - - m31 * m12 * m24 + - m31 * m14 * m22; + m11 * m24 * m32 + + m21 * m12 * m34 - + m21 * m14 * m32 - + m31 * m12 * m24 + + m31 * m14 * m22; inv[12] = -m21 * m32 * m43 + - m21 * m33 * m42 + - m31 * m22 * m43 - - m31 * m23 * m42 - - m41 * m22 * m33 + - m41 * m23 * m32; + m21 * m33 * m42 + + m31 * m22 * m43 - + m31 * m23 * m42 - + m41 * m22 * m33 + + m41 * m23 * m32; inv[13] = m11 * m32 * m43 - - m11 * m33 * m42 - - m31 * m12 * m43 + - m31 * m13 * m42 + - m41 * m12 * m33 - - m41 * m13 * m32; + m11 * m33 * m42 - + m31 * m12 * m43 + + m31 * m13 * m42 + + m41 * m12 * m33 - + m41 * m13 * m32; inv[14] = -m11 * m22 * m43 + - m11 * m23 * m42 + - m21 * m12 * m43 - - m21 * m13 * m42 - - m41 * m12 * m23 + - m41 * m13 * m22; + m11 * m23 * m42 + + m21 * m12 * m43 - + m21 * m13 * m42 - + m41 * m12 * m23 + + m41 * m13 * m22; inv[15] = m11 * m22 * m33 - - m11 * m23 * m32 - - m21 * m12 * m33 + - m21 * m13 * m32 + - m31 * m12 * m23 - - m31 * m13 * m22; + m11 * m23 * m32 - + m21 * m12 * m33 + + m21 * m13 * m32 + + m31 * m12 * m23 - + m31 * m13 * m22; T invDet = F(1.0) / det; for (unsigned int i = 0; i < 16; ++i) @@ -326,15 +453,27 @@ namespace Nz return false; } + /*! + * \brief Gets the inverse of this matrix + * \return true if matrix can be inverted + * + * \param dest Matrix to put the result + * + * \remark You can call this method on the same object + * \remark if NAZARA_DEBUG is defined and matrix is not affine, a NazaraWarning is produced and GetInverse is called + * \remark if NAZARA_DEBUG is defined, a NazaraError is produced if dest is null and false is returned + * + * \see GetInverse + */ + template bool Matrix4::GetInverseAffine(Matrix4* dest) const { - ///DOC: Il est possible d'appeler cette méthode avec la même matrice en argument qu'en appelant - #if NAZARA_MATH_SAFE + #ifdef NAZARA_DEBUG if (!IsAffine()) { - NazaraError("Matrix is not affine"); - return false; + NazaraWarning("Matrix is not affine"); + return GetInverse(dest); } if (!dest) @@ -350,58 +489,58 @@ namespace Nz // http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix T inv[16]; inv[0] = m22 * m33 - - m32 * m23; + m32 * m23; inv[1] = -m12 * m33 + - m32 * m13; + m32 * m13; inv[2] = m12 * m23 - - m22 * m13; + m22 * m13; inv[3] = F(0.0); inv[4] = -m21 * m33 + - m31 * m23; + m31 * m23; inv[5] = m11 * m33 - - m31 * m13; + m31 * m13; inv[6] = -m11 * m23 + - m21 * m13; + m21 * m13; inv[7] = F(0.0); inv[8] = m21 * m32 - - m31 * m22; + m31 * m22; inv[9] = -m11 * m32 + - m31 * m12; + m31 * m12; inv[10] = m11 * m22 - - m21 * m12; + m21 * m12; inv[11] = F(0.0); inv[12] = -m21 * m32 * m43 + - m21 * m33 * m42 + - m31 * m22 * m43 - - m31 * m23 * m42 - - m41 * m22 * m33 + - m41 * m23 * m32; + m21 * m33 * m42 + + m31 * m22 * m43 - + m31 * m23 * m42 - + m41 * m22 * m33 + + m41 * m23 * m32; inv[13] = m11 * m32 * m43 - - m11 * m33 * m42 - - m31 * m12 * m43 + - m31 * m13 * m42 + - m41 * m12 * m33 - - m41 * m13 * m32; + m11 * m33 * m42 - + m31 * m12 * m43 + + m31 * m13 * m42 + + m41 * m12 * m33 - + m41 * m13 * m32; inv[14] = -m11 * m22 * m43 + - m11 * m23 * m42 + - m21 * m12 * m43 - - m21 * m13 * m42 - - m41 * m12 * m23 + - m41 * m13 * m22; + m11 * m23 * m42 + + m21 * m12 * m43 - + m21 * m13 * m42 - + m41 * m12 * m23 + + m41 * m13 * m22; T invDet = F(1.0) / det; for (unsigned int i = 0; i < 16; ++i) @@ -416,6 +555,11 @@ namespace Nz return false; } + /*! + * \brief Gets the rotation from this matrix + * \return Quaternion which is the representation of the rotation in this matrix + */ + template Quaternion Matrix4::GetRotation() const { @@ -425,7 +569,7 @@ namespace Nz T trace = m11 + m22 + m33; if (trace > F(0.0)) { - T s = F(0.5)/std::sqrt(trace + F(1.0)); + T s = F(0.5) / std::sqrt(trace + F(1.0)); quat.w = F(0.25) / s; quat.x = (m23 - m32) * s; quat.y = (m31 - m13) * s; @@ -465,6 +609,16 @@ namespace Nz return quat; } + /*! + * \brief Gets the ith row of the matrix + * \return Vector4 which is the ith row of the matrix + * + * \param row Index of the row you want + * + * \remark Produce a NazaraError if you try to access index greater than 3 with NAZARA_MATH_SAFE defined + * \throw std::out_of_range if NAZARA_MATH_SAFE is defined and if you try to access index greater than 3 + */ + template Vector4 Matrix4::GetRow(unsigned int row) const { @@ -473,10 +627,10 @@ namespace Nz #if NAZARA_MATH_SAFE if (row > 3) { - StringStream ss; - ss << "Column out of range: (" << row << ") > 3"; + String error("Row out of range: (" + String::Number(row) + ") > 3"); - throw std::out_of_range(ss.ToString()); + NazaraError(error); + throw std::out_of_range(error); } #endif @@ -484,6 +638,13 @@ namespace Nz return Vector4(ptr[row], ptr[row+4], ptr[row+8], ptr[row+12]); } + /*! + * \brief Gets the scale from this matrix + * \return Vector3 which is the representation of the scale in this matrix + * + * \see GetSquaredScale + */ + template Vector3 Matrix4::GetScale() const { @@ -491,35 +652,80 @@ namespace Nz return Vector3(std::sqrt(squaredScale.x), std::sqrt(squaredScale.y), std::sqrt(squaredScale.z)); } + /*! + * \brief Gets the squared scale from this matrix + * \return Vector3 which is the representation of the squared scale in this matrix + * + * \see GetScale + */ + template Vector3 Matrix4::GetSquaredScale() const { return Vector3(m11*m11 + m21*m21 + m31*m31, - m12*m12 + m22*m22 + m32*m32, - m13*m13 + m23*m23 + m33*m33); + m12*m12 + m22*m22 + m32*m32, + m13*m13 + m23*m23 + m33*m33); } + /*! + * \brief Gets the translation from this matrix + * \return Vector3 which is the representation of the translation in this matrix + */ + template Vector3 Matrix4::GetTranslation() const { return Vector3(m41, m42, m43); } + /*! + * \brief Gets the transposed of this matrix + * + * \param dest Matrix to put the result + * + * \remark You can call this method on the same object + * \remark if NAZARA_DEBUG is defined, a NazaraError is produced if dest is null and dest is not changed + * + * \see Transpose + */ + template void Matrix4::GetTransposed(Matrix4* dest) const { + #ifdef NAZARA_DEBUG + if (!dest) + { + NazaraError("Destination matrix must be valid"); + return; + } + #endif + dest->Set(m11, m21, m31, m41, - m12, m22, m32, m42, - m13, m23, m33, m43, - m14, m24, m34, m44); + m12, m22, m32, m42, + m13, m23, m33, m43, + m14, m24, m34, m44); } + /*! + * \brief Checks whetever matrix has negative scale + * \return true if determinant is negative + * + * \see GetDeterminant + */ + template bool Matrix4::HasNegativeScale() const { return GetDeterminant() < F(0.0); } + /*! + * \brief Checks whetever matrix has scale + * \return true if determinant has scale + * + * \see HasNegativeScale + */ + template bool Matrix4::HasScale() const { @@ -538,6 +744,15 @@ namespace Nz return false; } + /*! + * \brief Inverts this matrix + * \return A reference to this matrix inverted + * + * \param bool Optional argument to know if matrix has been successfully inverted + * + * \see InverseAffine + */ + template Matrix4& Matrix4::Inverse(bool* succeeded) { @@ -548,6 +763,15 @@ namespace Nz return *this; } + /*! + * \brief Inverts this matrix + * \return A reference to this matrix inverted + * + * \param bool Optional argument to know if matrix has been successfully inverted + * + * \see Inverse + */ + template Matrix4& Matrix4::InverseAffine(bool* succeeded) { @@ -558,35 +782,63 @@ namespace Nz return *this; } + /*! + * \brief Checks whether the matrix is affine + * \return true if matrix is affine + */ + template bool Matrix4::IsAffine() const { return NumberEquals(m14, F(0.0)) && - NumberEquals(m24, F(0.0)) && - NumberEquals(m34, F(0.0)) && - NumberEquals(m44, F(1.0)); + NumberEquals(m24, F(0.0)) && + NumberEquals(m34, F(0.0)) && + NumberEquals(m44, F(1.0)); } + /*! + * \brief Checks whether the matrix is identity + * \return true if matrix is identity + */ + template bool Matrix4::IsIdentity() const { return (NumberEquals(m11, F(1.0)) && NumberEquals(m12, F(0.0)) && NumberEquals(m13, F(0.0)) && NumberEquals(m14, F(0.0)) && - NumberEquals(m21, F(0.0)) && NumberEquals(m22, F(1.0)) && NumberEquals(m23, F(0.0)) && NumberEquals(m24, F(0.0)) && - NumberEquals(m31, F(0.0)) && NumberEquals(m32, F(0.0)) && NumberEquals(m33, F(1.0)) && NumberEquals(m34, F(0.0)) && - NumberEquals(m41, F(0.0)) && NumberEquals(m42, F(0.0)) && NumberEquals(m43, F(0.0)) && NumberEquals(m44, F(1.0))); + NumberEquals(m21, F(0.0)) && NumberEquals(m22, F(1.0)) && NumberEquals(m23, F(0.0)) && NumberEquals(m24, F(0.0)) && + NumberEquals(m31, F(0.0)) && NumberEquals(m32, F(0.0)) && NumberEquals(m33, F(1.0)) && NumberEquals(m34, F(0.0)) && + NumberEquals(m41, F(0.0)) && NumberEquals(m42, F(0.0)) && NumberEquals(m43, F(0.0)) && NumberEquals(m44, F(1.0))); } + /*! + * \brief Makes the matrix identity (with 1 on diagonal and 0 for others) + * \return A reference to this matrix with components (1 on diagonal and 0 for others) + * + * \see Identity + */ + template Matrix4& Matrix4::MakeIdentity() { Set(F(1.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(1.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(1.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(1.0)); + F(0.0), F(1.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(1.0), F(0.0), + F(0.0), F(0.0), F(0.0), F(1.0)); return *this; } + /*! + * \brief Makes the matrix a 'look at matrix' + * \return A reference to this matrix transformed in 'look at matrix' + * + * \param eye Position of the camera + * \param target Position of the target of the camera + * \param up Direction of up vector according to the orientation of camera + * + * \see LookAt + */ + template Matrix4& Matrix4::MakeLookAt(const Vector3& eye, const Vector3& target, const Vector3& up) { @@ -595,25 +847,51 @@ namespace Nz Vector3 u = s.CrossProduct(f); Set(s.x, u.x, -f.x, T(0.0), - s.y, u.y, -f.y, T(0.0), - s.z, u.z, -f.z, T(0.0), - -s.DotProduct(eye), -u.DotProduct(eye), f.DotProduct(eye), T(1.0)); + s.y, u.y, -f.y, T(0.0), + s.z, u.z, -f.z, T(0.0), + -s.DotProduct(eye), -u.DotProduct(eye), f.DotProduct(eye), T(1.0)); return *this; } + /*! + * \brief Makes the matrix a 'orthographic matrix' + * \return A reference to this matrix transformed in 'orthographic matrix' + * + * \param left Distance between center and left + * \param right Distance between center and right + * \param top Distance between center and top + * \param bottom Distance between center and bottom + * \param zNear Distance where 'vision' begins + * \param zFar Distance where 'vision' ends + * + * \see Ortho + */ + template Matrix4& Matrix4::MakeOrtho(T left, T right, T top, T bottom, T zNear, T zFar) { // http://msdn.microsoft.com/en-us/library/windows/desktop/bb204942(v=vs.85).aspx Set(F(2.0) / (right - left), F(0.0), F(0.0), F(0.0), - F(0.0), F(2.0) / (top - bottom), F(0.0), F(0.0), - F(0.0), F(0.0), F(1.0) / (zNear - zFar), F(0.0), - (left + right) / (left - right), (top + bottom) / (bottom - top), zNear/(zNear - zFar), F(1.0)); + F(0.0), F(2.0) / (top - bottom), F(0.0), F(0.0), + F(0.0), F(0.0), F(1.0) / (zNear - zFar), F(0.0), + (left + right) / (left - right), (top + bottom) / (bottom - top), zNear/(zNear - zFar), F(1.0)); return *this; } + /*! + * \brief Makes the matrix a 'perspective matrix' + * \return A reference to this matrix transformed in 'perspective matrix' + * + * \param angle Unit depends on NAZARA_MATH_ANGLE_RADIAN + * \param ratio Rendering ratio (typically 16/9 or 4/3) + * \param zNear Distance where 'vision' begins + * \param zFar Distance where 'vision' ends + * + * \see Perspective + */ + template Matrix4& Matrix4::MakePerspective(T angle, T ratio, T zNear, T zFar) { @@ -627,19 +905,28 @@ namespace Nz T yScale = std::tan(static_cast(M_PI_2) - angle); Set(yScale / ratio, F(0.0), F(0.0), F(0.0), - F(0.0), yScale, F(0.0), F(0.0), - F(0.0), F(0.0), - (zFar + zNear) / (zFar - zNear), F(-1.0), - F(0.0), F(0.0), F(-2.0) * (zNear * zFar) / (zFar - zNear), F(0.0)); + F(0.0), yScale, F(0.0), F(0.0), + F(0.0), F(0.0), - (zFar + zNear) / (zFar - zNear), F(-1.0), + F(0.0), F(0.0), F(-2.0) * (zNear * zFar) / (zFar - zNear), F(0.0)); return *this; } + /*! + * \brief Makes the matrix the representation of the quaternion + * \return A reference to this matrix which is the rotation of the quaternion + * + * \param rotation Quaternion representing a rotation of space + * + * \see Rotate + */ + template Matrix4& Matrix4::MakeRotation(const Quaternion& rotation) { SetRotation(rotation); - // On complète la matrice + // We complete the matrix m14 = F(0.0); m24 = F(0.0); m34 = F(0.0); @@ -651,36 +938,66 @@ namespace Nz return *this; } + /*! + * \brief Makes the matrix with the scale + * \return A reference to this matrix which is the scale + * + * \param scale Vector3 representing the homothety + * + * \see Scale + */ + template Matrix4& Matrix4::MakeScale(const Vector3& scale) { Set(scale.x, F(0.0), F(0.0), F(0.0), - F(0.0), scale.y, F(0.0), F(0.0), - F(0.0), F(0.0), scale.z, F(0.0), - F(0.0), F(0.0), F(0.0), F(1.0)); + F(0.0), scale.y, F(0.0), F(0.0), + F(0.0), F(0.0), scale.z, F(0.0), + F(0.0), F(0.0), F(0.0), F(1.0)); return *this; } + /*! + * \brief Makes the matrix with the translation + * \return A reference to this matrix which is the translation + * + * \param translation Vector3 representing the translation + * + * \see Translate + */ + template Matrix4& Matrix4::MakeTranslation(const Vector3& translation) { Set(F(1.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(1.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(1.0), F(0.0), - translation.x, translation.y, translation.z, F(1.0)); + F(0.0), F(1.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(1.0), F(0.0), + translation.x, translation.y, translation.z, F(1.0)); return *this; } + /*! + * \brief Makes the matrix with the translation and the rotation + * \return A reference to this matrix which is transformation obtained by the translation and the rotation + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * + * \remark Rotation is applied first + * + * \see Transform + */ + template Matrix4& Matrix4::MakeTransform(const Vector3& translation, const Quaternion& rotation) { - // La rotation et la translation peuvent être appliquées directement + // The rotation and the translation may be directly applied SetRotation(rotation); SetTranslation(translation); - // On complète la matrice (les transformations sont affines) + // We complete the matrix (the transformations are affine) m14 = F(0.0); m24 = F(0.0); m34 = F(0.0); @@ -689,40 +1006,77 @@ namespace Nz return *this; } + /*! + * \brief Makes the matrix with the translation, the rotation and the scale + * \return A reference to this matrix which is transformation obtained by the translation, the rotation and the scale + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * \param scale Vector3 representing the homothety + * + * \remark Rotation is applied first, then translation + * + * \see Transform + */ + template Matrix4& Matrix4::MakeTransform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale) { MakeTransform(translation, rotation); - // Ensuite on fait une mise à l'échelle des valeurs déjà présentes + // Then we apply the homothety to current values return ApplyScale(scale); } + /*! + * \brief Makes the matrix a 'view matrix' + * \return A reference to this matrix transformed in 'view matrix' + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * + * \see ViewMatrix + */ + template Matrix4& Matrix4::MakeViewMatrix(const Vector3& translation, const Quaternion& rotation) { - // Une matrice de vue doit appliquer une transformation opposée à la matrice "monde" - Quaternion invRot = rotation.GetConjugate(); // Inverse de la rotation + // A view matrix must apply an inverse transformation of the 'world' matrix + Quaternion invRot = rotation.GetConjugate(); // Inverse of the rotation return MakeTransform(-(invRot * translation), invRot); } + /*! + * \brief Makes the matrix zero (with 0 everywhere) + * \return A reference to this matrix with components (0 everywhere) + * + * \see Zero + */ + template Matrix4& Matrix4::MakeZero() { Set(F(0.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(0.0)); + F(0.0), F(0.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(0.0), F(0.0)); return *this; } + /*! + * \brief Sets the components of the matrix + * \return A reference to this matrix + * + * \param rIJ Matrix components at index(I, J) + */ + template Matrix4& Matrix4::Set(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44) + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44) { m11 = r11; m12 = r12; @@ -744,15 +1098,29 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the matrix from an array of sixteen elements + * \return A reference to this matrix + * + * \param matrix[16] Matrix components + */ + template Matrix4& Matrix4::Set(const T matrix[16]) { - // Ici nous sommes certains de la continuité des éléments en mémoire - std::memcpy(&m11, matrix, 16*sizeof(T)); + // Here we are confident of the continuity of memory elements + std::memcpy(&m11, matrix, 16 * sizeof(T)); return *this; } + /*! + * \brief Sets the components of the matrix from another matrix + * \return A reference to this matrix + * + * \param matrix The other matrix + */ + template Matrix4& Matrix4::Set(const Matrix4& matrix) { @@ -761,18 +1129,34 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the matrix from another type of Matrix4 + * \return A reference to this matrix + * + * \param matrix Matrix4 of type U to convert its components + */ + template template Matrix4& Matrix4::Set(const Matrix4& matrix) { Set(F(matrix[ 0]), F(matrix[ 1]), F(matrix[ 2]), F(matrix[ 3]), - F(matrix[ 4]), F(matrix[ 5]), F(matrix[ 6]), F(matrix[ 7]), - F(matrix[ 8]), F(matrix[ 9]), F(matrix[10]), F(matrix[11]), - F(matrix[12]), F(matrix[13]), F(matrix[14]), F(matrix[15])); + F(matrix[ 4]), F(matrix[ 5]), F(matrix[ 6]), F(matrix[ 7]), + F(matrix[ 8]), F(matrix[ 9]), F(matrix[10]), F(matrix[11]), + F(matrix[12]), F(matrix[13]), F(matrix[14]), F(matrix[15])); return *this; } + /*! + * \brief Sets the components of the matrix from a quaternion + * \return A reference to this matrix which is the rotation of the quaternion + * + * \param rotation Quaternion representing a rotation of space + * + * \remark 3rd column and row are unchanged + */ + template Matrix4& Matrix4::SetRotation(const Quaternion& rotation) { @@ -804,6 +1188,15 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the matrix from a scale + * \return A reference to this matrix which is the scale of the Vector3 + * + * \param scale Vector3 representing the homothety + * + * \remark Components are unchanged, except the three first on the diagonal + */ + template Matrix4& Matrix4::SetScale(const Vector3& scale) { @@ -814,6 +1207,15 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the matrix from a translation + * \return A reference to this matrix which is the translation of the Vector3 + * + * \param translation Vector3 representing the translation + * + * \remark Components are unchanged, except the three first on the third row + */ + template Matrix4& Matrix4::SetTranslation(const Vector3& translation) { @@ -824,40 +1226,76 @@ namespace Nz return *this; } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Matrix4(m11, m12, m13, m14,\n ...)" + */ + template String Matrix4::ToString() const { StringStream ss; return ss << "Matrix4(" << m11 << ", " << m12 << ", " << m13 << ", " << m14 << ",\n" - << " " << m21 << ", " << m22 << ", " << m23 << ", " << m24 << ",\n" - << " " << m31 << ", " << m32 << ", " << m33 << ", " << m34 << ",\n" - << " " << m41 << ", " << m42 << ", " << m43 << ", " << m44 << ')'; + << " " << m21 << ", " << m22 << ", " << m23 << ", " << m24 << ",\n" + << " " << m31 << ", " << m32 << ", " << m33 << ", " << m34 << ",\n" + << " " << m41 << ", " << m42 << ", " << m43 << ", " << m44 << ')'; } + /*! + * \brief Transforms the Vector2 and two components by the matrix + * \return Vector2 transformed by the matrix + * + * \param vector To transform + * \param z Z Component of the imaginary Vector4 + * \param w W Component of the imaginary Vector4 + */ + template Vector2 Matrix4::Transform(const Vector2& vector, T z, T w) const { - return Vector2(m11*vector.x + m21*vector.y + m31*z + m41*w, - m12*vector.x + m22*vector.y + m32*z + m42*w); + return Vector2(m11 * vector.x + m21 * vector.y + m31 * z + m41 * w, + m12 * vector.x + m22 * vector.y + m32 * z + m42 * w); } + /*! + * \brief Transforms the Vector3 and one component by the matrix + * \return Vector3 transformed by the matrix + * + * \param vector To transform + * \param w W Component of the imaginary Vector4 + */ + template Vector3 Matrix4::Transform(const Vector3& vector, T w) const { - return Vector3(m11*vector.x + m21*vector.y + m31*vector.z + m41*w, - m12*vector.x + m22*vector.y + m32*vector.z + m42*w, - m13*vector.x + m23*vector.y + m33*vector.z + m43*w); + return Vector3(m11 * vector.x + m21 * vector.y + m31 * vector.z + m41 * w, + m12 * vector.x + m22 * vector.y + m32 * vector.z + m42 * w, + m13 * vector.x + m23 * vector.y + m33 * vector.z + m43 * w); } + /*! + * \brief Transforms the Vector4 by the matrix + * \return Vector4 transformed by the matrix + * + * \param vector To transform + */ + template Vector4 Matrix4::Transform(const Vector4& vector) const { - return Vector4(m11*vector.x + m21*vector.y + m31*vector.z + m41*vector.w, - m12*vector.x + m22*vector.y + m32*vector.z + m42*vector.w, - m13*vector.x + m23*vector.y + m33*vector.z + m43*vector.w, - m14*vector.x + m24*vector.y + m34*vector.z + m44*vector.w); + return Vector4(m11 * vector.x + m21 * vector.y + m31 * vector.z + m41 * vector.w, + m12 * vector.x + m22 * vector.y + m32 * vector.z + m42 * vector.w, + m13 * vector.x + m23 * vector.y + m33 * vector.z + m43 * vector.w, + m14 * vector.x + m24 * vector.y + m34 * vector.z + m44 * vector.w); } + /*! + * \brief Transposes the matrix + * \return A reference to this matrix transposed + * + * \see GetTransposed + */ + template Matrix4& Matrix4::Transpose() { @@ -871,51 +1309,87 @@ namespace Nz return *this; } + /*! + * \brief Converts matrix to pointer to its own data + * \return A pointer to the own data + * + * \remark Access to index greather than 15 is undefined behavior + */ + template - Matrix4::operator T*() + Matrix4::operator T* () { return &m11; } + /*! + * \brief Converts matrix to pointer to its own data + * \return A constant pointer to the own data + * + * \remark Access to index greather than 15 is undefined behavior + */ + template - Matrix4::operator const T*() const + Matrix4::operator const T* () const { return &m11; } + /*! + * \brief Gets the component (x, y) of the matrix + * \return A reference to the component (x, y) + * + * \remark Produce a NazaraError if you try to access index greater than 3 for x or y with NAZARA_MATH_SAFE defined + * \throw std::out_of_range if NAZARA_MATH_SAFE is defined and if you try to access index greater than 3 for x or y + */ + template T& Matrix4::operator()(unsigned int x, unsigned int y) { #if NAZARA_MATH_SAFE if (x > 3 || y > 3) { - StringStream ss; - ss << "Index out of range: (" << x << ", " << y << ") > (3,3)"; + String error("Index out of range: (" + String::Number(x) + ", " + String::Number(y) +") > (3, 3)"); - throw std::out_of_range(ss.ToString()); + NazaraError(error); + throw std::out_of_range(error); } #endif return (&m11)[y*4+x]; } + /*! + * \brief Gets the component (x, y) of the matrix + * \return The value of the component (x, y) + * + * \remark Produce a NazaraError if you try to access index greater than 3 for x or y with NAZARA_MATH_SAFE defined + * \throw std::out_of_range if NAZARA_MATH_SAFE is defined and if you try to access index greater than 3 for x or y + */ + template T Matrix4::operator()(unsigned int x, unsigned int y) const { #if NAZARA_MATH_SAFE if (x > 3 || y > 3) { - StringStream ss; - ss << "Index out of range: (" << x << ", " << y << ") > (3,3)"; + String error("Index out of range: (" + String::Number(x) + ", " + String::Number(y) +") > (3, 3)"); - NazaraError(ss); - throw std::out_of_range(ss.ToString()); + NazaraError(error); + throw std::out_of_range(error); } #endif return (&m11)[y*4+x]; } + /*! + * \brief Multiplies the components of the matrix with other matrix + * \return A matrix where components are the product of this matrix and the other one according to matrix product + * + * \param matrix The other matrix to multiply components with + */ + template Matrix4 Matrix4::operator*(const Matrix4& matrix) const { @@ -923,24 +1397,52 @@ namespace Nz return result.Concatenate(matrix); } + /*! + * \brief Multiplies the components of the matrix with a vector + * \return A vector transposed by this matrix + * + * \param vector The vector to multiply the matrix with + */ + template Vector2 Matrix4::operator*(const Vector2& vector) const { return Transform(vector); } + /*! + * \brief Multiplies the components of the matrix with a vector + * \return A vector transposed by this matrix + * + * \param vector The vector to multiply the matrix with + */ + template Vector3 Matrix4::operator*(const Vector3& vector) const { return Transform(vector); } + /*! + * \brief Multiplies the components of the matrix with a vector + * \return A vector transposed by this matrix + * + * \param vector The vector to multiply the matrix with + */ + template Vector4 Matrix4::operator*(const Vector4& vector) const { return Transform(vector); } + /*! + * \brief Multiplies the components of the matrix with a scalar + * \return A Matrix4 where components are the product of matrix'components and the scalar + * + * \param scalar The scalar to multiply the matrix'components with + */ + template Matrix4 Matrix4::operator*(T scalar) const { @@ -951,6 +1453,13 @@ namespace Nz return mat; } + /*! + * \brief Multiplies this matrix with another one + * \return A reference to this matrix which is the product with the other one + * + * \param matrix The matrix to multiply with + */ + template Matrix4& Matrix4::operator*=(const Matrix4& matrix) { @@ -959,6 +1468,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of the matrix with a scalar + * \return A reference to this matrix where components are the product with the scalar + * + * \param scalar The scalar to multiply with + */ + template Matrix4& Matrix4::operator*=(T scalar) { @@ -968,6 +1484,13 @@ namespace Nz return *this; } + /*! + * \brief Compares the matrix to other one + * \return true if the matrices are the same + * + * \param matrix Other matrix to compare with + */ + template bool Matrix4::operator==(const Matrix4& mat) const { @@ -978,30 +1501,64 @@ namespace Nz return true; } + /*! + * \brief Compares the matrix to other one + * \return false if the matrices are the same + * + * \param matrix Other matrix to compare with + */ + template bool Matrix4::operator!=(const Matrix4& mat) const { return !operator==(mat); } + /*! + * \brief Shorthand for the concatenation of two matrices + * \return A Matrix4 which is the product of two + * + * \param left Left-hand side matrix + * \param right Right-hand side matrix + * + * \see Concatenate + */ + template Matrix4 Matrix4::Concatenate(const Matrix4& left, const Matrix4& right) { - Matrix4 matrix(left); // Copie de la matrice de gauche - matrix.Concatenate(right); // Concaténation avec la matrice de droite + Matrix4 matrix(left); // Copy of left-hand side matrix + matrix.Concatenate(right); // Concatenation with right-hand side - return matrix; // Et on renvoie la matrice + return matrix; } + /*! + * \brief Shorthand for the concatenation of two affine matrices + * \return A Matrix4 which is the product of two + * + * \param left Left-hand side matrix + * \param right Right-hand side matrix + * + * \see ConcatenateAffine + */ + template Matrix4 Matrix4::ConcatenateAffine(const Matrix4& left, const Matrix4& right) { - Matrix4 matrix(left); // Copie de la matrice de gauche - matrix.ConcatenateAffine(right); // Concaténation (affine) avec la matrice de droite + Matrix4 matrix(left); // Copy of left-hand side matrix + matrix.ConcatenateAffine(right); // Affine concatenation with right-hand side - return matrix; // Et on renvoie la matrice + return matrix; } + /*! + * \brief Shorthand for the identity matrix + * \return A Matrix4 which is the identity matrix + * + * \see MakeIdentity + */ + template Matrix4 Matrix4::Identity() { @@ -1011,6 +1568,17 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'look at' matrix + * \return A Matrix4 which is the 'look at' matrix + * + * \param eye Position of the camera + * \param target Position of the target of the camera + * \param up Direction of up vector according to the orientation of camera + * + * \see MakeLookAt + */ + template Matrix4 Matrix4::LookAt(const Vector3& eye, const Vector3& target, const Vector3& up) { @@ -1020,6 +1588,20 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'orthographic' matrix + * \return A Matrix4 which is the 'orthographic' matrix + * + * \param left Distance between center and left + * \param right Distance between center and right + * \param top Distance between center and top + * \param bottom Distance between center and bottom + * \param zNear Distance where 'vision' begins + * \param zFar Distance where 'vision' ends + * + * \see MakeOrtho + */ + template Matrix4 Matrix4::Ortho(T left, T right, T top, T bottom, T zNear, T zFar) { @@ -1029,6 +1611,18 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'perspective' matrix + * \return A Matrix4 which is the 'perspective' matrix + * + * \param angle Unit depends on NAZARA_MATH_ANGLE_RADIAN + * \param ratio Rendering ratio (typically 16/9 or 4/3) + * \param zNear Distance where 'vision' begins + * \param zFar Distance where 'vision' ends + * + * \see MakePerspective + */ + template Matrix4 Matrix4::Perspective(T angle, T ratio, T zNear, T zFar) { @@ -1038,6 +1632,15 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'rotation' matrix + * \return A Matrix4 which is the rotation of the quaternion + * + * \param rotation Quaternion representing a rotation of space + * + * \see MakeRotation + */ + template Matrix4 Matrix4::Rotate(const Quaternion& rotation) { @@ -1047,6 +1650,15 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'scale' matrix + * \return A Matrix4 which is is the scale + * + * \param scale Vector3 representing the homothety + * + * \see MakeScale + */ + template Matrix4 Matrix4::Scale(const Vector3& scale) { @@ -1056,6 +1668,15 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'translation' matrix + * \return A Matrix4 which is is the translation + * + * \param translation Vector3 representing the translation + * + * \see MakeTranslation + */ + template Matrix4 Matrix4::Translate(const Vector3& translation) { @@ -1065,6 +1686,18 @@ namespace Nz return mat; } + /*! + * \brief Shorthand for the 'transform' matrix + * \return A Matrix4 which is transformation obtained by the translation and the rotation + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * + * \remark Rotation is applied first + * + * \see MakeTransform + */ + template Matrix4 Matrix4::Transform(const Vector3& translation, const Quaternion& rotation) { @@ -1074,6 +1707,19 @@ namespace Nz return mat; } + /*! + * \brief Shorthand for the 'transform' matrix + * \return A Matrix4 which is transformation obtained by the translation, the rotation and the scale + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * \param scale Vector3 representing the homothety + * + * \remark Rotation is applied first, then translation + * + * \see MakeTransform + */ + template Matrix4 Matrix4::Transform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale) { @@ -1083,6 +1729,16 @@ namespace Nz return mat; } + /*! + * \brief Shorthand for the 'view' matrix + * \return A Matrix4 which is the 'view matrix' + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * + * \see MakeViewMatrix + */ + template Matrix4 Matrix4::ViewMatrix(const Vector3& translation, const Quaternion& rotation) { @@ -1092,6 +1748,13 @@ namespace Nz return mat; } + /*! + * \brief Shorthand for the 'zero' matrix + * \return A Matrix4 with components (0 everywhere) + * + * \see MakeZero + */ + template Matrix4 Matrix4::Zero() { @@ -1102,12 +1765,28 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param matrix The matrix to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Matrix4& matrix) { return out << matrix.ToString(); } +/*! +* \brief Multiplies the components of the matrix with a scalar +* \return A Matrix4 where components are the product of matrix'components and the scalar +* +* \param scale The scalar to multiply the matrix'components with +* \param matrix Matrix to multiply with +*/ + template Nz::Matrix4 operator*(T scale, const Nz::Matrix4& matrix) {