source: trunk/orbital/mesh.h @ 1509

Last change on this file since 1509 was 1509, checked in by sam, 9 years ago

orbital: start working on the generic chamfer solution.

  • Property svn:keywords set to Id
File size: 21.9 KB
Line 
1//
2// Orbital
3//
4// Copyright: (c) 2009-2012 Cédric Lecacheur <jordx@free.fr>
5//            (c) 2009-2012 Benjamin Huet <huet.benjamin@gmail.com>
6//            (c) 2012 Sam Hocevar <sam@hocevar.net>
7//
8
9#if !defined __MESH_H__
10#define __MESH_H__
11
12extern char const *lolfx_shiny;
13
14class Mesh
15{
16public:
17    Mesh()
18      : m_color(0), m_color2(0)
19    {
20        m_cursors.Push(0, 0);
21    }
22
23    bool Compile(char const *command);
24
25    void OpenBrace()
26    {
27        m_cursors.Push(m_vert.Count(), m_indices.Count());
28    }
29
30    void CloseBrace()
31    {
32        m_cursors.Pop();
33    }
34
35    void MeshConvert()
36    {
37        m_gpu.shader = Shader::Create(lolfx_shiny);
38
39        m_gpu.modelview = m_gpu.shader->GetUniformLocation("in_ModelView");
40        m_gpu.proj = m_gpu.shader->GetUniformLocation("in_Proj");
41        m_gpu.normalmat = m_gpu.shader->GetUniformLocation("in_NormalMat");
42        m_gpu.damage = m_gpu.shader->GetUniformLocation("in_Damage");
43        m_gpu.coord = m_gpu.shader->GetAttribLocation("in_Vertex",
44                                              VertexUsage::Position, 0);
45        m_gpu.norm = m_gpu.shader->GetAttribLocation("in_Normal",
46                                             VertexUsage::Normal, 0);
47        m_gpu.color = m_gpu.shader->GetAttribLocation("in_Color",
48                                              VertexUsage::Color, 0);
49
50        m_gpu.vdecl = new VertexDeclaration(
51            VertexStream<vec3,vec3,u8vec4>(VertexUsage::Position,
52                                           VertexUsage::Normal,
53                                           VertexUsage::Color));
54
55        Array<vec3,vec3,u8vec4> vertexlist;
56        for (int i = 0; i < m_vert.Count(); i++)
57            vertexlist.Push(m_vert[i].m1,
58                            m_vert[i].m2,
59                            (u8vec4)(m_vert[i].m3 * 255.f));
60
61        Array<uint16_t> indexlist;
62        for (int i = 0; i < m_indices.Count(); i += 3)
63        {
64            indexlist << m_indices[i + 0];
65            indexlist << m_indices[i + 1];
66            indexlist << m_indices[i + 2];
67        }
68
69        m_gpu.vbo = new VertexBuffer(vertexlist.Bytes());
70        void *mesh = m_gpu.vbo->Lock(0, 0);
71        memcpy(mesh, &vertexlist[0], vertexlist.Bytes());
72        m_gpu.vbo->Unlock();
73
74        m_gpu.ibo = new IndexBuffer(indexlist.Bytes());
75        void *indices = m_gpu.ibo->Lock(0, 0);
76        memcpy(indices, &indexlist[0], indexlist.Bytes());
77        m_gpu.ibo->Unlock();
78
79        m_gpu.vertexcount = vertexlist.Count();
80        m_gpu.indexcount = indexlist.Count();
81    }
82
83    void Render(mat4 const &model, float damage = 0.f)
84    {
85        mat4 modelview = Scene::GetDefault()->GetViewMatrix() * model;
86        mat3 normalmat = transpose(inverse(mat3(modelview)));
87
88        m_gpu.shader->Bind();
89        m_gpu.shader->SetUniform(m_gpu.modelview, modelview);
90        m_gpu.shader->SetUniform(m_gpu.proj, Scene::GetDefault()->GetProjMatrix());
91        m_gpu.shader->SetUniform(m_gpu.normalmat, normalmat);
92        m_gpu.shader->SetUniform(m_gpu.damage, damage);
93        m_gpu.vdecl->SetStream(m_gpu.vbo, m_gpu.coord, m_gpu.norm, m_gpu.color);
94        m_gpu.vdecl->Bind();
95        m_gpu.ibo->Bind();
96        m_gpu.vdecl->DrawIndexedElements(MeshPrimitive::Triangles,
97                                         0, 0, m_gpu.vertexcount,
98                                         0, m_gpu.indexcount / 3);
99        m_gpu.ibo->Unbind();
100        m_gpu.vdecl->Unbind();
101    }
102
103    void SetCurColor(vec4 const &color) { m_color = color; }
104    void SetCurColor2(vec4 const &color) { m_color2 = color; }
105
106    void AddVertex(vec3 const &coord)
107    {
108        m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color);
109    }
110
111    void AddDuplicateVertex(int i)
112    {
113        m_vert.Push(m_vert[i].m1, vec3(0.f, 1.f, 0.f), m_vert[i].m3);
114    }
115
116    void AppendQuad(int i1, int i2, int i3, int i4, int base)
117    {
118        m_indices << base + i1;
119        m_indices << base + i2;
120        m_indices << base + i3;
121
122        m_indices << base + i4;
123        m_indices << base + i1;
124        m_indices << base + i3;
125    }
126
127    void AppendQuadDuplicateVerts(int i1, int i2, int i3, int i4, int base)
128    {
129        m_indices << m_vert.Count(); AddDuplicateVertex(base + i1);
130        m_indices << m_vert.Count(); AddDuplicateVertex(base + i2);
131        m_indices << m_vert.Count(); AddDuplicateVertex(base + i3);
132
133        m_indices << m_vert.Count(); AddDuplicateVertex(base + i4);
134        m_indices << m_vert.Count(); AddDuplicateVertex(base + i1);
135        m_indices << m_vert.Count(); AddDuplicateVertex(base + i3);
136    }
137
138    void AppendTriangle(int i1, int i2, int i3, int base)
139    {
140        m_indices << base + i1;
141        m_indices << base + i2;
142        m_indices << base + i3;
143    }
144
145    void AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base)
146    {
147        m_indices << m_vert.Count(); AddDuplicateVertex(base + i1);
148        m_indices << m_vert.Count(); AddDuplicateVertex(base + i2);
149        m_indices << m_vert.Count(); AddDuplicateVertex(base + i3);
150    }
151
152    void ComputeNormals(int start, int vcount)
153    {
154        for (int i = 0; i < vcount; i += 3)
155        {
156            vec3 v0 = m_vert[m_indices[start + i + 2]].m1
157                    - m_vert[m_indices[start + i + 0]].m1;
158            vec3 v1 = m_vert[m_indices[start + i + 1]].m1
159                    - m_vert[m_indices[start + i + 0]].m1;
160            vec3 n = normalize(cross(v1, v0));
161
162            for (int j = 0; j < 3; j++)
163                m_vert[m_indices[start + i + j]].m2 = n;
164        }
165    }
166
167    void SetVertColor(vec4 const &color)
168    {
169        for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
170            m_vert[i].m3 = color;
171    }
172
173    void SetCurVertNormal(vec3 const &normal)
174    {
175        m_vert[m_vert.Count() - 1].m2 = normal;
176    }
177
178    void SetCurVertColor(vec4 const &color)
179    {
180        m_vert[m_vert.Count() - 1].m3 = color;
181    }
182
183    void Translate(vec3 const &v)
184    {
185        for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
186            m_vert[i].m1 += v;
187    }
188
189    void RotateX(float t) { Rotate(t, vec3(1, 0, 0)); }
190    void RotateY(float t) { Rotate(t, vec3(0, 1, 0)); }
191    void RotateZ(float t) { Rotate(t, vec3(0, 0, 1)); }
192
193    void Rotate(float t, vec3 const &axis)
194    {
195        mat3 m = mat3::rotate(t, axis);
196        for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
197        {
198            m_vert[i].m1 = m * m_vert[i].m1;
199            m_vert[i].m2 = m * m_vert[i].m2;
200        }
201    }
202
203    void TaperX(float y, float z, float xoff)
204    {
205        /* FIXME: this code breaks normals! */
206        for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
207        {
208            m_vert[i].m1.y *= 1.f + (y * m_vert[i].m1.x + xoff);
209            m_vert[i].m1.z *= 1.f + (z * m_vert[i].m1.x + xoff);
210        }
211    }
212
213    void TaperY(float x, float z, float yoff)
214    {
215        for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
216        {
217            m_vert[i].m1.x *= 1.f + (x * m_vert[i].m1.y + yoff);
218            m_vert[i].m1.z *= 1.f + (z * m_vert[i].m1.y + yoff);
219        }
220    }
221
222    void TaperZ(float x, float y, float zoff)
223    {
224        for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
225        {
226            m_vert[i].m1.x *= 1.f + (x * m_vert[i].m1.z + zoff);
227            m_vert[i].m1.y *= 1.f + (y * m_vert[i].m1.z + zoff);
228        }
229    }
230
231    void Scale(vec3 const &s)
232    {
233        vec3 const invs = vec3(1) / s;
234
235        for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
236        {
237            m_vert[i].m1 *= s;
238            m_vert[i].m2 = normalize(m_vert[i].m2 * invs);
239        }
240
241        /* Flip winding if the scaling involves mirroring */
242        if (s.x * s.y * s.z < 0)
243        {
244            for (int i = m_cursors.Last().m2; i < m_indices.Count(); i += 3)
245            {
246                uint16_t tmp = m_indices[i + 0];
247                m_indices[i + 0] = m_indices[i + 1];
248                m_indices[i + 1] = tmp;
249            }
250        }
251    }
252
253    void MirrorX() { DupAndScale(vec3(-1, 1, 1)); }
254    void MirrorY() { DupAndScale(vec3(1, -1, 1)); }
255    void MirrorZ() { DupAndScale(vec3(1, 1, -1)); }
256
257    void DupAndScale(vec3 const &s)
258    {
259        int vlen = m_vert.Count() - m_cursors.Last().m1;
260        int tlen = m_indices.Count() - m_cursors.Last().m2;
261
262        for (int i = 0; i < vlen; i++)
263            m_vert << m_vert[m_cursors.Last().m1++];
264
265        for (int i = 0; i < tlen; i++)
266            m_indices << m_indices[m_cursors.Last().m2++] + vlen;
267
268        Scale(s);
269
270        m_cursors.Last().m1 -= vlen;
271        m_cursors.Last().m2 -= tlen;
272    }
273
274    void AppendCylinder(int nsides, float h, float r1, float r2,
275                        int dualside, int smooth)
276    {
277        int vbase = m_vert.Count();
278
279        mat3 rotmat = mat3::rotate(360.0f / nsides, 0.f, 1.f, 0.f);
280        vec3 p1(r1, -h * .5f, 0.f), p2(r2, h * .5f, 0.f), n;
281
282        /* Construct normal */
283        n = p2;
284        n.y = r1 * (r1 - r2) / h;
285        if (!smooth)
286            n = mat3::rotate(180.0f / nsides, 0.f, 1.f, 0.f) * n;
287        n = normalize(n);
288
289        /* FIXME: normals should be flipped in two-sided mode, but that
290         * means duplicating the vertices again... */
291        for (int i = 0; i < nsides; i++)
292        {
293            AddVertex(p1); SetCurVertNormal(n);
294            AddVertex(p2); SetCurVertNormal(n);
295            SetCurVertColor(m_color2);
296
297            if (smooth)
298            {
299                int j = (i + 1) % nsides;
300                AppendQuad(j * 2, j * 2 + 1, i * 2 + 1, i * 2, vbase);
301                if (dualside)
302                    AppendQuad(i * 2, i * 2 + 1, j * 2 + 1, j * 2, vbase);
303            }
304
305            p1 = rotmat * p1;
306            p2 = rotmat * p2;
307
308            if (!smooth)
309            {
310                AddVertex(p1); SetCurVertNormal(n);
311                AddVertex(p2); SetCurVertNormal(n);
312                SetCurVertColor(m_color2);
313
314                AppendQuad(i * 4 + 2, i * 4 + 3, i * 4 + 1, i * 4, vbase);
315                if (dualside)
316                    AppendQuad(i * 4, i * 4 + 1, i * 4 + 3, i * 4 + 2, vbase);
317            }
318
319            n = rotmat * n;
320        }
321    }
322
323    void AppendSphere(int ndivisions, vec3 const &size)
324    {
325        ndivisions *= 2;
326
327        int ibase = m_indices.Count();
328        int vbase = m_vert.Count();
329
330        vec3 d = size * 0.5f;
331        float const pi = std::acos(-1.0f);
332
333        Array<vec2> table;
334        for (int i = 0; i <= ndivisions; i++)
335            table.Push(vec2(std::sin(pi * 2 / ndivisions * i) + 1e-5f,
336                            std::cos(pi * 2 / ndivisions * i) + 1e-5f));
337
338        for (int j = 0; j <= ndivisions / 2; j++)
339            for (int i = 0; i < ndivisions; i++)
340            {
341                int j2 = j + 1;
342                int i2 = (i + 1) % ndivisions;
343
344                AddVertex(d * vec3(table[i], 1.0f) * table[j].xxy);
345                AddVertex(d * vec3(table[i2], 1.0f) * table[j].xxy);
346                AddVertex(d * vec3(table[i2], 1.0f) * table[j2].xxy);
347                AddVertex(d * vec3(table[i], 1.0f) * table[j2].xxy);
348            }
349
350        for (int i = vbase; i < m_vert.Count(); i += 4)
351            AppendQuad(0, 1, 2, 3, i);
352
353        ComputeNormals(ibase, m_indices.Count() - ibase);
354    }
355
356    void AppendBox(vec3 const &size, float chamf = 0.f)
357    {
358        AppendBox(size, chamf, false);
359    }
360
361    void AppendSmoothChamfBox(vec3 const &size, float chamf)
362    {
363        AppendBox(size, chamf, true);
364    }
365
366    void AppendFlatChamfBox(vec3 const &size, float chamf)
367    {
368        AppendBox(size, chamf, false);
369    }
370
371    void AppendBox(vec3 const &size, float chamf, bool smooth)
372    {
373        if (chamf < 0.0f)
374        {
375            AppendBox(size + vec3(chamf * 2.0f), -chamf, smooth);
376            return;
377        }
378
379        int vbase = m_vert.Count();
380        int ibase = m_indices.Count();
381
382        vec3 d = size * 0.5f;
383
384        AddVertex(vec3(-d.x, -d.y, -d.z - chamf));
385        AddVertex(vec3(-d.x, +d.y, -d.z - chamf));
386        AddVertex(vec3(+d.x, +d.y, -d.z - chamf));
387        AddVertex(vec3(+d.x, -d.y, -d.z - chamf));
388
389        AddVertex(vec3(-d.x - chamf, -d.y, +d.z));
390        AddVertex(vec3(-d.x - chamf, +d.y, +d.z));
391        AddVertex(vec3(-d.x - chamf, +d.y, -d.z));
392        AddVertex(vec3(-d.x - chamf, -d.y, -d.z));
393
394        AddVertex(vec3(+d.x, -d.y, +d.z + chamf));
395        AddVertex(vec3(+d.x, +d.y, +d.z + chamf));
396        AddVertex(vec3(-d.x, +d.y, +d.z + chamf));
397        AddVertex(vec3(-d.x, -d.y, +d.z + chamf));
398
399        AddVertex(vec3(+d.x + chamf, -d.y, -d.z));
400        AddVertex(vec3(+d.x + chamf, +d.y, -d.z));
401        AddVertex(vec3(+d.x + chamf, +d.y, +d.z));
402        AddVertex(vec3(+d.x + chamf, -d.y, +d.z));
403
404        AddVertex(vec3(-d.x, -d.y - chamf, +d.z));
405        AddVertex(vec3(-d.x, -d.y - chamf, -d.z));
406        AddVertex(vec3(+d.x, -d.y - chamf, -d.z));
407        AddVertex(vec3(+d.x, -d.y - chamf, +d.z));
408
409        AddVertex(vec3(-d.x, +d.y + chamf, -d.z));
410        AddVertex(vec3(-d.x, +d.y + chamf, +d.z));
411        AddVertex(vec3(+d.x, +d.y + chamf, +d.z));
412        AddVertex(vec3(+d.x, +d.y + chamf, -d.z));
413
414        /* The 6 quads on each side of the box */
415        for (int i = 0; i < 24; i += 4)
416            AppendQuad(i, i + 1, i + 2, i + 3, vbase);
417
418        ComputeNormals(ibase, m_indices.Count() - ibase);
419        ibase = m_indices.Count();
420
421        /* The 8 quads at each edge of the box */
422        if (chamf)
423        {
424            static int const quadlist[48] =
425            {
426                0, 3, 18, 17, 4, 7, 17, 16, 8, 11, 16, 19, 12, 15, 19, 18,
427                2, 1, 20, 23, 6, 5, 21, 20, 10, 9, 22, 21, 14, 13, 23, 22,
428                1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, 3, 2,
429            };
430
431            for (int i = 0; i < 48; i += 4)
432            {
433                if (smooth)
434                    AppendQuad(quadlist[i], quadlist[i + 1],
435                               quadlist[i + 2], quadlist[i + 3], vbase);
436                else
437                    AppendQuadDuplicateVerts(quadlist[i], quadlist[i + 1],
438                                     quadlist[i + 2], quadlist[i + 3], vbase);
439            }
440        }
441
442        /* The 8 triangles at each corner of the box */
443        if (chamf)
444        {
445            static int const trilist[24] =
446            {
447                3, 12, 18, 15, 8, 19, 11, 4, 16, 7, 0, 17,
448                2, 23, 13, 14, 22, 9, 10, 21, 5, 6, 20, 1,
449            };
450
451            for (int i = 0; i < 24; i += 3)
452            {
453                if (smooth)
454                    AppendTriangle(trilist[i], trilist[i + 1],
455                                   trilist[i + 2], vbase);
456                else
457                    AppendTriangleDuplicateVerts(trilist[i], trilist[i + 1],
458                                                 trilist[i + 2], vbase);
459            }
460        }
461
462        if (!smooth)
463            ComputeNormals(ibase, m_indices.Count() - ibase);
464    }
465
466    void AppendStar(int nbranches, float r1, float r2,
467                    int fade = 0, int fade2 = 0)
468    {
469        int vbase = m_vert.Count();
470
471        AddVertex(vec3(0.f, 0.f, 0.f));
472
473        mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f);
474        vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f);
475
476        p2 = rotmat * p2;
477        rotmat = rotmat * rotmat;
478
479        for (int i = 0; i < nbranches; i++)
480        {
481            AddVertex(p1);
482            if (fade2)
483                SetCurVertColor(m_color2);
484
485            AddVertex(p2);
486            if (fade)
487                SetCurVertColor(m_color2);
488
489            AppendQuad(0, 2 * i + 1, 2 * i + 2, (2 * i + 3) % (2 * nbranches),
490                       vbase);
491
492            p1 = rotmat * p1;
493            p2 = rotmat * p2;
494        }
495    }
496
497    void AppendExpandedStar(int nbranches, float r1, float r2, float extrar)
498    {
499        int vbase = m_vert.Count();
500
501        AddVertex(vec3(0.f, 0.f, 0.f));
502
503        mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f);
504        vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f),
505             p3(r1 + extrar, 0.f, 0.f), p4(r2 + extrar, 0.f, 0.f);;
506
507        p2 = rotmat * p2;
508        p4 = rotmat * p4;
509        rotmat = rotmat * rotmat;
510
511        for (int i = 0; i < nbranches; i++)
512        {
513            AddVertex(p1);
514            AddVertex(p2);
515            AddVertex(p3); SetCurVertColor(m_color2);
516            AddVertex(p4); SetCurVertColor(m_color2);
517
518            int j = (i + 1) % nbranches;
519            AppendQuad(0, 4 * i + 1, 4 * i + 2, 4 * j + 1, vbase);
520            AppendQuad(4 * i + 1, 4 * i + 3, 4 * i + 4, 4 * i + 2, vbase);
521            AppendQuad(4 * j + 1, 4 * i + 2, 4 * i + 4, 4 * j + 3, vbase);
522
523            p1 = rotmat * p1;
524            p2 = rotmat * p2;
525            p3 = rotmat * p3;
526            p4 = rotmat * p4;
527        }
528    }
529
530    void AppendDisc(int nsides, float r, int fade = 0)
531    {
532        int vbase = m_vert.Count();
533
534        AddVertex(vec3(0.f, 0.f, 0.f));
535
536        mat3 rotmat = mat3::rotate(360.0f / nsides, 0.f, 1.f, 0.f);
537        vec3 p1(r, 0.f, 0.f);
538
539        for (int i = 0; i < nsides; i++)
540        {
541            AddVertex(p1);
542            if (fade)
543                SetCurVertColor(m_color2);
544            AppendTriangle(0, i + 1, ((i + 1) % nsides) + 1, vbase);
545            p1 = rotmat * p1;
546        }
547    }
548
549    void AppendSimpleTriangle(float size, int fade = 0)
550    {
551        mat3 m = mat3::rotate(120.f, 0.f, 1.f, 0.f);
552        vec3 p(0.f, 0.f, size);
553
554        AddVertex(p);
555        p = m * p;
556        AddVertex(p);
557        if (fade)
558            SetCurVertColor(m_color2);
559        p = m * p;
560        AddVertex(p);
561        if (fade)
562            SetCurVertColor(m_color2);
563
564        AppendTriangle(0, 1, 2, m_vert.Count() - 3);
565    }
566
567    void AppendSimpleQuad(float size, int fade = 0)
568    {
569        AppendSimpleQuad(vec2(size * .5f), vec2(size * -.5f), 0.f, fade);
570    }
571
572    void AppendSimpleQuad(vec2 p1, vec2 p2, float z = 0.f, int fade = 0)
573    {
574        AddVertex(vec3(p2.x, z, -p1.y));
575        AddVertex(vec3(p2.x, z, -p2.y));
576        AddVertex(vec3(p1.x, z, -p2.y));
577        if (fade)
578            SetCurVertColor(m_color2);
579        AddVertex(vec3(p1.x, z, -p1.y));
580        if (fade)
581            SetCurVertColor(m_color2);
582
583        AppendQuad(3, 2, 1, 0, m_vert.Count() - 4);
584        ComputeNormals(m_indices.Count() - 6, 6);
585    }
586
587    void AppendCog(int nbsides, float h, float r1, float r2,
588                   float r12, float r22, float sidemul, int offset)
589    {
590        int ibase = m_indices.Count();
591        int vbase = m_vert.Count();
592
593        AddVertex(vec3(0.f, h * .5f, 0.f));
594        AddVertex(vec3(0.f, h * -.5f, 0.f));
595        SetCurVertColor(m_color2);
596
597        mat3 rotmat = mat3::rotate(180.0f / nbsides, 0.f, 1.f, 0.f);
598        mat3 smat1 = mat3::rotate(sidemul * 180.0f / nbsides, 0.f, 1.f, 0.f);
599        mat3 smat2 = mat3::rotate(sidemul * -360.0f / nbsides, 0.f, 1.f, 0.f);
600
601        vec3 p[8];
602
603        p[0] = vec3(r1, h * .5f, 0.f);
604        p[1] = rotmat * p[0];
605        p[2] = smat1 * (rotmat * vec3(r1 + r12, h * .5f, 0.f));
606        p[3] = smat2 * (rotmat * p[2]);
607
608        p[4] = vec3(r2, h * -.5f, 0.f);
609        p[5] = rotmat * p[4];
610        p[6] = smat1 * (rotmat * vec3(r2 + r22, h * -.5f, 0.f));
611        p[7] = smat2 * (rotmat * p[6]);
612
613        if (offset & 1)
614            for (int n = 0; n < 8; n++)
615                p[n] = rotmat * p[n];
616
617        rotmat = rotmat * rotmat;
618
619        for (int i = 0; i < nbsides; i++)
620        {
621            /* Each vertex will share three faces, so three different
622             * normals, therefore we add each vertex three times. */
623            for (int n = 0; n < 24; n++)
624            {
625                AddVertex(p[n / 3]);
626                if (n / 3 >= 4)
627                    SetCurVertColor(m_color2);
628            }
629
630            int j = 24 * i, k = 24 * ((i + 1) % nbsides);
631
632            /* The top and bottom faces */
633            AppendQuad(0, j + 2, j + 5, k + 2, vbase);
634            AppendQuad(1, k + 14, j + 17, j + 14, vbase);
635            AppendQuad(j + 5, j + 8, j + 11, k + 2, vbase);
636            AppendQuad(k + 14, j + 23, j + 20, j + 17, vbase);
637
638            /* The side quads */
639            AppendQuad(j + 6, j + 3, j + 15, j + 18, vbase);
640            AppendQuad(j + 9, j + 7, j + 19, j + 21, vbase);
641            AppendQuad(j + 12, j + 10, j + 22, j + 24, vbase);
642            AppendQuad(k + 4, j + 13, j + 25, k + 16, vbase);
643
644            for (int n = 0; n < 8; n++)
645                p[n] = rotmat * p[n];
646        }
647
648        ComputeNormals(ibase, m_indices.Count() - ibase);
649    }
650
651    void Chamfer(float f)
652    {
653        int vlen = m_vert.Count() - m_cursors.Last().m1;
654        int ilen = m_indices.Count() - m_cursors.Last().m2;
655
656        /* Step 1: enumerate all faces. This is done by merging triangles
657         * that are coplanar and share an edge. */
658        int *triangle_classes = new int[ilen / 3];
659        for (int i = 0; i < ilen / 3; i++)
660            triangle_classes[i] = -1;
661
662        for (int i = 0; i < ilen / 3; i++)
663        {
664             
665        }
666
667        /* Fun shit: reduce all triangles */
668        int *vertices = new int[vlen];
669        memset(vertices, 0, vlen * sizeof(int));
670        for (int i = 0; i < ilen; i++)
671            vertices[m_indices[i]]++;
672
673        for (int i = 0; i < ilen / 3; i++)
674        {
675        #if 0
676            if (vertices[m_indices[i * 3]] > 1)
677                continue;
678            if (vertices[m_indices[i * 3 + 1]] > 1)
679                continue;
680            if (vertices[m_indices[i * 3 + 2]] > 1)
681                continue;
682        #endif
683
684            vec3 bary = 1.f / 3.f * (m_vert[m_indices[i * 3]].m1 +
685                                     m_vert[m_indices[i * 3 + 1]].m1 +
686                                     m_vert[m_indices[i * 3 + 2]].m1);
687            for (int k = 0; k < 3; k++)
688            {
689                vec3 &p = m_vert[m_indices[i * 3 + k]].m1;
690                p -= normalize(p - bary) * f;
691            }
692        }
693    }
694
695private:
696    vec4 m_color, m_color2;
697    Array<uint16_t> m_indices;
698    Array<vec3, vec3, vec4> m_vert;
699    Array<int, int> m_cursors;
700
701    /* FIXME: put this in a separate class so that we can copy meshes. */
702    struct
703    {
704        Shader *shader;
705        ShaderAttrib coord, norm, color;
706        ShaderUniform modelview, proj, normalmat, damage;
707        VertexDeclaration *vdecl;
708        VertexBuffer *vbo;
709        IndexBuffer *ibo;
710        int vertexcount, indexcount;
711    }
712    m_gpu;
713};
714
715#endif /* __MESH_H__ */
716
Note: See TracBrowser for help on using the repository browser.