Rev Author Line No. Line
23 ovan 1 #include "mesh.h"
2 #include "geometry.h"
3 #include <math.h>
4  
5 #include "../library/glm/glm.hpp"
6 #include "../math/spline.h"
7 #include "../math/edgemap.h"
8  
9 namespace sleek
10 {
11     namespace driver
12     {
13         Geometry::Geometry() noexcept
14         {
15         }
16  
17         Geometry::~Geometry() noexcept
18         {
19         }
20  
21         MeshBuffer* Geometry::createPlane(const math::vec2f &size, const u32 polyCountX, const u32 polyCountY, const math::pixel &color) const noexcept
22         {
23             MeshBuffer *tmp = new MeshBuffer();
24                 tmp->vertices.resize(4);
25                     tmp->vertices[0].Pos = {-size.x/2, 0,-size.y/2};
26                     tmp->vertices[1].Pos = { size.x/2, 0,-size.y/2};
27                     tmp->vertices[2].Pos = { size.x/2, 0, size.y/2};
28                     tmp->vertices[3].Pos = {-size.x/2, 0, size.y/2};
29  
30                     tmp->vertices[0].Coord = {0.0f, 0.0f};
31                     tmp->vertices[1].Coord = {1.0f, 0.0f};
32                     tmp->vertices[2].Coord = {1.0f, 1.0f};
33                     tmp->vertices[3].Coord = {0.0f, 1.0f};
34  
35                     tmp->vertices[0].Normal = { 0.0f, 1.0f, 0.f};
36                     tmp->vertices[1].Normal = { 0.0f, 1.0f, 0.f};
37                     tmp->vertices[2].Normal = { 0.0f, 1.0f, 0.f};
38                     tmp->vertices[3].Normal = { 0.0f, 1.0f, 0.f};
39  
40                     tmp->vertices[0].Color = color;
41                     tmp->vertices[1].Color = color;
42                     tmp->vertices[2].Color = color;
43                     tmp->vertices[3].Color = color;
44                 tmp->indices.resize(2);
45                     tmp->indices[0] = math::index<3u>(0u,2u,1u);
46                     tmp->indices[1] = math::index<3u>(0u,3u,2u);
47             return tmp;
48         }
49  
50         MeshBuffer* Geometry::createWall(const math::vec2f &size, const math::pixel &color) const noexcept
51         {
52             MeshBuffer *tmp = new MeshBuffer();
53                 tmp->vertices.resize(4);
54                     tmp->vertices[0].Pos = {-size.x/2,-size.y/2, 0};
55                     tmp->vertices[1].Pos = { size.x/2,-size.y/2, 0};
56                     tmp->vertices[2].Pos = { size.x/2, size.y/2, 0};
57                     tmp->vertices[3].Pos = {-size.x/2, size.y/2, 0};
58  
59                     tmp->vertices[0].Coord = {0.0f, 0.0f};
60                     tmp->vertices[1].Coord = {1.0f, 0.0f};
61                     tmp->vertices[2].Coord = {1.0f, 1.0f};
62                     tmp->vertices[3].Coord = {0.0f, 1.0f};
63  
64                     tmp->vertices[0].Normal = { 0.0f, 0.0f, 1.f};
65                     tmp->vertices[1].Normal = { 0.0f, 0.0f, 1.f};
66                     tmp->vertices[2].Normal = { 0.0f, 0.0f, 1.f};
67                     tmp->vertices[3].Normal = { 0.0f, 0.0f, 1.f};
68  
69                     tmp->vertices[0].Color = color;
70                     tmp->vertices[1].Color = color;
71                     tmp->vertices[2].Color = color;
72                     tmp->vertices[3].Color = color;
73                 tmp->indices.resize(2);
74                     tmp->indices[0] = math::index<3u>(0u,2u,1u);
75                     tmp->indices[1] = math::index<3u>(2u,3u,0u);
76             return tmp;
77         }
78  
79         MeshBuffer* Geometry::createCircle(const math::vec2f &radiusxy, const f32 step_x, const f32 step_y, const math::pixel &color) const noexcept
80         {
81             MeshBuffer *tmp = new MeshBuffer();
82                 tmp->vertices.resize(step_x*step_y+1);
83                 register unsigned short psize = 0;
84                 register float anglex = 0.f, angley = 0.f;
85                 for(register float x = 0.f; x<step_x; ++x)
86                 {
87                     anglex += radiusxy.x;
88                     for(register float y = 0.f; x<step_y; ++y)
89                     {
90                         angley += radiusxy.y;
91                         tmp->vertices[psize].Pos = math::vec3f(sin(anglex), 0, cos(angley));
92                         psize++;
93                     }
94                 }
95             return tmp;
96         }
97  
98         MeshBuffer* Geometry::createSphere(const f32 radius, u32 polyCountX, u32 polyCountY, const math::pixel &color) const noexcept
99         {
100             MeshBuffer *tmp = new MeshBuffer();
101  
102             polyCountX = std::max(polyCountX, 2u);
103             polyCountY = std::max(polyCountY, 2u);
104  
105             const u32 polyCountXPitch = polyCountX+1;
106  
107             tmp->indices.reserve(polyCountX*polyCountY*6);
108             {
109                 const u32 polyCountSq = polyCountXPitch * polyCountY;         // top point
110                 const u32 polyCountSq1 = polyCountSq + 1;                     // bottom point
111                 const u32 polyCountSqM1 = (polyCountY - 1) * polyCountXPitch; // last row's first vertex
112                 u32 level = 0;
113  
114                 for(u32 p1 = 0; p1 < polyCountY-1; ++p1)
115                 {
116                     for(u32 p2 = 0; p2 < polyCountX - 1; ++p2)
117                     {
118                         const u32 curr = level + p2;
119                         tmp->indices.push_back(math::index<3>(curr + polyCountXPitch, curr + 1, curr));
120                         tmp->indices.push_back(math::index<3>(curr + polyCountXPitch, curr + 1 + polyCountXPitch, curr + 1));
121                     }
122  
123                     tmp->indices.push_back(math::index<3>(
124                         level + polyCountX - 1 + polyCountXPitch,
125                         level + polyCountX,
126                         level + polyCountX - 1
127                     ));
128                     tmp->indices.push_back(math::index<3>(
129                         level + polyCountX - 1 + polyCountXPitch,
130                         level + polyCountX + polyCountXPitch,
131                         level + polyCountX
132                     ));
133                     level += polyCountXPitch;
134                 }
135  
136                 for(u32 p2 = 0; p2 < polyCountX - 1; ++p2)
137                 {
138                     tmp->indices.push_back(math::index<3>(polyCountSq, p2, p2 + 1));
139                     tmp->indices.push_back(math::index<3>(polyCountSqM1 + p2, polyCountSq1, polyCountSqM1 + p2 + 1));
140                 }
141  
142                 tmp->indices.push_back(math::index<3>(polyCountSq, polyCountX-1, polyCountX));
143                 tmp->indices.push_back(math::index<3>(polyCountSqM1 + polyCountX - 1, polyCountSq1, polyCountSqM1));
144             }
145  
146             tmp->vertices.reserve(polyCountX*polyCountY);
147             {
148                 const f64 AngleX = 2 * PI / polyCountX;
149                 const f64 AngleY = PI / polyCountY;
150  
151                 u32 i=0;
152                 f64 axz, ay = 0;
153  
154                 tmp->vertices.resize((polyCountXPitch * polyCountY) + 2);
155                 for(u32 y = 0; y < polyCountY; ++y)
156                 {
157                     ay += AngleY;
158                     const f64 sinay = sin(ay);
159                     axz = 0;
160  
161                     for(u32 xz = 0;xz < polyCountX; ++xz)
162                     {
163                         const math::vec3f pos(
164                             radius/2.f * cos(axz) * sinay,
165                             radius/2.f * cos(ay),
166                             radius/2.f * sin(axz) * sinay
167                         );
168  
169                         math::vec3f normal = glm::normalize(pos);
170  
171                         f32 tu = 0.5f;
172  
173                         if(normal.y != -1.0f && normal.y != 1.0f)
174                             tu =  acos(math::clamp(normal.x/sinay, -1.0, 1.0)) * 0.5 * RECIPROCAL_PI;
175                         if(normal.z < 0.0f)
176                             tu = 1-tu;
177  
178                         tmp->vertices[i].Pos = pos;
179                         tmp->vertices[i].Normal = normal;
180                         tmp->vertices[i].Color = color;
181                         tmp->vertices[i].Coord.x = tu;
182                         tmp->vertices[i].Coord.y = ay*RECIPROCAL_PI;
183  
184                         ++i;
185                         axz += AngleX;
186                     }
187  
188                     tmp->vertices[i] = tmp->vertices[i-polyCountX];
189                     tmp->vertices[i].Coord.x = 1.0f;
190                     ++i;
191                 }
192  
193                 tmp->vertices[i].Pos = {0.0f, radius/2.f,0.0f};
194                 tmp->vertices[i].Normal = math::vec3f(0.0f,-1.f,0.0f);
195                 tmp->vertices[i].Coord = math::vec2f(0.5f,0.0f);
196                 tmp->vertices[i].Color = color;
197  
198                 ++i;
199  
200                 tmp->vertices[i].Pos = {0.0f, -radius/2.f,0.0f};
201                 tmp->vertices[i].Normal = math::vec3f(0.0f,1.f,0.0f);
202                 tmp->vertices[i].Coord = math::vec2f(0.5f,1.0f);
203                 tmp->vertices[i].Color = color;
204             }
205             return tmp;
206         }
207  
208         MeshBuffer* Geometry::createIcoSphere(const f32 radius, u32 subdivide, const math::pixel &color) const noexcept
209         {
210             MeshBuffer *tmp = new MeshBuffer();
211             subdivide = std::min(subdivide, 9u);
212  
213             //! --------------------------------------
214  
215             static constexpr const float phi = (1+sqrt(5))/2.;
216             struct triangle { math::vec3f a, b, c; };
217  
218             static const math::vec3f vertex[12] = {
219                 { phi, 1,0}, { phi,-1,0}, {-phi, 1,0}, {-phi,-1,0},
220                 { 1,0, phi}, { 1,0,-phi}, {-1,0, phi}, {-1,0,-phi},
221                 {0, phi, 1}, {0, phi,-1}, {0,-phi, 1}, {0,-phi,-1}
222             };
223  
224             static const uint index[][3] = {
225                 { 2, 8, 9}, { 9, 8, 0}, { 0, 8, 4}, { 4, 8, 6}, { 6, 8, 2},
226                 { 3,11,10}, {10,11, 1}, { 1,11, 5}, { 5,11, 7}, { 7,11, 3},
227                 { 3, 2, 7}, { 7, 2, 9}, { 7, 9, 5}, { 5, 9, 0}, { 5, 0, 1},
228                 { 1, 0, 4}, { 1, 4,10}, {10, 4, 6}, {10, 6, 3}, { 3, 6, 2}
229             };
230  
231             //! --------------------------------------
232  
233             std::vector<triangle> old_vert;
234             std::vector<triangle> cur_vert;
235  
236             cur_vert.resize(sizeof(index)/sizeof(index[0]));
237  
238             for(int i = 0; i<cur_vert.size(); ++i)
239             {
240                 cur_vert[i].a = glm::normalize(vertex[index[i][0]]);
241                 cur_vert[i].b = glm::normalize(vertex[index[i][1]]);
242                 cur_vert[i].c = glm::normalize(vertex[index[i][2]]);
243             }
244  
245             for(int s = 0; s<subdivide; ++s)
246             {
247                 for(int i = 0; i<cur_vert.size(); ++i)
248                 {
249                     math::vec3f v1 = cur_vert[i].a;
250                     math::vec3f v2 = cur_vert[i].b;
251                     math::vec3f v3 = cur_vert[i].c;
252                     math::vec3f v4 = glm::normalize(v1 + v2);
253                     math::vec3f v5 = glm::normalize(v2 + v3);
254                     math::vec3f v6 = glm::normalize(v3 + v1);
255                     old_vert.push_back({v1, v4, v6});
256                     old_vert.push_back({v4, v2, v5});
257                     old_vert.push_back({v6, v5, v3});
258                     old_vert.push_back({v4, v5, v6});
259                 }
260                 old_vert.swap(cur_vert);
261                 old_vert.clear();
262             }
263  
264             tmp->vertices.resize(cur_vert.size()*3);
265             tmp->indices.resize(cur_vert.size());
266  
267             for(unsigned int i = 0; i<cur_vert.size(); ++i)
268             {
269                 tmp->vertices[i*3+0].Pos = cur_vert[i].a * (radius/2.f);
270                 tmp->vertices[i*3+1].Pos = cur_vert[i].b * (radius/2.f);
271                 tmp->vertices[i*3+2].Pos = cur_vert[i].c * (radius/2.f);
272  
273                 tmp->vertices[i*3+0].Normal = cur_vert[i].a;
274                 tmp->vertices[i*3+1].Normal = cur_vert[i].b;
275                 tmp->vertices[i*3+2].Normal = cur_vert[i].c;
276  
277                 tmp->vertices[i*3+0].Color = color;
278                 tmp->vertices[i*3+1].Color = color;
279                 tmp->vertices[i*3+2].Color = color;
280  
281                 tmp->vertices[i*3+0].Coord.x = 0.5f - atan2(cur_vert[i].a.z, cur_vert[i].a.x)/(float)(2.0f*PI);
282                 tmp->vertices[i*3+1].Coord.x = 0.5f - atan2(cur_vert[i].b.z, cur_vert[i].b.x)/(float)(2.0f*PI);
283                 tmp->vertices[i*3+2].Coord.x = 0.5f - atan2(cur_vert[i].c.z, cur_vert[i].c.x)/(float)(2.0f*PI);
284  
285                 tmp->vertices[i*3+0].Coord.y = 0.5f - (0.2f * asin(cur_vert[i].a.y) / 2.0f*PI);
286                 tmp->vertices[i*3+1].Coord.y = 0.5f - (0.2f * asin(cur_vert[i].b.y) / 2.0f*PI);
287                 tmp->vertices[i*3+2].Coord.y = 0.5f - (0.2f * asin(cur_vert[i].c.y) / 2.0f*PI);
288  
289                 tmp->indices[i].vertex[0] = i*3;
290                 tmp->indices[i].vertex[1] = i*3+2u;
291                 tmp->indices[i].vertex[2] = i*3+1u;
292             }
293  
294             return tmp;
295         }
296  
297         MeshBuffer* Geometry::createCube(const math::vec3f &size, const math::pixel &color) const noexcept
298         {
299             MeshBuffer *tmp = new MeshBuffer();
300                 tmp->vertices.resize(24);
301                     tmp->vertices[ 0].Pos = {-size.x/2,-size.y/2, size.z/2};
302                     tmp->vertices[ 1].Pos = { size.x/2,-size.y/2, size.z/2};
303                     tmp->vertices[ 2].Pos = { size.x/2, size.y/2, size.z/2};
304                     tmp->vertices[ 3].Pos = {-size.x/2, size.y/2, size.z/2};
305                     tmp->vertices[ 4].Pos = {-size.x/2,-size.y/2,-size.z/2};
306                     tmp->vertices[ 5].Pos = {-size.x/2, size.y/2,-size.z/2};
307                     tmp->vertices[ 6].Pos = { size.x/2, size.y/2,-size.z/2};
308                     tmp->vertices[ 7].Pos = { size.x/2,-size.y/2,-size.z/2};
309                     tmp->vertices[ 8].Pos = {-size.x/2, size.y/2,-size.z/2};
310                     tmp->vertices[ 9].Pos = {-size.x/2, size.y/2, size.z/2};
311                     tmp->vertices[10].Pos = { size.x/2, size.y/2, size.z/2};
312                     tmp->vertices[11].Pos = { size.x/2, size.y/2,-size.z/2};
313                     tmp->vertices[12].Pos = {-size.x/2,-size.y/2,-size.z/2};
314                     tmp->vertices[13].Pos = { size.x/2,-size.y/2,-size.z/2};
315                     tmp->vertices[14].Pos = { size.x/2,-size.y/2, size.z/2};
316                     tmp->vertices[15].Pos = {-size.x/2,-size.y/2, size.z/2};
317                     tmp->vertices[16].Pos = { size.x/2,-size.y/2,-size.z/2};
318                     tmp->vertices[17].Pos = { size.x/2, size.y/2,-size.z/2};
319                     tmp->vertices[18].Pos = { size.x/2, size.y/2, size.z/2};
320                     tmp->vertices[19].Pos = { size.x/2,-size.y/2, size.z/2};
321                     tmp->vertices[20].Pos = {-size.x/2,-size.y/2,-size.z/2};
322                     tmp->vertices[21].Pos = {-size.x/2,-size.y/2, size.z/2};
323                     tmp->vertices[22].Pos = {-size.x/2, size.y/2, size.z/2};
324                     tmp->vertices[23].Pos = {-size.x/2, size.y/2,-size.z/2};
325  
326                     tmp->vertices[ 0].Coord = {0.0f, 0.0f};
327                     tmp->vertices[ 1].Coord = {1.0f, 0.0f};
328                     tmp->vertices[ 2].Coord = {1.0f, 1.0f};
329                     tmp->vertices[ 3].Coord = {0.0f, 1.0f};
330                     tmp->vertices[ 4].Coord = {1.0f, 0.0f};
331                     tmp->vertices[ 5].Coord = {1.0f, 1.0f};
332                     tmp->vertices[ 6].Coord = {0.0f, 1.0f};
333                     tmp->vertices[ 7].Coord = {0.0f, 0.0f};
334                     tmp->vertices[ 8].Coord = {0.0f, 1.0f};
335                     tmp->vertices[ 9].Coord = {0.0f, 0.0f};
336                     tmp->vertices[10].Coord = {1.0f, 0.0f};
337                     tmp->vertices[11].Coord = {1.0f, 1.0f};
338                     tmp->vertices[12].Coord = {1.0f, 1.0f};
339                     tmp->vertices[13].Coord = {0.0f, 1.0f};
340                     tmp->vertices[14].Coord = {0.0f, 0.0f};
341                     tmp->vertices[15].Coord = {1.0f, 0.0f};
342                     tmp->vertices[16].Coord = {1.0f, 0.0f};
343                     tmp->vertices[17].Coord = {1.0f, 1.0f};
344                     tmp->vertices[18].Coord = {0.0f, 1.0f};
345                     tmp->vertices[19].Coord = {0.0f, 0.0f};
346                     tmp->vertices[20].Coord = {0.0f, 0.0f};
347                     tmp->vertices[21].Coord = {1.0f, 0.0f};
348                     tmp->vertices[22].Coord = {1.0f, 1.0f};
349                     tmp->vertices[23].Coord = {0.0f, 1.0f};
350  
351                     tmp->vertices[ 0].Normal = { 0.0f, 0.0f, 1.0f};
352                     tmp->vertices[ 1].Normal = { 0.0f, 0.0f, 1.0f};
353                     tmp->vertices[ 2].Normal = { 0.0f, 0.0f, 1.0f};
354                     tmp->vertices[ 3].Normal = { 0.0f, 0.0f, 1.0f};
355                     tmp->vertices[ 4].Normal = { 0.0f, 0.0f,-1.0f};
356                     tmp->vertices[ 5].Normal = { 0.0f, 0.0f,-1.0f};
357                     tmp->vertices[ 6].Normal = { 0.0f, 0.0f,-1.0f};
358                     tmp->vertices[ 7].Normal = { 0.0f, 0.0f,-1.0f};
359                     tmp->vertices[ 8].Normal = { 0.0f, 1.0f, 0.0f};
360                     tmp->vertices[ 9].Normal = { 0.0f, 1.0f, 0.0f};
361                     tmp->vertices[10].Normal = { 0.0f, 1.0f, 0.0f};
362                     tmp->vertices[11].Normal = { 0.0f, 1.0f, 0.0f};
363                     tmp->vertices[12].Normal = { 0.0f,-1.0f, 0.0f};
364                     tmp->vertices[13].Normal = { 0.0f,-1.0f, 0.0f};
365                     tmp->vertices[14].Normal = { 0.0f,-1.0f, 0.0f};
366                     tmp->vertices[15].Normal = { 0.0f,-1.0f, 0.0f};
367                     tmp->vertices[16].Normal = { 1.0f, 0.0f, 0.0f};
368                     tmp->vertices[17].Normal = { 1.0f, 0.0f, 0.0f};
369                     tmp->vertices[18].Normal = { 1.0f, 0.0f, 0.0f};
370                     tmp->vertices[19].Normal = { 1.0f, 0.0f, 0.0f};
371                     tmp->vertices[20].Normal = {-1.0f, 0.0f, 0.0f};
372                     tmp->vertices[21].Normal = {-1.0f, 0.0f, 0.0f};
373                     tmp->vertices[22].Normal = {-1.0f, 0.0f, 0.0f};
374                     tmp->vertices[23].Normal = {-1.0f, 0.0f, 0.0f};
375  
376                     tmp->vertices[ 0].Color = color; tmp->vertices[ 1].Color = color;
377                     tmp->vertices[ 2].Color = color; tmp->vertices[ 3].Color = color;
378                     tmp->vertices[ 4].Color = color; tmp->vertices[ 5].Color = color;
379                     tmp->vertices[ 6].Color = color; tmp->vertices[ 7].Color = color;
380                     tmp->vertices[ 8].Color = color; tmp->vertices[ 9].Color = color;
381                     tmp->vertices[10].Color = color; tmp->vertices[11].Color = color;
382                     tmp->vertices[12].Color = color; tmp->vertices[13].Color = color;
383                     tmp->vertices[14].Color = color; tmp->vertices[15].Color = color;
384                     tmp->vertices[16].Color = color; tmp->vertices[17].Color = color;
385                     tmp->vertices[18].Color = color; tmp->vertices[19].Color = color;
386                     tmp->vertices[20].Color = color; tmp->vertices[21].Color = color;
387                     tmp->vertices[22].Color = color; tmp->vertices[23].Color = color;
388                 tmp->indices.resize(12);
389                     tmp->indices[ 0] = math::index<3>( 0u, 2u, 1u);
390                     tmp->indices[ 1] = math::index<3>( 0u, 3u, 2u);
391                     tmp->indices[ 2] = math::index<3>( 4u, 6u, 5u);
392                     tmp->indices[ 3] = math::index<3>( 4u, 7u, 6u);
393                     tmp->indices[ 4] = math::index<3>( 8u,10u, 9u);
394                     tmp->indices[ 5] = math::index<3>( 8u,11u,10u);
395                     tmp->indices[ 6] = math::index<3>(12u,14u,13u);
396                     tmp->indices[ 7] = math::index<3>(12u,15u,14u);
397                     tmp->indices[ 8] = math::index<3>(16u,18u,17u);
398                     tmp->indices[ 9] = math::index<3>(16u,19u,18u);
399                     tmp->indices[10] = math::index<3>(20u,22u,21u);
400                     tmp->indices[11] = math::index<3>(20u,23u,22u);
401             return tmp;
402         }
403  
404         MeshBuffer* Geometry::createPolygone(const math::vec3f &a,const math::vec3f &b,const math::vec3f &c, const math::pixel &color) const noexcept
405         {
406             MeshBuffer *tmp = new MeshBuffer();
407                 tmp->vertices.resize(3);
408                     tmp->vertices[0].Pos = a;
409                     tmp->vertices[1].Pos = b;
410                     tmp->vertices[2].Pos = c;
411                     tmp->vertices[0].Color = color;
412                     tmp->vertices[1].Color = color;
413                     tmp->vertices[2].Color = color;
414                     tmp->vertices[3].Color = color;
415                 tmp->indices.resize(1);
416                     tmp->indices[0] = math::index<3>(0u, 1u, 2u);
417             return tmp;
418         }
419  
420         MeshBuffer* Geometry::createPyramid(const math::vec3f &size, const math::pixel &color) const noexcept
421         {
422             MeshBuffer *tmp = new MeshBuffer();
423                 tmp->vertices.resize(16);
424                     tmp->vertices[ 0].Pos = {-size.x/2,-size.y/2,-size.z/2};
425                     tmp->vertices[ 1].Pos = { size.x/2,-size.y/2,-size.z/2};
426                     tmp->vertices[ 2].Pos = { size.x/2,-size.y/2, size.z/2};
427                     tmp->vertices[ 3].Pos = {-size.x/2,-size.y/2, size.z/2};
428                     tmp->vertices[ 4].Pos = {-size.x/2,-size.y/2,-size.z/2};
429                     tmp->vertices[ 5].Pos = { size.x/2,-size.y/2,-size.z/2};
430                     tmp->vertices[ 6].Pos = {        0, size.y/2,        0};
431                     tmp->vertices[ 7].Pos = { size.x/2,-size.y/2,-size.z/2};
432                     tmp->vertices[ 8].Pos = { size.x/2,-size.y/2, size.z/2};
433                     tmp->vertices[ 9].Pos = {        0, size.y/2,        0};
434                     tmp->vertices[10].Pos = { size.x/2,-size.y/2, size.z/2};
435                     tmp->vertices[11].Pos = {-size.x/2,-size.y/2, size.z/2};
436                     tmp->vertices[12].Pos = {        0, size.y/2,        0};
437                     tmp->vertices[13].Pos = {-size.x/2,-size.y/2,-size.z/2};
438                     tmp->vertices[14].Pos = {-size.x/2,-size.y/2, size.z/2};
439                     tmp->vertices[15].Pos = {        0, size.y/2,        0};
440  
441                     tmp->vertices[ 0].Coord = {1.0f, 1.0f};
442                     tmp->vertices[ 1].Coord = {0.0f, 1.0f};
443                     tmp->vertices[ 2].Coord = {0.0f, 0.0f};
444                     tmp->vertices[ 3].Coord = {1.0f, 0.0f};
445                     tmp->vertices[ 4].Coord = {0.0f, 0.0f};
446                     tmp->vertices[ 5].Coord = {1.0f, 0.0f};
447                     tmp->vertices[ 6].Coord = {0.5f, 1.0f};
448                     tmp->vertices[ 7].Coord = {0.0f, 0.0f};
449                     tmp->vertices[ 8].Coord = {1.0f, 0.0f};
450                     tmp->vertices[ 9].Coord = {0.5f, 1.0f};
451                     tmp->vertices[10].Coord = {0.0f, 0.0f};
452                     tmp->vertices[11].Coord = {1.0f, 0.0f};
453                     tmp->vertices[12].Coord = {0.5f, 1.0f};
454                     tmp->vertices[13].Coord = {0.0f, 0.0f};
455                     tmp->vertices[14].Coord = {1.0f, 0.0f};
456                     tmp->vertices[15].Coord = {0.5f, 1.0f};
457  
458                     tmp->vertices[ 0].Normal = { 0.0f,-1.0f, 0.0f};
459                     tmp->vertices[ 1].Normal = { 0.0f,-1.0f, 0.0f};
460                     tmp->vertices[ 2].Normal = { 0.0f,-1.0f, 0.0f};
461                     tmp->vertices[ 3].Normal = { 0.0f,-1.0f, 0.0f};
462                     tmp->vertices[ 4].Normal = {-1.0f,-1.0f,-1.0f};
463                     tmp->vertices[ 5].Normal = { 1.0f,-1.0f,-1.0f};
464                     tmp->vertices[ 6].Normal = { 0.0f, 1.0f, 0.0f};
465                     tmp->vertices[ 7].Normal = { 1.0f,-1.0f,-1.0f};
466                     tmp->vertices[ 8].Normal = { 1.0f,-1.0f, 1.0f};
467                     tmp->vertices[ 9].Normal = { 0.0f, 1.0f, 0.0f};
468                     tmp->vertices[10].Normal = { 1.0f,-1.0f, 1.0f};
469                     tmp->vertices[11].Normal = {-1.0f,-1.0f, 1.0f};
470                     tmp->vertices[12].Normal = { 0.0f, 1.0f, 0.0f};
471                     tmp->vertices[13].Normal = {-1.0f,-1.0f,-1.0f};
472                     tmp->vertices[14].Normal = {-1.0f,-1.0f, 1.0f};
473                     tmp->vertices[15].Normal = { 0.0f, 1.0f, 0.0f};
474  
475                     tmp->vertices[ 0].Color = color; tmp->vertices[ 1].Color = color;
476                     tmp->vertices[ 2].Color = color; tmp->vertices[ 3].Color = color;
477                     tmp->vertices[ 4].Color = color; tmp->vertices[ 5].Color = color;
478                     tmp->vertices[ 6].Color = color; tmp->vertices[ 7].Color = color;
479                     tmp->vertices[ 8].Color = color; tmp->vertices[ 9].Color = color;
480                     tmp->vertices[10].Color = color; tmp->vertices[11].Color = color;
481                     tmp->vertices[12].Color = color; tmp->vertices[13].Color = color;
482                     tmp->vertices[14].Color = color; tmp->vertices[15].Color = color;
483                 tmp->indices.resize(6);
484                     tmp->indices[0] = math::index<3>( 0u, 2u, 1u);
485                     tmp->indices[1] = math::index<3>( 0u, 3u, 2u);
486                     tmp->indices[2] = math::index<3>( 4u, 5u, 6u);
487                     tmp->indices[3] = math::index<3>( 7u, 8u, 9u);
488                     tmp->indices[4] = math::index<3>(10u,11u,12u);
489                     tmp->indices[5] = math::index<3>(13u,14u,15u);
490             return tmp;
491         }
492  
493         MeshBuffer* Geometry::createTorus(const f32 radiusX, const f32 radiusY, const u32 polyCountX, const u32 polyCountY, const math::pixel &color) const noexcept
494         {
495             MeshBuffer *tmp = new MeshBuffer();
496             return tmp;
497         }
498  
499         MeshBuffer* Geometry::createCone(const f32 radius, const f32 length, const u32 tesselation, const math::pixel &color) const noexcept
500         {
501             MeshBuffer *tmp = new MeshBuffer();
502             return tmp;
503         }
504  
505         MeshBuffer* Geometry::createCylindre(const f32 radius, const f32 length, const u32 tesselation, const math::pixel &color) const noexcept
506         {
507             MeshBuffer *tmp = new MeshBuffer();
508             return tmp;
509         }
510  
511         MeshBuffer* Geometry::createHeightfieldSurface(std::function<float(float, float)> gen, u16 xpath, u16 ypath, u16 segments, const math::pixel &color)
512         {
513             u32 XPATH = 20;
514             u32 YPATH = 20;
515             float sq = (xpath + ypath)/10;
516  
517             MeshBuffer *surface = new MeshBuffer();
518             surface->vertices.resize(xpath*ypath);
519  
520             for(unsigned y = 0; y<ypath; ++y)
521             {
522                 for(unsigned x = 0; x<xpath; ++x)
523                 {
524                     const unsigned int index = y*xpath + x;
525                     surface->vertices[index].Pos = {
526                         2*x/xpath - 1.f,
527                         gen(x,y)/sq,
528                         2*y/ypath - 1.f
529                     };
530                 }
531             }
532  
533             auto tmp = createSplineSurface(surface, xpath, ypath, segments, color);
534             delete surface;
535  
536             return tmp;
537         }
538  
539         MeshBuffer* Geometry::createSplineSurface(MeshBuffer *surface, u16 xpath, u16 ypath, u16 segments, const math::pixel &color)
540         {
541             MeshBuffer *render = new MeshBuffer();
542             render->vertices.resize(segments*segments);
543  
544             math::spline xsolver(xpath, 3);
545             math::spline ysolver(ypath, 3);
546  
547             std::vector<math::vec3f> tmp;
548             tmp.resize(surface->vertices.size());
549  
550             for(u32 i = 0u; i<surface->vertices.size(); ++i)
551                 tmp[i] = surface->vertices[i].Pos;
552  
553             for(float y = 0; y<segments; ++y)
554             {
555                 const unsigned int w = y*segments;
556                 for(float x = 0; x<segments; ++x)
557                 {
558                     const unsigned int n = w+x;
559                     const float u = x/segments;
560                     const float v = y/segments;
561  
562                     std::vector<math::vec3f> path;
563  
564                     for(unsigned k = 0; k<ypath; ++k)
565                     {
566                         auto view = arv::make_view(&tmp[k*xpath], (size_t)xpath);
567                         path.push_back(xsolver.eval_f(u,view));
568                     }
569  
570                     auto pos = ysolver.eval_f(v, path);
571  
572                     render->vertices[n].Pos = pos;
573                     render->vertices[n].Normal = {0,1,0};
574                     render->vertices[n].Coord = {u,v};
575                     render->vertices[n].Color = color;
576                 }
577             }
578  
579             const unsigned int last = segments-1;
580             render->indices.reserve(last*last*2);
581  
582             for(float y = 0; y<last; ++y)
583             {
584                 const unsigned int w = y*segments;
585                 for(float x = 0; x<last; ++x)
586                 {
587                     const unsigned int n = w+x;
588                     render->indices.push_back({n + segments, n + segments + 1, n + 1});
589                     render->indices.push_back({n + segments, n + 1, n});
590                 }
591             }
592  
593             for(float y = 1; y<last; ++y)
594             {
595                 const unsigned int w = y*segments;
596                 for(float x = 1; x<last; ++x)
597                 {
598                     const unsigned int n = w+x;
599  
600                     math::vec3f vertical = render->vertices[n + segments].Pos
601                                          - render->vertices[n - segments].Pos;
602  
603                     math::vec3f horizont = render->vertices[n + 1].Pos
604                                          - render->vertices[n - 1].Pos;
605  
606                     render->vertices[n].Normal = glm::normalize(glm::cross(vertical, horizont));
607                 }
608             }
609  
610             return render;
611         }
612  
613 //        void subdivide(MeshBuffer* subdiv, int subdivision)
614 //        {
615 //            if (subdivision <= 0)
616 //                return;
617 //
618 //            MeshBuffer* mesh = new MeshBuffer();
619 //
620 //            for (int i=0 ; i<subdivision; ++i)
621 //            {
622 //                std::vector<math::vec3f> position;
623 //                std::vector<math::vec4i> quad;
624 //
625 //                EdgeMap* edge_map = new EdgeMap(mesh->triangle);
626 //
627 //                for (vec3f temp_position: mesh->pos)
628 //                    position.push_back(temp_position);
629 //                for (vec2i edge: edge_map->edges())
630 //                    position.push_back((mesh->pos[edge.x] + mesh->pos[edge.y]) / 2);
631 //                for (vec3i vertex: mesh->triangle)
632 //                    position.push_back((mesh->pos[vertex.x] + mesh->pos[vertex.y] + mesh->pos[vertex.z]) / 3);
633 //                }
634 //                int edge_offset = mesh->pos.size();
635 //
636 //                int triangle_offset = edge_offset + edge_map->edges().size();
637 //                int quad_offset = triangle_offset + mesh->triangle.size();
638 //
639 //                // foreach triangle
640 //                for (int i=0; i < mesh->triangle.size(); i++)
641 //                {
642 //                    // add three quads to the new quad array
643 //                    vec3i temp_triangle = mesh->triangle[i];
644 //                    int edge_one = edge_offset + edge_map->edge_index(vec2i(temp_triangle.x, temp_triangle.y));
645 //                    int edge_two = edge_offset + edge_map->edge_index(vec2i(temp_triangle.y, temp_triangle.z));
646 //                    int edge_three = edge_offset + edge_map->edge_index(vec2i(temp_triangle.x, temp_triangle.z));
647 //
648 //                    int center = triangle_offset + i;
649 //
650 //                    quad.push_back(vec4i(temp_triangle.x, edge_one, center, edge_three));
651 //                    quad.push_back(vec4i(temp_triangle.y, edge_two, center, edge_one));
652 //                    quad.push_back(vec4i(temp_triangle.z, edge_three, center, edge_two));
653 //                }
654 //
655 //                // averaging pass ----------------------------------
656 //                // create arrays to compute pos averages (avg_pos, avg_count)
657 //                vector<vec3f> avg_pos;
658 //                vector<int> avg_count;
659 //                // arrays have the same length as the new pos array, and are init to zero
660 //                avg_pos = vector<vec3f>(position.size(), zero3f);
661 //                avg_count = vector<int>(position.size(), 0);
662 //
663 //                for (vec4i temp_quad: quad)
664 //                {
665 //                    // compute quad center using the new pos array
666 //                    vec3f quad_center = (position[temp_quad.x] + position[temp_quad.y] +
667 //                                        position[temp_quad.z] + position[temp_quad.w]) / 4;
668 //
669 //                    // foreach vertex index in the quad
670 //                    avg_pos[temp_quad.x] += quad_center;
671 //                    avg_pos[temp_quad.y] += quad_center;
672 //                    avg_pos[temp_quad.z] += quad_center;
673 //                    avg_pos[temp_quad.w] += quad_center;
674 //
675 //                    avg_count[temp_quad.x]++;
676 //                    avg_count[temp_quad.y]++;
677 //                    avg_count[temp_quad.z]++;
678 //                    avg_count[temp_quad.w]++;
679 //                }
680 //                // normalize avg_pos with its count avg_count
681 //                for (auto i: range(position.size())){
682 //                    avg_pos[i] /= avg_count[i];
683 //                }
684 //                // correction pass ----------------------------------
685 //                // foreach pos, compute correction p = p + (avg_p - p) * (4/avg_count)
686 //                for (auto i: range(position.size())) {
687 //                    position[i] += (avg_pos[i] - position[i]) * (4.0f / avg_count[i]);
688 //                }
689 //
690 //                mesh->pos = position;
691 //                mesh->triangle.clear();
692 //            }
693 //
694 //            if(subdivision)
695 //                smooth_normals(mesh);
696 //            else
697 //                facet_normals(mesh);
698 //
699 //            *subdiv = *mesh;
700 //
701 //            mesh->triangle.clear();
702 //        }
703  
704     }
705 }