X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;ds=sidebyside;f=tst%2Fgeometry%2FIntersectionTest.cpp;h=550c0f257c65fc2bf33325d59b4aa7c939215031;hb=48d34439f3d5bc8bebabe9f0ee35970359e61bfa;hp=7aac189f58fda280209cd5677f23c7cdb85aa708;hpb=0e069351615f1315a5c7103fe5c849a242f72683;p=gong.git diff --git a/tst/geometry/IntersectionTest.cpp b/tst/geometry/IntersectionTest.cpp index 7aac189..550c0f2 100644 --- a/tst/geometry/IntersectionTest.cpp +++ b/tst/geometry/IntersectionTest.cpp @@ -21,7 +21,65 @@ void IntersectionTest::tearDown() { } -void IntersectionTest::testSimpleRayBoxIntersection() { +void IntersectionTest::testAABB() { + AABB a{ { -1, -1, -1 }, { 1, 1, 1 } }; + AABB b(a); + + CPPUNIT_ASSERT_MESSAGE( + "coincidental AABBs should intersect", + Intersection(a, b) + ); + + b.Move({ 1, 0, 0 }); + CPPUNIT_ASSERT_MESSAGE( + "AABBs should intersect", + Intersection(a, b) + ); + + b.Move({ 2, 0, 0 }); + CPPUNIT_ASSERT_MESSAGE( + "AABBs should not intersect", + !Intersection(a, b) + ); + + b.Move({ -4, 0, 0 }); + CPPUNIT_ASSERT_MESSAGE( + "AABBs should intersect", + Intersection(a, b) + ); + + b.Move({ -2, 0, 0 }); + CPPUNIT_ASSERT_MESSAGE( + "AABBs should not intersect", + !Intersection(a, b) + ); + + b.Move({ 3, 1, 0 }); + CPPUNIT_ASSERT_MESSAGE( + "AABBs should intersect", + Intersection(a, b) + ); + + b.Move({ 0, 2, 0 }); + CPPUNIT_ASSERT_MESSAGE( + "AABBs should not intersect", + !Intersection(a, b) + ); + + b.Move({ 2, 0, 0 }); + CPPUNIT_ASSERT_MESSAGE( + "AABBs should not intersect", + !Intersection(a, b) + ); + + b.Move({ 0, 0, 2 }); + CPPUNIT_ASSERT_MESSAGE( + "AABBs should not intersect", + !Intersection(a, b) + ); +} + +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 +126,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 +273,7 @@ void IntersectionTest::testRayBoxIntersection() { ); } -void IntersectionTest::testBoxBoxIntersection() { +void IntersectionTest::testBoxBox() { const float delta = std::numeric_limits::epsilon(); float depth = 0; glm::vec3 normal(0); @@ -267,6 +325,183 @@ void IntersectionTest::testBoxBoxIntersection() { ); } +void IntersectionTest::testSphereSphere() { + const float delta = std::numeric_limits::epsilon(); + + Sphere a{{ 0.0f, 0.0f, 0.0f }, 1.0f}; + Sphere b{{ 0.0f, 0.0f, 0.0f }, 1.0f}; + float depth; + glm::vec3 normal; + + CPPUNIT_ASSERT_MESSAGE( + "coincidental spheres should intersect", + Intersection(a, b, depth, normal) + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "bad intersection distance", + 2.0f, depth, delta + ); + // normal can be just about anything + + b.Move({ 1, 0, 0 }); + CPPUNIT_ASSERT_MESSAGE( + "spheres should intersect", + Intersection(a, b, depth, normal) + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "bad intersection distance", + 1.0f, depth, delta + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "bad intersection normal", + glm::vec3(1, 0, 0), normal + ); + + b.Position({ -1.5, 0, 0 }); + CPPUNIT_ASSERT_MESSAGE( + "spheres should intersect", + Intersection(a, b, depth, normal) + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "bad intersection distance", + 0.5f, depth, delta + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "bad intersection normal", + glm::vec3(-1, 0, 0), normal + ); + + b.Move({ -1, 0, 0 }); + CPPUNIT_ASSERT_MESSAGE( + "spheres should not intersect", + !Intersection(a, b, depth, normal) + ); +} + +void IntersectionTest::testSpherePlane() { + const float delta = std::numeric_limits::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::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) + ); +} + } } }