1 #include "IntersectionTest.hpp"
3 #include "geometry/const.hpp"
4 #include "geometry/primitive.hpp"
7 #include <glm/gtx/io.hpp>
8 #include <glm/gtx/transform.hpp>
10 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::IntersectionTest);
16 void IntersectionTest::setUp() {
19 void IntersectionTest::tearDown() {
23 void IntersectionTest::testSimpleRayBoxIntersection() {
24 Ray ray{ { 0, 0, 0 }, { 1, 0, 0 }, { } }; // at origin, pointing right
26 AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
28 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, distance)
37 // move ray outside the box, but have it still point at it
38 // should be 4 units to the left now
40 CPPUNIT_ASSERT_MESSAGE(
41 "ray pointing at box doesn't intersect",
42 Intersection(ray, box, distance)
44 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
45 "intersection distance way off",
49 // move ray to the other side, so it's pointing away now
51 CPPUNIT_ASSERT_MESSAGE(
52 "ray pointing away from box still intersects",
53 !Intersection(ray, box, distance)
56 // 45 deg down from 4 units away, so should be about 4 * sqrt(2)
57 ray.orig = { -5.0f, 4.5f, 0.0f };
58 ray.dir = { 0.70710678118654752440f, -0.70710678118654752440f, 0.0f };
60 CPPUNIT_ASSERT_MESSAGE(
61 "ray pointing at box doesn't intersect",
62 Intersection(ray, box, distance)
64 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
65 "intersection distance way off",
66 5.65685424949238019520f, distance, delta
70 void IntersectionTest::testRayBoxIntersection() {
71 Ray ray{ { 0, 0, 0 }, { 1, 0, 0 }, { } }; // at origin, pointing right
72 AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
73 glm::mat4 M(1); // no transformation
75 const float delta = std::numeric_limits<float>::epsilon();
80 CPPUNIT_ASSERT_MESSAGE(
81 "ray at origin not intersecting box at origin",
82 Intersection(ray, box, M, &distance)
84 // normal undefined, so can't test
86 // move ray outside the box, but have it still point at it
87 // should be 4 units to the left now
89 CPPUNIT_ASSERT_MESSAGE(
90 "ray pointing at box to the right doesn't intersect",
91 Intersection(ray, box, M, &distance, &normal)
93 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
94 "intersection distance way off",
97 CPPUNIT_ASSERT_EQUAL_MESSAGE(
98 "wrong surface normal at intersection point",
99 glm::vec3(-1, 0, 0), normal
102 // move ray to the other side, so it's pointing away now
104 CPPUNIT_ASSERT_MESSAGE(
105 "ray pointing away from box to the left still intersects",
106 !Intersection(ray, box, M)
111 CPPUNIT_ASSERT_MESSAGE(
112 "ray pointing at box to the left does not intersect",
113 Intersection(ray, box, M, &distance, &normal)
115 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
116 "intersection distance way off",
117 4.0f, distance, delta
119 CPPUNIT_ASSERT_EQUAL_MESSAGE(
120 "wrong surface normal at intersection point",
121 glm::vec3(1, 0, 0), normal
125 ray.orig = { 0, -5, 0 };
126 ray.dir = { 0, 1, 0 };
127 CPPUNIT_ASSERT_MESSAGE(
128 "ray pointing at box above does not intersect",
129 Intersection(ray, box, M, &distance, &normal)
131 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
132 "intersection distance way off",
133 4.0f, distance, delta
135 CPPUNIT_ASSERT_EQUAL_MESSAGE(
136 "wrong surface normal at intersection point",
137 glm::vec3(0, -1, 0), normal
142 CPPUNIT_ASSERT_MESSAGE(
143 "ray pointing away from box above still intersects",
144 !Intersection(ray, box, M)
149 CPPUNIT_ASSERT_MESSAGE(
150 "ray pointing at box below does not intersect",
151 Intersection(ray, box, M, &distance, &normal)
153 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
154 "intersection distance way off",
155 4.0f, distance, delta
157 CPPUNIT_ASSERT_EQUAL_MESSAGE(
158 "wrong surface normal at intersection point",
159 glm::vec3(0, 1, 0), normal
163 ray.orig = { 0, 0, -5 };
164 ray.dir = { 0, 0, 1 };
165 CPPUNIT_ASSERT_MESSAGE(
166 "ray pointing at box in front does not intersect",
167 Intersection(ray, box, M, &distance, &normal)
169 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
170 "intersection distance way off",
171 4.0f, distance, delta
173 CPPUNIT_ASSERT_EQUAL_MESSAGE(
174 "wrong surface normal at intersection point",
175 glm::vec3(0, 0, -1), normal
180 CPPUNIT_ASSERT_MESSAGE(
181 "ray pointing away from box in front still intersects",
182 !Intersection(ray, box, M)
187 CPPUNIT_ASSERT_MESSAGE(
188 "ray pointing at box behind does not intersect",
189 Intersection(ray, box, M, &distance, &normal)
191 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
192 "intersection distance way off",
193 4.0f, distance, delta
195 CPPUNIT_ASSERT_EQUAL_MESSAGE(
196 "wrong surface normal at intersection point",
197 glm::vec3(0, 0, 1), normal
200 // 45 deg down from 4 units away, so should be about 4 * sqrt(2)
201 ray.orig = { -5.0f, 4.5f, 0.0f };
202 ray.dir = { 0.70710678118654752440f, -0.70710678118654752440f, 0.0f };
203 CPPUNIT_ASSERT_MESSAGE(
204 "ray pointing at box doesn't intersect",
205 Intersection(ray, box, M, &distance, &normal)
207 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
208 "intersection distance way off",
209 5.65685424949238019520f, distance, delta
211 CPPUNIT_ASSERT_EQUAL_MESSAGE(
212 "wrong surface normal at intersection point",
213 glm::vec3(-1, 0, 0), normal
217 void IntersectionTest::testBoxBoxIntersection() {
218 const float delta = std::numeric_limits<float>::epsilon();
222 AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
223 glm::mat4 Ma(1); // identity
224 glm::mat4 Mb(1); // identity
225 // they're identical, so should probably intersect ^^
227 CPPUNIT_ASSERT_MESSAGE(
228 "identical OBBs don't intersect",
229 Intersection(box, Ma, box, Mb, depth, normal)
231 // depth is two, but normal can be any
232 // (will probably be the first axis of box a, but any is valid)
233 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
234 "penetration depth of coincidental 2x2x2 boxes is not 2",
238 Ma = glm::translate(glm::vec3(-2, 0, 0)); // 2 to the left
239 Mb = glm::translate(glm::vec3(2, 0, 0)); // 2 to the right
240 CPPUNIT_ASSERT_MESSAGE(
241 "distant OBBs intersect (2 apart, no rotation)",
242 !Intersection(box, Ma, box, Mb, depth, normal)
244 // depth and normal undefined for non-intersecting objects
246 Ma = glm::rotate(PI_0p25, glm::vec3(0, 0, 1)); // rotated 45° around Z
247 Mb = glm::translate(glm::vec3(2.4, 0, 0)); // 2.4 to the right
248 // they should barely touch. intersect by about sqrt(2) - 1.4 if my head works
249 CPPUNIT_ASSERT_MESSAGE(
250 "OBBs don't intersect (one rotated by 45°)",
251 Intersection(box, Ma, box, Mb, depth, normal)
253 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
254 "bad penetration depth (with rotation)",
255 0.01421356237309504880f, depth, delta
257 CPPUNIT_ASSERT_EQUAL_MESSAGE(
258 "bad intersection normal (with rotation)",
259 glm::vec3(1, 0, 0), glm::abs(normal) // normal can be in + or - x, therefore abs()
262 Mb = glm::translate(glm::vec3(3, 0, 0)); // 3 to the right
263 CPPUNIT_ASSERT_MESSAGE(
264 "OBBs intersect (one rotated by 45°)",
265 !Intersection(box, Ma, box, Mb, depth, normal)