1 #include "GeometryTest.hpp"
3 #include "model/geometry.hpp"
6 #include <glm/gtx/io.hpp>
7 #include <glm/gtx/transform.hpp>
9 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::GeometryTest);
15 void GeometryTest::setUp() {
18 void GeometryTest::tearDown() {
22 void GeometryTest::testRayBoxIntersection() {
23 Ray ray{ { 0, 0, 0 }, { 1, 0, 0 } }; // at origin, pointing right
24 AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
25 glm::mat4 M(1); // no transformation
27 const float delta = std::numeric_limits<float>::epsilon();
32 CPPUNIT_ASSERT_MESSAGE(
33 "ray at origin not intersecting box at origin",
34 Intersection(ray, box, M, &distance)
36 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
37 "intersection distance way off",
40 // normal undefined, so can't test
42 // move ray outside the box, but have it still point at it
43 // should be 4 units to the left now
45 CPPUNIT_ASSERT_MESSAGE(
46 "ray pointing at box doesn't intersect",
47 Intersection(ray, box, M, &distance, &normal)
49 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
50 "intersection distance way off",
53 CPPUNIT_ASSERT_EQUAL_MESSAGE(
54 "wrong surface normal at intersection point",
55 glm::vec3(-1, 0, 0), normal
58 // move ray to the other side, so it's pointing away now
60 CPPUNIT_ASSERT_MESSAGE(
61 "ray pointing away from box still intersects",
62 !Intersection(ray, box, M)
66 void GeometryTest::testBoxBoxIntersection() {
67 const float delta = std::numeric_limits<float>::epsilon();
71 AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
72 glm::mat4 Ma(1); // identity
73 glm::mat4 Mb(1); // identity
74 // they're identical, so should probably intersect ^^
76 CPPUNIT_ASSERT_MESSAGE(
77 "identical OBBs don't intersect",
78 Intersection(box, Ma, box, Mb, depth, normal)
80 // depth is two, but normal can be any
81 // (will probably be the first axis of box a, but any is valid)
82 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
83 "penetration depth of coincidental 2x2x2 boxes is not 2",
87 Ma = glm::translate(glm::vec3(-2, 0, 0)); // 2 to the left
88 Mb = glm::translate(glm::vec3(2, 0, 0)); // 2 to the right
89 CPPUNIT_ASSERT_MESSAGE(
90 "distant OBBs intersect (2 apart, no rotation)",
91 !Intersection(box, Ma, box, Mb, depth, normal)
93 // depth and normal undefined for non-intersecting objects
95 Ma = glm::rotate(PI_0p25, glm::vec3(0, 0, 1)); // rotated 45° around Z
96 Mb = glm::translate(glm::vec3(2.4, 0, 0)); // 2.4 to the right
97 // they should barely touch. intersect by about sqrt(2) - 1.4 if my head works
98 CPPUNIT_ASSERT_MESSAGE(
99 "OBBs don't intersect (one rotated by 45°)",
100 Intersection(box, Ma, box, Mb, depth, normal)
102 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
103 "bad penetration depth (with rotation)",
104 0.01421356237309504880f, depth, delta
106 CPPUNIT_ASSERT_EQUAL_MESSAGE(
107 "bad intersection normal (with rotation)",
108 glm::vec3(1, 0, 0), abs(normal) // normal can be in + or - x, therefore abs()
111 Mb = glm::translate(glm::vec3(3, 0, 0)); // 3 to the right
112 CPPUNIT_ASSERT_MESSAGE(
113 "OBBs intersect (one rotated by 45°)",
114 !Intersection(box, Ma, box, Mb, depth, normal)