@@ -48,7 +48,7 @@ | |||||
%token T_TRANSLATEY T_ROTATEY T_TAPERY T_SCALEY T_MIRRORY | %token T_TRANSLATEY T_ROTATEY T_TAPERY T_SCALEY T_MIRRORY | ||||
%token T_TRANSLATEZ T_ROTATEZ T_TAPERZ T_SCALEZ T_MIRRORZ | %token T_TRANSLATEZ T_ROTATEZ T_TAPERZ T_SCALEZ T_MIRRORZ | ||||
%token T_TRANSLATE T_SCALE T_TOGGLESCALEWINDING T_RADIALJITTER | %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_CHAMFER | ||||
%token T_CYLINDER T_BOX T_SMOOTHCHAMFBOX T_FLATCHAMFBOX T_SPHERE T_CAPSULE | %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_TOGGLESCALEWINDING { mc.m_mesh.ToggleScaleWinding(); } | ||||
| T_CSGUNION { mc.m_mesh.CsgUnion(); } | | T_CSGUNION { mc.m_mesh.CsgUnion(); } | ||||
| T_CSGSUBSTRACT { mc.m_mesh.CsgSubstract(); } | | T_CSGSUBSTRACT { mc.m_mesh.CsgSubstract(); } | ||||
| T_CSGSUBSTRACTLOSS { mc.m_mesh.CsgSubstractLoss(); } | |||||
| T_CSGAND { mc.m_mesh.CsgAnd(); } | | T_CSGAND { mc.m_mesh.CsgAnd(); } | ||||
| T_CSGXOR { mc.m_mesh.CsgXor(); } | | T_CSGXOR { mc.m_mesh.CsgXor(); } | ||||
; | ; | ||||
@@ -74,6 +74,7 @@ rj { return token::T_RADIALJITTER; } | |||||
csgu { return token::T_CSGUNION; } | csgu { return token::T_CSGUNION; } | ||||
csgs { return token::T_CSGSUBSTRACT; } | csgs { return token::T_CSGSUBSTRACT; } | ||||
csgsl { return token::T_CSGSUBSTRACTLOSS; } | |||||
csga { return token::T_CSGAND; } | csga { return token::T_CSGAND; } | ||||
csgx { return token::T_CSGXOR; } | csgx { return token::T_CSGXOR; } | ||||
@@ -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. | //A vertex dictionnary for vertices on the same spot. | ||||
Array< int, int > vertex_dict; | Array< int, int > vertex_dict; | ||||
@@ -309,26 +309,29 @@ void EasyMesh::MeshCsg(int csg_operation) | |||||
//Triangle Kill Test | //Triangle Kill Test | ||||
if (//csgu : CSGUnion() -> m0_Outside + m1_Outside | 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 | //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 == 0 && tri_list[k].m1 == LEAF_BACK) || | ||||
(mesh_id == 1 && tri_list[k].m1 == LEAF_FRONT))) || | (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 | //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_to_kill.Push(tri_idx); | ||||
} | } | ||||
//Triangle Invert Test | //Triangle Invert Test | ||||
if (//csgs : CSGSubstract() -> m0_Outside + m1_Inside-inverted | 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 | //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. | //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. | //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++) | for (int l = 0; l < 3; l++) | ||||
{ | { | ||||
@@ -570,12 +573,13 @@ void EasyMesh::SetCurColor2(vec4 const &color) | |||||
void EasyMesh::AddVertex(vec3 const &coord) | 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); | m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color); | ||||
} | } | ||||
void EasyMesh::AddDuplicateVertex(int i) | 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) | 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; | int tlen = m_indices.Count() - m_cursors.Last().m2; | ||||
for (int i = 0; i < vlen; i++) | 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++) | for (int i = 0; i < tlen; i++) | ||||
m_indices << m_indices[m_cursors.Last().m2++] + vlen; | m_indices << m_indices[m_cursors.Last().m2++] + vlen; | ||||
@@ -21,6 +21,24 @@ | |||||
namespace lol | 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 | class EasyMesh | ||||
{ | { | ||||
friend class EasyMeshParser; | friend class EasyMeshParser; | ||||
@@ -34,18 +52,18 @@ public: | |||||
private: | private: | ||||
void UpdateVertexDict(Array< int, int > &vertex_dict); | 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: | public: | ||||
void OpenBrace(); | void OpenBrace(); | ||||
@@ -65,17 +83,19 @@ private: | |||||
void ComputeNormals(int start, int vcount); | void ComputeNormals(int start, int vcount); | ||||
void SetVertColor(vec4 const &color); | void SetVertColor(vec4 const &color); | ||||
public: | |||||
void SetCurVertNormal(vec3 const &normal); | void SetCurVertNormal(vec3 const &normal); | ||||
void SetCurVertColor(vec4 const &color); | void SetCurVertColor(vec4 const &color); | ||||
void RadialJitter(float r); | |||||
public: | |||||
//------------------------------------------------------------------------- | |||||
//Mesh transform operations | |||||
//------------------------------------------------------------------------- | |||||
void Translate(vec3 const &v); | void Translate(vec3 const &v); | ||||
void RotateX(float t); | void RotateX(float t); | ||||
void RotateY(float t); | void RotateY(float t); | ||||
void RotateZ(float t); | void RotateZ(float t); | ||||
void Rotate(float t, vec3 const &axis); | void Rotate(float t, vec3 const &axis); | ||||
void RadialJitter(float r); | |||||
void TaperX(float y, float z, float xoff); | void TaperX(float y, float z, float xoff); | ||||
void TaperY(float x, float z, float yoff); | void TaperY(float x, float z, float yoff); | ||||
void TaperZ(float x, float y, float zoff); | void TaperZ(float x, float y, float zoff); | ||||
@@ -86,6 +106,9 @@ public: | |||||
void DupAndScale(vec3 const &s); | void DupAndScale(vec3 const &s); | ||||
void Chamfer(float f); | void Chamfer(float f); | ||||
//------------------------------------------------------------------------- | |||||
//Mesh shape operations | |||||
//------------------------------------------------------------------------- | |||||
void AppendCylinder(int nsides, float h, float r1, float r2, | void AppendCylinder(int nsides, float h, float r1, float r2, | ||||
int dualside, int smooth); | int dualside, int smooth); | ||||
void AppendCapsule(int ndivisions, float h, float r); | 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, | void AppendCog(int nbsides, float h, float r10, float r20, float r1, | ||||
float r2, float r12, float r22, float sidemul, int offset); | float r2, float r12, float r22, float sidemul, int offset); | ||||
//------------------------------------------------------------------------- | |||||
//TODO : Mesh Bone operations | |||||
//------------------------------------------------------------------------- | |||||
//void AddBone(int parent_id) {} | |||||
//Convenience functions | //Convenience functions | ||||
public: | public: | ||||
int GetVertexCount() { return m_vert.Count(); } | int GetVertexCount() { return m_vert.Count(); } | ||||
@@ -113,10 +141,14 @@ public: | |||||
private: | private: | ||||
vec4 m_color, m_color2; | vec4 m_color, m_color2; | ||||
Array<uint16_t> m_indices; | Array<uint16_t> m_indices; | ||||
//TODO : <coord, norm, color, bone_id, bone_weight> | |||||
//TODO : Array<vec3, vec3, vec4, ivec2, vec2> m_vert; | |||||
//TODO : More bone blend support than 2 ? | |||||
//<coord, norm, color> | //<coord, norm, color> | ||||
Array<vec3, vec3, vec4> m_vert; | Array<vec3, vec3, vec4> m_vert; | ||||
//<vert count, indices count> | //<vert count, indices count> | ||||
Array<int, int> m_cursors; | Array<int, int> m_cursors; | ||||
//When this flag is up, negative scaling will not invert faces. | |||||
bool m_ignore_winding_on_scale; | bool m_ignore_winding_on_scale; | ||||
/* FIXME: put this in a separate class so that we can copy meshes. */ | /* FIXME: put this in a separate class so that we can copy meshes. */ | ||||