source: trunk/src/easymesh/easymesh.h @ 2506

Last change on this file since 2506 was 2506, checked in by sam, 7 years ago

base: start removing occurrences of NULL on our long journey to nullptr.

File size: 29.2 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
5//            (c) 2009-2013 Cédric Lecacheur <jordx@free.fr>
6//            (c) 2009-2013 Benjamin "Touky" 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://www.wtfpl.net/ for more details.
11//
12
13//
14// The EasyMesh class
15// ------------------
16//
17
18#if !defined __EASYMESH_EASYMESH_H__
19#define __EASYMESH_EASYMESH_H__
20
21namespace lol
22{
23
24//Utility enum for renderers
25struct MeshRender
26{
27    enum Value
28    {
29        NeedInit,
30        CanRender,
31        IgnoreRender
32    }
33    m_value;
34
35    inline MeshRender(Value v) : m_value(v) {}
36    inline MeshRender() : m_value(NeedInit) {}
37    inline operator Value() { return m_value; }
38};
39
40//Vertex datas for easymesh vertex list.
41//TODO : <COORD, NORM, COLOR, UV>
42struct VertexData
43{
44    vec3    m_coord;
45    vec3    m_normal;
46    vec4    m_color;
47    vec4    m_texcoord;
48    ivec4   m_bone_id;
49    vec4    m_bone_weight;
50
51    VertexData(vec3  new_coord      = vec3(0.f),
52               vec3  new_normal     = vec3(0.f, 1.f, 0.f),
53               vec4  new_color      = vec4(0.f),
54               vec4  new_texcoord   = vec4(0.f),
55               ivec4 new_bone_id    = ivec4(0),
56               vec4  new_bone_weight= vec4(0.f))
57    {
58        m_coord         = new_coord;
59        m_normal        = new_normal;
60        m_color         = new_color;
61        m_texcoord      = new_texcoord;
62        m_bone_id       = new_bone_id;
63        m_bone_weight   = new_bone_weight;
64    }
65};
66
67//Base class to declare shader datas
68class GpuShaderData
69{
70    friend class GpuEasyMeshData;
71
72protected:
73    GpuShaderData();
74public:
75    //--
76    GpuShaderData(uint16_t vert_decl_flags, Shader* shader, DebugRenderMode render_mode);
77    ~GpuShaderData();
78    //--
79    void AddUniform(const lol::String &new_uniform);
80    void AddAttribute(const lol::String &new_attribute, VertexUsage usage, int index);
81    ShaderUniform const *GetUniform(const lol::String &uniform);
82    ShaderAttrib const *GetAttribute(const lol::String &attribute);
83    //--
84    virtual void SetupShaderDatas(mat4 const &model) { UNUSED(model); }
85
86protected:
87    uint16_t                            m_vert_decl_flags;
88    Shader*                             m_shader;
89    DebugRenderMode                     m_render_mode;
90    Array<lol::String, ShaderUniform>   m_shader_uniform;
91    Array<lol::String, ShaderAttrib>    m_shader_attrib;
92};
93
94class DefaultShaderData : public GpuShaderData
95{
96public:
97    //---
98    DefaultShaderData(DebugRenderMode render_mode);
99    DefaultShaderData(uint16_t vert_decl_flags, Shader* shader, bool with_UV);
100    //---
101    void SetupDefaultData(bool with_UV);
102    virtual void SetupShaderDatas(mat4 const &model);
103};
104
105class GpuEasyMeshData
106{
107public:
108    //---
109    GpuEasyMeshData();
110    ~GpuEasyMeshData();
111    //---
112    void AddGpuData(GpuShaderData* gpudata, class EasyMesh* src_mesh);
113    void RenderMeshData(mat4 const &model);
114
115private:
116    void SetupVertexData(uint16_t vdecl_flags, EasyMesh* src_mesh);
117
118    Array<GpuShaderData*>               m_gpudatas;
119    //uint16_t are the vdecl/vbo flags to avoid copy same vdecl several times.
120    Array<uint16_t, VertexDeclaration*,
121                    VertexBuffer*>      m_vdatas;
122    int                                 m_vertexcount;
123    //We only need only one ibo for the whole mesh
124    IndexBuffer *                       m_ibo;
125    int                                 m_indexcount;
126};
127
128
129struct MeshBuildOperation
130{
131    enum Value
132    {
133        //When this flag is up, negative scaling will not invert faces.
134        Scale_Winding   = 1 << 0,
135
136        All     = 0xffffffff
137    }
138    m_value;
139
140    inline MeshBuildOperation(Value v) : m_value(v) {}
141    inline MeshBuildOperation(uint64_t i) : m_value((Value)i) {}
142    inline operator Value() { return m_value; }
143};
144
145struct MeshType
146{
147    enum Value
148    {
149        Triangle = 0,
150        Quad,
151        Box,
152        Sphere,
153        Capsule,
154        Torus,
155        Cylinder,
156        Disc,
157        Star,
158        ExpandedStar,
159        Cog,
160
161        Max
162    }
163    m_value;
164
165    inline MeshType(Value v) : m_value(v) {}
166    inline operator Value() { return m_value; }
167};
168
169//TODO : Add other Build type
170struct TexCoordBuildType
171{
172    enum Value
173    {
174        TriangleDefault     = 0,
175        QuadDefault         = 0,
176        BoxDefault          = 0,
177        SphereDefault       = 0,
178        CapsuleDefault      = 0,
179        TorusDefault        = 0,
180        CylinderDefault     = 0,
181        DiscDefault         = 0,
182        StarDefault         = 0,
183        ExpandedStarDefault = 0,
184        CogDefault          = 0,
185
186        //NEVER FORGET TO INCREMENT THIS WHEN ADDING A VALUE
187        Max = 1
188    }
189    m_value;
190
191    inline TexCoordBuildType() : m_value(TriangleDefault) {}
192    inline TexCoordBuildType(Value v) : m_value(v) {}
193    inline TexCoordBuildType(int v) : m_value((Value)v) {}
194    inline operator Value() { return m_value; }
195};
196
197struct MeshFaceType
198{
199    enum Value
200    {
201        BoxFront = 0,
202        BoxLeft  = 1,
203        BoxBack  = 2,
204        BoxRight = 3,
205        BoxTop    = 4,
206        BoxBottom  = 5,
207        QuadDefault = 0,
208
209        //NEVER FORGET TO INCREMENT THIS WHEN ADDING A VALUE
210        Max = 6
211    }
212    m_value;
213
214    inline MeshFaceType(Value v) : m_value(v) {}
215    inline operator Value() { return m_value; }
216};
217
218struct TexCoordPos
219{
220    enum Value
221    {
222        BL, //BottomLeft
223        BR, //BottomRight
224        TL, //TopLeft
225        TR  //TopRight
226    }
227    m_value;
228
229    inline TexCoordPos(Value v) : m_value(v) {}
230    inline operator Value() { return m_value; }
231};
232
233class EasyMeshBuildData
234{
235public:
236    EasyMeshBuildData()
237    {
238        m_color = vec4(0.f, 0.f, 0.f, 1.f);
239        m_color2 = vec4(0.f, 0.f, 0.f, 1.f);
240        m_texcoord_offset = vec2(0.f);
241        m_texcoord_offset2 = vec2(0.f);
242        m_texcoord_scale = vec2(1.f);
243        m_texcoord_scale2 = vec2(1.f);
244        m_build_flags = 0;
245        for (int i = 0; i < MeshType::Max; ++i)
246        {
247            m_texcoord_build_type[i] = TexCoordBuildType::TriangleDefault;
248            m_texcoord_build_type2[i] = TexCoordBuildType::TriangleDefault;
249        }
250    }
251
252    inline vec4 &Color()           { return m_color; }
253    inline vec4 &Color2()          { return m_color2; }
254    inline vec2 &TexCoordOffset()  { return m_texcoord_offset; }
255    inline vec2 &TexCoordScale()   { return m_texcoord_scale; }
256    inline vec2 &TexCoordOffset2() { return m_texcoord_offset2; }
257    inline vec2 &TexCoordScale2()  { return m_texcoord_scale2; }
258
259    //UV1
260    void SetTexCoordBuildType(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type[mt] = (1 << (tcbt + 1)) | (m_texcoord_build_type[mt] & 1); }
261    TexCoordBuildType GetTexCoordBuildType(MeshType mt)
262    {
263        uint32_t flag = (uint32_t)((m_texcoord_build_type[mt] & ~(1)) >> 1);
264        int i = 0;
265        while (flag >>= 1)
266            i++;
267        return TexCoordBuildType(i);
268    }
269    void SetTexCoordCustomBuild(MeshType mt, MeshFaceType face, vec2 BL, vec2 TR)
270    {
271        if (face >= m_texcoord_custom_build[mt].Count())
272            m_texcoord_custom_build[mt].Resize(face + 1);
273        m_texcoord_custom_build[mt][face].m1 = BL;
274        m_texcoord_custom_build[mt][face].m2 = TR;
275        m_texcoord_build_type[mt] |= 1;
276    }
277    void ClearTexCoordCustomBuild(MeshType mt) { m_texcoord_build_type[mt] &= ~1; }
278    /* FIXME : Do something better ? */
279    vec2 TexCoord(MeshType mt, TexCoordPos tcp, MeshFaceType face)
280    {
281        vec2 BL = vec2(0.f);
282        vec2 TR = vec2(0.f);
283        if (m_texcoord_build_type[mt] & 1 && face < m_texcoord_custom_build[mt].Count())
284        {
285            BL = m_texcoord_custom_build[mt][face].m1;
286            TR = m_texcoord_custom_build[mt][face].m2;
287        }
288        else
289        {
290            /* unused for now, but will be if new BuildType are added. */
291            TexCoordBuildType tcbt = GetTexCoordBuildType(mt);
292            UNUSED(tcbt);
293            if (mt == MeshType::Triangle)
294                mt = mt;
295            else if (mt == MeshType::Quad)
296            {
297                //There's nothin' else than QuadDefault
298                BL = vec2(0.f);
299                TR = vec2(1.f);
300            }
301            else if (mt == MeshType::Box)
302            {
303                vec2 data[][2] =
304                { //TexCoordBuildType::BoxDefault
305                    { vec2(0.f), vec2(.5f) },
306                    { vec2(.5f, 0.f), vec2(1.f, .5f) },
307                    { vec2(0.f), vec2(.5f) },
308                    { vec2(.5f, 0.f), vec2(1.f, .5f) },
309                    { vec2(0.f, .5f), vec2(.5f, 1.f) },
310                    { vec2(.5f, .5f), vec2(1.f, 1.f) }
311                };
312                BL = data[face][0]; //[tcbt]
313                TR = data[face][1]; //[tcbt]
314            }
315            else if (mt == MeshType::Sphere)
316                mt = mt;
317            else if (mt == MeshType::Capsule)
318                mt = mt;
319            else if (mt == MeshType::Torus)
320                mt = mt;
321            else if (mt == MeshType::Cylinder)
322                mt = mt;
323            else if (mt == MeshType::Disc)
324                mt = mt;
325            else if (mt == MeshType::Star)
326                mt = mt;
327            else if (mt == MeshType::ExpandedStar)
328                mt = mt;
329            else if (mt == MeshType::Cog)
330                mt = mt;
331        }
332
333        vec2 res = vec2(.0f);
334        if (tcp == TexCoordPos::BL)
335            res = BL;
336        else if (tcp == TexCoordPos::BR)
337            res = vec2(TR.x, BL.y);
338        else if (tcp == TexCoordPos::TL)
339            res = vec2(BL.x, TR.y);
340        else if (tcp == TexCoordPos::TR)
341            res = TR;
342
343        return res * m_texcoord_scale + m_texcoord_offset2;
344    }
345
346    //UV2
347    void SetTexCoordBuildType2(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type2[mt] = (1 << (tcbt + 1)) | (m_texcoord_build_type2[mt] & 1); }
348    TexCoordBuildType GetTexCoordBuildType2(MeshType mt)
349    {
350        uint32_t flag = ((m_texcoord_build_type2[mt] & ~(1)) >> 1);
351        int i = 0;
352        while (flag >>= 1)
353            i++;
354        return TexCoordBuildType(i);
355    }
356    void SetTexCoordCustomBuild2(MeshType mt, MeshFaceType face, vec2 BL, vec2 TR)
357    {
358        if (face >= m_texcoord_custom_build2[mt].Count())
359            m_texcoord_custom_build2[mt].Resize(face + 1);
360        m_texcoord_custom_build2[mt][face].m1 = BL;
361        m_texcoord_custom_build2[mt][face].m2 = TR;
362        m_texcoord_build_type2[mt] |= 1;
363    }
364    void ClearTexCoordCustomBuild2(MeshType mt) { m_texcoord_build_type2[mt] &= ~1; }
365    vec2 TexCoord2(MeshType mt, TexCoordPos tcp, MeshFaceType face)
366    {
367        vec2 BL = vec2(0.f);
368        vec2 TR = vec2(0.f);
369        if (m_texcoord_build_type2[mt] & 1 && face < m_texcoord_custom_build2[mt].Count())
370        {
371            BL = m_texcoord_custom_build2[mt][face].m1;
372            TR = m_texcoord_custom_build2[mt][face].m2;
373        }
374        else
375        {
376            TexCoordBuildType tcbt = GetTexCoordBuildType2(mt);
377            UNUSED(tcbt);
378            if (mt == MeshType::Triangle)
379                mt = mt;
380            else if (mt == MeshType::Quad)
381            {
382                //There's nothin' else than QuadDefault
383                BL = vec2(0.f);
384                TR = vec2(1.f);
385            }
386            else if (mt == MeshType::Box)
387            {
388                vec2 data[][2] =
389                { //TexCoordBuildType::BoxDefault
390                    { vec2(0.f), vec2(.5f) },
391                    { vec2(.5f, 0.f), vec2(1.f, .5f) },
392                    { vec2(0.f), vec2(.5f) },
393                    { vec2(.5f, 0.f), vec2(1.f, .5f) },
394                    { vec2(0.f, .5f), vec2(.5f, 1.f) },
395                    { vec2(.5f, .5f), vec2(1.f, 1.f) }
396                };
397                BL = data[face][0]; //[tcbt]
398                TR = data[face][1]; //[tcbt]
399            }
400            else if (mt == MeshType::Sphere)
401                mt = mt;
402            else if (mt == MeshType::Capsule)
403                mt = mt;
404            else if (mt == MeshType::Torus)
405                mt = mt;
406            else if (mt == MeshType::Cylinder)
407                mt = mt;
408            else if (mt == MeshType::Disc)
409                mt = mt;
410            else if (mt == MeshType::Star)
411                mt = mt;
412            else if (mt == MeshType::ExpandedStar)
413                mt = mt;
414            else if (mt == MeshType::Cog)
415                mt = mt;
416        }
417
418        vec2 res = vec2(.0f);
419        if (tcp == TexCoordPos::BL)
420            res = BL;
421        else if (tcp == TexCoordPos::BR)
422            res = vec2(TR.x, BL.y);
423        else if (tcp == TexCoordPos::TL)
424            res = vec2(BL.x, TR.y);
425        else if (tcp == TexCoordPos::TR)
426            res = TR;
427
428        return res * m_texcoord_scale + m_texcoord_offset2;
429    }
430
431    inline bool IsEnabled(MeshBuildOperation mbo) { return (m_build_flags & mbo) != 0; }
432    inline void Enable(MeshBuildOperation mbo) { m_build_flags |= mbo; }
433    inline void Disable(MeshBuildOperation mbo) { m_build_flags &= ~mbo; }
434    inline void Toggle(MeshBuildOperation mbo) { m_build_flags ^= mbo; }
435    inline void Set(MeshBuildOperation mbo, bool value) { if (value) Enable(mbo); else Disable(mbo); }
436
437public:
438    vec4                m_color;
439    vec4                m_color2;
440    vec2                m_texcoord_offset;
441    vec2                m_texcoord_offset2;
442    vec2                m_texcoord_scale;
443    vec2                m_texcoord_scale2;
444    Array<vec2, vec2>   m_texcoord_custom_build[MeshType::Max];
445    Array<vec2, vec2>   m_texcoord_custom_build2[MeshType::Max];
446    uint32_t            m_texcoord_build_type[MeshType::Max];
447    uint32_t            m_texcoord_build_type2[MeshType::Max];
448    uint32_t            m_build_flags;
449};
450
451/* A safe enum for MeshCSG operations. */
452struct CSGUsage
453{
454    enum Value
455    {
456        Union,
457        Substract,
458        SubstractLoss, //will remove B from A, but not add inverted B
459        And,
460        Xor,
461    }
462    m_value;
463
464    inline CSGUsage(Value v) : m_value(v) {}
465    inline operator Value() { return m_value; }
466};
467
468/* A safe enum for VertexDictionnary operations. */
469struct VDictType
470{
471    enum Value
472    {
473        DoesNotExist=-3,
474        Alone=-2,
475        Master=-1
476    }
477    m_value;
478
479    inline VDictType(Value v) : m_value(v) {}
480    inline operator Value() { return m_value; }
481};
482
483/* TODO : replace VDict by a proper Half-edge system */
484//a class whose goal is to keep a list of the adjacent vertices for mesh operations purposes
485class VertexDictionnary
486{
487public:
488    int FindVertexMaster(const int search_idx);
489    bool FindMatchingVertices(const int search_idx, Array<int> &matching_ids);
490    bool FindConnectedVertices(const int search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_vert, Array<int> const *ignored_tri = nullptr);
491    bool FindConnectedTriangles(const int search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_tri, Array<int> const *ignored_tri = nullptr);
492    bool FindConnectedTriangles(const ivec2 &search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_tri, Array<int> const *ignored_tri = nullptr);
493    bool FindConnectedTriangles(const ivec3 &search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_tri, Array<int> const *ignored_tri = nullptr);
494    void AddVertex(int vert_id, vec3 vert_coord);
495    bool GetMasterList(Array<int> &ret_master_list) { ret_master_list = master_list; return ret_master_list.Count() > 0; }
496    void Clear() { vertex_list.Empty(); }
497private:
498    //<VertexId, VertexLocation, VertexMasterId>
499    Array<int, vec3, int>   vertex_list;
500    //List of the master_ vertices
501    Array<int>              master_list;
502};
503
504struct Axis
505{
506    enum Value
507    {
508        X,
509        Y,
510        Z
511    }
512    m_value;
513
514    inline Axis(Value v) : m_value(v) {}
515    inline operator Value() { return m_value; }
516};
517
518class EasyMesh
519{
520    friend class EasyMeshParser;
521
522public:
523    EasyMesh();
524
525    bool Compile(char const *command);
526    void MeshConvert(GpuShaderData* new_gpu_sdata);
527    void MeshConvert(Shader* ProvidedShader = nullptr);
528    void Render(mat4 const &model);
529
530private:
531    void UpdateVertexDict(Array< int, int > &vertex_dict);
532
533    //-------------------------------------------------------------------------
534    //Mesh CSG operations
535    //-------------------------------------------------------------------------
536private:
537    void MeshCsg(CSGUsage csg_operation);
538public:
539    /* [cmd:csgu] Performs a Union operation as (mesh0_Outside + mesh1_Outside) */
540    void CsgUnion()         { MeshCsg(CSGUsage::Union); }
541    /* [cmd:csgs] Performs a Substract operation as (mesh0_Outside + mesh1_Inside-inverted) */
542    void CsgSubstract()     { MeshCsg(CSGUsage::Substract); }
543    /* [cmd:csgsl] Performs a Substract operation without keeping the mesh1 part */
544    void CsgSubstractLoss() { MeshCsg(CSGUsage::SubstractLoss); }
545    /* [cmd:csga] Performs an And operation as (mesh0_Inside + mesh1_Inside) */
546    void CsgAnd()           { MeshCsg(CSGUsage::And); }
547    /* [cmd:csgx] Performs a Xor operation as (m0_Outside/m0_Inside-inverted + m1_Outside/m1_Inside-inverted) */
548    void CsgXor()           { MeshCsg(CSGUsage::Xor); }
549
550public:
551    /* [cmd:[] from this point onward, any operation will not be performed on previous vertices */
552    void OpenBrace();
553    /* [cmd:]] Merge current vertices with previous context */
554    void CloseBrace();
555    /* [cmd:tsw] When activation, on negative-scaling, normal fixing will not occur */
556    void ToggleScaleWinding();
557    /* [cmd:sc] Set vertices color */
558    void SetCurColor(vec4 const &color);
559    /* [cmd:scb] Set vertices color 2 */
560    void SetCurColor2(vec4 const &color);
561
562private:
563    //-------------------------------------------------------------------------
564    //Internal : Basic triangle/vertex operations
565    //-------------------------------------------------------------------------
566    void AddVertex(vec3 const &coord);
567    void AddDuplicateVertex(int i);
568    void AddLerpVertex(int i, int j, float alpha);
569    void AppendQuad(int i1, int i2, int i3, int i4, int base);
570    void AppendQuadDuplicateVerts(int i1, int i2, int i3, int i4, int base);
571    void AppendTriangle(int i1, int i2, int i3, int base);
572    void AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base);
573    void ComputeNormals(int start, int vcount);
574public: //DEBUG
575    void ComputeTexCoord(float uv_scale, int uv_offset);
576
577    //-------------------------------------------------------------------------
578    //Vertices operations
579    //-------------------------------------------------------------------------
580    void SetVertColor(vec4 const &color);
581    void SetTexCoordData(vec2 const &new_offset, vec2 const &new_scale);
582    void SetTexCoordData2(vec2 const &new_offset, vec2 const &new_scale);
583
584    void SetCurVertNormal(vec3 const &normal);
585    void SetCurVertColor(vec4 const &color);
586    void SetCurVertTexCoord(vec2 const &texcoord);
587    void SetCurVertTexCoord2(vec2 const &texcoord);
588
589public:
590    //-------------------------------------------------------------------------
591    //Mesh transform operations
592    //-------------------------------------------------------------------------
593
594    /* [cmd:t/tx/ty/tz] Translate vertices
595        - v : Translation quantity.
596     */
597    void Translate(vec3 const &v);
598    /* See Rotate */
599    void RotateX(float angle);
600    /* See Rotate */
601    void RotateY(float angle);
602    /* See Rotate */
603    void RotateZ(float angle);
604    /* [cmd:r/rx/ry/rz] Rotate vertices
605        - angle : rotation quantity.
606        - axis : rotation axis.
607     */
608    void Rotate(float angle, vec3 const &axis);
609    /* [cmd:rj] Randomly move vertices along Origin-to-vertex as o2v *= (1.0 + rand(r))
610        - r : jitter maximum value.
611     */
612    void RadialJitter(float r);
613    /* [cmd:tax] multiply axis y&z by x as y *= (1.0 + (ny * x + xoff))
614        - ny : value of n for y.
615        - nz : value of n for z.
616        - xoff : value of xoff.
617        - absolute (def:1) : if (1) Multiply will use an absolute x.
618     */
619    void TaperX(float ny, float nz, float xoff, int absolute=1);
620    /* [cmd:tay] Same as TaperX, with Y */
621    void TaperY(float nx, float nz, float yoff, int absolute=1);
622    /* [cmd:taz] Same as TaperX, with Z */
623    void TaperZ(float nx, float ny, float zoff, int absolute=1);
624    /* [cmd:twx] Twist vertices around x axis with x as rotation value as p = (RotateX(x * t + toff) * p)
625        - t : Angle multiplier.
626        - toff : Applied offset.
627     */
628    void TwistX(float t, float toff);
629    /* [cmd:twy] Same as TwistX, with Y */
630    void TwistY(float t, float toff);
631    /* [cmd:twz] Same as TwistX, with Z */
632    void TwistZ(float t, float toff);
633    /* [cmd:shx] Shear vertices using x value as shear quantity as y += (ny * x + xoff)
634        - ny : Value of n for y.
635        - nz : Value of n for z.
636        - xoff : Value of xoff.
637        - absolute (def:1) : if (1) Multiply will use an absolute x.
638     */
639    void ShearX(float ny, float nz, float xoff, int absolute=1);
640    /* [cmd:shy] Same as ShearX, with Y */
641    void ShearY(float nx, float nz, float yoff, int absolute=1);
642    /* [cmd:shz] Same as ShearX, with Z */
643    void ShearZ(float nx, float ny, float zoff, int absolute=1);
644    /* [cmd:stx] Stretch vertices using x value as stretch quantity as y += (pow(x, ny) + xoff)
645        - ny : Value of n for y.
646        - nz : Value of n for z.
647        - xoff : Value of xoff.
648     */
649    void StretchX(float ny, float nz, float xoff);
650    /* [cmd:sty] Same as StretchX, with Y */
651    void StretchY(float nx, float nz, float yoff);
652    /* [cmd:stz] Same as StretchX, with Z */
653    void StretchZ(float nx, float ny, float zoff);
654    /* [cmd:bdxy] Bend vertices using x as bend quantity along y axis using p = (RotateY(x * t + toff) * p)
655        - t : Angle multiplier.
656        - xoff : Applied offset.
657     */
658    void BendXY(float t, float toff);
659    /* [cmd:bdxz] Same as BendXY, with X & Z */
660    void BendXZ(float t, float toff);
661    /* [cmd:bdyx] Same as BendXY, with Y & X */
662    void BendYX(float t, float toff);
663    /* [cmd:bdyz] Same as BendXY, with Y & Z */
664    void BendYZ(float t, float toff);
665    /* [cmd:bdzx] Same as BendXY, with Z & X */
666    void BendZX(float t, float toff);
667    /* [cmd:bdzy] Same as BendXY, with Z & Y */
668    void BendZY(float t, float toff);
669private:
670    struct MeshTransform
671    {
672        enum Value
673        {
674            Taper,
675            Twist,
676            Bend,
677            Stretch,
678            Shear
679        }
680        m_value;
681
682        inline MeshTransform(Value v) : m_value(v) {}
683        inline operator Value() { return m_value; }
684    };
685    void DoMeshTransform(MeshTransform ct, Axis axis0, Axis axis1, float n0, float n1, float noff, int absolute);
686public:
687    /* [cmd:s/sx/sy/sz] Scale vertices
688        - s : scale quantity.
689     */
690    void Scale(vec3 const &s);
691    /* [cmd:mx] Mirror vertices through X-plane
692        Acts as an OpenBrace
693     */
694    void MirrorX();
695    /* [cmd:my] Mirror vertices through Y-plane
696        Acts as an OpenBrace
697     */
698    void MirrorY();
699    /* [cmd:mz] Mirror vertices through Z-plane
700        Acts as an OpenBrace
701     */
702    void MirrorZ();
703    /* [no-cmd] Duplicates vertices and scale duplicate
704        Acts as an OpenBrace
705     */
706    void DupAndScale(vec3 const &s);
707    /* [cmd:ch] Performs a chamfer operation //TODO : Make it work.
708        - f : Chamfer quantity.
709     */
710    void Chamfer(float f);
711    /* [cmd:splt] split triangles in 4 smaller ones.
712        - pass : Number of pass applied.
713     */
714    void SplitTriangles(int pass);
715private:
716    void SplitTriangles(int pass, VertexDictionnary *vert_dict);
717public:
718    /* [cmd:smth] Smooth the mesh by subdivising it.
719        - main_pass : a main pass is made of (n0 split then n1 smooth) repeat.
720        - split_per_main_pass : n0 value in above explanation.
721        - smooth_per_main_pass : n1 value in above explanation.
722     */
723    void SmoothMesh(int main_pass, int split_per_main_pass, int smooth_per_main_pass);
724
725    //-------------------------------------------------------------------------
726    //Mesh shape operations
727    //-------------------------------------------------------------------------
728
729    /* [cmd:ac] Cylinder centered on (0,0,0) with BBox [-.5*max(d1, d2), -.5*h, -.5*max(d1, d2)]
730        - nbsides : Number of sides.                   [+.5*max(d1, d2), +.5*h, +.5*max(d1, d2)]
731        - h : Height of the cylinder.
732        - d1 : Lower diameter.
733        - d2 : Upper diameter.
734        - dualside : if (1) will also create inner sides : TOOD:TOREMOVE?? : needed ?
735        - smooth : if (1) will smooth normals : TOOD:TOREMOVE : smooth should be handled elsewhere
736        - close : if (1) will add discs to close the cylinder
737     */
738    void AppendCylinder(int nsides, float h, float d1, float d2,
739                        int dualside, int smooth, int close);
740    /* [cmd:asph] Sphere centered on (0,0,0) with BBox [-.5*d][.5*d]
741        - ndivisions : number of subdivisions each Sphere triangle will sustain.
742        - d : Diameter.
743     */
744    void AppendSphere(int ndivisions, float d);
745    /* [cmd:acap] Capsule centered on (0,0,0) with BBox [-.5*d, -(.5*d+h), -.5*d][.5*d, (.5*d+h), .5*d]
746        - ndivisions : number of subdivisions each Sphere triangle will sustain.
747        - h : Inner height.
748        - d : Diameter.
749     */
750    void AppendCapsule(int ndivisions, float h, float d);
751    /* [cmd:ato] Torus centered on (0,0,0) with BBox [-.5*d2][.5*d2]
752        - ndivisions : number of subdivisions of the torus.
753        - d1 : Inner diameter.
754        - d2 : Outer diameter.
755     */
756    void AppendTorus(int ndivisions, float d1, float d2);
757    /* [cmd:ab] Box centered on (0,0,0) with BBox [-.5 * size][.5 * size]
758        - size : size of the box.
759        - chamf : size of the chamfer.
760        - smooth : if (1) will smooth normals : TOOD:TOREMOVE : smooth should be handled elsewhere
761     */
762    void AppendBox(vec3 const &size, float chamf = 0.f);
763    //Same as AppendBox
764    void AppendSmoothChamfBox(vec3 const &size, float chamf);
765    //Same as AppendBox
766    void AppendFlatChamfBox(vec3 const &size, float chamf);
767    //Same as AppendBox
768    void AppendBox(vec3 const &size, float chamf, bool smooth);
769    /* [cmd:as]
770       Append a Star centered on (0,0,0) contained within a disc of "max(d1, d2)" diameter.
771        - nbranches : Number of branches.
772        - d1 : double Length of the branches.
773        - d2 : double Length of the "branch" located between d1-branches.
774        - fade : if (1) in-between branches use Color2.
775        - fade2 : if (1) Star branches use Color2.
776     */
777    void AppendStar(int nbranches, float d1, float d2,
778                    int fade = 0, int fade2 = 0);
779    /* [cmd:aes] Star centered on (0,0,0) contained within a disc of "max(max(d1, d2), max(d1 + extrad, d2 + extrad))" diameter.
780       Expanded star branches use Color2.
781        - nbranches : Number of branches.
782        - d1 : Double Length of the branches.
783        - d2 : Double Length of the "branch" located between r1-branches.
784        - extrad : Extra length added to expand all branches.
785     */
786    void AppendExpandedStar(int nbranches, float d1, float d2, float extrad);
787    /* [cmd:ad] Disc centered on (0,0,0) with d diameter.
788        - nbsides : Number of sides.
789        - d : Diameter.
790        - fade : if (1) Outer vertices will use Color2
791     */
792    void AppendDisc(int nsides, float d, int fade = 0);
793    /* [cmd:at] Triangle centered on (0,0,0) contained within a disc of "d" diameter.
794        - d : diameter of the containing disc..
795        - fade : if (1) 2nd & 3rd Vertices will use Color2
796     */
797    void AppendSimpleTriangle(float d, int fade = 0);
798    /* [cmd:aq] Quad centered on (0,0,0) contained within BBox [-size*.5f, 0, -size*.5f][size*.5f, 0, size*.5f]
799        - size : Size of quad.
800        - fade : if (1) 3rd & 4th Vertices will use Color2
801     */
802    void AppendSimpleQuad(float size, int fade = 0);
803private:
804    //complex version of above one
805    void AppendSimpleQuad(vec2 p1, vec2 p2, float z = 0.f, int fade = 0);
806public:
807    /* [cmd:acg] Gear centered on (0,0,0) contained within BBox [-.5*max(d1,d2), -.5*h, -.5*max(d1, d2)]
808        - h : Height of the Gear.                               [+.5*max(d1,d2), +.5*h, +.5*max(d1, d2)]
809        - d10 : Upper Inner diameter.
810        - d20 : Lower Inner diameter.
811        - d1  : Upper Outer diameter.
812        - d2  : Lower Outer diameter.
813        - d12 : Upper Cog diameter.
814        - d22 : Lower Cog diameter.
815        - sidemul : multiplier for the size of the cogs.
816        - offset : useless
817     */
818    void AppendCog(int nbsides, float h, float d10, float d20, float d1,
819                   float d2, float d12, float d22, float sidemul, int offset);
820
821    //-------------------------------------------------------------------------
822    //TODO : Mesh Bone operations
823    //-------------------------------------------------------------------------
824    //void AddBone(int parent_id) {}
825
826    //Convenience functions
827public:
828    int GetVertexCount() { return m_vert.Count(); }
829    vec3 const &GetVertexLocation(int i) { return m_vert[i].m_coord; }
830
831private:
832    Array<uint16_t> m_indices;
833    Array<VertexData> m_vert;
834
835    //<vert count, indices count>
836    Array<int, int> m_cursors;
837
838    friend class GpuEasyMeshData;
839    GpuEasyMeshData m_gpu_data;
840
841public:
842    inline EasyMeshBuildData* BD()
843    {
844        if (!m_build_data)
845            m_build_data = new EasyMeshBuildData();
846        return m_build_data;
847    };
848private:
849    class EasyMeshBuildData* m_build_data;
850};
851} /* namespace lol */
852
853#endif /* __EASYMESH_EASYMESH_H__ */
854
Note: See TracBrowser for help on using the repository browser.