From d2595cb471f03c0aa7bc603dc21de43c30b80bd2 Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 29 Sep 2023 14:20:38 -0700 Subject: [PATCH] Math lib: added matrix subtract and scalar divide operators --- Common/interface/BasicMath.hpp | 121 +++++++++++ .../src/Common/MathLibTest.cpp | 191 +++++++++++++++++- 2 files changed, 310 insertions(+), 2 deletions(-) diff --git a/Common/interface/BasicMath.hpp b/Common/interface/BasicMath.hpp index 955bc65e4..f82c7923d 100644 --- a/Common/interface/BasicMath.hpp +++ b/Common/interface/BasicMath.hpp @@ -817,6 +817,14 @@ template struct Matrix2x2 return *this; } + Matrix2x2& operator/=(T s) + { + for (int i = 0; i < 4; ++i) + (reinterpret_cast(this))[i] /= s; + + return *this; + } + Matrix2x2& operator*=(const Matrix2x2& right) { *this = Mul(*this, right); @@ -841,6 +849,24 @@ template struct Matrix2x2 // clang-format on } + Matrix2x2& operator-=(const Matrix2x2& right) + { + for (int i = 0; i < 4; ++i) + Data()[i] -= right.Data()[i]; + return *this; + } + + Matrix2x2 operator-(const Matrix2x2& right) const + { + // clang-format off + return Matrix2x2 + { + _11 - right._11, _12 - right._12, + _21 - right._21, _22 - right._22 + }; + // clang-format on + } + constexpr Matrix2x2 Transpose() const { return Matrix2x2{ @@ -925,6 +951,19 @@ inline constexpr Matrix2x2 operator*(T s, const Matrix2x2& Mat) return Mat * s; } +template +inline constexpr Matrix2x2 operator/(const Matrix2x2& Mat, T s) +{ + // clang-format off + return + { + Mat._11 / s, Mat._12 / s, + Mat._21 / s, Mat._22 / s + }; + // clang-format on +} + + template struct Matrix3x3 { union @@ -1038,6 +1077,14 @@ template struct Matrix3x3 return *this; } + Matrix3x3& operator/=(T s) + { + for (int i = 0; i < 9; ++i) + (reinterpret_cast(this))[i] /= s; + + return *this; + } + Matrix3x3& operator+=(const Matrix3x3& right) { for (int i = 0; i < 9; ++i) @@ -1057,6 +1104,25 @@ template struct Matrix3x3 // clang-format on } + Matrix3x3& operator-=(const Matrix3x3& right) + { + for (int i = 0; i < 9; ++i) + Data()[i] -= right.Data()[i]; + return *this; + } + + Matrix3x3 operator-(const Matrix3x3& right) const + { + // clang-format off + return Matrix3x3 + { + _11 - right._11, _12 - right._12, _13 - right._13, + _21 - right._21, _22 - right._22, _23 - right._23, + _31 - right._31, _32 - right._32, _33 - right._33 + }; + // clang-format on + } + Matrix3x3& operator*=(const Matrix3x3& right) { *this = Mul(*this, right); @@ -1242,6 +1308,19 @@ inline constexpr Matrix3x3 operator*(T s, const Matrix3x3& Mat) return Mat * s; } +template +inline constexpr Matrix3x3 operator/(const Matrix3x3& Mat, T s) +{ + // clang-format off + return + { + Mat._11 / s, Mat._12 / s, Mat._13 / s, + Mat._21 / s, Mat._22 / s, Mat._23 / s, + Mat._31 / s, Mat._32 / s, Mat._33 / s + }; + // clang-format on +} + template struct Matrix4x4 { @@ -1378,6 +1457,14 @@ template struct Matrix4x4 return *this; } + Matrix4x4& operator/=(T s) + { + for (int i = 0; i < 16; ++i) + (reinterpret_cast(this))[i] /= s; + + return *this; + } + Matrix4x4& operator*=(const Matrix4x4& right) { *this = Mul(*this, right); @@ -1404,6 +1491,26 @@ template struct Matrix4x4 // clang-format on } + Matrix4x4& operator-=(const Matrix4x4& right) + { + for (int i = 0; i < 16; ++i) + Data()[i] -= right.Data()[i]; + return *this; + } + + Matrix4x4 operator-(const Matrix4x4& right) const + { + // clang-format off + return Matrix4x4 + { + _11 - right._11, _12 - right._12, _13 - right._13, _14 - right._14, + _21 - right._21, _22 - right._22, _23 - right._23, _24 - right._24, + _31 - right._31, _32 - right._32, _33 - right._33, _34 - right._34, + _41 - right._41, _42 - right._42, _43 - right._43, _44 - right._44 + }; + // clang-format on + } + constexpr Matrix4x4 Transpose() const { return Matrix4x4 // @@ -1844,6 +1951,20 @@ inline constexpr Matrix4x4 operator*(T s, const Matrix4x4& Mat) return Mat * s; } +template +inline constexpr Matrix4x4 operator/(const Matrix4x4& Mat, T s) +{ + // clang-format off + return + { + Mat._11 / s, Mat._12 / s, Mat._13 / s, Mat._14 / s, + Mat._21 / s, Mat._22 / s, Mat._23 / s, Mat._24 / s, + Mat._31 / s, Mat._32 / s, Mat._33 / s, Mat._34 / s, + Mat._41 / s, Mat._42 / s, Mat._43 / s, Mat._44 / s + }; + // clang-format on +} + // Template Vector Operations diff --git a/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp b/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp index 5f7a3b9e3..6d5c24cfc 100644 --- a/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp +++ b/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp @@ -1373,7 +1373,112 @@ TEST(Common_BasicMath, ScalarMatrixMultiply) // clang-format on } -TEST(Common_BasicMath, ScalarMatrixOpeartorPlus) +TEST(Common_BasicMath, ScalarMatrixMultiplyEqual) +{ + // clang-format off + { + auto Mat = int2x2{1, 2, + 3, 4}; + Mat *= 2; + EXPECT_EQ(Mat, + int2x2(2, 4, + 6, 8) + ); + } + { + auto Mat = int3x3{1, 2, 3, + 4, 5, 6, + 7, 8, 9}; + Mat *= 2; + EXPECT_EQ(Mat, + int3x3( 2, 4, 6, + 8, 10, 12, + 14, 16, 18) + ); + } + { + auto Mat = int4x4{ 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10 ,11, 12, + 13, 14, 15, 16}; + Mat *= 2; + EXPECT_EQ(Mat, + int4x4( 2, 4, 6, 8, + 10, 12, 14, 16, + 18, 20 ,22, 24, + 26, 28, 30, 32) + ); + } + // clang-format on +} + +TEST(Common_BasicMath, MatrixScalarDivide) +{ + // clang-format off + EXPECT_EQ(float2x2(2, 4, + 6, 8) / 2.f, + float2x2(1, 2, + 3, 4) + ); + EXPECT_EQ(float3x3( 2, 4, 6, + 8, 10, 12, + 14, 16, 18) / 2.f, + float3x3(1, 2, 3, + 4, 5, 6, + 7, 8, 9) + ); + EXPECT_EQ(float4x4( 2, 4, 6, 8, + 10, 12, 14, 16, + 18, 20 ,22, 24, + 26, 28, 30, 32) / 2.f, + float4x4( 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10 ,11, 12, + 13, 14, 15, 16) + ); + // clang-format on +} + +TEST(Common_BasicMath, MatrixScalarDivideEqual) +{ + // clang-format off + { + auto Mat = float2x2{2, 4, + 6, 8}; + Mat /= 2.f; + EXPECT_EQ(Mat, + float2x2(1, 2, + 3, 4) + ); + } + { + auto Mat = float3x3{ 2, 4, 6, + 8, 10, 12, + 14, 16, 18}; + Mat /= 2.f; + EXPECT_EQ(Mat, + float3x3(1, 2, 3, + 4, 5, 6, + 7, 8, 9) + ); + } + { + auto Mat = float4x4{ 2, 4, 6, 8, + 10, 12, 14, 16, + 18, 20 ,22, 24, + 26, 28, 30, 32}; + Mat /= 2.f; + EXPECT_EQ(Mat, + float4x4( 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10 ,11, 12, + 13, 14, 15, 16) + ); + } + // clang-format on +} + +TEST(Common_BasicMath, MatrixOpeartorPlus) { // clang-format off EXPECT_EQ(float2x2(1, 2, @@ -1409,7 +1514,7 @@ TEST(Common_BasicMath, ScalarMatrixOpeartorPlus) // clang-format on } -TEST(Common_BasicMath, ScalarMatrixOpeartorPlusEqual) +TEST(Common_BasicMath, MatrixOpeartorPlusEqual) { // clang-format off { @@ -1454,6 +1559,88 @@ TEST(Common_BasicMath, ScalarMatrixOpeartorPlusEqual) // clang-format on } + +TEST(Common_BasicMath, MatrixOpeartorMinus) +{ + // clang-format off + EXPECT_EQ(float2x2( 6, 8, + 10, 12) - + float2x2(5, 6, + 7, 8), + float2x2(1, 2, + 3, 4)); + EXPECT_EQ(float3x3(11, 13, 15, + 17, 19, 21, + 23, 25, 27) - + float3x3(10, 11, 12, + 13, 14, 15, + 16, 17, 18), + float3x3(1, 2, 3, + 4, 5, 6, + 7, 8, 9)); + EXPECT_EQ(float4x4(18, 20, 22, 24, + 26, 28, 30, 32, + 34, 36, 38, 40, + 42, 44, 46, 48) - + float4x4(17, 18, 19, 20, + 21, 22, 23, 24, + 25, 26, 27, 28, + 29, 30, 31, 32), + float4x4( 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10 ,11, 12, + 13, 14, 15, 16) + ); + // clang-format on +} + + +TEST(Common_BasicMath, MatrixOpeartorMinusEqual) +{ + // clang-format off + { + auto Mat = float2x2{ 6, 8, + 10, 12}; + Mat -= float2x2{5, 6, + 7, 8}; + EXPECT_EQ(Mat, + float2x2(1, 2, + 3, 4) + ); + } + { + auto Mat = float3x3{11, 13, 15, + 17, 19, 21, + 23, 25, 27}; + Mat -= float3x3{10, 11, 12, + 13, 14, 15, + 16, 17, 18}; + EXPECT_EQ(Mat, + float3x3(1, 2, 3, + 4, 5, 6, + 7, 8, 9) + ); + } + { + auto Mat = float4x4(18, 20, 22, 24, + 26, 28, 30, 32, + 34, 36, 38, 40, + 42, 44, 46, 48); + Mat -= float4x4{17, 18, 19, 20, + 21, 22, 23, 24, + 25, 26, 27, 28, + 29, 30, 31, 32}; + EXPECT_EQ(Mat, + float4x4( 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10 ,11, 12, + 13, 14, 15, 16) + ); + } + // clang-format on +} + + TEST(Common_AdvancedMath, Planes) { Plane3D plane = {};