X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=tst%2Fmath%2FIntersectTest.cpp;h=f428aaa59a585ce0f3a84f941ff8df12fe23b3e2;hb=82c3e2c1e27f05b9617a4da8e4806ace7d38a5e1;hp=dc6667aaed3c03b05cc254bcbb31f04f03975feb;hpb=348143f5e41a5692ed7c8deab200f3c62f4395a2;p=blobs.git diff --git a/tst/math/IntersectTest.cpp b/tst/math/IntersectTest.cpp index dc6667a..f428aaa 100644 --- a/tst/math/IntersectTest.cpp +++ b/tst/math/IntersectTest.cpp @@ -177,8 +177,8 @@ void IntersectTest::testBoxBoxIntersection() { glm::dvec3 normal(0); AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin - glm::mat4 Ma(1); // identity - glm::mat4 Mb(1); // identity + glm::dmat4 Ma(1); // identity + glm::dmat4 Mb(1); // identity // they're identical, so should probably intersect ^^ CPPUNIT_ASSERT_MESSAGE( @@ -209,11 +209,11 @@ void IntersectTest::testBoxBoxIntersection() { ); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "bad penetration depth (with rotation)", - 0.0142134428024292, depth, delta + 0.014213562373095, depth, delta ); AssertEqual( "bad intersection normal (with rotation)", - glm::dvec3(1, 0, 0), abs(normal) // normal can be in + or - x, therefore abs() + glm::dvec3(1, 0, 0), glm::abs(normal) // normal can be in + or - x, therefore abs() ); Mb = glm::translate(glm::dvec3(3, 0, 0)); // 3 to the right @@ -223,6 +223,101 @@ void IntersectTest::testBoxBoxIntersection() { ); } +void IntersectTest::testRaySphereIntersection() { + const double epsilon = std::numeric_limits::epsilon(); + Ray ray{ { 0.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 } }; // at origin, pointing right + Sphere sphere{ { 0.0, 0.0, 0.0 }, 1.0 }; // unit sphere at origin + + glm::dvec3 normal(0.0); + double dist = 0.0; + CPPUNIT_ASSERT_MESSAGE( + "ray at origin does not intersect sphere at origin", + Intersect(ray, sphere, normal, dist) + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "distance along ray to unit sphere, both at origin, is not 1", + 1.0, dist, epsilon + ); + AssertEqual( + "bad intersection normal", + glm::dvec3(1.0, 0.0, 0.0), normal + ); + + ray.Origin({ 0.5, 0.0, 0.0 }); // a tad to the right + CPPUNIT_ASSERT_MESSAGE( + "ray does not intersect sphere at origin", + Intersect(ray, sphere, normal, dist) + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "distance along ray to unit sphere at origin is not 0.5", + 0.5, dist, epsilon + ); + AssertEqual( + "bad intersection normal", + glm::dvec3(1.0, 0.0, 0.0), normal + ); + + // corner case: ray origin exactly on sphere (should "intersect") + ray.Origin({ 1.0, 0.0, 0.0 }); + CPPUNIT_ASSERT_MESSAGE( + "ray touching sphere does not intersect it", + Intersect(ray, sphere, normal, dist) + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "distance along ray touching unit sphere is not 0.0", + 0.0, dist, epsilon + ); + AssertEqual( + "bad intersection normal", + glm::dvec3(1.0, 0.0, 0.0), normal + ); + + ray.Origin({ 2.0, 0.0, 0.0 }); // move outside + CPPUNIT_ASSERT_MESSAGE( + "ray pointing away from sphere intersects it for some reason", + !Intersect(ray, sphere, normal, dist) + ); + + ray.Direction({ -1.0, 0.0, 0.0 }); // flip it around + CPPUNIT_ASSERT_MESSAGE( + "negative X ray does not intersect sphere", + Intersect(ray, sphere, normal, dist) + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "distance along ray to unit sphere at origin is not 1", + 1.0, dist, epsilon + ); + AssertEqual( + "bad intersection normal", + glm::dvec3(1.0, 0.0, 0.0), normal + ); + + // sphere at 3,0,0; ray at 0,4,0 pointing directly at it + // should be 5 units apart, minus one for the radius + ray.Origin({ 0.0, 4.0, 0.0 }); + ray.Direction(glm::normalize(glm::dvec3(3.0, -4.0, 0.0))); + sphere.origin = { 3.0, 0.0, 0.0 }; + CPPUNIT_ASSERT_MESSAGE( + "diagonal ray does not intersect sphere", + Intersect(ray, sphere, normal, dist) + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "distance along ray to unit sphere is not 4", + 4.0, dist, epsilon + ); + AssertEqual( + "bad intersection normal", + glm::normalize(glm::dvec3(-3.0, 4.0, 0.0)), normal + ); + + // point the ray straight down, so it misses + ray.Direction({ 0.0, -1.0, 0.0}); + CPPUNIT_ASSERT_MESSAGE( + "vertical ray should not intersect sphere", + !Intersect(ray, sphere, normal, dist) + ); +} + } } }