|
- //
- // Lol Engine
- //
- // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
- // (c) 2009-2013 Cédric Lecacheur <jordx@free.fr>
- // (c) 2009-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the Do What The Fuck You Want To
- // Public License, Version 2, as published by Sam Hocevar. See
- // http://www.wtfpl.net/ for more details.
- //
-
- //
- // The EasyMesh class
- // ------------------
- //
-
- #if !defined __EASYMESH_EASYMESH_H__
- #define __EASYMESH_EASYMESH_H__
-
- namespace lol
- {
-
- //Utility struct to convert command code to pseudo-bytecode
- struct CommandStack
- {
- private:
- Array<int, int, int> m_commands;
- Array<float> m_floats;
- Array<int> m_ints;
- int m_f_cur;
- int m_i_cur;
-
- public:
- //cmd storage
- void AddCmd(int cmd) { m_commands.Push(cmd, m_floats.Count(), m_ints.Count()); }
- int GetCmdNb() { return m_commands.Count(); }
- int GetCmd(int i)
- {
- ASSERT(0 <= i && i < m_commands.Count());
- m_f_cur = m_commands[i].m2;
- m_i_cur = m_commands[i].m3;
- return m_commands[i].m1;
- }
-
- //GETTER
- inline float F() { return m_floats[m_f_cur++]; }
- inline int I() { return m_ints[m_i_cur++]; }
- inline int E() { return I(); }
- inline bool B() { return !!I(); }
- inline vec2 V2() { vec2 v(F()); v.y = F(); return v; }
- inline vec3 V3() { vec3 v(V2(), 0.f); v.z = F(); return v; }
- inline vec4 V4() { vec4 v(V3(), 0.f); v.w = F(); return v; }
- inline ivec2 IV2() { ivec2 v(I()); v.y = I(); return v; }
- inline ivec3 IV3() { ivec3 v(IV2(), 0); v.z = I(); return v; }
- inline ivec4 IV4() { ivec4 v(IV3(), 0); v.w = I(); return v; }
-
- //Alternate getters
- inline void GetValue(float &f) { f = F(); }
- inline void GetValue(int &i) { i = I(); }
- inline void GetValue(bool &b) { b = B(); }
- inline void GetValue(vec2 &v2) { v2 = V2(); }
- inline void GetValue(vec3 &v3) { v3 = V3(); }
- inline void GetValue(vec4 &v4) { v4 = V4(); }
- inline void GetValue(ivec2 &iv2) { iv2 = IV2(); }
- inline void GetValue(ivec3 &iv3) { iv3 = IV3(); }
- inline void GetValue(ivec4 &iv4) { iv4 = IV4(); }
- //For Safe Enum
- template< class T > inline
- void GetValue(T &i) { i = T((typename T::Value)I()); }
-
- //SETTER
- CommandStack &operator<<(int i) { m_ints << i; return *this; }
- CommandStack &operator<<(float f) { m_floats << f; return *this; }
- CommandStack &operator<<(bool b) { return (*this << (int)b); }
- CommandStack &operator<<(vec2 v) { return (*this << v.x << v.y); }
- CommandStack &operator<<(vec3 v) { return (*this << v.xy << v.z); }
- CommandStack &operator<<(vec4 v) { return (*this << v.xyz << v.w); }
- CommandStack &operator<<(ivec2 iv) { return (*this << iv.x << iv.y); }
- CommandStack &operator<<(ivec3 iv) { return (*this << iv.xy << iv.z); }
- CommandStack &operator<<(ivec4 iv) { return (*this << iv.xyz << iv.w); }
- };
-
- //Utility enum for renderers
- struct MeshRender
- {
- enum Value
- {
- NeedData,
- NeedConvert,
- CanRender,
- IgnoreRender,
-
- Max
- }
- m_value;
-
- inline MeshRender(Value v) : m_value(v) {}
- inline MeshRender() : m_value(NeedData) {}
- inline operator Value() { return m_value; }
- };
-
- //Vertex datas for easymesh vertex list.
- //TODO : <COORD, NORM, COLOR, UV>
- struct VertexData
- {
- vec3 m_coord;
- vec3 m_normal;
- vec4 m_color;
- vec4 m_texcoord;
- ivec4 m_bone_id;
- vec4 m_bone_weight;
-
- VertexData(vec3 new_coord = vec3(0.f),
- vec3 new_normal = vec3(0.f, 1.f, 0.f),
- vec4 new_color = vec4(0.f),
- vec4 new_texcoord = vec4(0.f),
- ivec4 new_bone_id = ivec4(0),
- vec4 new_bone_weight= vec4(0.f))
- {
- m_coord = new_coord;
- m_normal = new_normal;
- m_color = new_color;
- m_texcoord = new_texcoord;
- m_bone_id = new_bone_id;
- m_bone_weight = new_bone_weight;
- }
- };
-
- //Base class to declare shader datas
- class GpuShaderData
- {
- friend class GpuEasyMeshData;
-
- protected:
- GpuShaderData();
- public:
- //--
- GpuShaderData(uint16_t vert_decl_flags, Shader* shader, DebugRenderMode render_mode);
- virtual ~GpuShaderData();
- //--
- void AddUniform(const lol::String &new_uniform);
- void AddAttribute(VertexUsage usage, int index);
- ShaderUniform const *GetUniform(const lol::String &uniform);
- ShaderAttrib const *GetAttribute(VertexUsage usage, int index);
- //--
- virtual void SetupShaderDatas(mat4 const &model) { UNUSED(model); }
- //--
-
- protected:
- uint16_t m_vert_decl_flags;
- Shader* m_shader;
- DebugRenderMode m_render_mode;
- Array<lol::String, ShaderUniform> m_shader_uniform;
- Array<ShaderAttrib> m_shader_attrib;
- };
-
- class DefaultShaderData : public GpuShaderData
- {
- public:
- //---
- DefaultShaderData(DebugRenderMode render_mode);
- DefaultShaderData(uint16_t vert_decl_flags, Shader* shader, bool with_UV);
- virtual ~DefaultShaderData() {}
- void StoreUniformNames();
- //---
- void SetupDefaultData(bool with_UV);
- virtual void SetupShaderDatas(mat4 const &model);
- //--
- Array<String> m_uniform_names;
- };
-
- class GpuEasyMeshData
- {
- friend class EasyMesh;
-
- public:
- //---
- GpuEasyMeshData();
- ~GpuEasyMeshData();
- //---
- void AddGpuData(GpuShaderData* gpudata, class EasyMesh* src_mesh);
- void RenderMeshData(mat4 const &model);
-
- private:
- void SetupVertexData(uint16_t vdecl_flags, EasyMesh* src_mesh);
-
- Array<GpuShaderData*> m_gpudatas;
- //uint16_t are the vdecl/vbo flags to avoid copy same vdecl several times.
- Array<uint16_t, VertexDeclaration*,
- VertexBuffer*> m_vdatas;
- int m_vertexcount;
- //We only need only one ibo for the whole mesh
- IndexBuffer * m_ibo;
- int m_indexcount;
- };
-
-
- struct MeshBuildOperation
- {
- enum Value
- {
- //When this flag is up, negative scaling will not invert faces.
- ScaleWinding = (1 << 0),
- CommandRecording = (1 << 1),
- CommandExecution = (1 << 2),
- QuadWeighting = (1 << 3),
- IgnoreQuadWeighting = (1 << 4),
-
- All = 0xffffffff
- }
- m_value;
-
- inline MeshBuildOperation(Value v) : m_value(v) {}
- inline MeshBuildOperation(uint64_t i) : m_value((Value)i) {}
- inline operator Value() { return m_value; }
- };
-
- struct EasyMeshCmdType
- {
- enum Value
- {
- MeshCsg = 0,
-
- LoopStart,
- LoopEnd,
- OpenBrace,
- CloseBrace,
-
- ScaleWinding,
- QuadWeighting,
- SetColorA,
- SetColorB,
- SetVertColor,
-
- Translate,
- Rotate,
- RadialJitter,
- MeshTranform,
- Scale,
- DupAndScale,
- Chamfer,
-
- SplitTriangles,
- SmoothMesh,
-
- AppendCylinder,
- AppendCapsule,
- AppendTorus,
- AppendBox,
- AppendStar,
- AppendExpandedStar,
- AppendDisc,
- AppendSimpleTriangle,
- AppendSimpleQuad,
- AppendCog,
-
- Max
- }
- m_value;
-
- inline EasyMeshCmdType(Value v) : m_value(v) {}
- inline operator Value() { return m_value; }
- inline int Value() { return m_value; }
- };
-
-
- struct MeshType
- {
- enum Value
- {
- Triangle = 0,
- Quad,
- Box,
- Sphere,
- Capsule,
- Torus,
- Cylinder,
- Disc,
- Star,
- ExpandedStar,
- Cog,
-
- Max
- }
- m_value;
-
- inline MeshType(Value v) : m_value(v) {}
- inline operator Value() { return m_value; }
- };
-
- //TODO : Add other Build type
- struct TexCoordBuildType
- {
- enum Value
- {
- TriangleDefault = 0,
- QuadDefault = 0,
- BoxDefault = 0,
- SphereDefault = 0,
- CapsuleDefault = 0,
- TorusDefault = 0,
- CylinderDefault = 0,
- DiscDefault = 0,
- StarDefault = 0,
- ExpandedStarDefault = 0,
- CogDefault = 0,
-
- //NEVER FORGET TO INCREMENT THIS WHEN ADDING A VALUE
- Max = 1
- }
- m_value;
-
- inline TexCoordBuildType() : m_value(TriangleDefault) {}
- inline TexCoordBuildType(Value v) : m_value(v) {}
- inline TexCoordBuildType(int v) : m_value((Value)v) {}
- inline operator Value() { return m_value; }
- };
-
- struct MeshFaceType
- {
- enum Value
- {
- BoxFront = 0,
- BoxLeft = 1,
- BoxBack = 2,
- BoxRight = 3,
- BoxTop = 4,
- BoxBottom = 5,
- QuadDefault = 0,
-
- //NEVER FORGET TO INCREMENT THIS WHEN ADDING A VALUE
- Max = 6
- }
- m_value;
-
- inline MeshFaceType(Value v) : m_value(v) {}
- inline operator Value() { return m_value; }
- };
-
- struct TexCoordPos
- {
- enum Value
- {
- BL, //BottomLeft
- BR, //BottomRight
- TL, //TopLeft
- TR //TopRight
- }
- m_value;
-
- inline TexCoordPos(Value v) : m_value(v) {}
- inline operator Value() { return m_value; }
- };
-
- class EasyMeshBuildData
- {
- public:
- EasyMeshBuildData()
- {
- m_color_a = vec4(0.f, 0.f, 0.f, 1.f);
- m_color_b = vec4(0.f, 0.f, 0.f, 1.f);
- m_texcoord_offset = vec2(0.f);
- m_texcoord_offset2 = vec2(0.f);
- m_texcoord_scale = vec2(1.f);
- m_texcoord_scale2 = vec2(1.f);
- m_build_flags = 0;
- for (int i = 0; i < MeshType::Max; ++i)
- {
- m_texcoord_build_type[i] = TexCoordBuildType::TriangleDefault;
- m_texcoord_build_type2[i] = TexCoordBuildType::TriangleDefault;
- }
- }
-
- inline CommandStack &CmdStack() { return m_stack; }
- inline int &Cmdi() { return m_cmd_i; }
- inline Array<int, int> &LoopStack(){ return m_loop_stack; }
- inline vec4 &ColorA() { return m_color_a; }
- inline vec4 &ColorB() { return m_color_b; }
- inline vec2 &TexCoordOffset() { return m_texcoord_offset; }
- inline vec2 &TexCoordScale() { return m_texcoord_scale; }
- inline vec2 &TexCoordOffset2() { return m_texcoord_offset2; }
- inline vec2 &TexCoordScale2() { return m_texcoord_scale2; }
-
- //UV1
- void SetTexCoordBuildType(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type[mt] = (1 << (tcbt + 1)) | (m_texcoord_build_type[mt] & 1); }
- TexCoordBuildType GetTexCoordBuildType(MeshType mt)
- {
- uint32_t flag = (uint32_t)((m_texcoord_build_type[mt] & ~(1)) >> 1);
- int i = 0;
- while (flag >>= 1)
- i++;
- return TexCoordBuildType(i);
- }
- void SetTexCoordCustomBuild(MeshType mt, MeshFaceType face, vec2 BL, vec2 TR)
- {
- if (face >= m_texcoord_custom_build[mt].Count())
- m_texcoord_custom_build[mt].Resize(face + 1);
- m_texcoord_custom_build[mt][face].m1 = BL;
- m_texcoord_custom_build[mt][face].m2 = TR;
- m_texcoord_build_type[mt] |= 1;
- }
- void ClearTexCoordCustomBuild(MeshType mt) { m_texcoord_build_type[mt] &= ~1; }
- /* FIXME : Do something better ? */
- vec2 TexCoord(MeshType mt, TexCoordPos tcp, MeshFaceType face)
- {
- vec2 BL = vec2(0.f);
- vec2 TR = vec2(0.f);
- if (m_texcoord_build_type[mt] & 1 && face < m_texcoord_custom_build[mt].Count())
- {
- BL = m_texcoord_custom_build[mt][face].m1;
- TR = m_texcoord_custom_build[mt][face].m2;
- }
- else
- {
- /* unused for now, but will be if new BuildType are added. */
- TexCoordBuildType tcbt = GetTexCoordBuildType(mt);
- UNUSED(tcbt);
- if (mt == MeshType::Triangle)
- mt = mt;
- else if (mt == MeshType::Quad)
- {
- //There's nothin' else than QuadDefault
- BL = vec2(0.f);
- TR = vec2(1.f);
- }
- else if (mt == MeshType::Box)
- {
- vec2 data[][2] =
- { //TexCoordBuildType::BoxDefault
- { vec2(0.f), vec2(.5f) },
- { vec2(.5f, 0.f), vec2(1.f, .5f) },
- { vec2(0.f), vec2(.5f) },
- { vec2(.5f, 0.f), vec2(1.f, .5f) },
- { vec2(0.f, .5f), vec2(.5f, 1.f) },
- { vec2(.5f, .5f), vec2(1.f, 1.f) }
- };
- BL = data[face][0]; //[tcbt]
- TR = data[face][1]; //[tcbt]
- }
- else if (mt == MeshType::Sphere)
- mt = mt;
- else if (mt == MeshType::Capsule)
- mt = mt;
- else if (mt == MeshType::Torus)
- mt = mt;
- else if (mt == MeshType::Cylinder)
- mt = mt;
- else if (mt == MeshType::Disc)
- mt = mt;
- else if (mt == MeshType::Star)
- mt = mt;
- else if (mt == MeshType::ExpandedStar)
- mt = mt;
- else if (mt == MeshType::Cog)
- mt = mt;
- }
-
- vec2 res = vec2(.0f);
- if (tcp == TexCoordPos::BL)
- res = BL;
- else if (tcp == TexCoordPos::BR)
- res = vec2(TR.x, BL.y);
- else if (tcp == TexCoordPos::TL)
- res = vec2(BL.x, TR.y);
- else if (tcp == TexCoordPos::TR)
- res = TR;
-
- return res * m_texcoord_scale + m_texcoord_offset2;
- }
-
- //UV2
- void SetTexCoordBuildType2(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type2[mt] = (1 << (tcbt + 1)) | (m_texcoord_build_type2[mt] & 1); }
- TexCoordBuildType GetTexCoordBuildType2(MeshType mt)
- {
- uint32_t flag = ((m_texcoord_build_type2[mt] & ~(1)) >> 1);
- int i = 0;
- while (flag >>= 1)
- i++;
- return TexCoordBuildType(i);
- }
- void SetTexCoordCustomBuild2(MeshType mt, MeshFaceType face, vec2 BL, vec2 TR)
- {
- if (face >= m_texcoord_custom_build2[mt].Count())
- m_texcoord_custom_build2[mt].Resize(face + 1);
- m_texcoord_custom_build2[mt][face].m1 = BL;
- m_texcoord_custom_build2[mt][face].m2 = TR;
- m_texcoord_build_type2[mt] |= 1;
- }
- void ClearTexCoordCustomBuild2(MeshType mt) { m_texcoord_build_type2[mt] &= ~1; }
- vec2 TexCoord2(MeshType mt, TexCoordPos tcp, MeshFaceType face)
- {
- vec2 BL = vec2(0.f);
- vec2 TR = vec2(0.f);
- if (m_texcoord_build_type2[mt] & 1 && face < m_texcoord_custom_build2[mt].Count())
- {
- BL = m_texcoord_custom_build2[mt][face].m1;
- TR = m_texcoord_custom_build2[mt][face].m2;
- }
- else
- {
- TexCoordBuildType tcbt = GetTexCoordBuildType2(mt);
- UNUSED(tcbt);
- if (mt == MeshType::Triangle)
- mt = mt;
- else if (mt == MeshType::Quad)
- {
- //There's nothin' else than QuadDefault
- BL = vec2(0.f);
- TR = vec2(1.f);
- }
- else if (mt == MeshType::Box)
- {
- vec2 data[][2] =
- { //TexCoordBuildType::BoxDefault
- { vec2(0.f), vec2(.5f) },
- { vec2(.5f, 0.f), vec2(1.f, .5f) },
- { vec2(0.f), vec2(.5f) },
- { vec2(.5f, 0.f), vec2(1.f, .5f) },
- { vec2(0.f, .5f), vec2(.5f, 1.f) },
- { vec2(.5f, .5f), vec2(1.f, 1.f) }
- };
- BL = data[face][0]; //[tcbt]
- TR = data[face][1]; //[tcbt]
- }
- else if (mt == MeshType::Sphere)
- mt = mt;
- else if (mt == MeshType::Capsule)
- mt = mt;
- else if (mt == MeshType::Torus)
- mt = mt;
- else if (mt == MeshType::Cylinder)
- mt = mt;
- else if (mt == MeshType::Disc)
- mt = mt;
- else if (mt == MeshType::Star)
- mt = mt;
- else if (mt == MeshType::ExpandedStar)
- mt = mt;
- else if (mt == MeshType::Cog)
- mt = mt;
- }
-
- vec2 res = vec2(.0f);
- if (tcp == TexCoordPos::BL)
- res = BL;
- else if (tcp == TexCoordPos::BR)
- res = vec2(TR.x, BL.y);
- else if (tcp == TexCoordPos::TL)
- res = vec2(BL.x, TR.y);
- else if (tcp == TexCoordPos::TR)
- res = TR;
-
- return res * m_texcoord_scale + m_texcoord_offset2;
- }
-
- inline bool IsEnabled(MeshBuildOperation mbo) { return (m_build_flags & mbo) != 0; }
- inline void Enable(MeshBuildOperation mbo) { m_build_flags |= mbo; }
- inline void Disable(MeshBuildOperation mbo) { m_build_flags &= ~mbo; }
- inline void Toggle(MeshBuildOperation mbo) { m_build_flags ^= mbo; }
- inline void Set(MeshBuildOperation mbo, bool value) { if (value) Enable(mbo); else Disable(mbo); }
-
- public:
- CommandStack m_stack;
- int m_cmd_i;
- Array<int, int> m_loop_stack;
- vec4 m_color_a;
- vec4 m_color_b;
- vec2 m_texcoord_offset;
- vec2 m_texcoord_offset2;
- vec2 m_texcoord_scale;
- vec2 m_texcoord_scale2;
- Array<vec2, vec2> m_texcoord_custom_build[MeshType::Max];
- Array<vec2, vec2> m_texcoord_custom_build2[MeshType::Max];
- uint32_t m_texcoord_build_type[MeshType::Max];
- uint32_t m_texcoord_build_type2[MeshType::Max];
- uint32_t m_build_flags;
- };
-
- /* A safe enum for MeshCSG operations. */
- struct CSGUsage
- {
- enum Value
- {
- Union = 0,
- Substract,
- SubstractLoss, //will remove B from A, but not add inverted B
- And,
- Xor,
-
- Max
- }
- m_value;
-
- inline CSGUsage() : m_value(Union) {}
- inline CSGUsage(Value v) : m_value(v) {}
- inline CSGUsage(int v) : m_value((Value)v) {}
- inline operator Value() { return m_value; }
- };
-
- /* A safe enum for VertexDictionnary operations. */
- struct VDictType
- {
- enum Value
- {
- DoesNotExist=-3,
- Alone=-2,
- Master=-1
- }
- m_value;
-
- inline VDictType(Value v) : m_value(v) {}
- inline operator Value() { return m_value; }
- };
-
- /* TODO : replace VDict by a proper Half-edge system */
- //a class whose goal is to keep a list of the adjacent vertices for mesh operations purposes
- class VertexDictionnary
- {
- public:
- int FindVertexMaster(const int search_idx);
- bool FindMatchingVertices(const int search_idx, Array<int> &matching_ids);
- 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);
- 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);
- 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);
- 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);
- void AddVertex(int vert_id, vec3 vert_coord);
- bool GetMasterList(Array<int> &ret_master_list) { ret_master_list = master_list; return ret_master_list.Count() > 0; }
- void Clear() { vertex_list.Empty(); }
- private:
- //<VertexId, VertexLocation, VertexMasterId>
- Array<int, vec3, int> vertex_list;
- //List of the master_ vertices
- Array<int> master_list;
- };
-
- struct Axis
- {
- enum Value
- {
- X,
- Y,
- Z
- }
- m_value;
-
- inline Axis() : m_value(X) {}
- inline Axis(Value v) : m_value(v) {}
- inline operator Value() { return m_value; }
- };
-
- class EasyMesh
- {
- friend class EasyMeshParser;
- friend class GpuEasyMeshData;
-
- public:
- EasyMesh();
- EasyMesh(const EasyMesh& em);
-
- bool Compile(char const *command);
- void ExecuteCmdStack();
- void MeshConvert(GpuShaderData* new_gpu_sdata);
- void MeshConvert(Shader* ProvidedShader = nullptr);
- bool Render(mat4 const &model);
- MeshRender GetMeshState() { return m_state; }
- bool SetRender(bool should_render);
-
- private:
- void UpdateVertexDict(Array< int, int > &vertex_dict);
-
- //-------------------------------------------------------------------------
- //Mesh CSG operations
- //-------------------------------------------------------------------------
- private:
- void MeshCsg(CSGUsage csg_operation);
- public:
- /* [cmd:csgu] Performs a Union operation as (mesh0_Outside + mesh1_Outside) */
- void CsgUnion() { MeshCsg(CSGUsage::Union); }
- /* [cmd:csgs] Performs a Substract operation as (mesh0_Outside + mesh1_Inside-inverted) */
- void CsgSub() { MeshCsg(CSGUsage::Substract); }
- /* [cmd:csgsl] Performs a Substract operation without keeping the mesh1 part */
- void CsgSubL() { MeshCsg(CSGUsage::SubstractLoss); }
- /* [cmd:csga] Performs an And operation as (mesh0_Inside + mesh1_Inside) */
- void CsgAnd() { MeshCsg(CSGUsage::And); }
- /* [cmd:csgx] Performs a Xor operation as (m0_Outside/m0_Inside-inverted + m1_Outside/m1_Inside-inverted) */
- void CsgXor() { MeshCsg(CSGUsage::Xor); }
-
- //-------------------------------------------------------------------------
- //Mesh Base operations
- //-------------------------------------------------------------------------
- public:
- /* [cmd:lp[ ]] will perform a loop of loopnb */
- void LoopStart(int loopnb);
- /* No cmd, implicit ] */
- void LoopEnd();
- /* [cmd:[] from this point onward, any operation will not be performed on previous vertices */
- void OpenBrace();
- /* [cmd:]] Merge current vertices with previous context */
- void CloseBrace();
- /* [cmd:tsw] When active, on negative-scaling, normal-vector correction will not occur */
- void ToggleScaleWinding();
- /* [cmd:tqw] When active, quad will have a fifth center vertex */
- void ToggleQuadWeighting();
- /* [cmd:sc] Set both color */
- void SetCurColor(vec4 const &color);
- /* [cmd:sca] Set base color A */
- void SetCurColorA(vec4 const &color);
- /* [cmd:scb] Set base color B */
- void SetCurColorB(vec4 const &color);
- /* [cmd:scv] Sets all vertices in this scope color. */
- void SetVertColor(vec4 const &color);
-
- //-------------------------------------------------------------------------
- //Internal : Basic triangle/vertex operations
- //-------------------------------------------------------------------------
- private:
- void AddVertex(vec3 const &coord);
- void AddDuplicateVertex(int i);
- void AddLerpVertex(int i, int j, float alpha);
- void AddLerpVertex(VertexData const &vi, VertexData const &vj, float alpha);
- VertexData GetLerpVertex(int i, int j, float alpha);
- VertexData GetLerpVertex(VertexData const &vi, VertexData const &vj, float alpha);
- void AppendQuad(int i1, int i2, int i3, int i4, int base);
- void AppendQuadDuplicateVerts(int i1, int i2, int i3, int i4, int base);
- void AppendTriangle(int i1, int i2, int i3, int base);
- void AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base);
- void ComputeNormals(int start, int vcount);
- public: //DEBUG
- void ComputeTexCoord(float uv_scale, int uv_offset);
-
- //-------------------------------------------------------------------------
- //Internal : Vertices operations
- //-------------------------------------------------------------------------
- private:
- void SetTexCoordData(vec2 const &new_offset, vec2 const &new_scale);
- void SetTexCoordData2(vec2 const &new_offset, vec2 const &new_scale);
-
- void SetCurVertNormal(vec3 const &normal);
- void SetCurVertColor(vec4 const &color);
- void SetCurVertTexCoord(vec2 const &texcoord);
- void SetCurVertTexCoord2(vec2 const &texcoord);
-
- public:
- //-------------------------------------------------------------------------
- //Mesh transform operations
- //-------------------------------------------------------------------------
-
- /* [cmd:t/tx/ty/tz] Translate vertices
- - v : Translation quantity.
- */
- void Translate(vec3 const &v);
- /* See Rotate */
- void RotateX(float angle);
- /* See Rotate */
- void RotateY(float angle);
- /* See Rotate */
- void RotateZ(float angle);
- /* [cmd:r/rx/ry/rz] Rotate vertices
- - angle : rotation quantity.
- - axis : rotation axis.
- */
- void Rotate(float angle, vec3 const &axis);
- /* [cmd:rj] Randomly move vertices along Origin-to-vertex as f(vtx) = vtx + o2v * (1.0 + rand(r))
- - r : jitter maximum value.
- */
- void RadialJitter(float r);
- /* [cmd:tax] multiply axis y&z by x as f(y) = y * (1.0 + (ny * x + xoff))
- - ny : value of n for y.
- - nz : value of n for z.
- - xoff : value of xoff.
- - absolute (def:true) : if (true) Multiply will use an absolute x.
- */
- void TaperX(float ny, float nz, float xoff=0.f, bool absolute=true);
- /* [cmd:tay] Same as TaperX, with Y */
- void TaperY(float nx, float nz, float yoff=0.f, bool absolute=true);
- /* [cmd:taz] Same as TaperX, with Z */
- void TaperZ(float nx, float ny, float zoff=0.f, bool absolute=true);
- /* [cmd:twx] Twist vertices around x axis with x as rotation value as f(p) = (RotateX(x * t + toff) * p)
- - t : Angle multiplier.
- - toff : Applied offset.
- */
- void TwistX(float t, float toff=0.f);
- /* [cmd:twy] Same as TwistX, with Y */
- void TwistY(float t, float toff=0.f);
- /* [cmd:twz] Same as TwistX, with Z */
- void TwistZ(float t, float toff=0.f);
- /* [cmd:shx] Shear vertices using x value as shear quantity as f(y) = y + (ny * x + xoff)
- - ny : Value of n for y.
- - nz : Value of n for z.
- - xoff : Value of xoff.
- - absolute (def:true) : if (true) Multiply will use an absolute x.
- */
- void ShearX(float ny, float nz, float xoff=0.f, bool absolute=true);
- /* [cmd:shy] Same as ShearX, with Y */
- void ShearY(float nx, float nz, float yoff=0.f, bool absolute=true);
- /* [cmd:shz] Same as ShearX, with Z */
- void ShearZ(float nx, float ny, float zoff=0.f, bool absolute=true);
- /* [cmd:stx] Stretch vertices using x value as stretch quantity as f(y) = y + (pow(x, ny) + xoff)
- - ny : Value of n for y.
- - nz : Value of n for z.
- - xoff : Value of xoff.
- */
- void StretchX(float ny, float nz, float xoff=0.f);
- /* [cmd:sty] Same as StretchX, with Y */
- void StretchY(float nx, float nz, float yoff=0.f);
- /* [cmd:stz] Same as StretchX, with Z */
- void StretchZ(float nx, float ny, float zoff=0.f);
- /* [cmd:bdxy] Bend vertices using x as bend quantity along y axis using f(p) = (RotateY(x * t + toff) * p)
- - t : Angle multiplier.
- - xoff : Applied offset.
- */
- void BendXY(float t, float toff=0.f);
- /* [cmd:bdxz] Same as BendXY, with X & Z */
- void BendXZ(float t, float toff=0.f);
- /* [cmd:bdyx] Same as BendXY, with Y & X */
- void BendYX(float t, float toff=0.f);
- /* [cmd:bdyz] Same as BendXY, with Y & Z */
- void BendYZ(float t, float toff=0.f);
- /* [cmd:bdzx] Same as BendXY, with Z & X */
- void BendZX(float t, float toff=0.f);
- /* [cmd:bdzy] Same as BendXY, with Z & Y */
- void BendZY(float t, float toff=0.f);
- private:
- struct MeshTransform
- {
- enum Value
- {
- Taper,
- Twist,
- Bend,
- Stretch,
- Shear
- }
- m_value;
-
- inline MeshTransform() : m_value(Taper) {}
- inline MeshTransform(Value v) : m_value(v) {}
- inline operator Value() { return m_value; }
- };
- void DoMeshTransform(MeshTransform ct, Axis axis0, Axis axis1, float n0, float n1, float noff, bool absolute=false);
- public:
- /* [cmd:s/sx/sy/sz] Scale vertices
- - s : scale quantity.
- */
- void Scale(vec3 const &s);
- void Scale(float s) { Scale(vec3(s)); }
- /* [cmd:mx] Mirror vertices through X-plane
- Acts as an OpenBrace
- */
- void MirrorX();
- /* [cmd:my] Mirror vertices through Y-plane
- Acts as an OpenBrace
- */
- void MirrorY();
- /* [cmd:mz] Mirror vertices through Z-plane
- Acts as an OpenBrace
- */
- void MirrorZ();
- /* [no-cmd] Duplicates vertices and scale duplicate
- Acts as an OpenBrace
- */
- void DupAndScale(vec3 const &s, bool open_brace=false);
- /* [cmd:ch] Performs a chamfer operation //TODO : Make it work
- - f : Chamfer quantity.
- */
- void Chamfer(float f);
- /* [cmd:splt] split triangles in 4 smaller ones
- - pass : Number of pass applied.
- */
- void SplitTriangles(int pass);
- private:
- void SplitTriangles(int pass, VertexDictionnary *vert_dict);
- public:
- /* [cmd:smth] Smooth the mesh by subdivising it.
- - pass : a pass is made of (n0 split then n1 smooth) repeat.
- - split_per_pass : n0 value in above explanation.
- - smooth_per_pass : n1 value in above explanation.
- */
- void SmoothMesh(int pass, int split_per_pass, int smooth_per_pass);
-
- //-------------------------------------------------------------------------
- //Mesh shape operations
- //-------------------------------------------------------------------------
-
- /* [cmd:ac] Cylinder centered on (0,0,0) with BBox [-.5*max(d1, d2), -.5*h, -.5*max(d1, d2)]
- - nbsides : Number of sides. [+.5*max(d1, d2), +.5*h, +.5*max(d1, d2)]
- - h : Height of the cylinder.
- - d1 : Lower diameter.
- - d2 : Upper diameter.
- - dualside : if (true) will also create inner sides : TOOD:TOREMOVE?? : needed ?
- - smooth : if (true) will smooth normals : TOOD:TOREMOVE : smooth should be handled elsewhere
- - close : if (true) will add discs to close the cylinder
- */
- void AppendCylinder(int nsides, float h, float d1, float d2,
- bool dualside=false, bool smooth=false, bool close=false);
- /* [cmd:asph] Sphere centered on (0,0,0) with BBox [-.5*d][.5*d]
- - ndivisions : number of subdivisions each Sphere triangle will sustain.
- - d : Diameter.
- */
- void AppendSphere(int ndivisions, float d);
- /* [cmd:acap] Capsule centered on (0,0,0) with BBox [-.5*d, -(.5*d+h), -.5*d][.5*d, (.5*d+h), .5*d]
- - ndivisions : number of subdivisions each Sphere triangle will sustain.
- - h : Inner height.
- - d : Diameter.
- */
- void AppendCapsule(int ndivisions, float h, float d);
- /* [cmd:ato] Torus centered on (0,0,0) with BBox [-.5*d2][.5*d2]
- - ndivisions : number of subdivisions of the torus.
- - d1 : Inner diameter.
- - d2 : Outer diameter.
- */
- void AppendTorus(int ndivisions, float d1, float d2);
- /* [cmd:ab] Box centered on (0,0,0) with BBox [-.5 * size][.5 * size]
- - size : size of the box.
- - chamf : size of the chamfer.
- */
- void AppendBox(vec3 const &size, float chamf=0.f);
- //Same as AppendBox
- void AppendSmoothChamfBox(vec3 const &size, float chamf);
- //Same as AppendBox
- void AppendFlatChamfBox(vec3 const &size, float chamf);
- //Same as AppendBox
- void AppendBox(vec3 const &size, float chamf, bool smooth);
- /* [cmd:as]
- Append a Star centered on (0,0,0) contained within a disc of "max(d1, d2)" diameter.
- - nbranches : Number of branches.
- - d1 : double Length of the branches.
- - d2 : double Length of the "branch" located between d1-branches.
- - fade : if (true) in-between branches use ColorB.
- - fade2 : if (true) Star branches use ColorB.
- */
- void AppendStar(int nbranches, float d1, float d2,
- bool fade=false, bool fade2=false);
- /* [cmd:aes] Star centered on (0,0,0) contained within a disc of "max(max(d1, d2), max(d1 + extrad, d2 + extrad))" diameter.
- Expanded star branches use ColorB.
- - nbranches : Number of branches.
- - d1 : Double Length of the branches.
- - d2 : Double Length of the "branch" located between r1-branches.
- - extrad : Extra length added to expand all branches.
- */
- void AppendExpandedStar(int nbranches, float d1, float d2, float extrad=0.f);
- /* [cmd:ad] Disc centered on (0,0,0) with d diameter.
- - nbsides : Number of sides.
- - d : Diameter.
- - fade : if (true) Outer vertices will use ColorB
- */
- void AppendDisc(int nsides, float d, bool fade=false);
- /* [cmd:at] Triangle centered on (0,0,0) contained within a disc of "d" diameter.
- - d : diameter of the containing disc..
- - fade : if (true) 2nd & 3rd Vertices will use ColorB
- */
- void AppendSimpleTriangle(float d, bool fade=false);
- /* [cmd:aq] Quad centered on (0,0,0) contained within BBox [-size*.5f, 0, -size*.5f][size*.5f, 0, size*.5f]
- - size : Size of quad.
- - fade : if (true) 3rd & 4th Vertices will use ColorB
- */
- void AppendSimpleQuad(float size, bool fade=false);
- private:
- //complex version of above one
- void AppendSimpleQuad(vec2 p1, vec2 p2, float z=0.f, bool fade=false);
- public:
- /* [cmd:acg] Gear centered on (0,0,0) contained within BBox [-.5*max(d1,d2), -.5*h, -.5*max(d1, d2)]
- - h : Height of the Gear. [+.5*max(d1,d2), +.5*h, +.5*max(d1, d2)]
- - d10 : Upper Inner diameter.
- - d20 : Lower Inner diameter.
- - d1 : Upper Outer diameter.
- - d2 : Lower Outer diameter.
- - d12 : Upper Cog diameter.
- - d22 : Lower Cog diameter.
- - sidemul : multiplier for the size of the cogs.
- - offset : useless
- */
- void AppendCog(int nbsides, float h, float d10, float d20, float d11,
- float d21, float d12, float d22, float sidemul=0.f, bool offset=false);
-
- //-------------------------------------------------------------------------
- //TODO : Mesh Bone operations
- //-------------------------------------------------------------------------
- //void AddBone(int parent_id) {}
-
- //Convenience functions
- public:
- int GetVertexCount() { return m_vert.Count(); }
- vec3 const &GetVertexLocation(int i) { return m_vert[i].m_coord; }
-
- private:
- Array<uint16_t> m_indices;
- Array<VertexData> m_vert;
-
- //<vert count, indices count>
- Array<int, int> m_cursors;
-
- MeshRender m_state;
- GpuEasyMeshData m_gpu_data;
-
- public:
- inline EasyMeshBuildData* BD()
- {
- if (!m_build_data)
- m_build_data = new EasyMeshBuildData();
- return m_build_data;
- };
- private:
- class EasyMeshBuildData* m_build_data;
- };
- } /* namespace lol */
-
- #endif /* __EASYMESH_EASYMESH_H__ */
|