fix invertTo function
unitTest to make sure matrix calling invertTo does not get changed.
reimplemented gauss jordan.
This commit is contained in:
marauder2k7 2024-07-31 18:52:18 +01:00
parent ab4b4cbf96
commit 165a2bea01
2 changed files with 19 additions and 71 deletions

View file

@ -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.");

View file

@ -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)