source: trunk/src/easymesh/easymesh.cpp @ 1510

Last change on this file since 1510 was 1510, checked in by sam, 8 years ago

easymesh: move the Mesh builder into the engine core.

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