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