]> git.localhorst.tv Git - gong.git/blobdiff - tst/geometry/IntersectionTest.cpp
spheres
[gong.git] / tst / geometry / IntersectionTest.cpp
index 7aac189f58fda280209cd5677f23c7cdb85aa708..d2332fe7f74b7ddb55ee2a449b0fdb9459788411 100644 (file)
@@ -21,7 +21,7 @@ void IntersectionTest::tearDown() {
 }
 
 
-void IntersectionTest::testSimpleRayBoxIntersection() {
+void IntersectionTest::testSimpleRayBox() {
        Ray ray{ { 0, 0, 0 }, { 1, 0, 0 }, { } }; // at origin, pointing right
        ray.Update();
        AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
@@ -68,7 +68,7 @@ void IntersectionTest::testSimpleRayBoxIntersection() {
        );
 }
 
-void IntersectionTest::testRayBoxIntersection() {
+void IntersectionTest::testRayBox() {
        Ray ray{ { 0, 0, 0 }, { 1, 0, 0 }, { } }; // at origin, pointing right
        AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
        glm::mat4 M(1); // no transformation
@@ -215,7 +215,7 @@ void IntersectionTest::testRayBoxIntersection() {
        );
 }
 
-void IntersectionTest::testBoxBoxIntersection() {
+void IntersectionTest::testBoxBox() {
        const float delta = std::numeric_limits<float>::epsilon();
        float depth = 0;
        glm::vec3 normal(0);
@@ -267,6 +267,130 @@ void IntersectionTest::testBoxBoxIntersection() {
        );
 }
 
+void IntersectionTest::testSpherePlane() {
+       const float delta = std::numeric_limits<float>::epsilon();
+
+       // unit sphere at origin
+       Sphere sphere{{ 0.0f, 0.0f, 0.0f }, 1.0f};
+       // horizontal plane at origin (the XZ plane)
+       Plane plane{{ 0.0f, 1.0f, 0.0f }, 0.0f };
+       float depth;
+       glm::vec3 normal;
+
+       CPPUNIT_ASSERT_MESSAGE(
+               "sphere at origin does not intersect plane at origin",
+               Intersection(sphere, plane, depth, normal)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "bad penetration depth of sphere with plane",
+               1.0f, depth, delta
+       );
+       // normal is actually undefined in this case, but either will work
+       CPPUNIT_ASSERT_MESSAGE(
+               "bad contact normal of sphere intersecting plane",
+               normal == glm::vec3(0.0f, 1.0f, 0.0f) || normal == glm::vec3(0.0f, -1.0f, 0.0f)
+       );
+
+       // center above, but still intersecting
+       sphere.origin.y = 0.5f;
+       CPPUNIT_ASSERT_MESSAGE(
+               "sphere does not intersect plane",
+               Intersection(sphere, plane, depth, normal)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "bad penetration depth of sphere with plane",
+               0.5f, depth, delta
+       );
+       CPPUNIT_ASSERT_EQUAL_MESSAGE(
+               "bad contact normal of sphere intersecting plane",
+               glm::vec3(0.0f, 1.0f, 0.0f), normal
+       );
+
+       // center below, but still intersecting
+       sphere.origin.y = -0.5f;
+       CPPUNIT_ASSERT_MESSAGE(
+               "sphere does not intersect plane",
+               Intersection(sphere, plane, depth, normal)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "bad penetration depth of sphere with plane",
+               0.5f, depth, delta
+       );
+       CPPUNIT_ASSERT_EQUAL_MESSAGE(
+               "bad contact normal of sphere intersecting plane",
+               glm::vec3(0.0f, -1.0f, 0.0f), normal
+       );
+
+       // sphere completely above
+       sphere.origin.y = 1.5f;
+       CPPUNIT_ASSERT_MESSAGE(
+               "sphere above plane intersects",
+               !Intersection(sphere, plane, depth, normal)
+       );
+
+       // sphere completely below
+       sphere.origin.y = -1.5f;
+       CPPUNIT_ASSERT_MESSAGE(
+               "sphere below plane intersects",
+               !Intersection(sphere, plane, depth, normal)
+       );
+}
+
+void IntersectionTest::testSphereHalfSpace() {
+       const float delta = std::numeric_limits<float>::epsilon();
+
+       // unit sphere at origin
+       Sphere sphere{{ 0.0f, 0.0f, 0.0f }, 1.0f};
+       // horizontal plane at origin (the XZ plane)
+       Plane plane{{ 0.0f, 1.0f, 0.0f }, 0.0f };
+       float depth;
+
+       CPPUNIT_ASSERT_MESSAGE(
+               "sphere at origin does not intersect half space to origin",
+               Intersection(sphere, plane, depth)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "bad penetration depth of sphere with half space",
+               1.0f, depth, delta
+       );
+
+       sphere.origin.y = 0.5f;
+       CPPUNIT_ASSERT_MESSAGE(
+               "sphere does not intersect half space",
+               Intersection(sphere, plane, depth)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "bad penetration depth of sphere with half space",
+               0.5f, depth, delta
+       );
+
+       sphere.origin.y = -0.5f;
+       CPPUNIT_ASSERT_MESSAGE(
+               "sphere does not intersect half space",
+               Intersection(sphere, plane, depth)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "bad penetration depth of sphere with half space",
+               1.5f, depth, delta
+       );
+
+       sphere.origin.y = -1.5f;
+       CPPUNIT_ASSERT_MESSAGE(
+               "sphere inside half space does not intersect",
+               Intersection(sphere, plane, depth)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "bad penetration depth of sphere with half space",
+               2.5f, depth, delta
+       );
+
+       sphere.origin.y = 1.5f;
+       CPPUNIT_ASSERT_MESSAGE(
+               "sphere outside half space intersects",
+               !Intersection(sphere, plane, depth)
+       );
+}
+
 }
 }
 }