]> git.localhorst.tv Git - blank.git/blob - tst/model/GeometryTest.cpp
82f88eeefcf5de296a3aaf9e013d65cd97509dde
[blank.git] / tst / model / GeometryTest.cpp
1 #include "GeometryTest.hpp"
2
3 #include "model/geometry.hpp"
4
5 #include <limits>
6 #include <glm/gtx/io.hpp>
7 #include <glm/gtx/transform.hpp>
8
9 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::GeometryTest);
10
11
12 namespace blank {
13 namespace test {
14
15 void GeometryTest::setUp() {
16 }
17
18 void GeometryTest::tearDown() {
19 }
20
21
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
26
27         const float delta = std::numeric_limits<float>::epsilon();
28
29         float distance = 0;
30         glm::vec3 normal(0);
31
32         CPPUNIT_ASSERT_MESSAGE(
33                 "ray at origin not intersecting box at origin",
34                 Intersection(ray, box, M, &distance)
35         );
36         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
37                 "intersection distance way off",
38                 0.0f, distance, delta
39         );
40         // normal undefined, so can't test
41
42         // move ray outside the box, but have it still point at it
43         // should be 4 units to the left now
44         ray.orig.x = -5;
45         CPPUNIT_ASSERT_MESSAGE(
46                 "ray pointing at box doesn't intersect",
47                 Intersection(ray, box, M, &distance, &normal)
48         );
49         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
50                 "intersection distance way off",
51                 4.0f, distance, delta
52         );
53         CPPUNIT_ASSERT_EQUAL_MESSAGE(
54                 "wrong surface normal at intersection point",
55                 glm::vec3(-1, 0, 0), normal
56         );
57
58         // move ray to the other side, so it's pointing away now
59         ray.orig.x = 5;
60         CPPUNIT_ASSERT_MESSAGE(
61                 "ray pointing away from box still intersects",
62                 !Intersection(ray, box, M)
63         );
64 }
65
66 void GeometryTest::testBoxBoxIntersection() {
67         const float delta = std::numeric_limits<float>::epsilon();
68         float depth = 0;
69         glm::vec3 normal(0);
70
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 ^^
75
76         CPPUNIT_ASSERT_MESSAGE(
77                 "identical OBBs don't intersect",
78                 Intersection(box, Ma, box, Mb, depth, normal)
79         );
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",
84                 2.0f, depth, delta
85         );
86
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)
92         );
93         // depth and normal undefined for non-intersecting objects
94
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)
101         );
102         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
103                 "bad penetration depth (with rotation)",
104                 0.01421356237309504880f, depth, delta
105         );
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()
109         );
110
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)
115         );
116 }
117
118 }
119 }