diff --git a/Code/Framework/AzCore/AzCore/Math/Matrix3x3.h b/Code/Framework/AzCore/AzCore/Math/Matrix3x3.h index e1736e1444..973bb52df3 100644 --- a/Code/Framework/AzCore/AzCore/Math/Matrix3x3.h +++ b/Code/Framework/AzCore/AzCore/Math/Matrix3x3.h @@ -142,27 +142,44 @@ namespace AZ void SetBasis(const Vector3& basisX, const Vector3& basisY, const Vector3& basisZ); //! @} - Matrix3x3 operator*(const Matrix3x3& rhs) const; - //! Calculates (this->GetTranspose() * rhs). Matrix3x3 TransposedMultiply(const Matrix3x3& rhs) const; //! Post-multiplies the matrix by a vector. Vector3 operator*(const Vector3& rhs) const; - Matrix3x3 operator+(const Matrix3x3& rhs) const; - Matrix3x3 operator-(const Matrix3x3& rhs) const; - - Matrix3x3 operator*(float multiplier) const; - Matrix3x3 operator/(float divisor) const; - - Matrix3x3 operator-() const; - - Matrix3x3& operator*=(const Matrix3x3& rhs); + //! Operator for matrix-matrix addition. + //! @{ + [[nodiscard]] Matrix3x3 operator+(const Matrix3x3& rhs) const; Matrix3x3& operator+=(const Matrix3x3& rhs); + //! @} + + //! Operator for matrix-matrix substraction. + //! @{ + [[nodiscard]] Matrix3x3 operator-(const Matrix3x3& rhs) const; Matrix3x3& operator-=(const Matrix3x3& rhs); + //! @} + + //! Operator for matrix-matrix multiplication. + //! @{ + [[nodiscard]] Matrix3x3 operator*(const Matrix3x3& rhs) const; + Matrix3x3& operator*=(const Matrix3x3& rhs); + //! @} + + //! Operator for multiplying all matrix's elements with a scalar + //! @{ + [[nodiscard]] Matrix3x3 operator*(float multiplier) const; Matrix3x3& operator*=(float multiplier); + //! @} + + //! Operator for dividing all matrix's elements with a scalar + //! @{ + [[nodiscard]] Matrix3x3 operator/(float divisor) const; Matrix3x3& operator/=(float divisor); + //! @} + + //! Operator for negating all matrix's elements + [[nodiscard]] Matrix3x3 operator-() const; bool operator==(const Matrix3x3& rhs) const; bool operator!=(const Matrix3x3& rhs) const; @@ -187,7 +204,10 @@ namespace AZ //! @} //! Gets the scale part of the transformation, i.e. the length of the scale components. - Vector3 RetrieveScale() const; + [[nodiscard]] Vector3 RetrieveScale() const; + + //! Gets the squared scale part of the transformation (the squared length of the basis vectors). + [[nodiscard]] Vector3 RetrieveScaleSq() const; //! Gets the scale part of the transformation as in RetrieveScale, and also removes this scaling from the matrix. Vector3 ExtractScale(); @@ -195,6 +215,9 @@ namespace AZ //! Quick multiplication by a scale matrix, equivalent to m*=Matrix3x3::CreateScale(scale). void MultiplyByScale(const Vector3& scale); + //! Returns a matrix with the reciprocal scale, keeping the same rotation and translation. + [[nodiscard]] Matrix3x3 GetReciprocalScaled() const; + //! Polar decomposition, M=U*H, U is orthogonal (unitary) and H is symmetric (hermitian). //! This function returns the orthogonal part only Matrix3x3 GetPolarDecomposition() const; @@ -241,7 +264,9 @@ namespace AZ //! Note that this is not the usual multiplication order for transformations. Vector3& operator*=(Vector3& lhs, const Matrix3x3& rhs); + //! Pre-multiplies the matrix by a scalar. Matrix3x3 operator*(float lhs, const Matrix3x3& rhs); -} + +} // namespace AZ #include diff --git a/Code/Framework/AzCore/AzCore/Math/Matrix3x3.inl b/Code/Framework/AzCore/AzCore/Math/Matrix3x3.inl index ff92da1398..6b4dccf3c1 100644 --- a/Code/Framework/AzCore/AzCore/Math/Matrix3x3.inl +++ b/Code/Framework/AzCore/AzCore/Math/Matrix3x3.inl @@ -392,14 +392,6 @@ namespace AZ } - AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(const Matrix3x3& rhs) const - { - Matrix3x3 result; - Simd::Vec3::Mat3x3Multiply(GetSimdValues(), rhs.GetSimdValues(), result.GetSimdValues()); - return result; - } - - AZ_MATH_INLINE Matrix3x3 Matrix3x3::TransposedMultiply(const Matrix3x3& rhs) const { Matrix3x3 result; @@ -416,51 +408,12 @@ namespace AZ AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator+(const Matrix3x3& rhs) const { - return Matrix3x3(Simd::Vec3::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()) - , Simd::Vec3::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()) - , Simd::Vec3::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())); - } - - - AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-(const Matrix3x3& rhs) const - { - return Matrix3x3(Simd::Vec3::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()) - , Simd::Vec3::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()) - , Simd::Vec3::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())); - } - - - AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(float multiplier) const - { - const Simd::Vec3::FloatType mulVec = Simd::Vec3::Splat(multiplier); - return Matrix3x3(Simd::Vec3::Mul(m_rows[0].GetSimdValue(), mulVec) - , Simd::Vec3::Mul(m_rows[1].GetSimdValue(), mulVec) - , Simd::Vec3::Mul(m_rows[2].GetSimdValue(), mulVec)); - } - - - AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator/(float divisor) const - { - const Simd::Vec3::FloatType divVec = Simd::Vec3::Splat(divisor); - return Matrix3x3(Simd::Vec3::Div(m_rows[0].GetSimdValue(), divVec) - , Simd::Vec3::Div(m_rows[1].GetSimdValue(), divVec) - , Simd::Vec3::Div(m_rows[2].GetSimdValue(), divVec)); - } - - - AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-() const - { - const Simd::Vec3::FloatType zeroVec = Simd::Vec3::ZeroFloat(); - return Matrix3x3(Simd::Vec3::Sub(zeroVec, m_rows[0].GetSimdValue()) - , Simd::Vec3::Sub(zeroVec, m_rows[1].GetSimdValue()) - , Simd::Vec3::Sub(zeroVec, m_rows[2].GetSimdValue())); - } - - - AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator*=(const Matrix3x3& rhs) - { - *this = *this * rhs; - return *this; + return Matrix3x3 + ( + Simd::Vec3::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()), + Simd::Vec3::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()), + Simd::Vec3::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()) + ); } @@ -471,6 +424,17 @@ namespace AZ } + AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-(const Matrix3x3& rhs) const + { + return Matrix3x3 + ( + Simd::Vec3::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()), + Simd::Vec3::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()), + Simd::Vec3::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()) + ); + } + + AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator-=(const Matrix3x3& rhs) { *this = *this - rhs; @@ -478,6 +442,33 @@ namespace AZ } + AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(const Matrix3x3& rhs) const + { + Matrix3x3 result; + Simd::Vec3::Mat3x3Multiply(GetSimdValues(), rhs.GetSimdValues(), result.GetSimdValues()); + return result; + } + + + AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator*=(const Matrix3x3& rhs) + { + *this = *this * rhs; + return *this; + } + + + AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(float multiplier) const + { + const Simd::Vec3::FloatType mulVec = Simd::Vec3::Splat(multiplier); + return Matrix3x3 + ( + Simd::Vec3::Mul(m_rows[0].GetSimdValue(), mulVec), + Simd::Vec3::Mul(m_rows[1].GetSimdValue(), mulVec), + Simd::Vec3::Mul(m_rows[2].GetSimdValue(), mulVec) + ); + } + + AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator*=(float multiplier) { *this = *this * multiplier; @@ -485,6 +476,18 @@ namespace AZ } + AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator/(float divisor) const + { + const Simd::Vec3::FloatType divVec = Simd::Vec3::Splat(divisor); + return Matrix3x3 + ( + Simd::Vec3::Div(m_rows[0].GetSimdValue(), divVec), + Simd::Vec3::Div(m_rows[1].GetSimdValue(), divVec), + Simd::Vec3::Div(m_rows[2].GetSimdValue(), divVec) + ); + } + + AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator/=(float divisor) { *this = *this / divisor; @@ -492,6 +495,18 @@ namespace AZ } + AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-() const + { + const Simd::Vec3::FloatType zeroVec = Simd::Vec3::ZeroFloat(); + return Matrix3x3 + ( + Simd::Vec3::Sub(zeroVec, m_rows[0].GetSimdValue()), + Simd::Vec3::Sub(zeroVec, m_rows[1].GetSimdValue()), + Simd::Vec3::Sub(zeroVec, m_rows[2].GetSimdValue()) + ); + } + + AZ_MATH_INLINE bool Matrix3x3::operator==(const Matrix3x3& rhs) const { return (Simd::Vec3::CmpAllEq(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()) @@ -552,6 +567,12 @@ namespace AZ } + AZ_MATH_INLINE Vector3 Matrix3x3::RetrieveScaleSq() const + { + return Vector3(GetBasisX().GetLengthSq(), GetBasisY().GetLengthSq(), GetBasisZ().GetLengthSq()); + } + + AZ_MATH_INLINE Vector3 Matrix3x3::ExtractScale() { const Vector3 x = GetBasisX(); @@ -584,6 +605,14 @@ namespace AZ } + AZ_MATH_INLINE Matrix3x3 Matrix3x3::GetReciprocalScaled() const + { + Matrix3x3 result = *this; + result.MultiplyByScale(RetrieveScaleSq().GetReciprocal()); + return result; + } + + AZ_MATH_INLINE void Matrix3x3::GetPolarDecomposition(Matrix3x3* orthogonalOut, Matrix3x3* symmetricOut) const { *orthogonalOut = GetPolarDecomposition(); @@ -679,8 +708,6 @@ namespace AZ AZ_MATH_INLINE Matrix3x3 operator*(float lhs, const Matrix3x3& rhs) { - const Simd::Vec3::FloatType lhsVec = Simd::Vec3::Splat(lhs); - const Simd::Vec3::FloatType* rows = rhs.GetSimdValues(); - return Matrix3x3(Simd::Vec3::Mul(lhsVec, rows[0]), Simd::Vec3::Mul(lhsVec, rows[1]), Simd::Vec3::Mul(lhsVec, rows[2])); + return rhs * lhs; } -} +} // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Math/Matrix3x4.h b/Code/Framework/AzCore/AzCore/Math/Matrix3x4.h index 09f443c1cf..a18f1e7565 100644 --- a/Code/Framework/AzCore/AzCore/Math/Matrix3x4.h +++ b/Code/Framework/AzCore/AzCore/Math/Matrix3x4.h @@ -225,23 +225,38 @@ namespace AZ //! Sets the three basis vectors and the translation. void SetBasisAndTranslation(const Vector3& basisX, const Vector3& basisY, const Vector3& basisZ, const Vector3& translation); - //! Operator for matrix-matrix multiplication. - [[nodiscard]] Matrix3x4 operator*(const Matrix3x4& rhs) const; - - //! Compound assignment operator for matrix-matrix multiplication. - Matrix3x4& operator*=(const Matrix3x4& rhs); - //! Operator for matrix-matrix addition. + //! @{ [[nodiscard]] Matrix3x4 operator+(const Matrix3x4& rhs) const; - - //! Compound assignment operator for matrix-matrix addition. Matrix3x4& operator+=(const Matrix3x4& rhs); + //! @} + + //! Operator for matrix-matrix substraction. + //! @{ + [[nodiscard]] Matrix3x4 operator-(const Matrix3x4& rhs) const; + Matrix3x4& operator-=(const Matrix3x4& rhs); + //! @} + + //! Operator for matrix-matrix multiplication. + //! @{ + [[nodiscard]] Matrix3x4 operator*(const Matrix3x4& rhs) const; + Matrix3x4& operator*=(const Matrix3x4& rhs); + //! @} //! Operator for multiplying all matrix's elements with a scalar - [[nodiscard]] Matrix3x4 operator*(float scalar) const; + //! @{ + [[nodiscard]] Matrix3x4 operator*(float multiplier) const; + Matrix3x4& operator*=(float multiplier); + //! @} - //! Compound assignment operator for multiplying all matrix's elements with a scalar - Matrix3x4& operator*=(float scalar); + //! Operator for dividing all matrix's elements with a scalar + //! @{ + [[nodiscard]] Matrix3x4 operator/(float divisor) const; + Matrix3x4& operator/=(float divisor); + //! @} + + //! Operator for negating all matrix's elements + [[nodiscard]] Matrix3x4 operator-() const; //! Operator for transforming a Vector3. [[nodiscard]] Vector3 operator*(const Vector3& rhs) const; @@ -353,6 +368,10 @@ namespace AZ Vector4 m_rows[RowCount]; }; + + //! Pre-multiplies the matrix by a scalar. + Matrix3x4 operator*(float lhs, const Matrix3x4& rhs); + } // namespace AZ #include diff --git a/Code/Framework/AzCore/AzCore/Math/Matrix3x4.inl b/Code/Framework/AzCore/AzCore/Math/Matrix3x4.inl index 232e8a5b30..781dcf9b66 100644 --- a/Code/Framework/AzCore/AzCore/Math/Matrix3x4.inl +++ b/Code/Framework/AzCore/AzCore/Math/Matrix3x4.inl @@ -472,21 +472,6 @@ namespace AZ } - AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator*(const Matrix3x4& rhs) const - { - Matrix3x4 result; - Simd::Vec4::Mat3x4Multiply(GetSimdValues(), rhs.GetSimdValues(), result.GetSimdValues()); - return result; - } - - - AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator*=(const Matrix3x4& rhs) - { - *this = *this * rhs; - return *this; - } - - AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator+(const Matrix3x4& rhs) const { return Matrix3x4 @@ -505,25 +490,89 @@ namespace AZ } - AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator*(float scalar) const + AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator-(const Matrix3x4& rhs) const { - const Vector4 vector4Scalar(scalar); return Matrix3x4 ( - Simd::Vec4::Mul(m_rows[0].GetSimdValue(), vector4Scalar.GetSimdValue()), - Simd::Vec4::Mul(m_rows[1].GetSimdValue(), vector4Scalar.GetSimdValue()), - Simd::Vec4::Mul(m_rows[2].GetSimdValue(), vector4Scalar.GetSimdValue()) + Simd::Vec4::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()), + Simd::Vec4::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()), + Simd::Vec4::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()) ); } - AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator*=(float scalar) + AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator-=(const Matrix3x4& rhs) { - *this = *this * scalar; + *this = *this - rhs; return *this; } + AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator*(const Matrix3x4& rhs) const + { + Matrix3x4 result; + Simd::Vec4::Mat3x4Multiply(GetSimdValues(), rhs.GetSimdValues(), result.GetSimdValues()); + return result; + } + + + AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator*=(const Matrix3x4& rhs) + { + *this = *this * rhs; + return *this; + } + + + AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator*(float multiplier) const + { + const Simd::Vec4::FloatType mulVec = Simd::Vec4::Splat(multiplier); + return Matrix3x4 + ( + Simd::Vec4::Mul(m_rows[0].GetSimdValue(), mulVec), + Simd::Vec4::Mul(m_rows[1].GetSimdValue(), mulVec), + Simd::Vec4::Mul(m_rows[2].GetSimdValue(), mulVec) + ); + } + + + AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator*=(float multiplier) + { + *this = *this * multiplier; + return *this; + } + + + AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator/(float divisor) const + { + const Simd::Vec4::FloatType divVec = Simd::Vec4::Splat(divisor); + return Matrix3x4 + ( + Simd::Vec4::Div(m_rows[0].GetSimdValue(), divVec), + Simd::Vec4::Div(m_rows[1].GetSimdValue(), divVec), + Simd::Vec4::Div(m_rows[2].GetSimdValue(), divVec) + ); + } + + + AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator/=(float divisor) + { + *this = *this / divisor; + return *this; + } + + + AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator-() const + { + const Simd::Vec4::FloatType zeroVec = Simd::Vec4::ZeroFloat(); + return Matrix3x4 + ( + Simd::Vec4::Sub(zeroVec, m_rows[0].GetSimdValue()), + Simd::Vec4::Sub(zeroVec, m_rows[1].GetSimdValue()), + Simd::Vec4::Sub(zeroVec, m_rows[2].GetSimdValue()) + ); + } + + AZ_MATH_INLINE Vector3 Matrix3x4::operator*(const Vector3& rhs) const { return Vector3 @@ -711,4 +760,10 @@ namespace AZ { return reinterpret_cast(m_rows); } + + + AZ_MATH_INLINE Matrix3x4 operator*(float lhs, const Matrix3x4& rhs) + { + return rhs * lhs; + } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Math/Matrix4x4.h b/Code/Framework/AzCore/AzCore/Math/Matrix4x4.h index 1612f8c962..a94b3c7ae2 100644 --- a/Code/Framework/AzCore/AzCore/Math/Matrix4x4.h +++ b/Code/Framework/AzCore/AzCore/Math/Matrix4x4.h @@ -171,14 +171,38 @@ namespace AZ void SetTranslation(const Vector3& v); //! @} - Matrix4x4 operator+(const Matrix4x4& rhs) const; + //! Operator for matrix-matrix addition. + //! @{ + [[nodiscard]] Matrix4x4 operator+(const Matrix4x4& rhs) const; Matrix4x4& operator+=(const Matrix4x4& rhs); + //! @} - Matrix4x4 operator-(const Matrix4x4& rhs) const; + //! Operator for matrix-matrix substraction. + //! @{ + [[nodiscard]] Matrix4x4 operator-(const Matrix4x4& rhs) const; Matrix4x4& operator-=(const Matrix4x4& rhs); + //! @} - Matrix4x4 operator*(const Matrix4x4& rhs) const; + //! Operator for matrix-matrix multiplication. + //! @{ + [[nodiscard]] Matrix4x4 operator*(const Matrix4x4& rhs) const; Matrix4x4& operator*=(const Matrix4x4& rhs); + //! @} + + //! Operator for multiplying all matrix's elements with a scalar + //! @{ + [[nodiscard]] Matrix4x4 operator*(float multiplier) const; + Matrix4x4& operator*=(float multiplier); + //! @} + + //! Operator for dividing all matrix's elements with a scalar + //! @{ + [[nodiscard]] Matrix4x4 operator/(float divisor) const; + Matrix4x4& operator/=(float divisor); + //! @} + + //! Operator for negating all matrix's elements + [[nodiscard]] Matrix4x4 operator-() const; //! Post-multiplies the matrix by a vector. //! Assumes that the w-component of the Vector3 is 1.0. @@ -222,7 +246,10 @@ namespace AZ //! @} //! Gets the scale part of the transformation, i.e. the length of the scale components. - Vector3 RetrieveScale() const; + [[nodiscard]] Vector3 RetrieveScale() const; + + //! Gets the squared scale part of the transformation (the squared length of the basis vectors). + [[nodiscard]] Vector3 RetrieveScaleSq() const; //! Gets the scale part of the transformation as in RetrieveScale, and also removes this scaling from the matrix. Vector3 ExtractScale(); @@ -230,6 +257,9 @@ namespace AZ //! Quick multiplication by a scale matrix, equivalent to m*=Matrix4x4::CreateScale(scale). void MultiplyByScale(const Vector3& scale); + //! Returns a matrix with the reciprocal scale, keeping the same rotation and translation. + [[nodiscard]] Matrix4x4 GetReciprocalScaled() const; + bool IsClose(const Matrix4x4& rhs, float tolerance = Constants::Tolerance) const; bool operator==(const Matrix4x4& rhs) const; @@ -270,6 +300,10 @@ namespace AZ //! Pre-multiplies the matrix by a vector in-place. //! Note that this is not the usual multiplication order for transformations. Vector4& operator*=(Vector4& lhs, const Matrix4x4& rhs); -} + + //! Pre-multiplies the matrix by a scalar. + Matrix4x4 operator*(float lhs, const Matrix4x4& rhs); + +} // namespace AZ #include diff --git a/Code/Framework/AzCore/AzCore/Math/Matrix4x4.inl b/Code/Framework/AzCore/AzCore/Math/Matrix4x4.inl index 3c4572accd..e32ebe31af 100644 --- a/Code/Framework/AzCore/AzCore/Math/Matrix4x4.inl +++ b/Code/Framework/AzCore/AzCore/Math/Matrix4x4.inl @@ -480,20 +480,12 @@ namespace AZ AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator+(const Matrix4x4& rhs) const { return Matrix4x4 - ( Simd::Vec4::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()) - , Simd::Vec4::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()) - , Simd::Vec4::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()) - , Simd::Vec4::Add(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue())); - } - - - AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator-(const Matrix4x4& rhs) const - { - return Matrix4x4 - ( Simd::Vec4::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()) - , Simd::Vec4::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()) - , Simd::Vec4::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()) - , Simd::Vec4::Sub(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue())); + ( + Simd::Vec4::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()), + Simd::Vec4::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()), + Simd::Vec4::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()), + Simd::Vec4::Add(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue()) + ); } AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator+=(const Matrix4x4& rhs) @@ -502,6 +494,18 @@ namespace AZ return *this; } + + AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator-(const Matrix4x4& rhs) const + { + return Matrix4x4 + ( + Simd::Vec4::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()), + Simd::Vec4::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()), + Simd::Vec4::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()), + Simd::Vec4::Sub(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue()) + ); + } + AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator-=(const Matrix4x4& rhs) { *this = *this - rhs; @@ -523,6 +527,59 @@ namespace AZ } + AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator*(float multiplier) const + { + const Simd::Vec4::FloatType mulVec = Simd::Vec4::Splat(multiplier); + return Matrix4x4 + ( + Simd::Vec4::Mul(m_rows[0].GetSimdValue(), mulVec), + Simd::Vec4::Mul(m_rows[1].GetSimdValue(), mulVec), + Simd::Vec4::Mul(m_rows[2].GetSimdValue(), mulVec), + Simd::Vec4::Mul(m_rows[3].GetSimdValue(), mulVec) + ); + } + + + AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator*=(float multiplier) + { + *this = *this * multiplier; + return *this; + } + + + AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator/(float divisor) const + { + const Simd::Vec4::FloatType divVec = Simd::Vec4::Splat(divisor); + return Matrix4x4 + ( + Simd::Vec4::Div(m_rows[0].GetSimdValue(), divVec), + Simd::Vec4::Div(m_rows[1].GetSimdValue(), divVec), + Simd::Vec4::Div(m_rows[2].GetSimdValue(), divVec), + Simd::Vec4::Div(m_rows[3].GetSimdValue(), divVec) + ); + } + + + AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator/=(float divisor) + { + *this = *this / divisor; + return *this; + } + + + AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator-() const + { + const Simd::Vec4::FloatType zeroVec = Simd::Vec4::ZeroFloat(); + return Matrix4x4 + ( + Simd::Vec4::Sub(zeroVec, m_rows[0].GetSimdValue()), + Simd::Vec4::Sub(zeroVec, m_rows[1].GetSimdValue()), + Simd::Vec4::Sub(zeroVec, m_rows[2].GetSimdValue()), + Simd::Vec4::Sub(zeroVec, m_rows[3].GetSimdValue()) + ); + } + + AZ_MATH_INLINE Vector3 Matrix4x4::operator*(const Vector3& rhs) const { return Vector3(Simd::Vec4::Mat4x4TransformPoint3(GetSimdValues(), rhs.GetSimdValue())); @@ -595,6 +652,12 @@ namespace AZ } + AZ_MATH_INLINE Vector3 Matrix4x4::RetrieveScaleSq() const + { + return Vector3(GetBasisX().GetLengthSq(), GetBasisY().GetLengthSq(), GetBasisZ().GetLengthSq()); + } + + AZ_MATH_INLINE Vector3 Matrix4x4::ExtractScale() { Vector4 x = GetBasisX(); @@ -619,6 +682,14 @@ namespace AZ } + AZ_MATH_INLINE Matrix4x4 Matrix4x4::GetReciprocalScaled() const + { + Matrix4x4 result = *this; + result.MultiplyByScale(RetrieveScaleSq().GetReciprocal()); + return result; + } + + AZ_MATH_INLINE bool Matrix4x4::IsClose(const Matrix4x4& rhs, float tolerance) const { const Simd::Vec4::FloatType vecTolerance = Simd::Vec4::Splat(tolerance); @@ -702,4 +773,10 @@ namespace AZ lhs = lhs * rhs; return lhs; } -} + + + AZ_MATH_INLINE Matrix4x4 operator*(float lhs, const Matrix4x4& rhs) + { + return rhs * lhs; + } +} // namespace AZ diff --git a/Code/Framework/AzCore/Tests/Math/Matrix3x3Tests.cpp b/Code/Framework/AzCore/Tests/Math/Matrix3x3Tests.cpp index a849cfdaab..efa0ee531c 100644 --- a/Code/Framework/AzCore/Tests/Math/Matrix3x3Tests.cpp +++ b/Code/Framework/AzCore/Tests/Math/Matrix3x3Tests.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace AZ; @@ -251,19 +252,19 @@ namespace UnitTest m2.SetRow(2, 13.0f, 14.0f, 15.0f); Matrix3x3 m3 = m1 * m2; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(66.0f, 72.0f, 78.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(156.0f, 171.0f, 186.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(246.0f, 270.0f, 294.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(66.0f, 72.0f, 78.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(156.0f, 171.0f, 186.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(246.0f, 270.0f, 294.0f))); Matrix3x3 m4 = m1; m4 *= m2; - AZ_TEST_ASSERT(m4.GetRow(0).IsClose(Vector3(66.0f, 72.0f, 78.0f))); - AZ_TEST_ASSERT(m4.GetRow(1).IsClose(Vector3(156.0f, 171.0f, 186.0f))); - AZ_TEST_ASSERT(m4.GetRow(2).IsClose(Vector3(246.0f, 270.0f, 294.0f))); + EXPECT_THAT(m4.GetRow(0), IsClose(Vector3(66.0f, 72.0f, 78.0f))); + EXPECT_THAT(m4.GetRow(1), IsClose(Vector3(156.0f, 171.0f, 186.0f))); + EXPECT_THAT(m4.GetRow(2), IsClose(Vector3(246.0f, 270.0f, 294.0f))); m3 = m1.TransposedMultiply(m2); - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(138.0f, 150.0f, 162.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(168.0f, 183.0f, 198.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(198.0f, 216.0f, 234.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(138.0f, 150.0f, 162.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(168.0f, 183.0f, 198.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(198.0f, 216.0f, 234.0f))); } TEST(MATH_Matrix3x3, TestVectorMultiplication) @@ -277,11 +278,11 @@ namespace UnitTest m2.SetRow(1, 10.0f, 11.0f, 12.0f); m2.SetRow(2, 13.0f, 14.0f, 15.0f); - AZ_TEST_ASSERT((m1 * Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(14.0f, 32.0f, 50.0f))); + EXPECT_THAT((m1 * Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(14.0f, 32.0f, 50.0f))); Vector3 v1(1.0f, 2.0f, 3.0f); - AZ_TEST_ASSERT((v1 * m1).IsClose(Vector3(30.0f, 36.0f, 42.0f))); + EXPECT_THAT((v1 * m1), IsClose(Vector3(30.0f, 36.0f, 42.0f))); v1 *= m1; - AZ_TEST_ASSERT(v1.IsClose(Vector3(30.0f, 36.0f, 42.0f))); + EXPECT_THAT(v1, IsClose(Vector3(30.0f, 36.0f, 42.0f))); } TEST(MATH_Matrix3x3, TestSum) @@ -296,15 +297,15 @@ namespace UnitTest m2.SetRow(2, 13.0f, 14.0f, 15.0f); Matrix3x3 m3 = m1 + m2; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(8.0f, 10.0f, 12.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(14.0f, 16.0f, 18.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(20.0f, 22.0f, 24.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(8.0f, 10.0f, 12.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(14.0f, 16.0f, 18.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(20.0f, 22.0f, 24.0f))); m3 = m1; m3 += m2; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(8.0f, 10.0f, 12.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(14.0f, 16.0f, 18.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(20.0f, 22.0f, 24.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(8.0f, 10.0f, 12.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(14.0f, 16.0f, 18.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(20.0f, 22.0f, 24.0f))); } TEST(MATH_Matrix3x3, TestDifference) @@ -319,14 +320,14 @@ namespace UnitTest m2.SetRow(2, 13.0f, 14.0f, 15.0f); Matrix3x3 m3 = m1 - m2; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-6.0f, -6.0f, -6.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-6.0f, -6.0f, -6.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(-6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(-6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(-6.0f, -6.0f, -6.0f))); m3 = m1; m3 -= m2; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-6.0f, -6.0f, -6.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-6.0f, -6.0f, -6.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(-6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(-6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(-6.0f, -6.0f, -6.0f))); } TEST(MATH_Matrix3x3, TestScalarMultiplication) @@ -341,18 +342,18 @@ namespace UnitTest m2.SetRow(2, 13.0f, 14.0f, 15.0f); Matrix3x3 m3 = m1 * 2.0f; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f))); m3 = m1; m3 *= 2.0f; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f))); m3 = 2.0f * m1; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f))); } TEST(MATH_Matrix3x3, TestScalarDivision) @@ -367,18 +368,32 @@ namespace UnitTest m2.SetRow(2, 13.0f, 14.0f, 15.0f); Matrix3x3 m3 = m1 / 0.5f; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f))); m3 = m1; m3 /= 0.5f; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f))); - m3 = -m1; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-1.0f, -2.0f, -3.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-4.0f, -5.0f, -6.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-7.0f, -8.0f, -9.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f))); + } + + TEST(MATH_Matrix3x3, TestNegation) + { + Matrix3x3 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f); + m1.SetRow(1, 4.0f, 5.0f, 6.0f); + m1.SetRow(2, 7.0f, 8.0f, 9.0f); + EXPECT_THAT(-(-m1), IsClose(m1)); + EXPECT_THAT(-Matrix3x3::CreateZero(), IsClose(Matrix3x3::CreateZero())); + + Matrix3x3 m2 = -m1; + EXPECT_THAT(m2.GetRow(0), IsClose(Vector3(-1.0f, -2.0f, -3.0f))); + EXPECT_THAT(m2.GetRow(1), IsClose(Vector3(-4.0f, -5.0f, -6.0f))); + EXPECT_THAT(m2.GetRow(2), IsClose(Vector3(-7.0f, -8.0f, -9.0f))); + + Matrix3x3 m3 = m1 + (-m1); + EXPECT_THAT(m3, IsClose(Matrix3x3::CreateZero())); } TEST(MATH_Matrix3x3, TestTranspose) @@ -425,11 +440,33 @@ namespace UnitTest TEST(MATH_Matrix3x3, TestScaleAccess) { Matrix3x3 m1 = Matrix3x3::CreateRotationX(DegToRad(40.0f)) * Matrix3x3::CreateScale(Vector3(2.0f, 3.0f, 4.0f)); - AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3(2.0f, 3.0f, 4.0f))); - AZ_TEST_ASSERT(m1.ExtractScale().IsClose(Vector3(2.0f, 3.0f, 4.0f))); - AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3::CreateOne())); + EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f))); + EXPECT_THAT(m1.ExtractScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f))); + EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3::CreateOne())); m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f)); - AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3(3.0f, 4.0f, 5.0f))); + EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(3.0f, 4.0f, 5.0f))); + } + + TEST(MATH_Matrix3x3, TestScaleSqAccess) + { + Matrix3x3 m1 = Matrix3x3::CreateRotationX(DegToRad(40.0f)) * Matrix3x3::CreateScale(Vector3(2.0f, 3.0f, 4.0f)); + EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(4.0f, 9.0f, 16.0f))); + m1.ExtractScale(); + EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3::CreateOne())); + m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f)); + EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(9.0f, 16.0f, 25.0f))); + } + + TEST(MATH_Matrix3x3, TestReciprocalScaled) + { + Matrix3x3 orthogonalMatrix = Matrix3x3::CreateRotationX(DegToRad(40.0f)); + EXPECT_THAT(orthogonalMatrix.GetReciprocalScaled(), IsClose(orthogonalMatrix)); + const AZ::Vector3 scale(2.8f, 0.7f, 1.3f); + AZ::Matrix3x3 scaledMatrix = orthogonalMatrix; + scaledMatrix.MultiplyByScale(scale); + AZ::Matrix3x3 reciprocalScaledMatrix = orthogonalMatrix; + reciprocalScaledMatrix.MultiplyByScale(scale.GetReciprocal()); + EXPECT_THAT(scaledMatrix.GetReciprocalScaled(), IsClose(reciprocalScaledMatrix)); } TEST(MATH_Matrix3x3, TestPolarDecomposition) diff --git a/Code/Framework/AzCore/Tests/Math/Matrix3x4Tests.cpp b/Code/Framework/AzCore/Tests/Math/Matrix3x4Tests.cpp index 353b46874b..0bb64411e6 100644 --- a/Code/Framework/AzCore/Tests/Math/Matrix3x4Tests.cpp +++ b/Code/Framework/AzCore/Tests/Math/Matrix3x4Tests.cpp @@ -467,53 +467,136 @@ namespace UnitTest EXPECT_THAT(matrix.Multiply3x3(axisDirection), IsClose(forwardDirection)); } - TEST(MATH_Matrix3x4, MultiplyByMatrix3x4) + TEST(MATH_Matrix3x4, TestMatrixMultiplication) { - const AZ::Matrix3x4 matrix1 = AZ::Matrix3x4::CreateFromValue(1.2f); - const AZ::Matrix3x4 matrix2 = AZ::Matrix3x4::CreateDiagonal(AZ::Vector3(1.3f, 1.5f, 0.4f)); - const AZ::Matrix3x4 matrix3 = AZ::Matrix3x4::CreateFromQuaternionAndTranslation( - AZ::Quaternion(0.42f, 0.46f, -0.66f, 0.42f), AZ::Vector3(2.8f, -3.7f, 1.6f)); - const AZ::Matrix3x4 matrix4 = AZ::Matrix3x4::CreateRotationX(-0.7f) * AZ::Matrix3x4::CreateScale(AZ::Vector3(0.6f, 1.3f, 0.7f)); - AZ::Matrix3x4 matrix5 = matrix1; - matrix5 *= matrix4; - const AZ::Vector3 vector(1.9f, 2.3f, 0.2f); - EXPECT_TRUE((matrix1 * (matrix2 * matrix3)).IsClose((matrix1 * matrix2) * matrix3)); - EXPECT_THAT((matrix3 * matrix4) * vector, IsClose(matrix3 * (matrix4 * vector))); - EXPECT_TRUE((matrix2 * AZ::Matrix3x4::Identity()).IsClose(matrix2)); - EXPECT_TRUE((matrix3 * AZ::Matrix3x4::Identity()).IsClose(AZ::Matrix3x4::Identity() * matrix3)); - EXPECT_TRUE(matrix5.IsClose(matrix1 * matrix4)); + AZ::Matrix3x4 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f); + m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); + m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); + AZ::Matrix3x4 m2; + m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f); + m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f); + m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f); + AZ::Matrix3x4 m3 = m1 * m2; + EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(74.0f, 80.0f, 86.0f, 96.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(206.0f, 224.0f, 242.0f, 268.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(338.0f, 368.0f, 398.0f, 440.0f))); + AZ::Matrix3x4 m4 = m1; + m4 *= m2; + EXPECT_THAT(m4.GetRow(0), IsClose(AZ::Vector4(74.0f, 80.0f, 86.0f, 96.0f))); + EXPECT_THAT(m4.GetRow(1), IsClose(AZ::Vector4(206.0f, 224.0f, 242.0f, 268.0f))); + EXPECT_THAT(m4.GetRow(2), IsClose(AZ::Vector4(338.0f, 368.0f, 398.0f, 440.0f))); } - TEST(MATH_Matrix3x4, AddMatrix3x4) + TEST(MATH_Matrix3x4, TestSum) { - const AZ::Matrix3x4 matrix1 = AZ::Matrix3x4::CreateFromValue(1.2f); - const AZ::Matrix3x4 matrix2 = AZ::Matrix3x4::CreateDiagonal(AZ::Vector3(1.3f, 1.5f, 0.4f)); - const AZ::Matrix3x4 matrix3 = AZ::Matrix3x4::CreateFromQuaternionAndTranslation( - AZ::Quaternion(0.42f, 0.46f, -0.66f, 0.42f), AZ::Vector3(2.8f, -3.7f, 1.6f)); - const AZ::Matrix3x4 matrix4 = AZ::Matrix3x4::CreateRotationX(-0.7f) * AZ::Matrix3x4::CreateScale(AZ::Vector3(0.6f, 1.3f, 0.7f)); - AZ::Matrix3x4 matrix5 = matrix1; - matrix5 += matrix4; - EXPECT_THAT(matrix1 + (matrix2 + matrix3), IsClose((matrix1 + matrix2) + matrix3)); - EXPECT_THAT(matrix2 + AZ::Matrix3x4::CreateZero(), IsClose(matrix2)); - EXPECT_THAT(matrix3 + AZ::Matrix3x4::CreateZero(), IsClose(AZ::Matrix3x4::CreateZero() + matrix3)); - EXPECT_THAT(matrix3 + matrix3, IsClose(matrix3 * 2.0f)); - EXPECT_THAT(matrix5, IsClose(matrix1 + matrix4)); + AZ::Matrix3x4 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f); + m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); + m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); + AZ::Matrix3x4 m2; + m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f); + m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f); + m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f); + + AZ::Matrix3x4 m3 = m1 + m2; + EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(8.0f, 10.0f, 12.0f, 14.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(16.0f, 18.0f, 20.0f, 22.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(24.0f, 26.0f, 28.0f, 30.0f))); + + m3 = m1; + m3 += m2; + EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(8.0f, 10.0f, 12.0f, 14.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(16.0f, 18.0f, 20.0f, 22.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(24.0f, 26.0f, 28.0f, 30.0f))); } - TEST(MATH_Matrix3x4, MultiplyByScalar) + TEST(MATH_Matrix3x4, TestDifference) { - const AZ::Vector4 row0(1.488f, 2.56f, 0.096f, 2.3f); - const AZ::Vector4 row1(0.384f, -1.92f, 0.428f, -1.6f); - const AZ::Vector4 row2(1.28f, -2.4f, -0.24f, 3.7f); - const float scalar = 3.2f; - const AZ::Vector4 row0Result = row0 * scalar; - const AZ::Vector4 row1Result = row1 * scalar; - const AZ::Vector4 row2Result = row2 * scalar; - AZ::Matrix3x4 matrix = AZ::Matrix3x4::CreateFromRows(row0, row1, row2); - EXPECT_THAT(matrix * 0.0f, IsClose(AZ::Matrix3x4::CreateZero())); - EXPECT_THAT(matrix * 1.0f, IsClose(matrix)); - EXPECT_THAT(matrix * scalar, IsClose(AZ::Matrix3x4::CreateFromRows(row0Result, row1Result, row2Result))); - EXPECT_THAT(matrix * 2.0f, IsClose(matrix + matrix)); + AZ::Matrix3x4 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f); + m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); + m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); + AZ::Matrix3x4 m2; + m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f); + m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f); + m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f); + + AZ::Matrix3x4 m3 = m1 - m2; + EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + m3 = m1; + m3 -= m2; + EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + } + + TEST(MATH_Matrix3x4, TestScalarMultiplication) + { + AZ::Matrix3x4 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f); + m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); + m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); + AZ::Matrix3x4 m2; + m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f); + m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f); + m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f); + + AZ::Matrix3x4 m3 = m1 * 2.0f; + EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f))); + m3 = m1; + m3 *= 2.0f; + EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f))); + m3 = 2.0f * m1; + EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f))); + } + + TEST(MATH_Matrix3x4, TestScalarDivision) + { + AZ::Matrix3x4 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f); + m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); + m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); + AZ::Matrix3x4 m2; + m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f); + m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f); + m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f); + + AZ::Matrix3x4 m3 = m1 / 0.5f; + EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f))); + m3 = m1; + m3 /= 0.5f; + EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f))); + } + + TEST(MATH_Matrix3x4, TestNegation) + { + AZ::Matrix3x4 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f); + m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); + m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); + EXPECT_THAT(-(-m1), IsClose(m1)); + EXPECT_THAT(-AZ::Matrix3x4::CreateZero(), IsClose(AZ::Matrix3x4::CreateZero())); + + AZ::Matrix3x4 m2 = -m1; + EXPECT_THAT(m2.GetRow(0), IsClose(AZ::Vector4(-1.0f, -2.0f, -3.0f, -4.0f))); + EXPECT_THAT(m2.GetRow(1), IsClose(AZ::Vector4(-5.0f, -6.0f, -7.0f, -8.0f))); + EXPECT_THAT(m2.GetRow(2), IsClose(AZ::Vector4(-9.0f, -10.0f, -11.0f, -12.0f))); + + AZ::Matrix3x4 m3 = m1 + (-m1); + EXPECT_THAT(m3, IsClose(AZ::Matrix3x4::CreateZero())); } TEST(MATH_Matrix3x4, MultiplyByVector3) diff --git a/Code/Framework/AzCore/Tests/Math/Matrix4x4Tests.cpp b/Code/Framework/AzCore/Tests/Math/Matrix4x4Tests.cpp index 851de490d0..a9baa3ddea 100644 --- a/Code/Framework/AzCore/Tests/Math/Matrix4x4Tests.cpp +++ b/Code/Framework/AzCore/Tests/Math/Matrix4x4Tests.cpp @@ -246,16 +246,16 @@ namespace UnitTest m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f); m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f); Matrix4x4 m3 = m1 * m2; - AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f))); - AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f))); - AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f))); - AZ_TEST_ASSERT(m3.GetRow(3).IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f))); + EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f))); + EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f))); Matrix4x4 m4 = m1; m4 *= m2; - AZ_TEST_ASSERT(m4.GetRow(0).IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f))); - AZ_TEST_ASSERT(m4.GetRow(1).IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f))); - AZ_TEST_ASSERT(m4.GetRow(2).IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f))); - AZ_TEST_ASSERT(m4.GetRow(3).IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f))); + EXPECT_THAT(m4.GetRow(0), IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f))); + EXPECT_THAT(m4.GetRow(1), IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f))); + EXPECT_THAT(m4.GetRow(2), IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f))); + EXPECT_THAT(m4.GetRow(3), IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f))); } TEST(MATH_Matrix4x4, TestVectorMultiplication) @@ -265,18 +265,148 @@ namespace UnitTest m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f); - AZ_TEST_ASSERT((m1 * Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(18.0f, 46.0f, 74.0f))); - AZ_TEST_ASSERT((m1 * Vector4(1.0f, 2.0f, 3.0f, 4.0f)).IsClose(Vector4(30.0f, 70.0f, 110.0f, 150.0f))); - AZ_TEST_ASSERT(m1.TransposedMultiply3x3(Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(38.0f, 44.0f, 50.0f))); - AZ_TEST_ASSERT(m1.Multiply3x3(Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(14.0f, 38.0f, 62.0f))); + EXPECT_THAT((m1 * Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(18.0f, 46.0f, 74.0f))); + EXPECT_THAT((m1 * Vector4(1.0f, 2.0f, 3.0f, 4.0f)), IsClose(Vector4(30.0f, 70.0f, 110.0f, 150.0f))); + EXPECT_THAT(m1.TransposedMultiply3x3(Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(38.0f, 44.0f, 50.0f))); + EXPECT_THAT(m1.Multiply3x3(Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(14.0f, 38.0f, 62.0f))); Vector3 v1(1.0f, 2.0f, 3.0f); - AZ_TEST_ASSERT((v1 * m1).IsClose(Vector3(51.0f, 58.0f, 65.0f))); + EXPECT_THAT((v1 * m1), IsClose(Vector3(51.0f, 58.0f, 65.0f))); v1 *= m1; - AZ_TEST_ASSERT(v1.IsClose(Vector3(51.0f, 58.0f, 65.0f))); + EXPECT_THAT(v1, IsClose(Vector3(51.0f, 58.0f, 65.0f))); Vector4 v2(1.0f, 2.0f, 3.0f, 4.0f); - AZ_TEST_ASSERT((v2 * m1).IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f))); + EXPECT_THAT((v2 * m1), IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f))); v2 *= m1; - AZ_TEST_ASSERT(v2.IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f))); + EXPECT_THAT(v2, IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f))); + } + + TEST(MATH_Matrix4x4, TestSum) + { + Matrix4x4 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f); + m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); + m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); + m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f); + Matrix4x4 m2; + m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f); + m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f); + m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f); + m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f); + + Matrix4x4 m3 = m1 + m2; + EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(8.0f, 10.0f, 12.0f, 14.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(16.0f, 18.0f, 20.0f, 22.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(24.0f, 26.0f, 28.0f, 30.0f))); + EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(32.0f, 34.0f, 36.0f, 38.0f))); + + m3 = m1; + m3 += m2; + EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(8.0f, 10.0f, 12.0f, 14.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(16.0f, 18.0f, 20.0f, 22.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(24.0f, 26.0f, 28.0f, 30.0f))); + EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(32.0f, 34.0f, 36.0f, 38.0f))); + } + + TEST(MATH_Matrix4x4, TestDifference) + { + Matrix4x4 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f); + m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); + m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); + m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f); + Matrix4x4 m2; + m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f); + m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f); + m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f); + m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f); + + Matrix4x4 m3 = m1 - m2; + EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + m3 = m1; + m3 -= m2; + EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f))); + } + + TEST(MATH_Matrix4x4, TestScalarMultiplication) + { + Matrix4x4 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f); + m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); + m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); + m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f); + Matrix4x4 m2; + m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f); + m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f); + m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f); + m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f); + + Matrix4x4 m3 = m1 * 2.0f; + EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f))); + EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f))); + m3 = m1; + m3 *= 2.0f; + EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f))); + EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f))); + m3 = 2.0f * m1; + EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f))); + EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f))); + } + + TEST(MATH_Matrix4x4, TestScalarDivision) + { + Matrix4x4 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f); + m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); + m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); + m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f); + Matrix4x4 m2; + m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f); + m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f); + m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f); + m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f); + + Matrix4x4 m3 = m1 / 0.5f; + EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f))); + EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f))); + m3 = m1; + m3 /= 0.5f; + EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f))); + EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f))); + EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f))); + EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f))); + } + + TEST(MATH_Matrix4x4, TestNegation) + { + Matrix4x4 m1; + m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f); + m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f); + m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f); + m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f); + EXPECT_THAT(-(-m1), IsClose(m1)); + EXPECT_THAT(-Matrix4x4::CreateZero(), IsClose(Matrix4x4::CreateZero())); + + Matrix4x4 m2 = -m1; + EXPECT_THAT(m2.GetRow(0), IsClose(Vector4(-1.0f, -2.0f, -3.0f, -4.0f))); + EXPECT_THAT(m2.GetRow(1), IsClose(Vector4(-5.0f, -6.0f, -7.0f, -8.0f))); + EXPECT_THAT(m2.GetRow(2), IsClose(Vector4(-9.0f, -10.0f, -11.0f, -12.0f))); + EXPECT_THAT(m2.GetRow(3), IsClose(Vector4(-13.0f, -14.0f, -15.0f, -16.0f))); + + Matrix4x4 m3 = m1 + (-m1); + EXPECT_THAT(m3, IsClose(Matrix4x4::CreateZero())); } TEST(MATH_Matrix4x4, TestTranspose) @@ -368,4 +498,36 @@ namespace UnitTest m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f); AZ_TEST_ASSERT(m1.GetDiagonal() == Vector4(1.0f, 6.0f, 11.0f, 16.0f)); } + + TEST(MATH_Matrix4x4, TestScaleAccess) + { + Matrix4x4 m1 = Matrix4x4::CreateRotationX(DegToRad(40.0f)) * Matrix4x4::CreateScale(Vector3(2.0f, 3.0f, 4.0f)); + EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f))); + EXPECT_THAT(m1.ExtractScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f))); + EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3::CreateOne())); + m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f)); + EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(3.0f, 4.0f, 5.0f))); + } + + TEST(MATH_Matrix4x4, TestScaleSqAccess) + { + Matrix4x4 m1 = Matrix4x4::CreateRotationX(DegToRad(40.0f)) * Matrix4x4::CreateScale(Vector3(2.0f, 3.0f, 4.0f)); + EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(4.0f, 9.0f, 16.0f))); + m1.ExtractScale(); + EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3::CreateOne())); + m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f)); + EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(9.0f, 16.0f, 25.0f))); + } + + TEST(MATH_Matrix4x4, TestReciprocalScaled) + { + Matrix4x4 orthogonalMatrix = Matrix4x4::CreateRotationX(DegToRad(40.0f)); + EXPECT_THAT(orthogonalMatrix.GetReciprocalScaled(), IsClose(orthogonalMatrix)); + const AZ::Vector3 scale(2.8f, 0.7f, 1.3f); + AZ::Matrix4x4 scaledMatrix = orthogonalMatrix; + scaledMatrix.MultiplyByScale(scale); + AZ::Matrix4x4 reciprocalScaledMatrix = orthogonalMatrix; + reciprocalScaledMatrix.MultiplyByScale(scale.GetReciprocal()); + EXPECT_THAT(scaledMatrix.GetReciprocalScaled(), IsClose(reciprocalScaledMatrix)); + } } diff --git a/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.cpp b/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.cpp index 35fa1136f9..e2e425fb57 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.cpp @@ -69,7 +69,7 @@ namespace ScriptCanvasTesting void PropertyExample::In() { - for (auto& num : Numbers) + for ([[maybe_unused]] auto& num : Numbers) { AZ_TracePrintf("ScriptCanvas", "%f", num); }