]> git.localhorst.tv Git - blank.git/blob - src/model/shape.cpp
"streamlined" model/VAO handling
[blank.git] / src / model / shape.cpp
1 #include "Shape.hpp"
2 #include "shapes.hpp"
3
4
5 namespace blank {
6
7 void Shape::Vertices(
8         EntityModel::Positions &vertex,
9         EntityModel::Normals &normal,
10         EntityModel::Indices &index
11 ) const {
12         for (const auto &pos : vtx_pos) {
13                 vertex.emplace_back(pos);
14         }
15         for (const auto &nrm : vtx_nrm) {
16                 normal.emplace_back(nrm);
17         }
18         for (auto idx : vtx_idx) {
19                 index.emplace_back(idx);
20         }
21 }
22
23 void Shape::Vertices(
24         EntityModel::Positions &vertex,
25         EntityModel::Normals &normal,
26         EntityModel::Indices &index,
27         const glm::mat4 &transform,
28         EntityModel::Index idx_offset
29 ) const {
30         for (const auto &pos : vtx_pos) {
31                 vertex.emplace_back(transform * glm::vec4(pos, 1.0f));
32         }
33         for (const auto &nrm : vtx_nrm) {
34                 normal.emplace_back(transform * glm::vec4(nrm, 0.0f));
35         }
36         for (auto idx : vtx_idx) {
37                 index.emplace_back(idx_offset + idx);
38         }
39 }
40
41 void Shape::Vertices(
42         BlockModel::Positions &vertex,
43         BlockModel::Indices &index,
44         const glm::mat4 &transform,
45         BlockModel::Index idx_offset
46 ) const {
47         for (const auto &pos : vtx_pos) {
48                 vertex.emplace_back(transform * glm::vec4(pos, 1.0f));
49         }
50         for (auto idx : vtx_idx) {
51                 index.emplace_back(idx_offset + idx);
52         }
53 }
54
55 void Shape::Outline(
56         OutlineModel::Positions &vertex,
57         OutlineModel::Indices &index,
58         const OutlineModel::Position &elem_offset,
59         OutlineModel::Index idx_offset
60 ) const {
61         for (const auto &pos : out_pos) {
62                 vertex.emplace_back(elem_offset + pos);
63         }
64         for (auto idx : out_idx) {
65                 index.emplace_back(idx_offset + idx);
66         }
67 }
68
69
70 NullShape::NullShape()
71 : Shape() {
72
73 }
74
75 bool NullShape::Intersects(
76         const Ray &,
77         const glm::mat4 &,
78         float &, glm::vec3 &
79 ) const noexcept {
80         return false;
81 }
82
83 bool NullShape::Intersects(
84         const glm::mat4 &,
85         const AABB &,
86         const glm::mat4 &,
87         float &,
88         glm::vec3 &
89 ) const noexcept {
90         return false;
91 }
92
93
94 CuboidShape::CuboidShape(const AABB &b)
95 : Shape()
96 , bb(b) {
97         bb.Adjust();
98         SetShape({
99                 { bb.min.x, bb.min.y, bb.max.z }, // front
100                 { bb.max.x, bb.min.y, bb.max.z },
101                 { bb.min.x, bb.max.y, bb.max.z },
102                 { bb.max.x, bb.max.y, bb.max.z },
103                 { bb.min.x, bb.min.y, bb.min.z }, // back
104                 { bb.min.x, bb.max.y, bb.min.z },
105                 { bb.max.x, bb.min.y, bb.min.z },
106                 { bb.max.x, bb.max.y, bb.min.z },
107                 { bb.min.x, bb.max.y, bb.min.z }, // top
108                 { bb.min.x, bb.max.y, bb.max.z },
109                 { bb.max.x, bb.max.y, bb.min.z },
110                 { bb.max.x, bb.max.y, bb.max.z },
111                 { bb.min.x, bb.min.y, bb.min.z }, // bottom
112                 { bb.max.x, bb.min.y, bb.min.z },
113                 { bb.min.x, bb.min.y, bb.max.z },
114                 { bb.max.x, bb.min.y, bb.max.z },
115                 { bb.min.x, bb.min.y, bb.min.z }, // left
116                 { bb.min.x, bb.min.y, bb.max.z },
117                 { bb.min.x, bb.max.y, bb.min.z },
118                 { bb.min.x, bb.max.y, bb.max.z },
119                 { bb.max.x, bb.min.y, bb.min.z }, // right
120                 { bb.max.x, bb.max.y, bb.min.z },
121                 { bb.max.x, bb.min.y, bb.max.z },
122                 { bb.max.x, bb.max.y, bb.max.z },
123         }, {
124                 {  0.0f,  0.0f,  1.0f }, // front
125                 {  0.0f,  0.0f,  1.0f },
126                 {  0.0f,  0.0f,  1.0f },
127                 {  0.0f,  0.0f,  1.0f },
128                 {  0.0f,  0.0f, -1.0f }, // back
129                 {  0.0f,  0.0f, -1.0f },
130                 {  0.0f,  0.0f, -1.0f },
131                 {  0.0f,  0.0f, -1.0f },
132                 {  0.0f,  1.0f,  0.0f }, // top
133                 {  0.0f,  1.0f,  0.0f },
134                 {  0.0f,  1.0f,  0.0f },
135                 {  0.0f,  1.0f,  0.0f },
136                 {  0.0f, -1.0f,  0.0f }, // bottom
137                 {  0.0f, -1.0f,  0.0f },
138                 {  0.0f, -1.0f,  0.0f },
139                 {  0.0f, -1.0f,  0.0f },
140                 { -1.0f,  0.0f,  0.0f }, // left
141                 { -1.0f,  0.0f,  0.0f },
142                 { -1.0f,  0.0f,  0.0f },
143                 { -1.0f,  0.0f,  0.0f },
144                 {  1.0f,  0.0f,  0.0f }, // right
145                 {  1.0f,  0.0f,  0.0f },
146                 {  1.0f,  0.0f,  0.0f },
147                 {  1.0f,  0.0f,  0.0f },
148         }, {
149                   0,  1,  2,  2,  1,  3, // front
150                   4,  5,  6,  6,  5,  7, // back
151                   8,  9, 10, 10,  9, 11, // top
152                  12, 13, 14, 14, 13, 15, // bottom
153                  16, 17, 18, 18, 17, 19, // left
154                  20, 21, 22, 22, 21, 23, // right
155         });
156         SetOutline({
157                 { bb.min.x, bb.min.y, bb.min.z }, // back
158                 { bb.max.x, bb.min.y, bb.min.z },
159                 { bb.min.x, bb.max.y, bb.min.z },
160                 { bb.max.x, bb.max.y, bb.min.z },
161                 { bb.min.x, bb.min.y, bb.max.z }, // front
162                 { bb.max.x, bb.min.y, bb.max.z },
163                 { bb.min.x, bb.max.y, bb.max.z },
164                 { bb.max.x, bb.max.y, bb.max.z },
165         }, {
166                 0, 1, 1, 3, 3, 2, 2, 0, // back
167                 4, 5, 5, 7, 7, 6, 6, 4, // front
168                 0, 4, 1, 5, 2, 6, 3, 7, // sides
169         });
170 }
171
172 bool CuboidShape::Intersects(
173         const Ray &ray,
174         const glm::mat4 &M,
175         float &dist, glm::vec3 &normal
176 ) const noexcept {
177         return Intersection(ray, bb, M, &dist, &normal);
178 }
179
180 bool CuboidShape::Intersects(
181         const glm::mat4 &M,
182         const AABB &box,
183         const glm::mat4 &box_M,
184         float &depth,
185         glm::vec3 &normal
186 ) const noexcept {
187         return Intersection(bb, M, box, box_M, depth, normal);
188 }
189
190
191 StairShape::StairShape(const AABB &bb, const glm::vec2 &clip)
192 : Shape()
193 , top({ { bb.min.x, clip.y, bb.min.z }, { bb.max.x, bb.max.y, clip.x } })
194 , bot({ bb.min, { bb.max.x, clip.y, bb.max.z } }) {
195         SetShape({
196                 { top.min.x, top.min.y, top.max.z }, // front, upper
197                 { top.max.x, top.min.y, top.max.z },
198                 { top.min.x, top.max.y, top.max.z },
199                 { top.max.x, top.max.y, top.max.z },
200                 { bot.min.x, bot.min.y, bot.max.z }, // front, lower
201                 { bot.max.x, bot.min.y, bot.max.z },
202                 { bot.min.x, bot.max.y, bot.max.z },
203                 { bot.max.x, bot.max.y, bot.max.z },
204                 { bot.min.x, bot.min.y, bot.min.z }, // back
205                 { bot.min.x, top.max.y, bot.min.z },
206                 { top.max.x, bot.min.y, bot.min.z },
207                 { top.max.x, top.max.y, bot.min.z },
208                 { top.min.x, top.max.y, top.min.z }, // top, upper
209                 { top.min.x, top.max.y, top.max.z },
210                 { top.max.x, top.max.y, top.min.z },
211                 { top.max.x, top.max.y, top.max.z },
212                 { bot.min.x, bot.max.y, top.max.z }, // top, lower
213                 { bot.min.x, bot.max.y, bot.max.z },
214                 { bot.max.x, bot.max.y, top.max.z },
215                 { bot.max.x, bot.max.y, bot.max.z },
216                 { bot.min.x, bot.min.y, bot.min.z }, // bottom
217                 { bot.max.x, bot.min.y, bot.min.z },
218                 { bot.min.x, bot.min.y, bot.max.z },
219                 { bot.max.x, bot.min.y, bot.max.z },
220                 { top.min.x, top.min.y, top.min.z }, // left, upper
221                 { top.min.x, top.min.y, top.max.z },
222                 { top.min.x, top.max.y, top.min.z },
223                 { top.min.x, top.max.y, top.max.z },
224                 { bot.min.x, bot.min.y, bot.min.z }, // left, lower
225                 { bot.min.x, bot.min.y, bot.max.z },
226                 { bot.min.x, bot.max.y, bot.min.z },
227                 { bot.min.x, bot.max.y, bot.max.z },
228                 { top.max.x, top.min.y, top.min.z }, // right, upper
229                 { top.max.x, top.max.y, top.min.z },
230                 { top.max.x, top.min.y, top.max.z },
231                 { top.max.x, top.max.y, top.max.z },
232                 { bot.max.x, bot.min.y, bot.min.z }, // right, lower
233                 { bot.max.x, bot.max.y, bot.min.z },
234                 { bot.max.x, bot.min.y, bot.max.z },
235                 { bot.max.x, bot.max.y, bot.max.z },
236         }, {
237                 {  0.0f,  0.0f,  1.0f }, // front x2
238                 {  0.0f,  0.0f,  1.0f },
239                 {  0.0f,  0.0f,  1.0f },
240                 {  0.0f,  0.0f,  1.0f },
241                 {  0.0f,  0.0f,  1.0f },
242                 {  0.0f,  0.0f,  1.0f },
243                 {  0.0f,  0.0f,  1.0f },
244                 {  0.0f,  0.0f,  1.0f },
245                 {  0.0f,  0.0f, -1.0f }, // back
246                 {  0.0f,  0.0f, -1.0f },
247                 {  0.0f,  0.0f, -1.0f },
248                 {  0.0f,  0.0f, -1.0f },
249                 {  0.0f,  1.0f,  0.0f }, // top x2
250                 {  0.0f,  1.0f,  0.0f },
251                 {  0.0f,  1.0f,  0.0f },
252                 {  0.0f,  1.0f,  0.0f },
253                 {  0.0f,  1.0f,  0.0f },
254                 {  0.0f,  1.0f,  0.0f },
255                 {  0.0f,  1.0f,  0.0f },
256                 {  0.0f,  1.0f,  0.0f },
257                 {  0.0f, -1.0f,  0.0f }, // bottom
258                 {  0.0f, -1.0f,  0.0f },
259                 {  0.0f, -1.0f,  0.0f },
260                 {  0.0f, -1.0f,  0.0f },
261                 { -1.0f,  0.0f,  0.0f }, // left x2
262                 { -1.0f,  0.0f,  0.0f },
263                 { -1.0f,  0.0f,  0.0f },
264                 { -1.0f,  0.0f,  0.0f },
265                 { -1.0f,  0.0f,  0.0f },
266                 { -1.0f,  0.0f,  0.0f },
267                 { -1.0f,  0.0f,  0.0f },
268                 { -1.0f,  0.0f,  0.0f },
269                 {  1.0f,  0.0f,  0.0f }, // right x2
270                 {  1.0f,  0.0f,  0.0f },
271                 {  1.0f,  0.0f,  0.0f },
272                 {  1.0f,  0.0f,  0.0f },
273                 {  1.0f,  0.0f,  0.0f },
274                 {  1.0f,  0.0f,  0.0f },
275                 {  1.0f,  0.0f,  0.0f },
276                 {  1.0f,  0.0f,  0.0f },
277         }, {
278                  0,  1,  2,  2,  1,  3, // front, upper
279                  4,  5,  6,  6,  5,  7, // front, lower
280                  8,  9, 10, 10,  9, 11, // back
281                 12, 13, 14, 14, 13, 15, // top, upper
282                 16, 17, 18, 18, 17, 19, // top, lower
283                 20, 21, 22, 22, 21, 23, // bottom
284                 24, 25, 26, 26, 25, 27, // left, upper
285                 28, 29, 30, 30, 29, 31, // left, lower
286                 32, 33, 34, 34, 33, 35, // right, upper
287                 36, 37, 38, 38, 37, 39, // right, lower
288         });
289         SetOutline({
290                 { bot.min.x, bot.min.y, bot.min.z }, // bottom
291                 { bot.max.x, bot.min.y, bot.min.z },
292                 { bot.min.x, bot.min.y, bot.max.z },
293                 { bot.max.x, bot.min.y, bot.max.z },
294                 { bot.min.x, bot.max.y, top.max.z }, // middle
295                 { bot.max.x, bot.max.y, top.max.z },
296                 { bot.min.x, bot.max.y, bot.max.z },
297                 { bot.max.x, bot.max.y, bot.max.z },
298                 { top.min.x, top.max.y, top.min.z }, // top
299                 { top.max.x, top.max.y, top.min.z },
300                 { top.min.x, top.max.y, top.max.z },
301                 { top.max.x, top.max.y, top.max.z },
302         }, {
303                  0,  1,  1,  3,  3,  2,  2,  0, // bottom
304                  4,  5,  5,  7,  7,  6,  6,  4, // middle
305                  8,  9,  9, 11, 11, 10, 10 , 8, // top
306                  0,  8,  4, 10,  2,  6, // verticals, btf
307                  1,  9,  5, 11,  3,  7,
308         //       5,  8,  7, 10,
309         //       1,  9,  3, 11,
310         });
311 }
312
313 bool StairShape::Intersects(
314         const Ray &ray,
315         const glm::mat4 &M,
316         float &dist,
317         glm::vec3 &norm
318 ) const noexcept {
319         float top_dist, bot_dist;
320         glm::vec3 top_norm, bot_norm;
321         bool top_hit = Intersection(ray, top, M, &top_dist, &top_norm);
322         bool bot_hit = Intersection(ray, bot, M, &bot_dist, &bot_norm);
323
324         if (top_hit) {
325                 if (bot_hit) {
326                         if (top_dist < bot_dist) {
327                                 dist = top_dist;
328                                 norm = top_norm;
329                                 return true;
330                         } else {
331                                 dist = bot_dist;
332                                 norm = bot_norm;
333                                 return true;
334                         }
335                 } else {
336                         dist = top_dist;
337                         norm = top_norm;
338                         return true;
339                 }
340         } else if (bot_hit) {
341                 dist = bot_dist;
342                 norm = bot_norm;
343                 return true;
344         } else {
345                 return false;
346         }
347 }
348
349 bool StairShape::Intersects(
350         const glm::mat4 &M,
351         const AABB &box,
352         const glm::mat4 &box_M,
353         float &depth,
354         glm::vec3 &normal
355 ) const noexcept {
356         // TODO: this is wrong, but simple. so for now will have to do
357         return Intersection(bot, M, box, box_M, depth, normal) || Intersection(top, M, box, box_M, depth, normal);
358 }
359
360 }