]> git.localhorst.tv Git - tacos.git/blob - tst/world/FloorTest.cpp
better ray/floor intersection algorithm
[tacos.git] / tst / world / FloorTest.cpp
1 #include "FloorTest.hpp"
2
3 #include "../vector_assert.hpp"
4
5 #include <world/Floor.hpp>
6
7 CPPUNIT_TEST_SUITE_REGISTRATION(tacos::test::FloorTest);
8
9 namespace tacos {
10 namespace test {
11
12 void FloorTest::setUp() {
13 }
14
15 void FloorTest::tearDown() {
16 }
17
18
19 void FloorTest::testIntersection() {
20         Floor floor(33, 33);
21         Ray ray;
22         glm::vec3 point;
23
24         // default floor has all heights at 0, so a ray within the grid at height 1 pointing
25         // straight down should intersect it
26         // this ray hits the triangle somewhere near the middle
27         ray.origin = glm::vec3(0.5f, 1.0f, 0.75f);
28         ray.direction = glm::vec3(0.0f, -1.0f, 0.0f);
29         CPPUNIT_ASSERT_MESSAGE(
30                 "ray pointing down at a triangle does not intersect floor when it should",
31                 floor.Intersection(ray, point)
32         );
33         AssertEqual(
34                 "unexpected intersection point",
35                 glm::vec3(0.5f, 0.0f, 0.75f), point
36         );
37         // this ray should hit on the low X edge of the triangle
38         ray.origin = glm::vec3(0.0f, 1.0f, 0.5f);
39         ray.direction = glm::vec3(0.0f, -1.0f, 0.0f);
40         CPPUNIT_ASSERT_MESSAGE(
41                 "ray pointing down at a low X triangle edge does not intersect floor when it should",
42                 floor.Intersection(ray, point)
43         );
44         AssertEqual(
45                 "unexpected intersection point",
46                 glm::vec3(0.0f, 0.0f, 0.5f), point
47         );
48         // this ray should hit on the low Z edge of the triangle
49         ray.origin = glm::vec3(0.5f, 1.0f, 0.0f);
50         ray.direction = glm::vec3(0.0f, -1.0f, 0.0f);
51         CPPUNIT_ASSERT_MESSAGE(
52                 "ray pointing down  at a low Z triangle edgedoes not intersect floor when it should",
53                 floor.Intersection(ray, point)
54         );
55         AssertEqual(
56                 "unexpected intersection point",
57                 glm::vec3(0.5f, 0.0f, 0.0f), point
58         );
59         // this ray should hit on the diagonal edge of the triangle
60         ray.origin = glm::vec3(0.5f, 1.0f, 0.5f);
61         ray.direction = glm::vec3(0.0f, -1.0f, 0.0f);
62         CPPUNIT_ASSERT_MESSAGE(
63                 "ray pointing down at a diagonal triangle edgedoes not intersect floor when it should",
64                 floor.Intersection(ray, point)
65         );
66         AssertEqual(
67                 "unexpected intersection point",
68                 glm::vec3(0.5f, 0.0f, 0.5f), point
69         );
70         // this ray points straight away from the floor, so should not intersect
71         ray.origin = glm::vec3(0.5f, 1.0f, 0.5f);
72         ray.direction = glm::vec3(0.0f, 1.0f, 0.0f);
73         CPPUNIT_ASSERT_MESSAGE(
74                 "ray pointing up intersects floor when it shouldn't",
75                 !floor.Intersection(ray, point)
76         );
77         // this ray start below the floor and points down, so stays "underground" the whole time
78         ray.origin = glm::vec3(0.5f, -1.0f, 0.5f);
79         ray.direction = glm::vec3(0.0f, -1.0f, 0.0f);
80         CPPUNIT_ASSERT_MESSAGE(
81                 "ray pointing down intersects floor when it shouldn't",
82                 !floor.Intersection(ray, point)
83         );
84         // this ray start below the floor and points up, that means it intersects, although from the unexpected side
85         ray.origin = glm::vec3(0.5f, -1.0f, 0.5f);
86         ray.direction = glm::vec3(0.0f, 1.0f, 0.0f);
87         CPPUNIT_ASSERT_MESSAGE(
88                 "ray below the floor pointing up does not intersect floor when it should",
89                 floor.Intersection(ray, point)
90         );
91         AssertEqual(
92                 "unexpected intersection point",
93                 glm::vec3(0.5f, 0.0f, 0.5f), point
94         );
95
96         ray.origin = glm::vec3(0.0f, 1.0f, 1.0f);
97         ray.direction = glm::normalize(glm::vec3(1.0f, -1.0f, 0.0f));
98         CPPUNIT_ASSERT_MESSAGE(
99                 "diagonal ray, starts 1 unit above the floor and points down and to the right does not intersect floor when it should",
100                 floor.Intersection(ray, point)
101         );
102         AssertEqual(
103                 "unexpected intersection point",
104                 glm::vec3(1.0f, 0.0f, 1.0f), point
105         );
106         // the same ray, but with origin outside the XZ grid
107         ray.origin = glm::vec3(-1.0f, 2.0f, 1.0f);
108         ray.direction = glm::normalize(glm::vec3(1.0f, -1.0f, 0.0f));
109         CPPUNIT_ASSERT_MESSAGE(
110                 "ray entering from the left does not intersect floor when it should",
111                 floor.Intersection(ray, point)
112         );
113         AssertEqual(
114                 "unexpected intersection point",
115                 glm::vec3(1.0f, 0.0f, 1.0f), point
116         );
117         ray.origin = glm::vec3(3.0f, 2.0f, 1.0f);
118         ray.direction = glm::normalize(glm::vec3(-1.0f, -1.0f, 0.0f));
119         CPPUNIT_ASSERT_MESSAGE(
120                 "ray entering from the right does not intersect floor when it should",
121                 floor.Intersection(ray, point)
122         );
123         AssertEqual(
124                 "unexpected intersection point",
125                 glm::vec3(1.0f, 0.0f, 1.0f), point
126         );
127         ray.origin = glm::vec3(1.0f, 1.0f, 1.0f);
128         ray.direction = glm::normalize(glm::vec3(1.0f, 0.0f, 1.0f));
129         CPPUNIT_ASSERT_MESSAGE(
130                 "ray parallel to the floor intersects floor when it shouldn't",
131                 !floor.Intersection(ray, point)
132         );
133
134         ray.origin = glm::vec3(19.993f, 49.947f, 106.518f);
135         ray.direction = glm::normalize(glm::vec3(-0.07f, -0.528f, -0.846f));
136         CPPUNIT_ASSERT_MESSAGE(
137                 "weird ray #1 from interactive testing doesn't intersect :(",
138                 floor.Intersection(ray, point)
139         );
140         AssertEqual(
141                 "unexpected intersection point",
142                 glm::vec3(13.37123870f, 0.0f, 26.48928486f), point,
143                 0.00001f // using custom delta since values above are somewhat rounded/truncated
144         );
145         ray.origin = glm::vec3(19.995f, 49.952f, 106.515f);
146         ray.direction = glm::normalize(glm::vec3(-0.046f, -0.477f, -0.878f));
147         CPPUNIT_ASSERT_MESSAGE(
148                 "weird ray #2 from interactive testing doesn't intersect :(",
149                 floor.Intersection(ray, point)
150         );
151         AssertEqual(
152                 "unexpected intersection point",
153                 glm::vec3(15.17783f, 0.0f, 14.56982f), point,
154                 0.00001f
155         );
156 }
157
158 }
159 }