diff --git a/include/RaZ/Math/Matrix.hpp b/include/RaZ/Math/Matrix.hpp index b87d4218..e430db4b 100644 --- a/include/RaZ/Math/Matrix.hpp +++ b/include/RaZ/Math/Matrix.hpp @@ -9,12 +9,12 @@ namespace Raz { -template -class Vector; - template class Matrix; +template +class Vector; + template std::ostream& operator<<(std::ostream& stream, const Matrix& mat); @@ -61,16 +61,16 @@ class Matrix { static constexpr Matrix identity() noexcept; /// Constructs a matrix from the given row vectors. /// \note All vectors must be of the same inner type as the matrix's, and must have a size equal to the matrix's width. - /// \tparam Vecs Types of the vectors to construct the matrix with. + /// \tparam VecsTs Types of the vectors to construct the matrix with. /// \param vecs Row vectors to construct the matrix with. - template - static constexpr Matrix fromRows(Vecs&&... vecs) noexcept; + template + static constexpr Matrix fromRows(VecsTs&&... vecs) noexcept; /// Constructs a matrix from the given column vectors. /// \note All vectors must be of the same inner type as the matrix's, and must have a size equal to the matrix's height. - /// \tparam Vecs Types of the vectors to construct the matrix with. + /// \tparam VecsTs Types of the vectors to construct the matrix with. /// \param vecs Column vectors to construct the matrix with. - template - static constexpr Matrix fromColumns(Vecs&&... vecs) noexcept; + template + static constexpr Matrix fromColumns(VecsTs&&... vecs) noexcept; /// Transposed matrix computation. /// \return Transposed matrix. @@ -211,36 +211,47 @@ class Matrix { template constexpr void setValues(T2&& val, Args&&... args) noexcept; - template - constexpr void setRows(Vec&& vec, Vecs&&... args) noexcept; + template + constexpr void setRows(VecT&& vec, VecsTs&&... args) noexcept; - template - constexpr void setColumns(Vec&& vec, Vecs&&... args) noexcept; + template + constexpr void setColumns(VecT&& vec, VecsTs&&... args) noexcept; std::array m_data {}; }; /// Matrix-matrix multiplication operator. -/// \tparam W Width of the left-hand matrix. -/// \tparam H Height of the left-hand matrix & width of the resulting one. -/// \tparam WI Width of the right-hand matrix & height of the resulting one. -/// \tparam HI Height of the right-hand matrix. -/// \param mat1 Left-hand matrix. -/// \param mat2 Right-hand matrix. +/// \tparam T Type of the matrices' data. +/// \tparam WL Width of the left-hand side matrix. +/// \tparam HL Height of the left-hand side matrix & width of the resulting one. +/// \tparam WR Width of the right-hand side matrix & height of the resulting one. +/// \tparam HR Height of the right-hand side matrix. +/// \param mat1 Left-hand side matrix. +/// \param mat2 Right-hand side matrix. /// \return Result of the multiplied matrices. -template -constexpr Matrix operator*(const Matrix& mat1, const Matrix& mat2) noexcept; +template +constexpr Matrix operator*(const Matrix& mat1, const Matrix& mat2) noexcept; /// Matrix-vector multiplication operator (assumes the vector to be vertical). /// \tparam T Type of the matrix's & vector's data. /// \tparam W Width of the matrix & size of the input vector. /// \tparam H Height of the matrix & size of the resulting vector. -/// \param mat Left-hand matrix. -/// \param vec Right-hand vector. +/// \param mat Left-hand side matrix. +/// \param vec Right-hand side vector. /// \return Result of the matrix-vector multiplication. template constexpr Vector operator*(const Matrix& mat, const Vector& vec) noexcept; +/// Vector-matrix multiplication operator (assumes the vector to be horizontal). +/// \tparam T Type of the vector's & matrix's data. +/// \tparam W Width of the matrix & size of the resulting vector. +/// \tparam H Height of the matrix & size of the input vector. +/// \param vec Left-hand side vector. +/// \param mat Right-hand side matrix. +/// \return Result of the vector-matrix multiplication. +template +constexpr Vector operator*(const Vector& vec, const Matrix& mat) noexcept; + // Aliases template using Mat2 = Matrix; diff --git a/include/RaZ/Math/Matrix.inl b/include/RaZ/Math/Matrix.inl index c49e819f..3191c11f 100644 --- a/include/RaZ/Math/Matrix.inl +++ b/include/RaZ/Math/Matrix.inl @@ -177,7 +177,7 @@ constexpr Matrix::Matrix(const Matrix& mat) noexcept { std::size_t widthStride = 0; for (std::size_t heightIndex = 0; heightIndex < H; ++heightIndex) { - std::size_t resIndex = heightIndex * W; + const std::size_t resIndex = heightIndex * W; for (std::size_t widthIndex = 0; widthIndex < W; ++widthIndex) { const std::size_t finalIndex = resIndex + widthIndex; @@ -219,7 +219,7 @@ template constexpr Matrix Matrix::identity() noexcept { static_assert(W == H, "Error: Matrix must be a square one."); - Matrix res; + Matrix res; for (std::size_t diagIndex = 0; diagIndex < W; ++diagIndex) res[diagIndex * W + diagIndex] = 1.f; @@ -228,22 +228,22 @@ constexpr Matrix Matrix::identity() noexcept { } template -template -constexpr Matrix Matrix::fromRows(Vecs&&... vecs) noexcept { - static_assert(sizeof...(Vecs) == H, "Error: A Matrix can't be constructed with more or less vectors than it can hold."); +template +constexpr Matrix Matrix::fromRows(VecsTs&&... vecs) noexcept { + static_assert(sizeof...(VecsTs) == H, "Error: A Matrix can't be constructed with more or less vectors than it can hold."); Matrix res; - res.setRows(std::forward(vecs)...); + res.setRows(std::forward(vecs)...); return res; } template -template -constexpr Matrix Matrix::fromColumns(Vecs&&... vecs) noexcept { - static_assert(sizeof...(Vecs) == W, "Error: A Matrix can't be constructed with more or less vectors than it can hold."); +template +constexpr Matrix Matrix::fromColumns(VecsTs&&... vecs) noexcept { + static_assert(sizeof...(VecsTs) == W, "Error: A Matrix can't be constructed with more or less vectors than it can hold."); Matrix res; - res.setColumns(std::forward(vecs)...); + res.setColumns(std::forward(vecs)...); return res; } @@ -306,7 +306,7 @@ constexpr Vector Matrix::recoverColumn(std::size_t columnIndex) c } template -constexpr bool Matrix::strictlyEquals(const Matrix& mat) const noexcept { +constexpr bool Matrix::strictlyEquals(const Matrix& mat) const noexcept { return std::equal(m_data.cbegin(), m_data.cend(), mat.getData().cbegin()); } @@ -322,62 +322,62 @@ constexpr std::size_t Matrix::hash(std::size_t seed) const noexcept { template constexpr Matrix Matrix::operator+(const Matrix& mat) const noexcept { - Matrix res = *this; + Matrix res = *this; res += mat; return res; } template constexpr Matrix Matrix::operator+(T val) const noexcept { - Matrix res = *this; + Matrix res = *this; res += val; return res; } template constexpr Matrix Matrix::operator-(const Matrix& mat) const noexcept { - Matrix res = *this; + Matrix res = *this; res -= mat; return res; } template constexpr Matrix Matrix::operator-(T val) const noexcept { - Matrix res = *this; + Matrix res = *this; res -= val; return res; } template constexpr Matrix Matrix::operator%(const Matrix& mat) const noexcept { - Matrix res = *this; + Matrix res = *this; res %= mat; return res; } template constexpr Matrix Matrix::operator*(T val) const noexcept { - Matrix res = *this; + Matrix res = *this; res *= val; return res; } template constexpr Matrix Matrix::operator/(const Matrix& mat) const noexcept { - Matrix res = *this; + Matrix res = *this; res /= mat; return res; } template constexpr Matrix Matrix::operator/(T val) const noexcept { - Matrix res = *this; + Matrix res = *this; res /= val; return res; } template -constexpr Matrix& Matrix::operator+=(const Matrix& mat) noexcept { +constexpr Matrix& Matrix::operator+=(const Matrix& mat) noexcept { for (std::size_t i = 0; i < m_data.size(); ++i) m_data[i] += mat[i]; return *this; @@ -385,13 +385,13 @@ constexpr Matrix& Matrix::operator+=(const Matrix& ma template constexpr Matrix& Matrix::operator+=(T val) noexcept { - for (T& it : m_data) - it += val; + for (T& elt : m_data) + elt += val; return *this; } template -constexpr Matrix& Matrix::operator-=(const Matrix& mat) noexcept { +constexpr Matrix& Matrix::operator-=(const Matrix& mat) noexcept { for (std::size_t i = 0; i < m_data.size(); ++i) m_data[i] -= mat[i]; return *this; @@ -399,13 +399,13 @@ constexpr Matrix& Matrix::operator-=(const Matrix& ma template constexpr Matrix& Matrix::operator-=(T val) noexcept { - for (T& it : m_data) - it -= val; + for (T& elt : m_data) + elt -= val; return *this; } template -constexpr Matrix& Matrix::operator%=(const Matrix& mat) noexcept { +constexpr Matrix& Matrix::operator%=(const Matrix& mat) noexcept { for (std::size_t i = 0; i < m_data.size(); ++i) m_data[i] *= mat[i]; return *this; @@ -413,13 +413,13 @@ constexpr Matrix& Matrix::operator%=(const Matrix& ma template constexpr Matrix& Matrix::operator*=(T val) noexcept { - for (T& it : m_data) - it *= val; + for (T& elt : m_data) + elt *= val; return *this; } template -constexpr Matrix& Matrix::operator/=(const Matrix& mat) noexcept { +constexpr Matrix& Matrix::operator/=(const Matrix& mat) noexcept { for (std::size_t i = 0; i < m_data.size(); ++i) m_data[i] /= mat[i]; return *this; @@ -427,19 +427,19 @@ constexpr Matrix& Matrix::operator/=(const Matrix& ma template constexpr Matrix& Matrix::operator/=(T val) noexcept { - for (T& it : m_data) - it /= val; + for (T& elt : m_data) + elt /= val; return *this; } template -constexpr Matrix& Matrix::operator*=(const Matrix& mat) noexcept { +constexpr Matrix& Matrix::operator*=(const Matrix& mat) noexcept { *this = *this * mat; return *this; } template -constexpr bool Matrix::operator==(const Matrix& mat) const noexcept { +constexpr bool Matrix::operator==(const Matrix& mat) const noexcept { if constexpr (std::is_floating_point_v) return FloatUtils::areNearlyEqual(*this, mat); else @@ -488,46 +488,46 @@ constexpr void Matrix::setValues(T2&& val, Args&&... args) noexcept { } template -template -constexpr void Matrix::setRows(Vec&& vec, Vecs&&... args) noexcept { - static_assert(std::is_same_v, Vector>, "Error: Rows must all be vectors of the same type & size."); +template +constexpr void Matrix::setRows(VecT&& vec, VecsTs&&... args) noexcept { + static_assert(std::is_same_v, Vector>, "Error: Rows must all be vectors of the same type & size."); constexpr std::size_t firstIndex = H - sizeof...(args) - 1; for (std::size_t widthIndex = 0; widthIndex < W; ++widthIndex) - m_data[firstIndex + widthIndex * H] = vec[widthIndex]; + m_data[firstIndex + widthIndex * H] = std::forward(vec)[widthIndex]; if constexpr (sizeof...(args) > 0) - setRows(std::forward(args)...); + setRows(std::forward(args)...); } template -template -constexpr void Matrix::setColumns(Vec&& vec, Vecs&&... args) noexcept { - static_assert(std::is_same_v, Vector>, "Error: Columns must all be vectors of the same type & size."); +template +constexpr void Matrix::setColumns(VecT&& vec, VecsTs&&... args) noexcept { + static_assert(std::is_same_v, Vector>, "Error: Columns must all be vectors of the same type & size."); constexpr std::size_t firstIndex = H * (W - sizeof...(args) - 1); for (std::size_t heightIndex = 0; heightIndex < H; ++heightIndex) - m_data[firstIndex + heightIndex] = vec[heightIndex]; + m_data[firstIndex + heightIndex] = std::forward(vec)[heightIndex]; if constexpr (sizeof...(args) > 0) - setColumns(std::forward(args)...); + setColumns(std::forward(args)...); } -template -constexpr Matrix operator*(const Matrix& mat1, const Matrix& mat2) noexcept { - static_assert(W == HI, "Error: The left-hand matrix's width must be equal to the right-hand matrix's height."); +template +constexpr Matrix operator*(const Matrix& mat1, const Matrix& mat2) noexcept { + static_assert(WL == HR, "Error: The left-hand side matrix's width must be equal to the right-hand side matrix's height."); - Matrix res; + Matrix res; - for (std::size_t widthIndex = 0; widthIndex < WI; ++widthIndex) { - const std::size_t finalWidthIndex = widthIndex * H; + for (std::size_t widthIndex = 0; widthIndex < WR; ++widthIndex) { + const std::size_t finalWidthIndex = widthIndex * HL; - for (std::size_t heightIndex = 0; heightIndex < H; ++heightIndex) { + for (std::size_t heightIndex = 0; heightIndex < HL; ++heightIndex) { T& val = res[finalWidthIndex + heightIndex]; - for (std::size_t stride = 0; stride < W; ++stride) + for (std::size_t stride = 0; stride < WL; ++stride) val += mat1.getElement(stride, heightIndex) * mat2.getElement(widthIndex, stride); } } @@ -550,4 +550,19 @@ constexpr Vector operator*(const Matrix& mat, const Vector& return res; } +template +constexpr Vector operator*(const Vector& vec, const Matrix& mat) noexcept { + // This multiplication is made assuming the vector to be horizontal + Vector res; + + for (std::size_t widthIndex = 0; widthIndex < W; ++widthIndex) { + const std::size_t finalWidthIndex = widthIndex * H; + + for (std::size_t heightIndex = 0; heightIndex < H; ++heightIndex) + res[widthIndex] += vec[heightIndex] * mat[finalWidthIndex + heightIndex]; + } + + return res; +} + } // namespace Raz diff --git a/include/RaZ/Math/Quaternion.hpp b/include/RaZ/Math/Quaternion.hpp index e817d41d..52816ab0 100644 --- a/include/RaZ/Math/Quaternion.hpp +++ b/include/RaZ/Math/Quaternion.hpp @@ -45,7 +45,7 @@ class Quaternion { /// Creates a quaternion representing an identity transformation. /// \return Identity quaternion. - static constexpr Quaternion identity() noexcept { return Quaternion(1, 0, 0, 0); } + static constexpr Quaternion identity() noexcept { return Quaternion(1, 0, 0, 0); } /// Computes the dot product between quaternions. /// \param quat Quaternion to compute the dot product with. diff --git a/include/RaZ/Math/Quaternion.inl b/include/RaZ/Math/Quaternion.inl index 003d7040..26b63730 100644 --- a/include/RaZ/Math/Quaternion.inl +++ b/include/RaZ/Math/Quaternion.inl @@ -1,5 +1,3 @@ -#include "RaZ/Math/Constants.hpp" - namespace Raz { template @@ -13,7 +11,7 @@ constexpr Quaternion::Quaternion(Radians angle, const Vec3& axis) noexc template constexpr Quaternion Quaternion::normalize() const noexcept { - Quaternion res = *this; + Quaternion res = *this; const T invNorm = 1 / computeNorm(); res.m_real *= invNorm; @@ -73,16 +71,16 @@ constexpr Quaternion Quaternion::slerp(const Quaternion& quat, T coeff) co template constexpr Quaternion Quaternion::conjugate() const noexcept { - Quaternion res = *this; - res.m_complexes = -m_complexes; + Quaternion res = *this; + res.m_complexes = -m_complexes; return res; } template constexpr Quaternion Quaternion::inverse() const noexcept { - Quaternion res = *this; - const T sqNorm = computeSquaredNorm(); + Quaternion res = *this; + const T sqNorm = computeSquaredNorm(); if (sqNorm > 0) { const T invSqNorm = 1 / sqNorm; @@ -118,14 +116,14 @@ constexpr Mat4 Quaternion::computeMatrix() const noexcept { template constexpr Quaternion Quaternion::operator*(const Quaternion& quat) const noexcept { - Quaternion res = *this; + Quaternion res = *this; res *= quat; return res; } template constexpr Quaternion& Quaternion::operator*=(const Quaternion& quat) noexcept { - const Quaternion copy = *this; + const Quaternion copy = *this; m_real = copy.m_real * quat.m_real - copy.m_complexes.x() * quat.m_complexes.x() @@ -163,10 +161,10 @@ std::ostream& operator<<(std::ostream& stream, const Quaternion& quat) { template constexpr Quaternion Quaternion::lerp(const Quaternion& quat, T currCoeff, T otherCoeff) const noexcept { - return Quaternion(m_real * currCoeff + quat.m_real * otherCoeff, - m_complexes.x() * currCoeff + quat.m_complexes.x() * otherCoeff, - m_complexes.y() * currCoeff + quat.m_complexes.y() * otherCoeff, - m_complexes.z() * currCoeff + quat.m_complexes.z() * otherCoeff); + return Quaternion(m_real * currCoeff + quat.m_real * otherCoeff, + m_complexes.x() * currCoeff + quat.m_complexes.x() * otherCoeff, + m_complexes.y() * currCoeff + quat.m_complexes.y() * otherCoeff, + m_complexes.z() * currCoeff + quat.m_complexes.z() * otherCoeff); } template diff --git a/include/RaZ/Math/Vector.hpp b/include/RaZ/Math/Vector.hpp index b14cd4be..dc74319c 100644 --- a/include/RaZ/Math/Vector.hpp +++ b/include/RaZ/Math/Vector.hpp @@ -10,9 +10,6 @@ namespace Raz { -template -class Matrix; - template class Vector; @@ -257,16 +254,6 @@ constexpr Vector operator+(T val, const Vector& vec) noexcept template constexpr Vector operator*(T val, const Vector& vec) noexcept { return vec * val; } -/// Vector-matrix multiplication operator (assumes the vector to be horizontal). -/// \tparam T Type of the vector's & matrix's data. -/// \tparam Size Size of the input vector & height of the matrix. -/// \tparam W Width of the matrix & size of the resulting vector. -/// \param vec Left-hand vector. -/// \param mat Right-hand matrix. -/// \return Result of the vector-matrix multiplication. -template -constexpr Vector operator*(const Vector& vec, const Matrix& mat) noexcept; - // Deduction guides template diff --git a/include/RaZ/Math/Vector.inl b/include/RaZ/Math/Vector.inl index 4d07cd96..00d0204e 100644 --- a/include/RaZ/Math/Vector.inl +++ b/include/RaZ/Math/Vector.inl @@ -27,49 +27,45 @@ constexpr Vector::Vector(T val) noexcept { template constexpr const T& Vector::x() const noexcept { static_assert(Size >= 1, "Error: Getting the X component requires the vector to be of size 1 or more."); - return m_data[0]; } template constexpr T& Vector::x() noexcept { - return const_cast(static_cast*>(this)->x()); + return const_cast(static_cast(this)->x()); } template constexpr const T& Vector::y() const noexcept { static_assert(Size >= 2, "Error: Getting the Y component requires the vector to be of size 2 or more."); - return m_data[1]; } template constexpr T& Vector::y() noexcept { - return const_cast(static_cast*>(this)->y()); + return const_cast(static_cast(this)->y()); } template constexpr const T& Vector::z() const noexcept { static_assert(Size >= 3, "Error: Getting the Z component requires the vector to be of size 3 or more."); - return m_data[2]; } template constexpr T& Vector::z() noexcept { - return const_cast(static_cast*>(this)->z()); + return const_cast(static_cast(this)->z()); } template constexpr const T& Vector::w() const noexcept { static_assert(Size >= 4, "Error: Getting the W component requires the vector to be of size 4 or more."); - return m_data[3]; } template constexpr T& Vector::w() noexcept { - return const_cast(static_cast*>(this)->w()); + return const_cast(static_cast(this)->w()); } template @@ -140,7 +136,7 @@ constexpr std::size_t Vector::hash(std::size_t seed) const noexcept { template constexpr Vector Vector::operator-() const noexcept { - Vector res; + Vector res; for (std::size_t i = 0; i < Size; ++i) res.m_data[i] = -m_data[i]; return res; @@ -148,56 +144,56 @@ constexpr Vector Vector::operator-() const noexcept { template constexpr Vector Vector::operator+(const Vector& vec) const noexcept { - Vector res = *this; + Vector res = *this; res += vec; return res; } template constexpr Vector Vector::operator+(T val) const noexcept { - Vector res = *this; + Vector res = *this; res += val; return res; } template constexpr Vector Vector::operator-(const Vector& vec) const noexcept { - Vector res = *this; + Vector res = *this; res -= vec; return res; } template constexpr Vector Vector::operator-(T val) const noexcept { - Vector res = *this; + Vector res = *this; res -= val; return res; } template constexpr Vector Vector::operator*(const Vector& vec) const noexcept { - Vector res = *this; + Vector res = *this; res *= vec; return res; } template constexpr Vector Vector::operator*(T val) const noexcept { - Vector res = *this; + Vector res = *this; res *= val; return res; } template constexpr Vector Vector::operator/(const Vector& vec) const noexcept { - Vector res = *this; + Vector res = *this; res /= vec; return res; } template constexpr Vector Vector::operator/(T val) const noexcept { - Vector res = *this; + Vector res = *this; res /= val; return res; } @@ -266,7 +262,7 @@ constexpr Vector& Vector::operator/=(T val) noexcept { } template -constexpr bool Vector::operator==(const Vector& vec) const noexcept { +constexpr bool Vector::operator==(const Vector& vec) const noexcept { if constexpr (std::is_floating_point_v) return FloatUtils::areNearlyEqual(*this, vec); else @@ -296,19 +292,4 @@ std::ostream& operator<<(std::ostream& stream, const Vector& vec) { return stream; } -template -constexpr Vector operator*(const Vector& vec, const Matrix& mat) noexcept { - // This multiplication is made assuming the vector to be horizontal - Vector res; - - for (std::size_t widthIndex = 0; widthIndex < W; ++widthIndex) { - const std::size_t finalWidthIndex = widthIndex * Size; - - for (std::size_t heightIndex = 0; heightIndex < Size; ++heightIndex) - res[widthIndex] += vec[heightIndex] * mat[finalWidthIndex + heightIndex]; - } - - return res; -} - } // namespace Raz