Browse Source

Found and fixed a bug in ray to plane intersection.

David Piuva 6 months ago
parent
commit
947c8f3eec
2 changed files with 19 additions and 6 deletions
  1. 1 1
      Source/DFPSR/math/FPlane3D.h
  2. 18 5
      Source/test/tests/PlaneTest.cpp

+ 1 - 1
Source/DFPSR/math/FPlane3D.h

@@ -46,7 +46,7 @@ struct FPlane3D {
 	// The direction does not have to be normalized.
 	// Returns +-INF or NaN when there's no point of intersection.
 	inline FVector3D rayIntersect(const FVector3D &point, const FVector3D &direction) const {
-		float relativeOffset = -(this->offset + dotProduct(this->normal, point)) / dotProduct(this->normal, direction);
+		float relativeOffset = -(dotProduct(this->normal, point) - this->offset) / dotProduct(this->normal, direction);
 		return point + (direction * relativeOffset);
 	}
 };

+ 18 - 5
Source/test/tests/PlaneTest.cpp

@@ -43,9 +43,22 @@ START_TEST(Plane)
 	ASSERT_NEAR(FPlane3D(FVector3D(0.0f, 0.0f, -1.0f), 74.0f).signedDistance(FVector3D(745.1f, 135.2f, -75.0f)), 1.0f);
 	ASSERT_NEAR(FPlane3D(FVector3D(0.0f, 0.0f, -1.0f), 74.0f).signedDistance(FVector3D(246.5f, 294.6f, -74.0f)), 0.0f);
 	ASSERT_NEAR(FPlane3D(FVector3D(0.0f, 0.0f, -1.0f), 74.0f).signedDistance(FVector3D(865.7f, 625.3f, -73.0f)), -1.0f);
-	// Inside or outside
-	ASSERT_EQUAL(FPlane3D(FVector3D( 1.0f,  0.0f ,  0.0f), 0.0f).inside(FVector3D( 0.01f, 0.0f, 0.0f)), false);
-	ASSERT_EQUAL(FPlane3D(FVector3D( 1.0f,  0.0f ,  0.0f), 0.0f).inside(FVector3D(-0.01f, 0.0f, 0.0f)),  true);
-	ASSERT_EQUAL(FPlane3D(FVector3D(-1.0f,  0.0f ,  0.0f), 0.0f).inside(FVector3D( 0.01f, 0.0f, 0.0f)),  true);
-	ASSERT_EQUAL(FPlane3D(FVector3D(-1.0f,  0.0f ,  0.0f), 0.0f).inside(FVector3D(-0.01f, 0.0f, 0.0f)), false);
+	// Inside or outside.
+	ASSERT_EQUAL(FPlane3D(FVector3D( 1.0f, 0.0f, 0.0f), 0.0f).inside(FVector3D( 0.01f, 0.0f, 0.0f)), false);
+	ASSERT_EQUAL(FPlane3D(FVector3D( 1.0f, 0.0f, 0.0f), 0.0f).inside(FVector3D(-0.01f, 0.0f, 0.0f)),  true);
+	ASSERT_EQUAL(FPlane3D(FVector3D(-1.0f, 0.0f, 0.0f), 0.0f).inside(FVector3D( 0.01f, 0.0f, 0.0f)),  true);
+	ASSERT_EQUAL(FPlane3D(FVector3D(-1.0f, 0.0f, 0.0f), 0.0f).inside(FVector3D(-0.01f, 0.0f, 0.0f)), false);
+	ASSERT_EQUAL(FPlane3D(FVector3D( 1.0f, 0.0f, 0.0f), 45.0f).inside(FVector3D( 45.01f, 0.0f, 0.0f)), false);
+	ASSERT_EQUAL(FPlane3D(FVector3D( 1.0f, 0.0f, 0.0f), 45.0f).inside(FVector3D( 44.99f, 0.0f, 0.0f)),  true);
+	ASSERT_EQUAL(FPlane3D(FVector3D(-1.0f, 0.0f, 0.0f), 45.0f).inside(FVector3D(-44.99f, 0.0f, 0.0f)),  true);
+	ASSERT_EQUAL(FPlane3D(FVector3D(-1.0f, 0.0f, 0.0f), 45.0f).inside(FVector3D(-45.01f, 0.0f, 0.0f)), false);
+	ASSERT_EQUAL(FPlane3D(FVector3D( 1.0f, 0.0f, 0.0f), -45.0f).inside(FVector3D(-44.99f, 0.0f, 0.0f)), false);
+	ASSERT_EQUAL(FPlane3D(FVector3D( 1.0f, 0.0f, 0.0f), -45.0f).inside(FVector3D(-45.01f, 0.0f, 0.0f)),  true);
+	ASSERT_EQUAL(FPlane3D(FVector3D(-1.0f, 0.0f, 0.0f), -45.0f).inside(FVector3D( 45.01f, 0.0f, 0.0f)),  true);
+	ASSERT_EQUAL(FPlane3D(FVector3D(-1.0f, 0.0f, 0.0f), -45.0f).inside(FVector3D( 44.99f, 0.0f, 0.0f)), false);
+	// Ray intersection.
+	ASSERT_NEAR(FPlane3D(FVector3D(0.0f, 0.0f,  1.8f), 123.45f).rayIntersect(FVector3D(12.3f, 45.6f, -26.0f), FVector3D(0.0f, 0.0f,  1.2f)), FVector3D(12.3f, 45.6f,  123.45f));
+	ASSERT_NEAR(FPlane3D(FVector3D(0.0f, 0.0f,  1.2f), 123.45f).rayIntersect(FVector3D(22.5f, 74.8f,  42.0f), FVector3D(0.0f, 0.0f, -1.4f)), FVector3D(22.5f, 74.8f,  123.45f));
+	ASSERT_NEAR(FPlane3D(FVector3D(0.0f, 0.0f, -0.3f), 123.45f).rayIntersect(FVector3D(82.6f, 27.4f,  83.0f), FVector3D(0.0f, 0.0f,  0.1f)), FVector3D(82.6f, 27.4f, -123.45f));
+	ASSERT_NEAR(FPlane3D(FVector3D(0.0f, 0.0f, -9.6f), 123.45f).rayIntersect(FVector3D(-6.3f, 53.0f, -45.0f), FVector3D(0.0f, 0.0f, -1.6f)), FVector3D(-6.3f, 53.0f, -123.45f));
 END_TEST