diff --git a/src/easymesh/easymesh-parser.y b/src/easymesh/easymesh-parser.y index 9af1c0fb..b31a4139 100644 --- a/src/easymesh/easymesh-parser.y +++ b/src/easymesh/easymesh-parser.y @@ -48,7 +48,7 @@ %token T_TRANSLATEY T_ROTATEY T_TAPERY T_SCALEY T_MIRRORY %token T_TRANSLATEZ T_ROTATEZ T_TAPERZ T_SCALEZ T_MIRRORZ %token T_TRANSLATE T_SCALE T_TOGGLESCALEWINDING T_RADIALJITTER -%token T_CSGUNION T_CSGSUBSTRACT T_CSGAND T_CSGXOR +%token T_CSGUNION T_CSGSUBSTRACT T_CSGSUBSTRACTLOSS T_CSGAND T_CSGXOR %token T_CHAMFER %token T_CYLINDER T_BOX T_SMOOTHCHAMFBOX T_FLATCHAMFBOX T_SPHERE T_CAPSULE @@ -139,6 +139,7 @@ transform_command: | T_TOGGLESCALEWINDING { mc.m_mesh.ToggleScaleWinding(); } | T_CSGUNION { mc.m_mesh.CsgUnion(); } | T_CSGSUBSTRACT { mc.m_mesh.CsgSubstract(); } + | T_CSGSUBSTRACTLOSS { mc.m_mesh.CsgSubstractLoss(); } | T_CSGAND { mc.m_mesh.CsgAnd(); } | T_CSGXOR { mc.m_mesh.CsgXor(); } ; diff --git a/src/easymesh/easymesh-scanner.l b/src/easymesh/easymesh-scanner.l index 42ee7cbb..104a66a0 100644 --- a/src/easymesh/easymesh-scanner.l +++ b/src/easymesh/easymesh-scanner.l @@ -74,6 +74,7 @@ rj { return token::T_RADIALJITTER; } csgu { return token::T_CSGUNION; } csgs { return token::T_CSGSUBSTRACT; } +csgsl { return token::T_CSGSUBSTRACTLOSS; } csga { return token::T_CSGAND; } csgx { return token::T_CSGXOR; } diff --git a/src/easymesh/easymesh.cpp b/src/easymesh/easymesh.cpp index ae788560..2a283ad0 100644 --- a/src/easymesh/easymesh.cpp +++ b/src/easymesh/easymesh.cpp @@ -207,7 +207,7 @@ void EasyMesh::UpdateVertexDict(Array< int, int > &vertex_dict) } } -void EasyMesh::MeshCsg(int csg_operation) +void EasyMesh::MeshCsg(CSGUsage csg_operation) { //A vertex dictionnary for vertices on the same spot. Array< int, int > vertex_dict; @@ -309,26 +309,29 @@ void EasyMesh::MeshCsg(int csg_operation) //Triangle Kill Test if (//csgu : CSGUnion() -> m0_Outside + m1_Outside - (csg_operation == CSG_UNION && tri_list[k].m1 == LEAF_BACK) || + (csg_operation == CSGUsage::Union && tri_list[k].m1 == LEAF_BACK) || //csgs : CSGSubstract() -> m0_Outside + m1_Inside-inverted - (csg_operation == CSG_SUBSTRACT && + (csg_operation == CSGUsage::Substract && ((mesh_id == 0 && tri_list[k].m1 == LEAF_BACK) || (mesh_id == 1 && tri_list[k].m1 == LEAF_FRONT))) || + //csgs : CSGSubstractLoss() -> m0_Outside + (csg_operation == CSGUsage::SubstractLoss && + ((mesh_id == 0 && tri_list[k].m1 == LEAF_BACK) || mesh_id == 1)) || //csga : CSGAnd() -> Inside + Inside - (csg_operation == CSG_AND && tri_list[k].m1 == LEAF_FRONT)) + (csg_operation == CSGUsage::And && tri_list[k].m1 == LEAF_FRONT)) { triangle_to_kill.Push(tri_idx); } //Triangle Invert Test if (//csgs : CSGSubstract() -> m0_Outside + m1_Inside-inverted - (csg_operation == CSG_SUBSTRACT && mesh_id == 1 && tri_list[k].m1 == LEAF_BACK) || + (csg_operation == CSGUsage::Substract && mesh_id == 1 && tri_list[k].m1 == LEAF_BACK) || //csgx : CSGXor() -> Outside/Inside-inverted + Outside/Inside-inverted - (csg_operation == CSG_XOR && tri_list[k].m1 == LEAF_BACK)) + (csg_operation == CSGUsage::Xor && tri_list[k].m1 == LEAF_BACK)) { //a Xor means we will share vertices with the outside, so duplicate the vertices. //TODO : This operation disconnect all triangle, in some cases, not a good thing. - if (csg_operation == CSG_XOR) + if (csg_operation == CSGUsage::Xor) { for (int l = 0; l < 3; l++) { @@ -570,12 +573,13 @@ void EasyMesh::SetCurColor2(vec4 const &color) void EasyMesh::AddVertex(vec3 const &coord) { + //TODO : m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color, ivec2(0), vec2(0)); m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color); } void EasyMesh::AddDuplicateVertex(int i) { - m_vert.Push(m_vert[i].m1, vec3(0.f, 1.f, 0.f), m_vert[i].m3); + m_vert << m_vert[i]; } void EasyMesh::AppendQuad(int i1, int i2, int i3, int i4, int base) @@ -769,7 +773,7 @@ void EasyMesh::DupAndScale(vec3 const &s) int tlen = m_indices.Count() - m_cursors.Last().m2; for (int i = 0; i < vlen; i++) - m_vert << m_vert[m_cursors.Last().m1++]; + AddDuplicateVertex(m_cursors.Last().m1++); for (int i = 0; i < tlen; i++) m_indices << m_indices[m_cursors.Last().m2++] + vlen; diff --git a/src/easymesh/easymesh.h b/src/easymesh/easymesh.h index cf4da270..1992dd54 100644 --- a/src/easymesh/easymesh.h +++ b/src/easymesh/easymesh.h @@ -21,6 +21,24 @@ namespace lol { +/* A safe enum for MeshCSG operations. */ +struct CSGUsage +{ + enum Value + { + Union, + Substract, + SubstractLoss, //will remove B from A, but not add inverted B + And, + Xor, + } + m_value; + + inline CSGUsage(Value v) : m_value(v) {} + inline operator Value() { return m_value; } +}; + + class EasyMesh { friend class EasyMeshParser; @@ -34,18 +52,18 @@ public: private: void UpdateVertexDict(Array< int, int > &vertex_dict); -//DEBUG -public: -#define CSG_UNION 0 -#define CSG_SUBSTRACT 1 -#define CSG_AND 2 -#define CSG_XOR 3 - void MeshCsg(int csg_operation); - void CsgUnion() { MeshCsg(CSG_UNION); } - void CsgSubstract() { MeshCsg(CSG_SUBSTRACT); } - void CsgAnd() { MeshCsg(CSG_AND); } - void CsgXor() { MeshCsg(CSG_XOR); } + //------------------------------------------------------------------------- + //Mesh CSG operations + //------------------------------------------------------------------------- +private: + void MeshCsg(CSGUsage csg_operation); +public: + void CsgUnion() { MeshCsg(CSGUsage::Union); } + void CsgSubstract() { MeshCsg(CSGUsage::Substract); } + void CsgSubstractLoss() { MeshCsg(CSGUsage::SubstractLoss); } + void CsgAnd() { MeshCsg(CSGUsage::And); } + void CsgXor() { MeshCsg(CSGUsage::Xor); } public: void OpenBrace(); @@ -65,17 +83,19 @@ private: void ComputeNormals(int start, int vcount); void SetVertColor(vec4 const &color); -public: void SetCurVertNormal(vec3 const &normal); void SetCurVertColor(vec4 const &color); - void RadialJitter(float r); - +public: + //------------------------------------------------------------------------- + //Mesh transform operations + //------------------------------------------------------------------------- void Translate(vec3 const &v); void RotateX(float t); void RotateY(float t); void RotateZ(float t); void Rotate(float t, vec3 const &axis); + void RadialJitter(float r); void TaperX(float y, float z, float xoff); void TaperY(float x, float z, float yoff); void TaperZ(float x, float y, float zoff); @@ -86,6 +106,9 @@ public: void DupAndScale(vec3 const &s); void Chamfer(float f); + //------------------------------------------------------------------------- + //Mesh shape operations + //------------------------------------------------------------------------- void AppendCylinder(int nsides, float h, float r1, float r2, int dualside, int smooth); void AppendCapsule(int ndivisions, float h, float r); @@ -105,6 +128,11 @@ public: void AppendCog(int nbsides, float h, float r10, float r20, float r1, float r2, float r12, float r22, float sidemul, int offset); + //------------------------------------------------------------------------- + //TODO : Mesh Bone operations + //------------------------------------------------------------------------- + //void AddBone(int parent_id) {} + //Convenience functions public: int GetVertexCount() { return m_vert.Count(); } @@ -113,10 +141,14 @@ public: private: vec4 m_color, m_color2; Array m_indices; + //TODO : + //TODO : Array m_vert; + //TODO : More bone blend support than 2 ? // Array m_vert; // Array m_cursors; + //When this flag is up, negative scaling will not invert faces. bool m_ignore_winding_on_scale; /* FIXME: put this in a separate class so that we can copy meshes. */