]> git.localhorst.tv Git - blank.git/blob - src/shape.cpp
3df425785d5eb922948cdccd31b80ad638db6d23
[blank.git] / src / shape.cpp
1 #include "shape.hpp"
2
3
4 namespace blank {
5
6 CuboidShape::CuboidShape(const AABB &b)
7 : Shape()
8 , bb(b) {
9         bb.Adjust();
10 }
11
12
13 size_t CuboidShape::VertexCount() const {
14         return 36;
15 }
16
17 void CuboidShape::Vertices(std::vector<glm::vec3> &out, const glm::vec3 &pos) const {
18         out.reserve(36);
19         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); // front
20         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z);
21         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z);
22         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z);
23         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z);
24         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z);
25         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // back
26         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z);
27         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z);
28         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z);
29         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z);
30         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z);
31         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); // top
32         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z);
33         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z);
34         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z);
35         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z);
36         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z);
37         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // bottom
38         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z);
39         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z);
40         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z);
41         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z);
42         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z);
43         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // left
44         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z);
45         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z);
46         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z);
47         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z);
48         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z);
49         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); // right
50         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z);
51         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z);
52         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z);
53         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z);
54         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z);
55 }
56
57 void CuboidShape::Normals(std::vector<glm::vec3> &out) const {
58         out.reserve(36);
59         out.insert(out.end(), 6, glm::vec3( 0.0f,  0.0f,  1.0f)); // front
60         out.insert(out.end(), 6, glm::vec3( 0.0f,  0.0f, -1.0f)); // back
61         out.insert(out.end(), 6, glm::vec3( 0.0f,  1.0f,  0.0f)); // top
62         out.insert(out.end(), 6, glm::vec3( 0.0f, -1.0f,  0.0f)); // bottom
63         out.insert(out.end(), 6, glm::vec3(-1.0f,  0.0f,  0.0f)); // left
64         out.insert(out.end(), 6, glm::vec3( 1.0f,  0.0f,  0.0f)); // right
65 }
66
67
68 size_t CuboidShape::OutlineCount() const {
69         return 24;
70 }
71
72 void CuboidShape::Outline(std::vector<glm::vec3> &out, const glm::vec3 &pos) const {
73         out.reserve(24);
74         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z);
75         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z);
76         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z);
77         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z);
78         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z);
79         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z);
80         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z);
81         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z);
82         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z);
83         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z);
84         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z);
85         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z);
86         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z);
87         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z);
88         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z);
89         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z);
90         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z);
91         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z);
92         out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z);
93         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z);
94         out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z);
95         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z);
96         out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z);
97         out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z);
98 }
99
100 bool CuboidShape::Intersects(const Ray &ray, const glm::mat4 &M, float &dist, glm::vec3 &normal) const {
101         return Intersection(ray, bb, M, &dist, &normal);
102 }
103
104
105 StairShape::StairShape(const AABB &bb, const glm::vec2 &clip)
106 : top({ { clip.x, clip.y, bb.min.z }, bb.max })
107 , bot({ bb.min, { bb.max.x, clip.y, bb.max.z } }) {
108
109 }
110
111
112 size_t StairShape::VertexCount() const {
113         return 60;
114 }
115
116 void StairShape::Vertices(std::vector<glm::vec3> &out, const glm::vec3 &pos) const {
117         out.reserve(60);
118         out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.max.z); // front, upper
119         out.emplace_back(pos.x + top.max.x, pos.y + top.min.y, pos.z + top.max.z);
120         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z);
121         out.emplace_back(pos.x + top.max.x, pos.y + top.min.y, pos.z + top.max.z);
122         out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.max.z);
123         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z);
124         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); // front, lower
125         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z);
126         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z);
127         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z);
128         out.emplace_back(pos.x + bot.max.x, pos.y + bot.max.y, pos.z + bot.max.z);
129         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z);
130         out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.min.z); // back, upper
131         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z);
132         out.emplace_back(pos.x + top.max.x, pos.y + top.min.y, pos.z + top.min.z);
133         out.emplace_back(pos.x + top.max.x, pos.y + top.min.y, pos.z + top.min.z);
134         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z);
135         out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z);
136         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // back, lower
137         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z);
138         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z);
139         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z);
140         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z);
141         out.emplace_back(pos.x + bot.max.x, pos.y + bot.max.y, pos.z + bot.min.z);
142         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z); // top, upper
143         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z);
144         out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z);
145         out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z);
146         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z);
147         out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.max.z);
148         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); // top, lower
149         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z);
150         out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.min.z);
151         out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.min.z);
152         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z);
153         out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.max.z);
154         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // bottom
155         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z);
156         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z);
157         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z);
158         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z);
159         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z);
160         out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.min.z); // left, upper
161         out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.max.z);
162         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z);
163         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z);
164         out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.max.z);
165         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z);
166         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // left, lower
167         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z);
168         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z);
169         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z);
170         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z);
171         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z);
172         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); // right
173         out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z);
174         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z);
175         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z);
176         out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z);
177         out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.max.z);
178 }
179
180 void StairShape::Normals(std::vector<glm::vec3> &out) const {
181         out.reserve(60);
182         out.insert(out.end(), 12, glm::vec3( 0.0f,  0.0f,  1.0f)); // front, x2
183         out.insert(out.end(), 12, glm::vec3( 0.0f,  0.0f, -1.0f)); // back, x2
184         out.insert(out.end(), 12, glm::vec3( 0.0f,  1.0f,  0.0f)); // top, x2
185         out.insert(out.end(),  6, glm::vec3( 0.0f, -1.0f,  0.0f)); // bottom
186         out.insert(out.end(), 12, glm::vec3(-1.0f,  0.0f,  0.0f)); // left, x2
187         out.insert(out.end(),  6, glm::vec3( 1.0f,  0.0f,  0.0f)); // right
188 }
189
190
191 size_t StairShape::OutlineCount() const {
192         return 36;
193 }
194
195 void StairShape::Outline(std::vector<glm::vec3> &out, const glm::vec3 &pos) const {
196         out.reserve(36);
197         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // bottom
198         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z);
199         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z);
200         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z);
201         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z);
202         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z);
203         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z);
204         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z);
205         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); // middle
206         out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.min.z);
207         out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.min.z);
208         out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.max.z);
209         out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.max.z);
210         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z);
211         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z);
212         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z);
213         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.min.z); // top
214         out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.min.z);
215         out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.min.z);
216         out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.max.z);
217         out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.max.z);
218         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.max.z);
219         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.max.z);
220         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.min.z);
221         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // verticals, ltr/btf
222         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z);
223         out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z);
224         out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z);
225         out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + bot.min.z);
226         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.min.z);
227         out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + bot.max.z);
228         out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.max.z);
229         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z);
230         out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.min.z);
231         out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z);
232         out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.max.z);
233 }
234
235 bool StairShape::Intersects(const Ray &ray, const glm::mat4 &M, float &dist, glm::vec3 &norm) const {
236         float top_dist, bot_dist;
237         glm::vec3 top_norm, bot_norm;
238         bool top_hit = Intersection(ray, top, M, &top_dist, &top_norm);
239         bool bot_hit = Intersection(ray, bot, M, &bot_dist, &bot_norm);
240
241         if (top_hit) {
242                 if (bot_hit) {
243                         if (top_dist < bot_dist) {
244                                 dist = top_dist;
245                                 norm = top_norm;
246                                 return true;
247                         } else {
248                                 dist = bot_dist;
249                                 norm = bot_norm;
250                                 return true;
251                         }
252                 } else {
253                         dist = top_dist;
254                         norm = top_norm;
255                         return true;
256                 }
257         } else if (bot_hit) {
258                 dist = bot_dist;
259                 norm = bot_norm;
260                 return true;
261         } else {
262                 return false;
263         }
264 }
265
266
267 }