瀏覽代碼

more fixes

more unit tests revealed more discrepancies fixes applied.
marauder2k7 1 年之前
父節點
當前提交
d03851958d
共有 2 個文件被更改,包括 189 次插入16 次删除
  1. 6 16
      Engine/source/math/mMatrix.h
  2. 183 0
      Engine/source/testing/mathMatrixTest.cpp

+ 6 - 16
Engine/source/math/mMatrix.h

@@ -700,9 +700,7 @@ public:
 
    ///< M * a -> M
    Matrix<DATA_TYPE, rows, cols>& mul(const Matrix<DATA_TYPE, rows, cols>& a)
-   {
-      *this = *this * a;  return *this;
-   }
+   { return *this = *this * a; }
    ///< a * M -> M
    Matrix<DATA_TYPE, rows, cols>& mulL(const Matrix<DATA_TYPE, rows, cols>& a)
    { return *this = a * *this; }
@@ -711,7 +709,7 @@ public:
    { return *this = a * b; }
    ///< M * a -> M
    Matrix<DATA_TYPE, rows, cols>& mul(const F32 a)
-   { return *this * a; }
+   { return *this = *this * a; }
    ///< a * b -> M
    Matrix<DATA_TYPE, rows, cols>& mul(const Matrix<DATA_TYPE, rows, cols>& a, const F32 b)
    { return *this = a * b; }
@@ -1634,28 +1632,20 @@ template<typename DATA_TYPE, U32 rows, U32 cols>
 inline EulerF Matrix<DATA_TYPE, rows, cols>::toEuler() const
 {
    AssertFatal(rows >= 3 && cols >= 3, "Euler rotations require at least a 3x3 matrix.");
-   // Extract rotation matrix components
-   const DATA_TYPE m00 = (*this)(0, 0);
-   const DATA_TYPE m01 = (*this)(0, 1);
-   const DATA_TYPE m02 = (*this)(0, 2);
-   const DATA_TYPE m10 = (*this)(1, 0);
-   const DATA_TYPE m11 = (*this)(1, 1);
-   const DATA_TYPE m21 = (*this)(2, 1);
-   const DATA_TYPE m22 = (*this)(2, 2);
 
    // like all others assume float for now.
    EulerF r;
 
-   r.x = mAsin(mClampF(m21, -1.0, 1.0));
+   r.x = mAsin(mClampF((*this)(1,2), -1.0, 1.0));
    if (mCos(r.x) != 0.0f)
    {
-      r.y = mAtan2(-m02, m22); // yaw
-      r.z = mAtan2(-m10, m11); // roll
+      r.y = mAtan2(-(*this)(0, 2), (*this)(2, 2)); // yaw
+      r.z = mAtan2(-(*this)(1, 0), (*this)(1, 1)); // roll
    }
    else
    {
       r.y = 0.0f;
-      r.z = mAtan2(m01, m00); // this rolls when pitch is +90 degrees
+      r.z = mAtan2((*this)(0, 1), (*this)(0, 0)); // this rolls when pitch is +90 degrees
    }
 
    return r;

+ 183 - 0
Engine/source/testing/mathMatrixTest.cpp

@@ -7,6 +7,7 @@
 #include "console/simBase.h"
 #include "console/engineAPI.h"
 #include "math/mMath.h"
+#include "math/util/frustum.h"
 
 TEST(MatrixTest, TestIdentityInit)
 {
@@ -58,6 +59,16 @@ TEST(MatrixTest, TestEulerSet)
    EXPECT_NEAR(test(3, 0), 0.0f, 0.001f);      EXPECT_NEAR(test(3, 1), 0.0f, 0.001f);     EXPECT_NEAR(test(3, 2), 0.0f, 0.001f);    EXPECT_NEAR(test(3, 3), 1.0f, 0.001f);
 }
 
+TEST(MatrixTest, TestToEuler)
+{
+   MatrixF test(true);
+
+   test.set(EulerF(1.0f, 0.0f, 1.0f));
+
+   EulerF euler = test.toEuler();
+
+   EXPECT_NEAR(euler.x, 1.0f, 0.001f); EXPECT_NEAR(euler.y, 0.0f, 0.001f); EXPECT_NEAR(euler.z, 1.0f, 0.001f);
+}
 
 TEST(MatrixTest, TestEulerPointInit)
 {
@@ -164,6 +175,111 @@ TEST(MatrixTest, TestMulArgMatrixFunction)
    EXPECT_NEAR(testResult(3, 0), 0.0f, 0.001f);     EXPECT_NEAR(testResult(3, 1), 0.0f, 0.001f);     EXPECT_NEAR(testResult(3, 2), 0.0f, 0.001f);     EXPECT_NEAR(testResult(3, 3), 1.0f, 0.001f);
 }
 
+TEST(MatrixTest, TestMulScalarFunction)
+{
+   MatrixF test(true);
+   test.setPosition(Point3F(5.0f, 2.0f, 1.0f));
+   MatrixF test2(EulerF(1.0f, 0.0f, 1.0f));
+
+   test.mulL(test2);
+
+   test.mul(2.0f);
+
+   EXPECT_NEAR(test(0, 0), 1.0806f, 0.001f);  EXPECT_NEAR(test(0, 1), 1.6829f, 0.001f);  EXPECT_NEAR(test(0, 2), 0.0f, 0.001f);    EXPECT_NEAR(test(0, 3), 8.7689f, 0.001f);
+   EXPECT_NEAR(test(1, 0), -0.9093f, 0.001f); EXPECT_NEAR(test(1, 1), 0.5839f, 0.001f);  EXPECT_NEAR(test(1, 2), 1.6829f, 0.001f); EXPECT_NEAR(test(1, 3), -1.6958f, 0.001f);
+   EXPECT_NEAR(test(2, 0), 1.4161f, 0.001f);  EXPECT_NEAR(test(2, 1), -0.9093f, 0.001f); EXPECT_NEAR(test(2, 2), 1.0806f, 0.001f); EXPECT_NEAR(test(2, 3), 6.3427f, 0.001f);
+   EXPECT_NEAR(test(3, 0), 0.0f, 0.001f);     EXPECT_NEAR(test(3, 1), 0.0f, 0.001f);     EXPECT_NEAR(test(3, 2), 0.0f, 0.001f);    EXPECT_NEAR(test(3, 3), 2.0f, 0.001f);
+}
+
+TEST(MatrixTest, TestMulMatScalarFunction)
+{
+   MatrixF testTran(true);
+   testTran.setPosition(Point3F(5.0f, 2.0f, 1.0f));
+   MatrixF test2(EulerF(1.0f, 0.0f, 1.0f));
+
+   testTran.mulL(test2);
+
+   MatrixF test(true);
+   test.mul(testTran, 2.0f);
+
+   EXPECT_NEAR(test(0, 0), 1.0806f, 0.001f);  EXPECT_NEAR(test(0, 1), 1.6829f, 0.001f);  EXPECT_NEAR(test(0, 2), 0.0f, 0.001f);    EXPECT_NEAR(test(0, 3), 8.7689f, 0.001f);
+   EXPECT_NEAR(test(1, 0), -0.9093f, 0.001f); EXPECT_NEAR(test(1, 1), 0.5839f, 0.001f);  EXPECT_NEAR(test(1, 2), 1.6829f, 0.001f); EXPECT_NEAR(test(1, 3), -1.6958f, 0.001f);
+   EXPECT_NEAR(test(2, 0), 1.4161f, 0.001f);  EXPECT_NEAR(test(2, 1), -0.9093f, 0.001f); EXPECT_NEAR(test(2, 2), 1.0806f, 0.001f); EXPECT_NEAR(test(2, 3), 6.3427f, 0.001f);
+   EXPECT_NEAR(test(3, 0), 0.0f, 0.001f);     EXPECT_NEAR(test(3, 1), 0.0f, 0.001f);     EXPECT_NEAR(test(3, 2), 0.0f, 0.001f);    EXPECT_NEAR(test(3, 3), 2.0f, 0.001f);
+}
+
+TEST(MatrixTest, TestMulPoint4)
+{
+   MatrixF test(true);
+   test.setPosition(Point3F(5.0f, 2.0f, 1.0f));
+   MatrixF test2(EulerF(1.0f, 0.0f, 1.0f));
+
+   test.mulL(test2);
+
+   Point4F testPoint(0.5f, 1.0f, 2.0f, 1.0f);
+   test.mul(testPoint);
+
+   EXPECT_NEAR(testPoint.x, 5.496f, 0.001f);  EXPECT_NEAR(testPoint.y, 0.899f, 0.001f);  EXPECT_NEAR(testPoint.z, 4.151f, 0.001f); EXPECT_NEAR(testPoint.w, 1.0f, 0.001f);
+}
+
+TEST(MatrixTest, TestMulPoint3)
+{
+   MatrixF test(true);
+   test.setPosition(Point3F(5.0f, 2.0f, 1.0f));
+   MatrixF test2(EulerF(1.0f, 0.0f, 1.0f));
+
+   test.mulL(test2);
+
+   Point3F testPoint(0.5f, 1.0f, 2.0f);
+   test.mulP(testPoint);
+
+   EXPECT_NEAR(testPoint.x, 5.496f, 0.001f);  EXPECT_NEAR(testPoint.y, 0.899f, 0.001f);  EXPECT_NEAR(testPoint.z, 4.151f, 0.001f);
+}
+
+TEST(MatrixTest, TestMulPoint3ToPoint3)
+{
+   MatrixF test(true);
+   test.setPosition(Point3F(5.0f, 2.0f, 1.0f));
+   MatrixF test2(EulerF(1.0f, 0.0f, 1.0f));
+
+   test.mulL(test2);
+
+   Point3F point(0.5f, 1.0f, 2.0f);
+   Point3F testPoint;
+   test.mulP(point, &testPoint);
+
+   EXPECT_NEAR(testPoint.x, 5.496f, 0.001f);  EXPECT_NEAR(testPoint.y, 0.899f, 0.001f);  EXPECT_NEAR(testPoint.z, 4.151f, 0.001f);
+}
+
+TEST(MatrixTest, TestMulVector)
+{
+   MatrixF test(true);
+   test.setPosition(Point3F(5.0f, 2.0f, 1.0f));
+   MatrixF test2(EulerF(1.0f, 0.0f, 1.0f));
+
+   test.mulL(test2);
+
+   VectorF testPoint(0.5f, 1.0f, 2.0f);
+   test.mulV(testPoint);
+
+   EXPECT_NEAR(testPoint.x, 1.111f, 0.001f);  EXPECT_NEAR(testPoint.y, 1.747f, 0.001f);  EXPECT_NEAR(testPoint.z, 0.979f, 0.001f);
+}
+
+TEST(MatrixTest, TestMulVectorToPoint3)
+{
+   MatrixF test(true);
+   test.setPosition(Point3F(5.0f, 2.0f, 1.0f));
+   MatrixF test2(EulerF(1.0f, 0.0f, 1.0f));
+
+   test.mulL(test2);
+
+   VectorF vec(0.5f, 1.0f, 2.0f);
+   Point3F testPoint;
+   test.mulV(vec, &testPoint);
+
+   EXPECT_NEAR(testPoint.x, 1.111f, 0.001f);  EXPECT_NEAR(testPoint.y, 1.747f, 0.001f);  EXPECT_NEAR(testPoint.z, 0.979f, 0.001f);
+}
+
 TEST(MatrixTest, TestMulBox)
 {
    MatrixF test(true);
@@ -178,6 +294,30 @@ TEST(MatrixTest, TestMulBox)
    EXPECT_NEAR(testBox.maxExtents.x, 5.5f, 0.001f); EXPECT_NEAR(testBox.maxExtents.y, 2.5f, 0.001f); EXPECT_NEAR(testBox.maxExtents.z, 1.5f, 0.001f);
 }
 
+TEST(MatrixTest, TestReverseProjection)
+{
+   MatrixF test(true);
+   test.setPosition(Point3F(5.0f, 2.0f, 1.0f));
+
+   Frustum testFrustum(false, -1.0f, 1.0f, 1.0f, -1.0f, 0.1f, 100.0f, test);
+
+   testFrustum.getProjectionMatrix(&test);
+
+
+   // test before and after reverse.
+   EXPECT_NEAR(test(0, 0), 0.1f, 0.001f);  EXPECT_NEAR(test(0, 1), 0.0f, 0.001f);     EXPECT_NEAR(test(0, 2), 0.0f, 0.001f);  EXPECT_NEAR(test(0, 3), 0.0f, 0.001f);
+   EXPECT_NEAR(test(1, 0), 0.0f, 0.001f);  EXPECT_NEAR(test(1, 1), 0.0f, 0.001f);     EXPECT_NEAR(test(1, 2), 0.1, 0.001f);   EXPECT_NEAR(test(1, 3), 0.0f, 0.001f);
+   EXPECT_NEAR(test(2, 0), 0.0f, 0.001f);  EXPECT_NEAR(test(2, 1), -0.001f, 0.001f);  EXPECT_NEAR(test(2, 2), 0.0f, 0.001f);  EXPECT_NEAR(test(2, 3), 0.1001f, 0.001f);
+   EXPECT_NEAR(test(3, 0), 0.0f, 0.001f);  EXPECT_NEAR(test(3, 1), 1.0f, 0.001f);     EXPECT_NEAR(test(3, 2), 0.0f, 0.001f);  EXPECT_NEAR(test(3, 3), 0.0f, 0.001f);
+
+   test.reverseProjection();
+
+   EXPECT_NEAR(test(0, 0), 0.1f, 0.001f);  EXPECT_NEAR(test(0, 1), 0.0f, 0.001f);   EXPECT_NEAR(test(0, 2), 0.0f, 0.001f); EXPECT_NEAR(test(0, 3), 0.0f, 0.001f);
+   EXPECT_NEAR(test(1, 0), 0.0f, 0.001f);  EXPECT_NEAR(test(1, 1), 0.0f, 0.001f);   EXPECT_NEAR(test(1, 2), 0.1, 0.001f);  EXPECT_NEAR(test(1, 3), 0.0, 0.001f);
+   EXPECT_NEAR(test(2, 0), 0.0f, 0.001f);  EXPECT_NEAR(test(2, 1), 1.001f, 0.001f); EXPECT_NEAR(test(2, 2), 0.0f, 0.001f); EXPECT_NEAR(test(2, 3), -0.1001f, 0.001f);
+   EXPECT_NEAR(test(3, 0), 0.0f, 0.001f);  EXPECT_NEAR(test(3, 1), 1.0f, 0.001f);   EXPECT_NEAR(test(3, 2), 0.0f, 0.001f); EXPECT_NEAR(test(3, 3), 0.0f, 0.001f);
+}
+
 TEST(MatrixTest, TestInverse)
 {
    MatrixF test(true);
@@ -212,6 +352,49 @@ TEST(MatrixTest, TestInvertTo)
    EXPECT_NEAR(test(3, 0), 0.0f, 0.001f);     EXPECT_NEAR(test(3, 1), 0.0f, 0.001f);     EXPECT_NEAR(test(3, 2), 0.0f, 0.001f);     EXPECT_NEAR(test(3, 3), 1.0f, 0.001f);
 }
 
+TEST(MatrixTest, TestIsAffine)
+{
+   MatrixF test(true);
+   test.setPosition(Point3F(5.0f, 2.0f, 1.0f));
+   MatrixF test2(EulerF(1.0f, 0.0f, 1.0f));
+
+   test.mulL(test2);
+
+   EXPECT_TRUE(test.isAffine());
+}
+
+TEST(MatrixTest, TestScale)
+{
+   MatrixF test(true);
+   test.setPosition(Point3F(5.0f, 2.0f, 1.0f));
+   MatrixF test2(EulerF(1.0f, 0.0f, 1.0f));
+
+   test.mulL(test2);
+
+   test.scale(2.0f);
+
+   EXPECT_NEAR(test(0, 0), 1.0806f, 0.001f);  EXPECT_NEAR(test(0, 1), 1.6829f, 0.001f);  EXPECT_NEAR(test(0, 2), 0.0f, 0.001f);    EXPECT_NEAR(test(0, 3), 4.3845f, 0.001f);
+   EXPECT_NEAR(test(1, 0), -0.9093f, 0.001f); EXPECT_NEAR(test(1, 1), 0.5839f, 0.001f);  EXPECT_NEAR(test(1, 2), 1.6829f, 0.001f); EXPECT_NEAR(test(1, 3), -0.8479f, 0.001f);
+   EXPECT_NEAR(test(2, 0), 1.4161f, 0.001f);  EXPECT_NEAR(test(2, 1), -0.9093f, 0.001f); EXPECT_NEAR(test(2, 2), 1.0806f, 0.001f); EXPECT_NEAR(test(2, 3), 3.1714f, 0.001f);
+   EXPECT_NEAR(test(3, 0), 0.0f, 0.001f);     EXPECT_NEAR(test(3, 1), 0.0f, 0.001f);     EXPECT_NEAR(test(3, 2), 0.0f, 0.001f);    EXPECT_NEAR(test(3, 3), 1.0f, 0.001f);
+}
+
+TEST(MatrixTest, TestGetScale)
+{
+   MatrixF test(true);
+   test.setPosition(Point3F(5.0f, 2.0f, 1.0f));
+   MatrixF test2(EulerF(1.0f, 0.0f, 1.0f));
+
+   test.mulL(test2);
+
+   test.scale(2.0f);
+
+   Point3F scale;
+   scale = test.getScale();
+
+   EXPECT_NEAR(scale.x, 2.0f, 0.001f);  EXPECT_NEAR(scale.y, 2.0f, 0.001f);  EXPECT_NEAR(scale.z, 2.0f, 0.001f);
+}
+
 TEST(MatrixTest, TestAffineInverse)
 {
    MatrixF test(true);