Ver código fonte

EZMesh : Added CommandStack & subsequent Loop command.

undefined
Benjamin ‘Touky’ Huet Sam Hocevar <sam@hocevar.net> 11 anos atrás
pai
commit
6b2044349c
10 arquivos alterados com 1551 adições e 955 exclusões
  1. +4
    -1
      src/easymesh/easymesh-parser.y
  2. +1
    -0
      src/easymesh/easymesh-scanner.l
  3. +430
    -11
      src/easymesh/easymesh.cpp
  4. +142
    -14
      src/easymesh/easymesh.h
  5. +590
    -564
      src/generated/easymesh-parser.cpp
  6. +68
    -67
      src/generated/easymesh-parser.h
  7. +304
    -297
      src/generated/easymesh-scanner.cpp
  8. +9
    -0
      src/lol/base/assert.h
  9. +2
    -1
      test/data/mesh-buffer.txt
  10. +1
    -0
      test/easymeshdictionnary.js

+ 4
- 1
src/easymesh/easymesh-parser.y Ver arquivo

@@ -45,7 +45,7 @@

%start mesh_description

%token T_COLOR T_BCOLOR T_VCOLOR
%token T_LOOP T_COLOR T_BCOLOR T_VCOLOR

%token T_TRANSLATEX T_ROTATEX T_TAPERX T_TWISTX T_SHEARX T_STRETCHX T_BENDXY T_BENDXZ T_SCALEX T_MIRRORX
%token T_TRANSLATEY T_ROTATEY T_TAPERY T_TWISTY T_SHEARY T_STRETCHY T_BENDYX T_BENDYZ T_SCALEY T_MIRRORY
@@ -122,8 +122,11 @@ post_brace_command:
| T_CSGSUBSTRACTLOSS mesh_open mesh_expression_list ']' { mc.m_mesh.CsgSubL(); mc.m_mesh.CloseBrace(); }
| T_CSGAND mesh_open mesh_expression_list ']' { mc.m_mesh.CsgAnd(); mc.m_mesh.CloseBrace(); }
| T_CSGXOR mesh_open mesh_expression_list ']' { mc.m_mesh.CsgXor(); mc.m_mesh.CloseBrace(); }
| doloop '[' mesh_expression_list ']' { mc.m_mesh.LoopEnd(); }
;

doloop:
T_LOOP iv { mc.m_mesh.LoopStart($2); }
pre_brace_command:
T_DUPLICATE { mc.m_mesh.DupAndScale(vec3::one, true); }
;


+ 1
- 0
src/easymesh/easymesh-scanner.l Ver arquivo

@@ -53,6 +53,7 @@ typedef lol::EasyMeshParser::token_type token_type;
(csga|csgand) { return token::T_CSGAND; }
(csgx|csgxor) { return token::T_CSGXOR; }

(lp|loop) { return token::T_LOOP; }
(tsw|scalewinding) { return token::T_TOGGLESCALEWINDING; }
(sc|setcolor) { return token::T_COLOR; }
(scb|setbcolor) { return token::T_BCOLOR; }


+ 430
- 11
src/easymesh/easymesh.cpp Ver arquivo

@@ -439,19 +439,264 @@ EasyMesh::EasyMesh(const EasyMesh& em)
//-----------------------------------------------------------------------------
bool EasyMesh::Compile(char const *command)
{
bool res = false;
EasyMeshCompiler mc(*this);
return mc.ParseString(command);
BD()->Enable(MeshBuildOperation::CommandRecording);
if ((res = mc.ParseString(command)))
{
BD()->Disable(MeshBuildOperation::CommandRecording);
BD()->Enable(MeshBuildOperation::CommandExecution);
ExecuteCmdStack();
BD()->Disable(MeshBuildOperation::CommandExecution);
}
return res;
}

//-----------------------------------------------------------------------------
#define EZSET(M0) BD()->CmdStack().GetValue(M0);
#define EZDEF_1(T0) T0 m0; EZSET(m0)
#define EZDEF_2(T0, T1) EZDEF_1(T0) T1 m1; EZSET(m1)
#define EZDEF_3(T0, T1, T2) EZDEF_2(T0, T1) T2 m2; EZSET(m2)
#define EZDEF_4(T0, T1, T2, T3) EZDEF_3(T0, T1, T2) T3 m3; EZSET(m3)
#define EZDEF_5(T0, T1, T2, T3, T4) EZDEF_4(T0, T1, T2, T3) T4 m4; EZSET(m4)
#define EZDEF_6(T0, T1, T2, T3, T4, T5) EZDEF_5(T0, T1, T2, T3, T4) T5 m5; EZSET(m5)
#define EZDEF_7(T0, T1, T2, T3, T4, T5, T6) EZDEF_6(T0, T1, T2, T3, T4, T5) T6 m6; EZSET(m6)
#define EZDEF_8(T0, T1, T2, T3, T4, T5, T6, T7) EZDEF_7(T0, T1, T2, T3, T4, T5, T6) T7 m7; EZSET(m7)
#define EZDEF_9(T0, T1, T2, T3, T4, T5, T6, T7, T8) EZDEF_8(T0, T1, T2, T3, T4, T5, T6, T7) T8 m8; EZSET(m8)
#define EZDEF_10(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) EZDEF_9(T0, T1, T2, T3, T4, T5, T6, T7, T8) T9 m9; EZSET(m9)

//----
#define EZCALL_1(F) F();
#define EZCALL_2(F, T0) EZDEF_1(T0) F(m0);
#define EZCALL_3(F, T0, T1) EZDEF_2(T0, T1) F(m0, m1);
#define EZCALL_4(F, T0, T1, T2) EZDEF_3(T0, T1, T2) F(m0, m1, m2);
#define EZCALL_5(F, T0, T1, T2, T3) EZDEF_4(T0, T1, T2, T3) F(m0, m1, m2, m3);
#define EZCALL_6(F, T0, T1, T2, T3, T4) EZDEF_5(T0, T1, T2, T3, T4) F(m0, m1, m2, m3, m4);
#define EZCALL_7(F, T0, T1, T2, T3, T4, T5) EZDEF_6(T0, T1, T2, T3, T4, T5) F(m0, m1, m2, m3, m4, m5);
#define EZCALL_8(F, T0, T1, T2, T3, T4, T5, T6) EZDEF_7(T0, T1, T2, T3, T4, T5, T6) F(m0, m1, m2, m3, m4, m5, m6);
#define EZCALL_9(F, T0, T1, T2, T3, T4, T5, T6, T7) EZDEF_8(T0, T1, T2, T3, T4, T5, T6, T7) F(m0, m1, m2, m3, m4, m5, m6, m7);
#define EZCALL_10(F, T0, T1, T2, T3, T4, T5, T6, T7, T8) EZDEF_9(T0, T1, T2, T3, T4, T5, T6, T7, T8) F(m0, m1, m2, m3, m4, m5, m6, m7, m8);
#define EZCALL_11(F, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) EZDEF_10(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) F(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9);

//----
#define EZM_CALL_FUNC(...) \
LOL_CALL(LOL_CAT(EZCALL_, LOL_CALL(LOL_COUNT_TO_12, (__VA_ARGS__))), (__VA_ARGS__))

//-----------------------------------------------------------------------------
void EasyMesh::ExecuteCmdStack()
{
for (BD()->Cmdi() = 0; BD()->Cmdi() < BD()->CmdStack().GetCmdNb(); ++BD()->Cmdi())
{
switch (BD()->CmdStack().GetCmd(BD()->Cmdi()))
{
case EasyMeshCmdType::MeshCsg:
{
EZM_CALL_FUNC(MeshCsg, CSGUsage);
break;
}
case EasyMeshCmdType::LoopStart:
{
EZM_CALL_FUNC(LoopStart, int);
break;
}
case EasyMeshCmdType::LoopEnd:
{
EZM_CALL_FUNC(LoopEnd);
break;
}
case EasyMeshCmdType::OpenBrace:
{
EZM_CALL_FUNC(OpenBrace);
break;
}
case EasyMeshCmdType::CloseBrace:
{
EZM_CALL_FUNC(CloseBrace);
break;
}
case EasyMeshCmdType::ScaleWinding:
{
EZM_CALL_FUNC(ToggleScaleWinding);
break;
}
case EasyMeshCmdType::SetColor:
{
EZM_CALL_FUNC(SetCurColor, vec4);
break;
}
case EasyMeshCmdType::SetColor2:
{
EZM_CALL_FUNC(SetCurColor2, vec4);
break;
}
case EasyMeshCmdType::SetVertColor:
{
EZM_CALL_FUNC(SetVertColor, vec4);
break;
}
case EasyMeshCmdType::Translate:
{
EZM_CALL_FUNC(Translate, vec3);
break;
}
case EasyMeshCmdType::Rotate:
{
EZM_CALL_FUNC(Rotate, float, vec3);
break;
}
case EasyMeshCmdType::RadialJitter:
{
EZM_CALL_FUNC(RadialJitter, float);
break;
}
case EasyMeshCmdType::MeshTranform:
{
EZM_CALL_FUNC(DoMeshTransform, MeshTransform, Axis, Axis, float, float, float, bool);
break;
}
case EasyMeshCmdType::Scale:
{
EZM_CALL_FUNC(Scale, vec3);
break;
}
case EasyMeshCmdType::DupAndScale:
{
EZM_CALL_FUNC(DupAndScale, vec3, bool);
break;
}
case EasyMeshCmdType::Chamfer:
{
EZM_CALL_FUNC(Chamfer, float);
break;
}
case EasyMeshCmdType::SplitTriangles:
{
EZM_CALL_FUNC(SplitTriangles, int);
break;
}
case EasyMeshCmdType::SmoothMesh:
{
EZM_CALL_FUNC(SmoothMesh, int, int, int);
break;
}
case EasyMeshCmdType::AppendCylinder:
{
EZM_CALL_FUNC(AppendCylinder, int, float, float, float, bool, bool, bool);
break;
}
case EasyMeshCmdType::AppendCapsule:
{
EZM_CALL_FUNC(AppendCapsule, int, float, float);
break;
}
case EasyMeshCmdType::AppendTorus:
{
EZM_CALL_FUNC(AppendTorus, int, float, float);
break;
}
case EasyMeshCmdType::AppendBox:
{
EZM_CALL_FUNC(AppendBox, vec3, float, bool);
break;
}
case EasyMeshCmdType::AppendStar:
{
EZM_CALL_FUNC(AppendStar, int, float, float, bool, bool);
break;
}
case EasyMeshCmdType::AppendExpandedStar:
{
EZM_CALL_FUNC(AppendExpandedStar, int, float, float, float);
break;
}
case EasyMeshCmdType::AppendDisc:
{
EZM_CALL_FUNC(AppendDisc, int, float, bool);
break;
}
case EasyMeshCmdType::AppendSimpleTriangle:
{
EZM_CALL_FUNC(AppendSimpleTriangle, float, bool);
break;
}
case EasyMeshCmdType::AppendSimpleQuad:
{
EZM_CALL_FUNC(AppendSimpleQuad, vec2, vec2, float, bool);
break;
}
case EasyMeshCmdType::AppendCog:
{
EZM_CALL_FUNC(AppendCog, int, float, float, float, float, float, float, float, float, bool);
break;
}
default:
ASSERT(0, "Unknown command pseudo bytecode");
}
}
}

//-----------------------------------------------------------------------------
void EasyMesh::LoopStart(int loopnb)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::LoopStart);
BD()->CmdStack() << loopnb;
return;
}
//Loop is only available when executing a command recording
else if (BD()->IsEnabled(MeshBuildOperation::CommandExecution))
{
//Only register if we're not the current loop command
if (!BD()->LoopStack().Count() || BD()->LoopStack().Last().m1 != BD()->Cmdi())
BD()->LoopStack().Push(BD()->Cmdi(), loopnb);
}
}

//-----------------------------------------------------------------------------
void EasyMesh::LoopEnd()
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::LoopEnd);
return;
}
//Loop is only available when executing a command recording
else if (BD()->IsEnabled(MeshBuildOperation::CommandExecution))
{
//Only register if we're not the current loop command
if (BD()->LoopStack().Count())
{
BD()->LoopStack().Last().m2--;
if (BD()->LoopStack().Last().m2 > 0)
BD()->Cmdi() = BD()->LoopStack().Last().m1 - 1;
else
BD()->LoopStack().Pop();
}
}
}

//-----------------------------------------------------------------------------
void EasyMesh::OpenBrace()
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::OpenBrace);
return;
}

m_cursors.Push(m_vert.Count(), m_indices.Count());
}

//-----------------------------------------------------------------------------
void EasyMesh::CloseBrace()
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::CloseBrace);
return;
}

m_cursors.Pop();
}
//-----------------------------------------------------------------------------
@@ -682,6 +927,13 @@ void VertexDictionnary::AddVertex(const int vert_id, const vec3 vert_coord)
//-----------------------------------------------------------------------------
void EasyMesh::MeshCsg(CSGUsage csg_operation)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::MeshCsg);
BD()->CmdStack() << csg_operation;
return;
}

//A vertex dictionnary for vertices on the same spot.
Array< int, int > vertex_dict;
//This list keeps track of the triangle that will need deletion at the end.
@@ -865,21 +1117,55 @@ void EasyMesh::MeshCsg(CSGUsage csg_operation)
//-----------------------------------------------------------------------------
void EasyMesh::ToggleScaleWinding()
{
BD()->Toggle(MeshBuildOperation::Scale_Winding);
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::ScaleWinding);
return;
}

BD()->Toggle(MeshBuildOperation::ScaleWinding);
}

//-----------------------------------------------------------------------------
void EasyMesh::SetCurColor(vec4 const &color)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::SetColor);
BD()->CmdStack() << color;
return;
}

BD()->Color() = color;
}

//-----------------------------------------------------------------------------
void EasyMesh::SetCurColor2(vec4 const &color)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::SetColor2);
BD()->CmdStack() << color;
return;
}

BD()->Color2() = color;
}

//-----------------------------------------------------------------------------
void EasyMesh::SetVertColor(vec4 const &color)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::SetVertColor);
BD()->CmdStack() << color;
return;
}

for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
m_vert[i].m_color = color;
}

//-----------------------------------------------------------------------------
void EasyMesh::AddVertex(vec3 const &coord)
{
@@ -1147,13 +1433,6 @@ void EasyMesh::ComputeTexCoord(float uv_scale, int uv_offset)
#endif
}

//-----------------------------------------------------------------------------
void EasyMesh::SetVertColor(vec4 const &color)
{
for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
m_vert[i].m_color = color;
}

//-----------------------------------------------------------------------------
void EasyMesh::SetTexCoordData(vec2 const &new_offset, vec2 const &new_scale)
{
@@ -1195,6 +1474,13 @@ void EasyMesh::SetCurVertTexCoord2(vec2 const &texcoord)
//-----------------------------------------------------------------------------
void EasyMesh::Translate(vec3 const &v)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::Translate);
BD()->CmdStack() << v;
return;
}

for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
m_vert[i].m_coord += v;
}
@@ -1207,6 +1493,13 @@ void EasyMesh::RotateZ(float angle) { Rotate(angle, vec3(0, 0, 1)); }
//-----------------------------------------------------------------------------
void EasyMesh::Rotate(float angle, vec3 const &axis)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::Rotate);
BD()->CmdStack() << angle << axis;
return;
}

mat3 m = mat3::rotate(angle, axis);
for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
{
@@ -1218,6 +1511,13 @@ void EasyMesh::Rotate(float angle, vec3 const &axis)
//-----------------------------------------------------------------------------
void EasyMesh::RadialJitter(float r)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::RadialJitter);
BD()->CmdStack() << r;
return;
}

Array<int> Welded;
Welded.Push(-1);
for (int i = m_cursors.Last().m1 + 1; i < m_vert.Count(); i++)
@@ -1291,6 +1591,13 @@ void EasyMesh::BendZY(float t, float toff) { DoMeshTransform(MeshTransform::Bend
//-----------------------------------------------------------------------------
void EasyMesh::DoMeshTransform(MeshTransform ct, Axis axis0, Axis axis1, float n0, float n1, float noff, bool absolute)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::MeshTranform);
BD()->CmdStack() << ct << axis0 << axis1 << n0 << n1 << noff << absolute;
return;
}

for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
{
switch (ct)
@@ -1338,6 +1645,13 @@ void EasyMesh::DoMeshTransform(MeshTransform ct, Axis axis0, Axis axis1, float n
//-----------------------------------------------------------------------------
void EasyMesh::Scale(vec3 const &s)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::Scale);
BD()->CmdStack() << s;
return;
}

vec3 const invs = vec3(1) / s;

for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
@@ -1347,7 +1661,7 @@ void EasyMesh::Scale(vec3 const &s)
}

/* Flip winding if the scaling involves mirroring */
if (!BD()->IsEnabled(MeshBuildOperation::Scale_Winding) && s.x * s.y * s.z < 0)
if (!BD()->IsEnabled(MeshBuildOperation::ScaleWinding) && s.x * s.y * s.z < 0)
{
for (int i = m_cursors.Last().m2; i < m_indices.Count(); i += 3)
{
@@ -1366,6 +1680,13 @@ void EasyMesh::MirrorZ() { DupAndScale(vec3(1, 1, -1)); }
//-----------------------------------------------------------------------------
void EasyMesh::DupAndScale(vec3 const &s, bool open_brace)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::DupAndScale);
BD()->CmdStack() << s << open_brace;
return;
}

int vlen = m_vert.Count() - m_cursors.Last().m1;
int tlen = m_indices.Count() - m_cursors.Last().m2;

@@ -1393,6 +1714,13 @@ void EasyMesh::DupAndScale(vec3 const &s, bool open_brace)
void EasyMesh::AppendCylinder(int nsides, float h, float d1, float d2,
bool dualside, bool smooth, bool close)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::AppendCylinder);
BD()->CmdStack() << nsides << h << d1 << d2 << dualside << smooth << close;
return;
}

//XXX : This operation is done to convert radius to diameter without changing all the code.
float r1 = d1 * .5f;
float r2 = d2 * .5f;
@@ -1486,6 +1814,13 @@ void EasyMesh::AppendSphere(int ndivisions, float d)
//-----------------------------------------------------------------------------
void EasyMesh::AppendCapsule(int ndivisions, float h, float d)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::AppendCapsule);
BD()->CmdStack() << ndivisions << h << d;
return;
}

//XXX : This operation is done to convert radius to diameter without changing all the code.
float r = d * .5f;

@@ -1632,6 +1967,13 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float d)
//-----------------------------------------------------------------------------
void EasyMesh::AppendTorus(int ndivisions, float d1, float d2)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::AppendTorus);
BD()->CmdStack() << ndivisions << d1 << d2;
return;
}

//XXX : This operation is done to convert radius to diameter without changing all the code.
float r1 = d1 * .5f;
float r2 = d2 * .5f;
@@ -1695,6 +2037,13 @@ void EasyMesh::AppendFlatChamfBox(vec3 const &size, float chamf)
//-----------------------------------------------------------------------------
void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::AppendBox);
BD()->CmdStack() << size << chamf << smooth;
return;
}

if (chamf < 0.0f)
{
AppendBox(size + vec3(chamf * 2.0f), -chamf, smooth);
@@ -1882,6 +2231,13 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth)
void EasyMesh::AppendStar(int nbranches, float d1, float d2,
bool fade, bool fade2)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::AppendStar);
BD()->CmdStack() << nbranches << d1 << d2 << fade << fade2;
return;
}

//XXX : This operation is done to convert radius to diameter without changing all the code.
float r1 = d1 * .5f;
float r2 = d2 * .5f;
@@ -1921,6 +2277,13 @@ void EasyMesh::AppendStar(int nbranches, float d1, float d2,
//-----------------------------------------------------------------------------
void EasyMesh::AppendExpandedStar(int nbranches, float d1, float d2, float extrad)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::AppendExpandedStar);
BD()->CmdStack() << nbranches << d1 << d2 << extrad;
return;
}

//XXX : This operation is done to convert radius to diameter without changing all the code.
float r1 = d1 * .5f;
float r2 = d2 * .5f;
@@ -1965,6 +2328,13 @@ void EasyMesh::AppendExpandedStar(int nbranches, float d1, float d2, float extra
//-----------------------------------------------------------------------------
void EasyMesh::AppendDisc(int nsides, float d, bool fade)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::AppendDisc);
BD()->CmdStack() << nsides << d << fade;
return;
}

//XXX : This operation is done to convert radius to diameter without changing all the code.
float r = d * .5f;

@@ -1990,6 +2360,13 @@ void EasyMesh::AppendDisc(int nsides, float d, bool fade)
//-----------------------------------------------------------------------------
void EasyMesh::AppendSimpleTriangle(float d, bool fade)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::AppendSimpleTriangle);
BD()->CmdStack() << d << fade;
return;
}

//XXX : This operation is done to convert radius to diameter without changing all the code.
float size = d * .5f;

@@ -2018,6 +2395,13 @@ void EasyMesh::AppendSimpleQuad(float size, bool fade)
//-----------------------------------------------------------------------------
void EasyMesh::AppendSimpleQuad(vec2 p1, vec2 p2, float z, bool fade)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::AppendSimpleQuad);
BD()->CmdStack() << p1 << p2 << z << fade;
return;
}

MeshType mt = MeshType::Quad;
MeshFaceType mft = MeshFaceType::QuadDefault;

@@ -2053,6 +2437,17 @@ void EasyMesh::AppendCog(int nbsides, float h, float d10, float d20,
float d1, float d2, float d12, float d22,
float sidemul, bool offset)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::AppendCog);
BD()->CmdStack() << nbsides << h
<< d10 << d20
<< d1 << d2
<< d12 << d22
<< sidemul << offset;
return;
}

//XXX : This operation is done to convert radius to diameter without changing all the code.
float r10 = d10 * .5f;
float r20 = d20 * .5f;
@@ -2309,6 +2704,13 @@ void EasyMesh::AppendCog(int nbsides, float h, float d10, float d20,
//-----------------------------------------------------------------------------
void EasyMesh::Chamfer(float f)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::Chamfer);
BD()->CmdStack() << f;
return;
}

int vlen = m_vert.Count() - m_cursors.Last().m1;
int ilen = m_indices.Count() - m_cursors.Last().m2;

@@ -2353,7 +2755,17 @@ void EasyMesh::Chamfer(float f)
}

//-----------------------------------------------------------------------------
void EasyMesh::SplitTriangles(int pass) { SplitTriangles(pass, nullptr); }
void EasyMesh::SplitTriangles(int pass)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::SplitTriangles);
BD()->CmdStack() << pass;
return;
}

SplitTriangles(pass, nullptr);
}

//-----------------------------------------------------------------------------
void EasyMesh::SplitTriangles(int pass, VertexDictionnary *vert_dict)
@@ -2388,6 +2800,13 @@ void EasyMesh::SplitTriangles(int pass, VertexDictionnary *vert_dict)
//TODO : Smooth should only use connected vertices that are on edges of the mesh (See box).
void EasyMesh::SmoothMesh(int main_pass, int split_per_main_pass, int smooth_per_main_pass)
{
if (BD()->IsEnabled(MeshBuildOperation::CommandRecording))
{
BD()->CmdStack().AddCmd(EasyMeshCmdType::SmoothMesh);
BD()->CmdStack() << main_pass << split_per_main_pass << smooth_per_main_pass;
return;
}

VertexDictionnary vert_dict;
Array<vec3> smooth_buf[2];
Array<int> master_list;


+ 142
- 14
src/easymesh/easymesh.h Ver arquivo

@@ -21,6 +21,66 @@
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
{
@@ -141,7 +201,9 @@ struct MeshBuildOperation
enum Value
{
//When this flag is up, negative scaling will not invert faces.
Scale_Winding = 1 << 0,
ScaleWinding = (1 << 0),
CommandRecording = (1 << 1),
CommandExecution = (1 << 2),

All = 0xffffffff
}
@@ -152,6 +214,54 @@ struct MeshBuildOperation
inline operator Value() { return m_value; }
};

struct EasyMeshCmdType
{
enum Value
{
MeshCsg = 0,

LoopStart,
LoopEnd,
OpenBrace,
CloseBrace,

ScaleWinding,
SetColor,
SetColor2,
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
@@ -259,12 +369,15 @@ public:
}
}

inline vec4 &Color() { return m_color; }
inline vec4 &Color2() { return m_color2; }
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; }
inline CommandStack &CmdStack() { return m_stack; }
inline int &Cmdi() { return m_cmd_i; }
inline Array<int, int> &LoopStack(){ return m_loop_stack; }
inline vec4 &Color() { return m_color; }
inline vec4 &Color2() { return m_color2; }
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); }
@@ -445,6 +558,9 @@ public:
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;
vec4 m_color2;
vec2 m_texcoord_offset;
@@ -463,15 +579,19 @@ struct CSGUsage
{
enum Value
{
Union,
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; }
};

@@ -521,6 +641,7 @@ struct Axis
}
m_value;

inline Axis() : m_value(X) {}
inline Axis(Value v) : m_value(v) {}
inline operator Value() { return m_value; }
};
@@ -535,6 +656,7 @@ public:
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);
@@ -551,20 +673,24 @@ private:
void MeshCsg(CSGUsage csg_operation);
public:
/* [cmd:csgu] Performs a Union operation as (mesh0_Outside + mesh1_Outside) */
void CsgUnion() { MeshCsg(CSGUsage::Union); }
void CsgUnion() { MeshCsg(CSGUsage::Union); }
/* [cmd:csgs] Performs a Substract operation as (mesh0_Outside + mesh1_Inside-inverted) */
void CsgSub() { MeshCsg(CSGUsage::Substract); }
void CsgSub() { MeshCsg(CSGUsage::Substract); }
/* [cmd:csgsl] Performs a Substract operation without keeping the mesh1 part */
void CsgSubL() { MeshCsg(CSGUsage::SubstractLoss); }
void CsgSubL() { MeshCsg(CSGUsage::SubstractLoss); }
/* [cmd:csga] Performs an And operation as (mesh0_Inside + mesh1_Inside) */
void CsgAnd() { MeshCsg(CSGUsage::And); }
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); }
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 */
@@ -575,6 +701,8 @@ public:
void SetCurColor(vec4 const &color);
/* [cmd:scb] Set base color 2 */
void SetCurColor2(vec4 const &color);
/* [cmd:scv] Sets all vertices in this scope color. */
void SetVertColor(vec4 const &color);

//-------------------------------------------------------------------------
//Internal : Basic triangle/vertex operations
@@ -595,7 +723,6 @@ public: //DEBUG
//Internal : Vertices operations
//-------------------------------------------------------------------------
private:
void SetVertColor(vec4 const &color);
void SetTexCoordData(vec2 const &new_offset, vec2 const &new_scale);
void SetTexCoordData2(vec2 const &new_offset, vec2 const &new_scale);

@@ -697,6 +824,7 @@ private:
}
m_value;

inline MeshTransform() : m_value(Taper) {}
inline MeshTransform(Value v) : m_value(v) {}
inline operator Value() { return m_value; }
};


+ 590
- 564
src/generated/easymesh-parser.cpp
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 68
- 67
src/generated/easymesh-parser.h Ver arquivo

@@ -136,71 +136,72 @@ namespace lol {
/* Tokens. */
enum yytokentype {
T_END = 0,
T_COLOR = 258,
T_BCOLOR = 259,
T_VCOLOR = 260,
T_TRANSLATEX = 261,
T_ROTATEX = 262,
T_TAPERX = 263,
T_TWISTX = 264,
T_SHEARX = 265,
T_STRETCHX = 266,
T_BENDXY = 267,
T_BENDXZ = 268,
T_SCALEX = 269,
T_MIRRORX = 270,
T_TRANSLATEY = 271,
T_ROTATEY = 272,
T_TAPERY = 273,
T_TWISTY = 274,
T_SHEARY = 275,
T_STRETCHY = 276,
T_BENDYX = 277,
T_BENDYZ = 278,
T_SCALEY = 279,
T_MIRRORY = 280,
T_TRANSLATEZ = 281,
T_ROTATEZ = 282,
T_TAPERZ = 283,
T_TWISTZ = 284,
T_SHEARZ = 285,
T_STRETCHZ = 286,
T_BENDZX = 287,
T_BENDZY = 288,
T_SCALEZ = 289,
T_MIRRORZ = 290,
T_TRANSLATE = 291,
T_ROTATE = 292,
T_SCALE = 293,
T_TOGGLESCALEWINDING = 294,
T_RADIALJITTER = 295,
T_SPLITTRIANGLE = 296,
T_SMOOTHMESH = 297,
T_DUPLICATE = 298,
T_CSGUNION = 299,
T_CSGSUBSTRACT = 300,
T_CSGSUBSTRACTLOSS = 301,
T_CSGAND = 302,
T_CSGXOR = 303,
T_CHAMFER = 304,
T_CYLINDER = 305,
T_BOX = 306,
T_SMOOTHCHAMFBOX = 307,
T_FLATCHAMFBOX = 308,
T_SPHERE = 309,
T_CAPSULE = 310,
T_STAR = 311,
T_EXPANDEDSTAR = 312,
T_DISC = 313,
T_TRIANGLE = 314,
T_QUAD = 315,
T_COG = 316,
T_TORUS = 317,
T_ERROR = 318,
F_NUMBER = 319,
I_NUMBER = 320,
BOOLEAN = 321,
COLOR = 322
T_LOOP = 258,
T_COLOR = 259,
T_BCOLOR = 260,
T_VCOLOR = 261,
T_TRANSLATEX = 262,
T_ROTATEX = 263,
T_TAPERX = 264,
T_TWISTX = 265,
T_SHEARX = 266,
T_STRETCHX = 267,
T_BENDXY = 268,
T_BENDXZ = 269,
T_SCALEX = 270,
T_MIRRORX = 271,
T_TRANSLATEY = 272,
T_ROTATEY = 273,
T_TAPERY = 274,
T_TWISTY = 275,
T_SHEARY = 276,
T_STRETCHY = 277,
T_BENDYX = 278,
T_BENDYZ = 279,
T_SCALEY = 280,
T_MIRRORY = 281,
T_TRANSLATEZ = 282,
T_ROTATEZ = 283,
T_TAPERZ = 284,
T_TWISTZ = 285,
T_SHEARZ = 286,
T_STRETCHZ = 287,
T_BENDZX = 288,
T_BENDZY = 289,
T_SCALEZ = 290,
T_MIRRORZ = 291,
T_TRANSLATE = 292,
T_ROTATE = 293,
T_SCALE = 294,
T_TOGGLESCALEWINDING = 295,
T_RADIALJITTER = 296,
T_SPLITTRIANGLE = 297,
T_SMOOTHMESH = 298,
T_DUPLICATE = 299,
T_CSGUNION = 300,
T_CSGSUBSTRACT = 301,
T_CSGSUBSTRACTLOSS = 302,
T_CSGAND = 303,
T_CSGXOR = 304,
T_CHAMFER = 305,
T_CYLINDER = 306,
T_BOX = 307,
T_SMOOTHCHAMFBOX = 308,
T_FLATCHAMFBOX = 309,
T_SPHERE = 310,
T_CAPSULE = 311,
T_STAR = 312,
T_EXPANDEDSTAR = 313,
T_DISC = 314,
T_TRIANGLE = 315,
T_QUAD = 316,
T_COG = 317,
T_TORUS = 318,
T_ERROR = 319,
F_NUMBER = 320,
I_NUMBER = 321,
BOOLEAN = 322,
COLOR = 323
};

};
@@ -279,7 +280,7 @@ namespace lol {
/* Tables. */
/// For a state, the index in \a yytable_ of its portion.
static const short int yypact_[];
static const signed char yypact_ninf_;
static const short int yypact_ninf_;

/// For a state, default rule to reduce.
/// Unless\a yytable_ specifies something else to do.
@@ -374,7 +375,7 @@ namespace lol {
} // lol

/* Line 34 of lalr1.cc */
#line 378 "generated/easymesh-parser.h"
#line 379 "generated/easymesh-parser.h"





+ 304
- 297
src/generated/easymesh-scanner.cpp
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 9
- 0
src/lol/base/assert.h Ver arquivo

@@ -66,6 +66,15 @@ static inline void DebugAbort()
8, 8, 8, 8, 8, 7, 6, 5, 4, 3, \
2, 1, TOO_FEW_ARGUMENTS))

#define LOL_COUNT_TO_12(...) \
LOL_EVAL(LOL_GET_63RD(__VA_ARGS__, 10,10,10,10,10,10,10,10,10,10,\
10,10,10,10,10,10,10,10,10,10,\
10,10,10,10,10,10,10,10,10,10,\
10,10,10,10,10,10,10,10,10,10,\
10,10,10,10,10,10,10,10,10,10,\
12,11,10,9, 8, 7, 6, 5, 4, 3, \
2, 1, TOO_FEW_ARGUMENTS))

/* Three levels of dispatch are needed because of Visual Studio's bizarre
* handling of __VA_ARGS__ inside macro calls */
#define LOL_CAT3(a, b) a##b


+ 2
- 1
test/data/mesh-buffer.txt Ver arquivo

@@ -9,7 +9,7 @@ clearcolor #000
custom setmesh "
[sc#0f0 scb#0f0 ac 3 .5 .4 0 ty .25 [ad 3 .4 sy -1] ty .5 ac 3 1 .1 .1 ty .5 dup [ rz 90 ry 90 scv#00f dup [ ry 90 scv#f00 ] ] ]
[sc#fff ab .1]
//[sc#fff loop 4 [ [loop 4 [ab 1 tx 2]] tz 2]]
//[sc#f00 scb#f00 ac 3 .5 .4 0 ty .25 [ad 3 .4 sy -1] ty .5 ac 3 1 .1 .1 ty .5 rz -90]
@@ -23,6 +23,7 @@ custom setmesh "
"
//splt 0
//test
//[sc#f8f ab 1 splt 4 twy 90]


+ 1
- 0
test/easymeshdictionnary.js Ver arquivo

@@ -26,6 +26,7 @@ CmdType(["tsw", "scalewinding"], "When activated, on negative-scaling,\nnormal-v
CmdType(["sc", "setcolor"], "Set A color", [CmdArg("color", "color")]);
CmdType(["scb", "setcolorb"], "Set B color", [CmdArg("color", "color")]);
CmdType(["scv", "setcolorv"], "Set the color of all vertices in this scope", [CmdArg("color", "color")]);
CmdType(["lp", "loop"], "performs a loop", [CmdArg("int", "loopnb"), CmdArg("[ ]", "command to loop, no new context")]);

//-------------------------------------------------------------------------
//Mesh transform operations


Carregando…
Cancelar
Salvar