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(
);
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
);
}
+void IntersectTest::testRaySphereIntersection() {
+ const double epsilon = std::numeric_limits<double>::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)
+ );
+}
+
}
}
}