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

Last change on this file since 1599 was 1599, checked in by touky, 10 years ago

EasyMesh : Fixed normals on disc when one of the radius == 0
EasyPhysics : Added Cone primitive.

File size: 20.3 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        if (r2 != .0f)
308                n = vec3(r2, h * .5f, 0.f);
309        else
310                n = vec3(r1, h * .5f, 0.f);
311    n.y = r1 * (r1 - r2) / h;
312    if (!smooth)
313        n = mat3::rotate(180.0f / nsides, 0.f, 1.f, 0.f) * n;
314    n = normalize(n);
315
316    /* FIXME: normals should be flipped in two-sided mode, but that
317     * means duplicating the vertices again... */
318    for (int i = 0; i < nsides; i++)
319    {
320        AddVertex(p1); SetCurVertNormal(n);
321        AddVertex(p2); SetCurVertNormal(n);
322        SetCurVertColor(m_color2);
323
324        if (smooth)
325        {
326            int j = (i + 1) % nsides;
327            AppendQuad(j * 2, j * 2 + 1, i * 2 + 1, i * 2, vbase);
328            if (dualside)
329                AppendQuad(i * 2, i * 2 + 1, j * 2 + 1, j * 2, vbase);
330        }
331
332        p1 = rotmat * p1;
333        p2 = rotmat * p2;
334
335        if (!smooth)
336        {
337            AddVertex(p1); SetCurVertNormal(n);
338            AddVertex(p2); SetCurVertNormal(n);
339            SetCurVertColor(m_color2);
340
341            AppendQuad(i * 4 + 2, i * 4 + 3, i * 4 + 1, i * 4, vbase);
342            if (dualside)
343                AppendQuad(i * 4, i * 4 + 1, i * 4 + 3, i * 4 + 2, vbase);
344        }
345
346        n = rotmat * n;
347    }
348}
349
350void EasyMesh::AppendSphere(int ndivisions, vec3 const &size)
351{
352    ndivisions *= 2;
353
354    int ibase = m_indices.Count();
355    int vbase = m_vert.Count();
356
357    vec3 d = size * 0.5f;
358    float const pi = acos(-1.0f);
359
360    Array<vec2> table;
361    for (int i = 0; i <= ndivisions; i++)
362        table.Push(vec2(sin(pi * 2 / ndivisions * i) + 1e-5f,
363                        cos(pi * 2 / ndivisions * i) + 1e-5f));
364
365    for (int j = 0; j <= ndivisions / 2; j++)
366        for (int i = 0; i < ndivisions; i++)
367        {
368            int j2 = j + 1;
369            int i2 = (i + 1) % ndivisions;
370
371            AddVertex(d * vec3(table[i], 1.0f) * table[j].xxy);
372            AddVertex(d * vec3(table[i2], 1.0f) * table[j].xxy);
373            AddVertex(d * vec3(table[i2], 1.0f) * table[j2].xxy);
374            AddVertex(d * vec3(table[i], 1.0f) * table[j2].xxy);
375        }
376
377    for (int i = vbase; i < m_vert.Count(); i += 4)
378        AppendQuad(0, 1, 2, 3, i);
379
380    ComputeNormals(ibase, m_indices.Count() - ibase);
381}
382
383void EasyMesh::AppendBox(vec3 const &size, float chamf)
384{
385    AppendBox(size, chamf, false);
386}
387
388void EasyMesh::AppendSmoothChamfBox(vec3 const &size, float chamf)
389{
390    AppendBox(size, chamf, true);
391}
392
393void EasyMesh::AppendFlatChamfBox(vec3 const &size, float chamf)
394{
395    AppendBox(size, chamf, false);
396}
397
398void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth)
399{
400    if (chamf < 0.0f)
401    {
402        AppendBox(size + vec3(chamf * 2.0f), -chamf, smooth);
403        return;
404    }
405
406    int vbase = m_vert.Count();
407    int ibase = m_indices.Count();
408
409    vec3 d = size * 0.5f;
410
411    AddVertex(vec3(-d.x, -d.y, -d.z - chamf));
412    AddVertex(vec3(-d.x, +d.y, -d.z - chamf));
413    AddVertex(vec3(+d.x, +d.y, -d.z - chamf));
414    AddVertex(vec3(+d.x, -d.y, -d.z - chamf));
415
416    AddVertex(vec3(-d.x - chamf, -d.y, +d.z));
417    AddVertex(vec3(-d.x - chamf, +d.y, +d.z));
418    AddVertex(vec3(-d.x - chamf, +d.y, -d.z));
419    AddVertex(vec3(-d.x - chamf, -d.y, -d.z));
420
421    AddVertex(vec3(+d.x, -d.y, +d.z + chamf));
422    AddVertex(vec3(+d.x, +d.y, +d.z + chamf));
423    AddVertex(vec3(-d.x, +d.y, +d.z + chamf));
424    AddVertex(vec3(-d.x, -d.y, +d.z + chamf));
425
426    AddVertex(vec3(+d.x + chamf, -d.y, -d.z));
427    AddVertex(vec3(+d.x + chamf, +d.y, -d.z));
428    AddVertex(vec3(+d.x + chamf, +d.y, +d.z));
429    AddVertex(vec3(+d.x + chamf, -d.y, +d.z));
430
431    AddVertex(vec3(-d.x, -d.y - chamf, +d.z));
432    AddVertex(vec3(-d.x, -d.y - chamf, -d.z));
433    AddVertex(vec3(+d.x, -d.y - chamf, -d.z));
434    AddVertex(vec3(+d.x, -d.y - chamf, +d.z));
435
436    AddVertex(vec3(-d.x, +d.y + chamf, -d.z));
437    AddVertex(vec3(-d.x, +d.y + chamf, +d.z));
438    AddVertex(vec3(+d.x, +d.y + chamf, +d.z));
439    AddVertex(vec3(+d.x, +d.y + chamf, -d.z));
440
441    /* The 6 quads on each side of the box */
442    for (int i = 0; i < 24; i += 4)
443        AppendQuad(i, i + 1, i + 2, i + 3, vbase);
444
445    ComputeNormals(ibase, m_indices.Count() - ibase);
446    ibase = m_indices.Count();
447
448    /* The 8 quads at each edge of the box */
449    if (chamf)
450    {
451        static int const quadlist[48] =
452        {
453            0, 3, 18, 17, 4, 7, 17, 16, 8, 11, 16, 19, 12, 15, 19, 18,
454            2, 1, 20, 23, 6, 5, 21, 20, 10, 9, 22, 21, 14, 13, 23, 22,
455            1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, 3, 2,
456        };
457
458        for (int i = 0; i < 48; i += 4)
459        {
460            if (smooth)
461                AppendQuad(quadlist[i], quadlist[i + 1],
462                           quadlist[i + 2], quadlist[i + 3], vbase);
463            else
464                AppendQuadDuplicateVerts(quadlist[i], quadlist[i + 1],
465                                 quadlist[i + 2], quadlist[i + 3], vbase);
466        }
467    }
468
469    /* The 8 triangles at each corner of the box */
470    if (chamf)
471    {
472        static int const trilist[24] =
473        {
474            3, 12, 18, 15, 8, 19, 11, 4, 16, 7, 0, 17,
475            2, 23, 13, 14, 22, 9, 10, 21, 5, 6, 20, 1,
476        };
477
478        for (int i = 0; i < 24; i += 3)
479        {
480            if (smooth)
481                AppendTriangle(trilist[i], trilist[i + 1],
482                               trilist[i + 2], vbase);
483            else
484                AppendTriangleDuplicateVerts(trilist[i], trilist[i + 1],
485                                             trilist[i + 2], vbase);
486        }
487    }
488
489    if (!smooth)
490        ComputeNormals(ibase, m_indices.Count() - ibase);
491}
492
493void EasyMesh::AppendStar(int nbranches, float r1, float r2,
494                          int fade, int fade2)
495{
496    int vbase = m_vert.Count();
497
498    AddVertex(vec3(0.f, 0.f, 0.f));
499
500    mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f);
501    vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f);
502
503    p2 = rotmat * p2;
504    rotmat = rotmat * rotmat;
505
506    for (int i = 0; i < nbranches; i++)
507    {
508        AddVertex(p1);
509        if (fade2)
510            SetCurVertColor(m_color2);
511
512        AddVertex(p2);
513        if (fade)
514            SetCurVertColor(m_color2);
515
516        AppendQuad(0, 2 * i + 1, 2 * i + 2, (2 * i + 3) % (2 * nbranches),
517                   vbase);
518
519        p1 = rotmat * p1;
520        p2 = rotmat * p2;
521    }
522}
523
524void EasyMesh::AppendExpandedStar(int nbranches, float r1,
525                                  float r2, float extrar)
526{
527    int vbase = m_vert.Count();
528
529    AddVertex(vec3(0.f, 0.f, 0.f));
530
531    mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f);
532    vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f),
533         p3(r1 + extrar, 0.f, 0.f), p4(r2 + extrar, 0.f, 0.f);;
534
535    p2 = rotmat * p2;
536    p4 = rotmat * p4;
537    rotmat = rotmat * rotmat;
538
539    for (int i = 0; i < nbranches; i++)
540    {
541        AddVertex(p1);
542        AddVertex(p2);
543        AddVertex(p3); SetCurVertColor(m_color2);
544        AddVertex(p4); SetCurVertColor(m_color2);
545
546        int j = (i + 1) % nbranches;
547        AppendQuad(0, 4 * i + 1, 4 * i + 2, 4 * j + 1, vbase);
548        AppendQuad(4 * i + 1, 4 * i + 3, 4 * i + 4, 4 * i + 2, vbase);
549        AppendQuad(4 * j + 1, 4 * i + 2, 4 * i + 4, 4 * j + 3, vbase);
550
551        p1 = rotmat * p1;
552        p2 = rotmat * p2;
553        p3 = rotmat * p3;
554        p4 = rotmat * p4;
555    }
556}
557
558void EasyMesh::AppendDisc(int nsides, float r, int fade)
559{
560    int vbase = m_vert.Count();
561
562    AddVertex(vec3(0.f, 0.f, 0.f));
563
564    mat3 rotmat = mat3::rotate(360.0f / nsides, 0.f, 1.f, 0.f);
565    vec3 p1(r, 0.f, 0.f);
566
567    for (int i = 0; i < nsides; i++)
568    {
569        AddVertex(p1);
570        if (fade)
571            SetCurVertColor(m_color2);
572        AppendTriangle(0, i + 1, ((i + 1) % nsides) + 1, vbase);
573        p1 = rotmat * p1;
574    }
575}
576
577void EasyMesh::AppendSimpleTriangle(float size, int fade)
578{
579    mat3 m = mat3::rotate(120.f, 0.f, 1.f, 0.f);
580    vec3 p(0.f, 0.f, size);
581
582    AddVertex(p);
583    p = m * p;
584    AddVertex(p);
585    if (fade)
586        SetCurVertColor(m_color2);
587    p = m * p;
588    AddVertex(p);
589    if (fade)
590        SetCurVertColor(m_color2);
591
592    AppendTriangle(0, 1, 2, m_vert.Count() - 3);
593}
594
595void EasyMesh::AppendSimpleQuad(float size, int fade)
596{
597    AppendSimpleQuad(vec2(size * .5f), vec2(size * -.5f), 0.f, fade);
598}
599
600void EasyMesh::AppendSimpleQuad(vec2 p1, vec2 p2, float z, int fade)
601{
602    AddVertex(vec3(p2.x, z, -p1.y));
603    AddVertex(vec3(p2.x, z, -p2.y));
604    AddVertex(vec3(p1.x, z, -p2.y));
605    if (fade)
606        SetCurVertColor(m_color2);
607    AddVertex(vec3(p1.x, z, -p1.y));
608    if (fade)
609        SetCurVertColor(m_color2);
610
611    AppendQuad(3, 2, 1, 0, m_vert.Count() - 4);
612    ComputeNormals(m_indices.Count() - 6, 6);
613}
614
615void EasyMesh::AppendCog(int nbsides, float h, float r1, float r2, float r12,
616                         float r22, float sidemul, int offset)
617{
618    int ibase = m_indices.Count();
619    int vbase = m_vert.Count();
620
621    AddVertex(vec3(0.f, h * .5f, 0.f));
622    AddVertex(vec3(0.f, h * -.5f, 0.f));
623    SetCurVertColor(m_color2);
624
625    mat3 rotmat = mat3::rotate(180.0f / nbsides, 0.f, 1.f, 0.f);
626    mat3 smat1 = mat3::rotate(sidemul * 180.0f / nbsides, 0.f, 1.f, 0.f);
627    mat3 smat2 = mat3::rotate(sidemul * -360.0f / nbsides, 0.f, 1.f, 0.f);
628
629    vec3 p[8];
630
631    p[0] = vec3(r1, h * .5f, 0.f);
632    p[1] = rotmat * p[0];
633    p[2] = smat1 * (rotmat * vec3(r1 + r12, h * .5f, 0.f));
634    p[3] = smat2 * (rotmat * p[2]);
635
636    p[4] = vec3(r2, h * -.5f, 0.f);
637    p[5] = rotmat * p[4];
638    p[6] = smat1 * (rotmat * vec3(r2 + r22, h * -.5f, 0.f));
639    p[7] = smat2 * (rotmat * p[6]);
640
641    if (offset & 1)
642        for (int n = 0; n < 8; n++)
643            p[n] = rotmat * p[n];
644
645    rotmat = rotmat * rotmat;
646
647    for (int i = 0; i < nbsides; i++)
648    {
649        /* Each vertex will share three faces, so three different
650         * normals, therefore we add each vertex three times. */
651        for (int n = 0; n < 24; n++)
652        {
653            AddVertex(p[n / 3]);
654            if (n / 3 >= 4)
655                SetCurVertColor(m_color2);
656        }
657
658        int j = 24 * i, k = 24 * ((i + 1) % nbsides);
659
660        /* The top and bottom faces */
661        AppendQuad(0, j + 2, j + 5, k + 2, vbase);
662        AppendQuad(1, k + 14, j + 17, j + 14, vbase);
663        AppendQuad(j + 5, j + 8, j + 11, k + 2, vbase);
664        AppendQuad(k + 14, j + 23, j + 20, j + 17, vbase);
665
666        /* The side quads */
667        AppendQuad(j + 6, j + 3, j + 15, j + 18, vbase);
668        AppendQuad(j + 9, j + 7, j + 19, j + 21, vbase);
669        AppendQuad(j + 12, j + 10, j + 22, j + 24, vbase);
670        AppendQuad(k + 4, j + 13, j + 25, k + 16, vbase);
671
672        for (int n = 0; n < 8; n++)
673            p[n] = rotmat * p[n];
674    }
675
676    ComputeNormals(ibase, m_indices.Count() - ibase);
677}
678
679void EasyMesh::Chamfer(float f)
680{
681    int vlen = m_vert.Count() - m_cursors.Last().m1;
682    int ilen = m_indices.Count() - m_cursors.Last().m2;
683
684    /* Step 1: enumerate all faces. This is done by merging triangles
685     * that are coplanar and share an edge. */
686    int *triangle_classes = new int[ilen / 3];
687    for (int i = 0; i < ilen / 3; i++)
688        triangle_classes[i] = -1;
689
690    for (int i = 0; i < ilen / 3; i++)
691    {
692         
693    }
694
695    /* Fun shit: reduce all triangles */
696    int *vertices = new int[vlen];
697    memset(vertices, 0, vlen * sizeof(int));
698    for (int i = 0; i < ilen; i++)
699        vertices[m_indices[i]]++;
700
701    for (int i = 0; i < ilen / 3; i++)
702    {
703    #if 0
704        if (vertices[m_indices[i * 3]] > 1)
705            continue;
706        if (vertices[m_indices[i * 3 + 1]] > 1)
707            continue;
708        if (vertices[m_indices[i * 3 + 2]] > 1)
709            continue;
710    #endif
711
712        vec3 bary = 1.f / 3.f * (m_vert[m_indices[i * 3]].m1 +
713                                 m_vert[m_indices[i * 3 + 1]].m1 +
714                                 m_vert[m_indices[i * 3 + 2]].m1);
715        for (int k = 0; k < 3; k++)
716        {
717            vec3 &p = m_vert[m_indices[i * 3 + k]].m1;
718            p -= normalize(p - bary) * f;
719        }
720    }
721}
722
723} /* namespace lol */
724
Note: See TracBrowser for help on using the repository browser.