]> git.localhorst.tv Git - blank.git/blob - tst/geometry/IntersectionTest.cpp
41fb81a8764b6c5b955f8bb9c13d8ef5b4253afa
[blank.git] / tst / geometry / IntersectionTest.cpp
1 #include "IntersectionTest.hpp"
2
3 #include "geometry/const.hpp"
4 #include "geometry/primitive.hpp"
5
6 #include <limits>
7 #include <glm/gtx/io.hpp>
8 #include <glm/gtx/transform.hpp>
9
10 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::IntersectionTest);
11
12
13 namespace blank {
14 namespace test {
15
16 void IntersectionTest::setUp() {
17 }
18
19 void IntersectionTest::tearDown() {
20 }
21
22
23 void IntersectionTest::testRayBoxIntersection() {
24         Ray ray{ { 0, 0, 0 }, { 1, 0, 0 } }; // at origin, pointing right
25         AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
26         glm::mat4 M(1); // no transformation
27
28         const float delta = std::numeric_limits<float>::epsilon();
29
30         float distance = 0;
31         glm::vec3 normal(0);
32
33         CPPUNIT_ASSERT_MESSAGE(
34                 "ray at origin not intersecting box at origin",
35                 Intersection(ray, box, M, &distance)
36         );
37         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
38                 "intersection distance way off",
39                 0.0f, distance, delta
40         );
41         // normal undefined, so can't test
42
43         // move ray outside the box, but have it still point at it
44         // should be 4 units to the left now
45         ray.orig.x = -5;
46         CPPUNIT_ASSERT_MESSAGE(
47                 "ray pointing at box doesn't intersect",
48                 Intersection(ray, box, M, &distance, &normal)
49         );
50         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
51                 "intersection distance way off",
52                 4.0f, distance, delta
53         );
54         CPPUNIT_ASSERT_EQUAL_MESSAGE(
55                 "wrong surface normal at intersection point",
56                 glm::vec3(-1, 0, 0), normal
57         );
58
59         // move ray to the other side, so it's pointing away now
60         ray.orig.x = 5;
61         CPPUNIT_ASSERT_MESSAGE(
62                 "ray pointing away from box still intersects",
63                 !Intersection(ray, box, M)
64         );
65 }
66
67 void IntersectionTest::testBoxBoxIntersection() {
68         const float delta = std::numeric_limits<float>::epsilon();
69         float depth = 0;
70         glm::vec3 normal(0);
71
72         AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
73         glm::mat4 Ma(1); // identity
74         glm::mat4 Mb(1); // identity
75         // they're identical, so should probably intersect ^^
76
77         CPPUNIT_ASSERT_MESSAGE(
78                 "identical OBBs don't intersect",
79                 Intersection(box, Ma, box, Mb, depth, normal)
80         );
81         // depth is two, but normal can be any
82         // (will probably be the first axis of box a, but any is valid)
83         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
84                 "penetration depth of coincidental 2x2x2 boxes is not 2",
85                 2.0f, depth, delta
86         );
87
88         Ma = glm::translate(glm::vec3(-2, 0, 0)); // 2 to the left
89         Mb = glm::translate(glm::vec3(2, 0, 0)); // 2 to the right
90         CPPUNIT_ASSERT_MESSAGE(
91                 "distant OBBs intersect (2 apart, no rotation)",
92                 !Intersection(box, Ma, box, Mb, depth, normal)
93         );
94         // depth and normal undefined for non-intersecting objects
95
96         Ma = glm::rotate(PI_0p25, glm::vec3(0, 0, 1)); // rotated 45° around Z
97         Mb = glm::translate(glm::vec3(2.4, 0, 0)); // 2.4 to the right
98         // they should barely touch. intersect by about sqrt(2) - 1.4 if my head works
99         CPPUNIT_ASSERT_MESSAGE(
100                 "OBBs don't intersect (one rotated by 45°)",
101                 Intersection(box, Ma, box, Mb, depth, normal)
102         );
103         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
104                 "bad penetration depth (with rotation)",
105                 0.01421356237309504880f, depth, delta
106         );
107         CPPUNIT_ASSERT_EQUAL_MESSAGE(
108                 "bad intersection normal (with rotation)",
109                 glm::vec3(1, 0, 0), abs(normal) // normal can be in + or - x, therefore abs()
110         );
111
112         Mb = glm::translate(glm::vec3(3, 0, 0)); // 3 to the right
113         CPPUNIT_ASSERT_MESSAGE(
114                 "OBBs intersect (one rotated by 45°)",
115                 !Intersection(box, Ma, box, Mb, depth, normal)
116         );
117 }
118
119 }
120 }