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