Prechádzať zdrojové kódy

fix

fix invertTo function
unitTest to make sure matrix calling invertTo does not get changed.
reimplemented gauss jordan.
marauder2k7 1 rok pred
rodič
commit
165a2bea01

+ 13 - 4
Engine/source/math/mMatrix.h

@@ -734,7 +734,14 @@ public:
    ///< M * p -> p (full [4x4] * [1x4])
    void mul(Point4F& p) const { p = *this * p; }
    ///< M * p -> p (assume w = 1.0f)
-   void mulP(Point3F& p) const { p = *this * p; }
+   void mulP(Point3F& p) const {
+      Point3F result;
+      result.x = (*this)(0, 0) * p.x + (*this)(0, 1) * p.y + (*this)(0, 2) * p.z + (*this)(0, 3);
+      result.y = (*this)(1, 0) * p.x + (*this)(1, 1) * p.y + (*this)(1, 2) * p.z + (*this)(1, 3);
+      result.z = (*this)(2, 0) * p.x + (*this)(2, 1) * p.y + (*this)(2, 2) * p.z + (*this)(2, 3);
+
+      p = result;
+   }
    ///< M * p -> d (assume w = 1.0f)
    void mulP(const Point3F& p, Point3F* d) const { *d = *this * p; }
    ///< M * v -> v (assume w = 0.0f)
@@ -1252,7 +1259,9 @@ inline void Matrix<DATA_TYPE, rows, cols>::invertTo(Matrix<DATA_TYPE, cols, rows
 template<typename DATA_TYPE, U32 rows, U32 cols>
 inline void Matrix<DATA_TYPE, rows, cols>::invertTo(Matrix<DATA_TYPE, cols, rows>* matrix)
 {
-   Matrix<DATA_TYPE, rows, cols> invMatrix = this->inverse();
+   Matrix<DATA_TYPE, rows, cols> invMatrix = *this;
+
+   invMatrix.inverse();
 
    for (U32 i = 0; i < rows; ++i)
    {
@@ -1433,7 +1442,7 @@ inline Matrix<DATA_TYPE, rows, cols>& Matrix<DATA_TYPE, rows, cols>::set(const E
 template<typename DATA_TYPE, U32 rows, U32 cols>
 inline Matrix<DATA_TYPE, rows, cols>& Matrix<DATA_TYPE, rows, cols>::inverse()
 {
-#if 0
+#if 1
    // NOTE: Gauss-Jordan elimination is yielding unpredictable results due to precission handling and
    // numbers near 0.0
    // 
@@ -1565,7 +1574,7 @@ inline Matrix<DATA_TYPE, rows, cols>& Matrix<DATA_TYPE, rows, cols>::inverse()
 template<typename DATA_TYPE, U32 rows, U32 cols>
 inline bool Matrix<DATA_TYPE, rows, cols>::fullInverse()
 {
-#if 0
+#if 1
    // NOTE: Gauss-Jordan elimination is yielding unpredictable results due to precission handling and
    // numbers near 0.0
    AssertFatal(rows == cols, "Can only perform inverse on square matrices.");

+ 6 - 67
Engine/source/testing/mathMatrixTest.cpp

@@ -801,73 +801,6 @@ TEST(MatrixTest, TestMatrixAdd)
 
 }
 
-TEST(MatrixTest, TestCalcPlaneCulls)
-{
-   Point3F lightDir(-0.346188605f, -0.742403805f, -0.573576510f);
-   const F32 shadowDistance = 100.0f;
-   // frustum transform
-   MatrixF test(true);
-
-   test(0, 0) = -0.8930f;  test(0, 1) = 0.3043f;   test(0, 2) = 0.3314f;   test(0, 3) = -8.3111f;
-   test(1, 0) = -0.4499f;  test(1, 1) = -0.6039f;  test(1, 2) = -0.6578f;  test(1, 3) = 8.4487f;
-   test(2, 0) = -0.0f;     test(2, 1) = -0.7366f;  test(2, 2) = 0.6763f;   test(2, 3) = 12.5414f;
-   test(0, 0) = 0.00f;     test(0, 1) = 0.0f;      test(0, 2) = 0.0f;      test(0, 3) = 1.0f;
-
-   Box3F viewBB(-shadowDistance, -shadowDistance, -shadowDistance,
-      shadowDistance, shadowDistance, shadowDistance);
-
-   Frustum testFrustum(false, -0.119894862f, 0.119894862f, 0.0767327100f, -0.0767327100f, 0.1f, 1000.0f, test);
-   testFrustum.getTransform().mul(viewBB);
-
-   testFrustum.cropNearFar(0.1f, shadowDistance);
-
-   PlaneF lightFarPlane, lightNearPlane;
-
-   Point3F viewDir = testFrustum.getTransform().getForwardVector();
-   EXPECT_NEAR(viewDir.x, 0.0f, 0.001f);  EXPECT_NEAR(viewDir.y, -0.6039f, 0.001f);  EXPECT_NEAR(viewDir.z, -0.7365f, 0.001f);
-
-   viewDir.normalize();
-   const Point3F viewPosition = testFrustum.getPosition();
-   EXPECT_NEAR(viewPosition.x, 1.0f, 0.001f);  EXPECT_NEAR(viewPosition.y, 8.4486f, 0.001f);  EXPECT_NEAR(viewPosition.z, 12.5414f, 0.001f);
-
-   const F32 viewDistance = testFrustum.getBounds().len();
-   EXPECT_NEAR(viewDistance, 243.6571f, 0.001f);
-
-   lightNearPlane = PlaneF(viewPosition + (viewDistance * -lightDir), lightDir);
-
-   const Point3F lightFarPlanePos = viewPosition + (viewDistance * lightDir);
-   lightFarPlane = PlaneF(lightFarPlanePos, -lightDir);
-
-   MatrixF invLightFarPlaneMat(true);
-
-   MatrixF lightFarPlaneMat = MathUtils::createOrientFromDir(-lightDir);
-   lightFarPlaneMat.setPosition(lightFarPlanePos);
-   lightFarPlaneMat.invertTo(&invLightFarPlaneMat);
-
-   Vector<Point2F> projVertices;
-
-   //project all frustum vertices into plane
-   // all vertices are 2d and local to far plane
-   projVertices.setSize(8);
-   for (int i = 0; i < 8; ++i) //
-   {
-      const Point3F& point = testFrustum.getPoints()[i];
-
-      Point3F localPoint(lightFarPlane.project(point));
-      invLightFarPlaneMat.mulP(localPoint);
-      projVertices[i] = Point2F(localPoint.x, localPoint.z);
-   }
-
-   EXPECT_NEAR(projVertices[0].x, 0.0240f, 0.001f); EXPECT_NEAR(projVertices[0].y, 0.0117f, 0.001f);
-   EXPECT_NEAR(projVertices[1].x, 0.0696f, 0.001f); EXPECT_NEAR(projVertices[1].y, 0.0678f, 0.001f);
-   EXPECT_NEAR(projVertices[2].x, -0.0186f, 0.001f); EXPECT_NEAR(projVertices[2].y, -0.1257f, 0.001f);
-   EXPECT_NEAR(projVertices[3].x, 0.0269f, 0.001f); EXPECT_NEAR(projVertices[3].y, -0.0696f, 0.001f);
-   EXPECT_NEAR(projVertices[4].x, 24.0571f, 0.001f); EXPECT_NEAR(projVertices[4].y, 11.7618f, 0.001f);
-   EXPECT_NEAR(projVertices[5].x, 69.6498f, 0.001f); EXPECT_NEAR(projVertices[5].y, 67.8426f, 0.001f);
-   EXPECT_NEAR(projVertices[6].x, -18.6059f, 0.001f); EXPECT_NEAR(projVertices[6].y, -125.7341f, 0.001f);
-   EXPECT_NEAR(projVertices[7].x, 26.9866f, 0.001f); EXPECT_NEAR(projVertices[7].y, -69.6534f, 0.001f);
-}
-
 TEST(MatrixTest, TestFrustumProjectionMatrix)
 {
    MatrixF test(true);
@@ -943,6 +876,12 @@ TEST(MatrixTest, TestInvertTo)
    EXPECT_NEAR(test(1, 0), 0.8415f, 0.001f);  EXPECT_NEAR(test(1, 1), 0.2919f, 0.001f);  EXPECT_NEAR(test(1, 2), -0.4546f, 0.001f); EXPECT_NEAR(test(1, 3), -2.0f, 0.001f);
    EXPECT_NEAR(test(2, 0), 0.0, 0.001f);      EXPECT_NEAR(test(2, 1), 0.8415f, 0.001f);  EXPECT_NEAR(test(2, 2), 0.5403f, 0.001f);  EXPECT_NEAR(test(2, 3), -1.0f, 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);
+
+   // make sure our original matrix is unchanged
+   EXPECT_NEAR(test1(0, 0), 0.5403f, 0.001f);  EXPECT_NEAR(test1(0, 1), 0.8415f, 0.001f);  EXPECT_NEAR(test1(0, 2), 0.0f, 0.001f);     EXPECT_NEAR(test1(0, 3), 4.3845f, 0.001f);
+   EXPECT_NEAR(test1(1, 0), -0.4546f, 0.001f); EXPECT_NEAR(test1(1, 1), 0.2919f, 0.001f);  EXPECT_NEAR(test1(1, 2), 0.8415f, 0.001f);  EXPECT_NEAR(test1(1, 3), -0.8479f, 0.001f);
+   EXPECT_NEAR(test1(2, 0), 0.7081f, 0.001f);  EXPECT_NEAR(test1(2, 1), -0.4546f, 0.001f); EXPECT_NEAR(test1(2, 2), 0.5403f, 0.001f);  EXPECT_NEAR(test1(2, 3), 3.1714, 0.001f);
+   EXPECT_NEAR(test1(3, 0), 0.0f, 0.001f);     EXPECT_NEAR(test1(3, 1), 0.0f, 0.001f);     EXPECT_NEAR(test1(3, 2), 0.0f, 0.001f);     EXPECT_NEAR(test1(3, 3), 1.0f, 0.001f);
 }
 
 TEST(MatrixTest, TestFullInverse)