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