瀏覽代碼

easymesh: all operations now generate UVs for the mesh.

legacy
Benjamin ‘Touky’ Huet touky 11 年之前
父節點
當前提交
fb7bb880ea
共有 9 個文件被更改,包括 1121 次插入653 次删除
  1. +5
    -3
      src/easymesh/easymesh-parser.y
  2. +407
    -99
      src/easymesh/easymesh.cpp
  3. +169
    -8
      src/easymesh/easymesh.h
  4. +39
    -1
      src/easymesh/shinydebugUV.lolfx
  5. +307
    -388
      src/generated/easymesh-parser.cpp
  6. +66
    -38
      src/generated/easymesh-parser.h
  7. +113
    -108
      src/generated/easymesh-scanner.cpp
  8. +2
    -2
      test/MeshViewer.cpp
  9. +13
    -6
      test/MeshViewerBuffer.txt

+ 5
- 3
src/easymesh/easymesh-parser.y 查看文件

@@ -147,14 +147,16 @@ transform_command:
primitive_command: primitive_command:
T_CYLINDER args6 { mc.m_mesh.AppendCylinder((int)$2.f0, $2.f1, T_CYLINDER args6 { mc.m_mesh.AppendCylinder((int)$2.f0, $2.f1,
$2.f2, $2.f3, $2.f2, $2.f3,
(int)$2.f4, (int)$2.f5); }
(int)$2.f4, (int)$2.f5, 0); }
| T_CYLINDER args7 { mc.m_mesh.AppendCylinder((int)$2.f0, $2.f1,
$2.f2, $2.f3,
(int)$2.f4, (int)$2.f5, (int)$2.f6); }
| T_BOX args3 { mc.m_mesh.AppendBox(vec3($2.f0, $2.f1, $2.f2)); } | T_BOX args3 { mc.m_mesh.AppendBox(vec3($2.f0, $2.f1, $2.f2)); }
| T_SMOOTHCHAMFBOX args4 { mc.m_mesh.AppendSmoothChamfBox(vec3($2.f0, $2.f1, | T_SMOOTHCHAMFBOX args4 { mc.m_mesh.AppendSmoothChamfBox(vec3($2.f0, $2.f1,
$2.f2), $2.f3); } $2.f2), $2.f3); }
| T_FLATCHAMFBOX args4 { mc.m_mesh.AppendFlatChamfBox(vec3($2.f0, $2.f1, | T_FLATCHAMFBOX args4 { mc.m_mesh.AppendFlatChamfBox(vec3($2.f0, $2.f1,
$2.f2), $2.f3); } $2.f2), $2.f3); }
| T_SPHERE args4 { mc.m_mesh.AppendSphere($2.f0,
vec3($2.f1, $2.f2, $2.f3)); }
| T_SPHERE args2 { mc.m_mesh.AppendSphere($2.f0, $2.f1); }
| T_CAPSULE args3 { mc.m_mesh.AppendCapsule($2.f0, $2.f1, $2.f2); } | T_CAPSULE args3 { mc.m_mesh.AppendCapsule($2.f0, $2.f1, $2.f2); }
| T_TORUS args3 { mc.m_mesh.AppendTorus((int)$2.f0, $2.f1, $2.f2); } | T_TORUS args3 { mc.m_mesh.AppendTorus((int)$2.f0, $2.f1, $2.f2); }
| T_STAR args5 { mc.m_mesh.AppendStar((int)$2.f0, $2.f1, $2.f2, | T_STAR args5 { mc.m_mesh.AppendStar((int)$2.f0, $2.f1, $2.f2,


+ 407
- 99
src/easymesh/easymesh.cpp 查看文件

@@ -47,7 +47,8 @@ namespace lol


//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
EasyMesh::EasyMesh() EasyMesh::EasyMesh()
: m_color(0), m_color2(0), m_ignore_winding_on_scale(0)
: m_color(0), m_color2(0), m_ignore_winding_on_scale(0),
m_texcoord_offset(vec2(.0f)), m_texcoord_scale(vec2(1.f))
{ {
m_cursors.Push(0, 0); m_cursors.Push(0, 0);
} }
@@ -478,7 +479,7 @@ void EasyMesh::MeshCsg(CSGUsage csg_operation)
//csgs : CSGSubstractLoss() -> m0_Outside //csgs : CSGSubstractLoss() -> m0_Outside
(csg_operation == CSGUsage::SubstractLoss && (csg_operation == CSGUsage::SubstractLoss &&
((mesh_id == 0 && tri_list[k].m1 == LEAF_BACK) || mesh_id == 1)) || ((mesh_id == 0 && tri_list[k].m1 == LEAF_BACK) || mesh_id == 1)) ||
//csga : CSGAnd() -> Inside + Inside
//csga : CSGAnd() -> m0_Inside + m1_Inside
(csg_operation == CSGUsage::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);
@@ -487,7 +488,7 @@ void EasyMesh::MeshCsg(CSGUsage csg_operation)
//Triangle Invert Test //Triangle Invert Test
if (//csgs : CSGSubstract() -> m0_Outside + m1_Inside-inverted if (//csgs : CSGSubstract() -> m0_Outside + m1_Inside-inverted
(csg_operation == CSGUsage::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() -> m0_Outside/m0_Inside-inverted + m1_Outside/m1_Inside-inverted
(csg_operation == CSGUsage::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.
@@ -546,7 +547,6 @@ void EasyMesh::MeshCsg(CSGUsage csg_operation)
//DONE for the splitting ! //DONE for the splitting !
} }



//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void EasyMesh::ToggleScaleWinding() void EasyMesh::ToggleScaleWinding()
{ {
@@ -749,7 +749,7 @@ void EasyMesh::ComputeTexCoord(float uv_scale, int uv_offset)
vec3 v02 = m_vert[v[2]].m1 - m_vert[v[0]].m1; vec3 v02 = m_vert[v[2]].m1 - m_vert[v[0]].m1;
vec3 v_dir = normalize(cross(m_vert[m_indices[cur_tri]].m2, v01)); vec3 v_dir = normalize(cross(m_vert[m_indices[cur_tri]].m2, v01));
vec2 texu_dir = uv[1] - uv[0]; vec2 texu_dir = uv[1] - uv[0];
vec2 texv_dir = vec2(texu_dir.y, -texu_dir.x);
vec2 texv_dir = vec2(texu_dir.y, texu_dir.x);
//Final calculations //Final calculations
uv[2] = texu_dir * dot(v01, v02) + texv_dir * dot(v_dir, v02); uv[2] = texu_dir * dot(v01, v02) + texv_dir * dot(v_dir, v02);


@@ -776,7 +776,7 @@ void EasyMesh::ComputeTexCoord(float uv_scale, int uv_offset)
//Get connected triangles and go from there. //Get connected triangles and go from there.
for (int j = 0; j < 3; j++) for (int j = 0; j < 3; j++)
{ {
#if 0
#if 1
//This finds triangle that are connected to this triangle //This finds triangle that are connected to this triangle
vert_dict.FindConnectedTriangles(ivec2(v[j], v[(j + 1) % 3]), tri_list, tri_check, &tri_done); vert_dict.FindConnectedTriangles(ivec2(v[j], v[(j + 1) % 3]), tri_list, tri_check, &tri_done);
#else #else
@@ -787,6 +787,17 @@ void EasyMesh::ComputeTexCoord(float uv_scale, int uv_offset)
} }
else if (uv_set == 3) else if (uv_set == 3)
{ {
for (int j = 0; j < 3; j++)
{
m_vert[tri_list[cur_tri]].m4 = vec2(-1.0f);
m_vert[tri_list[cur_tri + 1]].m4 = vec2(-1.0f);
m_vert[tri_list[cur_tri + 2]].m4 = vec2(-1.0f);
}
//uv[0] = vec2(-1.0f);
//uv[1] = vec2(-1.0f);
//uv[2] = vec2(-1.0f);
/*
bool tri_present = false; bool tri_present = false;
for (int j = 0; j < tri_done.Count(); j++) for (int j = 0; j < tri_done.Count(); j++)
if (cur_tri == tri_done[j]) if (cur_tri == tri_done[j])
@@ -794,6 +805,7 @@ void EasyMesh::ComputeTexCoord(float uv_scale, int uv_offset)
if (!tri_present) if (!tri_present)
tri_done << cur_tri; tri_done << cur_tri;
tri_check.Remove(0); tri_check.Remove(0);
*/
} }


if (tri_check.Count() == 0 && tri_done.Count() != tri_count) if (tri_check.Count() == 0 && tri_done.Count() != tri_count)
@@ -820,6 +832,13 @@ void EasyMesh::SetVertColor(vec4 const &color)
m_vert[i].m3 = color; m_vert[i].m3 = color;
} }


//-----------------------------------------------------------------------------
void EasyMesh::SetTexCoordData(vec2 const &new_offset, vec2 const &new_scale)
{
m_texcoord_offset = new_offset;
m_texcoord_scale = new_scale;
}

//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void EasyMesh::SetCurVertNormal(vec3 const &normal) void EasyMesh::SetCurVertNormal(vec3 const &normal)
{ {
@@ -832,6 +851,15 @@ void EasyMesh::SetCurVertColor(vec4 const &color)
m_vert[m_vert.Count() - 1].m3 = color; m_vert[m_vert.Count() - 1].m3 = color;
} }


//-----------------------------------------------------------------------------
void EasyMesh::SetCurVertTexCoord(vec2 const &texcoord)
{
#if VERTEX_USEAGE == VU_BONES
#elif VERTEX_USEAGE == VU_TEX_UV
m_vert[m_vert.Count() - 1].m4 = (texcoord * m_texcoord_scale) + m_texcoord_offset;
#endif
}

//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void EasyMesh::Translate(vec3 const &v) void EasyMesh::Translate(vec3 const &v)
{ {
@@ -840,14 +868,14 @@ void EasyMesh::Translate(vec3 const &v)
} }


//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void EasyMesh::RotateX(float t) { Rotate(t, vec3(1, 0, 0)); }
void EasyMesh::RotateY(float t) { Rotate(t, vec3(0, 1, 0)); }
void EasyMesh::RotateZ(float t) { Rotate(t, vec3(0, 0, 1)); }
void EasyMesh::RotateX(float angle) { Rotate(angle, vec3(1, 0, 0)); }
void EasyMesh::RotateY(float angle) { Rotate(angle, vec3(0, 1, 0)); }
void EasyMesh::RotateZ(float angle) { Rotate(angle, vec3(0, 0, 1)); }


//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void EasyMesh::Rotate(float t, vec3 const &axis)
void EasyMesh::Rotate(float angle, vec3 const &axis)
{ {
mat3 m = mat3::rotate(t, axis);
mat3 m = mat3::rotate(angle, axis);
for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++) for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
{ {
m_vert[i].m1 = m * m_vert[i].m1; m_vert[i].m1 = m * m_vert[i].m1;
@@ -906,8 +934,8 @@ void EasyMesh::TaperX(float y, float z, float xoff)
/* FIXME: this code breaks normals! */ /* FIXME: this code breaks normals! */
for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++) for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
{ {
m_vert[i].m1.y *= 1.f + (y * m_vert[i].m1.x + xoff);
m_vert[i].m1.z *= 1.f + (z * m_vert[i].m1.x + xoff);
m_vert[i].m1.y *= 1.f + (y * abs(m_vert[i].m1.x) + xoff);
m_vert[i].m1.z *= 1.f + (z * abs(m_vert[i].m1.x) + xoff);
} }
} }


@@ -916,8 +944,8 @@ void EasyMesh::TaperY(float x, float z, float yoff)
{ {
for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++) for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
{ {
m_vert[i].m1.x *= 1.f + (x * m_vert[i].m1.y + yoff);
m_vert[i].m1.z *= 1.f + (z * m_vert[i].m1.y + yoff);
m_vert[i].m1.x *= 1.f + (x * abs(m_vert[i].m1.y) + yoff);
m_vert[i].m1.z *= 1.f + (z * abs(m_vert[i].m1.y) + yoff);
} }
} }


@@ -926,8 +954,8 @@ void EasyMesh::TaperZ(float x, float y, float zoff)
{ {
for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++) for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
{ {
m_vert[i].m1.x *= 1.f + (x * m_vert[i].m1.z + zoff);
m_vert[i].m1.y *= 1.f + (y * m_vert[i].m1.z + zoff);
m_vert[i].m1.x *= 1.f + (x * abs(m_vert[i].m1.z) + zoff);
m_vert[i].m1.y *= 1.f + (y * abs(m_vert[i].m1.z) + zoff);
} }
} }


@@ -979,12 +1007,21 @@ void EasyMesh::DupAndScale(vec3 const &s)


//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void EasyMesh::AppendCylinder(int nsides, float h, float r1, float r2, void EasyMesh::AppendCylinder(int nsides, float h, float r1, float r2,
int dualside, int smooth)
int dualside, int smooth, int close)
{ {
//SAVE
vec4 Saved_Color = m_color;
vec4 Saved_Color2 = m_color2;
vec2 Save_texcoord_offset = m_texcoord_offset;
vec2 Save_texcoord_scale = m_texcoord_scale;

int vbase = m_vert.Count(); int vbase = m_vert.Count();


mat3 rotmat = mat3::rotate(360.0f / nsides, 0.f, 1.f, 0.f);
mat3 rotmat = mat3::rotate(360.0f / (float)nsides, 0.f, 1.f, 0.f);
vec3 p1(r1, -h * .5f, 0.f), p2(r2, h * .5f, 0.f), n; vec3 p1(r1, -h * .5f, 0.f), p2(r2, h * .5f, 0.f), n;
vec2 uv1(.0f, .0f), uv2(.0f, 1.0f), uvadd(1.0f / (float)nsides, .0f);
if (close)
SetTexCoordData(vec2(.0f), vec2(1.0f, .5f));


/* Construct normal */ /* Construct normal */
if (r2 != .0f) if (r2 != .0f)
@@ -1000,8 +1037,8 @@ void EasyMesh::AppendCylinder(int nsides, float h, float r1, float r2,
* means duplicating the vertices again... */ * means duplicating the vertices again... */
for (int i = 0; i < nsides; i++) for (int i = 0; i < nsides; i++)
{ {
AddVertex(p1); SetCurVertNormal(n);
AddVertex(p2); SetCurVertNormal(n);
AddVertex(p1); SetCurVertNormal(n); SetCurVertTexCoord(uv1);
AddVertex(p2); SetCurVertNormal(n); SetCurVertTexCoord(uv2);
SetCurVertColor(m_color2); SetCurVertColor(m_color2);


if (smooth) if (smooth)
@@ -1012,13 +1049,13 @@ void EasyMesh::AppendCylinder(int nsides, float h, float r1, float r2,
AppendQuad(i * 2, i * 2 + 1, j * 2 + 1, j * 2, vbase); AppendQuad(i * 2, i * 2 + 1, j * 2 + 1, j * 2, vbase);
} }


p1 = rotmat * p1;
p2 = rotmat * p2;
p1 = rotmat * p1; uv1 += uvadd;
p2 = rotmat * p2; uv2 += uvadd;


if (!smooth) if (!smooth)
{ {
AddVertex(p1); SetCurVertNormal(n);
AddVertex(p2); SetCurVertNormal(n);
AddVertex(p1); SetCurVertNormal(n); SetCurVertTexCoord(uv1);
AddVertex(p2); SetCurVertNormal(n); SetCurVertTexCoord(uv2);
SetCurVertColor(m_color2); SetCurVertColor(m_color2);


AppendQuad(i * 4 + 2, i * 4 + 3, i * 4 + 1, i * 4, vbase); AppendQuad(i * 4 + 2, i * 4 + 3, i * 4 + 1, i * 4, vbase);
@@ -1028,6 +1065,34 @@ void EasyMesh::AppendCylinder(int nsides, float h, float r1, float r2,


n = rotmat * n; n = rotmat * n;
} }

if (close)
{
//START
OpenBrace();
//LOWER DISC
SetTexCoordData(vec2(.0f, .5f), vec2(.5f, .5f));
SetCurColor(m_color);
AppendDisc(nsides, r1);
Translate(vec3(.0f, h, .0f));
RotateX(180.0f);
//UPPER DISC
SetTexCoordData(vec2(.5f, .5f), vec2(.5f, .5f));
SetCurColor(m_color2);
AppendDisc(nsides, r2);
Translate(vec3(.0f, h * .5f, .0f));
CloseBrace();
}
//RESTORE
SetCurColor(Saved_Color);
SetCurColor2(Saved_Color2);
SetTexCoordData(Save_texcoord_offset, Save_texcoord_scale);
}

//-----------------------------------------------------------------------------
void EasyMesh::AppendSphere(int ndivisions, float r)
{
AppendCapsule(ndivisions, 0.f, r);
} }


//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -1036,11 +1101,18 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float r)
int ibase = m_indices.Count(); int ibase = m_indices.Count();


Array<vec3> vertices; Array<vec3> vertices;
float uv_h = 0;
float uv_r = 0;


/* FIXME: we don't know how to handle even-divided capsules, so we /* FIXME: we don't know how to handle even-divided capsules, so we
* force the count to be odd. */ * force the count to be odd. */
if (h) if (h)
{
ndivisions |= 1; ndivisions |= 1;
//calculate uv h&r percents
uv_h = (float)h / (float)(h + r * 2);
uv_r = (float)r / (float)(h + r * 2);
}


/* Fill in the icosahedron vertices, rotating them so that there /* Fill in the icosahedron vertices, rotating them so that there
* is a vertex at [0 1 0] and [0 -1 0] after normalisation. */ * is a vertex at [0 1 0] and [0 -1 0] after normalisation. */
@@ -1083,14 +1155,31 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float r)
p[0] + vb, p[0] + vb,
p[0] + vc, p[0] + vc,
p[0] + vb + vc }; p[0] + vb + vc };
vec2 uv[4];


/* FIXME: when we normalise here, we get a volume that is slightly /* FIXME: when we normalise here, we get a volume that is slightly
* smaller than the sphere of radius 1, since we are not using * smaller than the sphere of radius 1, since we are not using
* the midradius. */ * the midradius. */
for (int k = 0; k < 4; k++) for (int k = 0; k < 4; k++)
p[k] = normalize(p[k]) * r;
{
//keep normalized until the end of the UV calculations
p[k] = normalize(p[k]);

uv[k].x = (lol::atan2(p[k].z, p[k].x) + (float)M_PI) / ((float)M_PI * 2.f);
if (abs(p[k].y) >= 1.0f)
uv[k].x = -1.f;
uv[k].y = (lol::atan2(p[k].y, dot(p[k], normalize(p[k] * vec3(1.f,0.f,1.f)))) + (float)M_PI_2) / (float)M_PI;
if (h)
{
if (uv[k].y > .5f)
uv[k].y = uv_r + uv_h + (uv[k].y - .5f) * uv_r * 2.f;
else
uv[k].y *= uv_r * 2.f;
}
p[k] *= r;
}


/* If this is a capsule, grow in the Z direction */
/* If this is a capsule, grow in the Y direction */
if (h > 0.f) if (h > 0.f)
{ {
for (int k = 0; k < 4; k++) for (int k = 0; k < 4; k++)
@@ -1098,20 +1187,40 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float r)
} }


/* Add zero, one or two triangles */ /* Add zero, one or two triangles */
if (y < line - 1)
{
AddVertex(p[0]);
AddVertex(p[1]);
AddVertex(p[2]);
AppendTriangle(0, 2, 1, m_vert.Count() - 3);
}

if (y < line - 2)
int id[] = { 0, 1, 2,
1, 3 ,2 };
int l = 6;
while ((l -= 3) >= 0)
{ {
AddVertex(p[1]);
AddVertex(p[3]);
AddVertex(p[2]);
AppendTriangle(0, 2, 1, m_vert.Count() - 3);
if ((l == 0 && y < line - 1) || (l == 3 && y < line - 2))
{
int k = -1;
while (++k < 3)
{
int rid[] = { id[k + l], id[(k + 1) % 3 + l] };
if (uv[rid[0]].x >= .0f &&
uv[rid[1]].x >= .0f &&
abs(uv[rid[0]].x - uv[rid[1]].x) > .5f)
{
if (uv[rid[0]].x < uv[rid[1]].x)
uv[rid[0]].x += 1.0f;
else
uv[rid[1]].x += 1.0f;
}
}
k = -1;
while (++k < 3)
{
int rid[] = { id[k + l], id[(k + 1) % 3 + l], id[(k + 2) % 3 + l] };
AddVertex(p[rid[0]]);
if (uv[rid[0]].x < .0f)
SetCurVertTexCoord(vec2((uv[rid[1]].x + uv[rid[2]].x) * .5f,
uv[rid[0]].y));
else
SetCurVertTexCoord(uv[rid[0]]);
}
AppendTriangle(0, 2, 1, m_vert.Count() - 3);
}
} }


y++; y++;
@@ -1127,15 +1236,6 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float r)
ComputeNormals(ibase, m_indices.Count() - ibase); ComputeNormals(ibase, m_indices.Count() - ibase);
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendSphere(int ndivisions, vec3 const &size)
{
OpenBrace();
AppendCapsule(ndivisions, 0.f, 1.f);
Scale(size);
CloseBrace();
}

//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void EasyMesh::AppendTorus(int ndivisions, float r1, float r2) void EasyMesh::AppendTorus(int ndivisions, float r1, float r2)
{ {
@@ -1151,16 +1251,22 @@ void EasyMesh::AppendTorus(int ndivisions, float r1, float r2)
{ {
int i2 = (i + di) % nidiv; int i2 = (i + di) % nidiv;
int j2 = (j + dj) % njdiv; int j2 = (j + dj) % njdiv;
float x = 0.5f * (r1 + r2) + 0.5f * (r2 - r1) * (float)lol::cos(2.0 * M_PI * i2 / nidiv);

//Location on the donut
float x = 0.5f * (r2 - r1) * (float)lol::cos(2.0 * M_PI * i2 / nidiv) + 0.5f * (r1 + r2);
float y = 0.5f * (r2 - r1) * (float)lol::sin(2.0 * M_PI * i2 / nidiv); float y = 0.5f * (r2 - r1) * (float)lol::sin(2.0 * M_PI * i2 / nidiv);
float z = 0.0f; float z = 0.0f;


//Center circle
float ca = (float)lol::cos(2.0 * M_PI * j2 / njdiv); float ca = (float)lol::cos(2.0 * M_PI * j2 / njdiv);
float sa = (float)lol::sin(2.0 * M_PI * j2 / njdiv); float sa = (float)lol::sin(2.0 * M_PI * j2 / njdiv);

//Actual location
float x2 = x * ca - z * sa; float x2 = x * ca - z * sa;
float z2 = z * ca + x * sa; float z2 = z * ca + x * sa;


AddVertex(vec3(x2, y, z2)); AddVertex(vec3(x2, y, z2));
SetCurVertTexCoord(vec2((float)(i + di) / (float)nidiv, (float)(j + dj) / (float)nidiv));
} }


AppendTriangle(0, 2, 3, m_vert.Count() - 4); AppendTriangle(0, 2, 3, m_vert.Count() - 4);
@@ -1202,35 +1308,62 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth)


vec3 d = size * 0.5f; vec3 d = size * 0.5f;


//Side vertices
AddVertex(vec3(-d.x, -d.y, -d.z - chamf)); AddVertex(vec3(-d.x, -d.y, -d.z - chamf));
SetCurVertTexCoord(vec2(0.f, .5f));
AddVertex(vec3(-d.x, +d.y, -d.z - chamf)); AddVertex(vec3(-d.x, +d.y, -d.z - chamf));
SetCurVertTexCoord(vec2(0.f, 0.f));
AddVertex(vec3(+d.x, +d.y, -d.z - chamf)); AddVertex(vec3(+d.x, +d.y, -d.z - chamf));
SetCurVertTexCoord(vec2(.5f, 0.f));
AddVertex(vec3(+d.x, -d.y, -d.z - chamf)); AddVertex(vec3(+d.x, -d.y, -d.z - chamf));
SetCurVertTexCoord(vec2(.5f, .5f));


AddVertex(vec3(-d.x - chamf, -d.y, +d.z)); AddVertex(vec3(-d.x - chamf, -d.y, +d.z));
SetCurVertTexCoord(vec2(.5f, 0.5f));
AddVertex(vec3(-d.x - chamf, +d.y, +d.z)); AddVertex(vec3(-d.x - chamf, +d.y, +d.z));
SetCurVertTexCoord(vec2(.5f, 0.f));
AddVertex(vec3(-d.x - chamf, +d.y, -d.z)); AddVertex(vec3(-d.x - chamf, +d.y, -d.z));
SetCurVertTexCoord(vec2(1.f, 0.f));
AddVertex(vec3(-d.x - chamf, -d.y, -d.z)); AddVertex(vec3(-d.x - chamf, -d.y, -d.z));
SetCurVertTexCoord(vec2(1.f, .5f));


AddVertex(vec3(+d.x, -d.y, +d.z + chamf)); AddVertex(vec3(+d.x, -d.y, +d.z + chamf));
SetCurVertTexCoord(vec2(0.f, .5f));
AddVertex(vec3(+d.x, +d.y, +d.z + chamf)); AddVertex(vec3(+d.x, +d.y, +d.z + chamf));
SetCurVertTexCoord(vec2(0.f, 0.f));
AddVertex(vec3(-d.x, +d.y, +d.z + chamf)); AddVertex(vec3(-d.x, +d.y, +d.z + chamf));
SetCurVertTexCoord(vec2(.5f, 0.f));
AddVertex(vec3(-d.x, -d.y, +d.z + chamf)); AddVertex(vec3(-d.x, -d.y, +d.z + chamf));
SetCurVertTexCoord(vec2(.5f, .5f));


AddVertex(vec3(+d.x + chamf, -d.y, -d.z)); AddVertex(vec3(+d.x + chamf, -d.y, -d.z));
SetCurVertTexCoord(vec2(.5f, .5f));
AddVertex(vec3(+d.x + chamf, +d.y, -d.z)); AddVertex(vec3(+d.x + chamf, +d.y, -d.z));
SetCurVertTexCoord(vec2(.5f, .0f));
AddVertex(vec3(+d.x + chamf, +d.y, +d.z)); AddVertex(vec3(+d.x + chamf, +d.y, +d.z));
SetCurVertTexCoord(vec2(1.f, .0f));
AddVertex(vec3(+d.x + chamf, -d.y, +d.z)); AddVertex(vec3(+d.x + chamf, -d.y, +d.z));
SetCurVertTexCoord(vec2(1.f, .5f));


//Bottom vertices
AddVertex(vec3(-d.x, -d.y - chamf, +d.z)); AddVertex(vec3(-d.x, -d.y - chamf, +d.z));
SetCurVertTexCoord(vec2(0.f, 1.f));
AddVertex(vec3(-d.x, -d.y - chamf, -d.z)); AddVertex(vec3(-d.x, -d.y - chamf, -d.z));
SetCurVertTexCoord(vec2(0.f, .5f));
AddVertex(vec3(+d.x, -d.y - chamf, -d.z)); AddVertex(vec3(+d.x, -d.y - chamf, -d.z));
SetCurVertTexCoord(vec2(.5f, .5f));
AddVertex(vec3(+d.x, -d.y - chamf, +d.z)); AddVertex(vec3(+d.x, -d.y - chamf, +d.z));
SetCurVertTexCoord(vec2(.5f, 1.f));


//Top vertices
AddVertex(vec3(-d.x, +d.y + chamf, -d.z)); AddVertex(vec3(-d.x, +d.y + chamf, -d.z));
SetCurVertTexCoord(vec2(0.f, 1.f));
AddVertex(vec3(-d.x, +d.y + chamf, +d.z)); AddVertex(vec3(-d.x, +d.y + chamf, +d.z));
SetCurVertTexCoord(vec2(0.f, .5f));
AddVertex(vec3(+d.x, +d.y + chamf, +d.z)); AddVertex(vec3(+d.x, +d.y + chamf, +d.z));
SetCurVertTexCoord(vec2(.5f, .5f));
AddVertex(vec3(+d.x, +d.y + chamf, -d.z)); AddVertex(vec3(+d.x, +d.y + chamf, -d.z));
SetCurVertTexCoord(vec2(.5f, 1.f));


/* The 6 quads on each side of the box */ /* The 6 quads on each side of the box */
for (int i = 0; i < 24; i += 4) for (int i = 0; i < 24; i += 4)
@@ -1288,31 +1421,35 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth)
void EasyMesh::AppendStar(int nbranches, float r1, float r2, void EasyMesh::AppendStar(int nbranches, float r1, float r2,
int fade, int fade2) int fade, int fade2)
{ {
//TODO: It would probably be good to think of another way of UV painting this, like "branch repeating"
int vbase = m_vert.Count(); int vbase = m_vert.Count();
float maxr = max(r1, r2);


AddVertex(vec3(0.f, 0.f, 0.f));
AddVertex(vec3(0.f, 0.f, 0.f)); SetCurVertTexCoord(vec2(.5f, .5f));


mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f); mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f);
vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f); vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f);
vec3 uv1(0.f, 0.f, -.5f * ((float)r1 / maxr)),
uv2(0.f, 0.f, -.5f * ((float)r2 / maxr));


p2 = rotmat * p2;
p2 = rotmat * p2; uv2 = rotmat * uv2;
rotmat = rotmat * rotmat; rotmat = rotmat * rotmat;


for (int i = 0; i < nbranches; i++) for (int i = 0; i < nbranches; i++)
{ {
AddVertex(p1);
AddVertex(p1); SetCurVertTexCoord(uv1.xz + vec2(.5f));
if (fade2) if (fade2)
SetCurVertColor(m_color2); SetCurVertColor(m_color2);


AddVertex(p2);
AddVertex(p2); SetCurVertTexCoord(uv2.xz + vec2(.5f));
if (fade) if (fade)
SetCurVertColor(m_color2); SetCurVertColor(m_color2);


AppendQuad(0, 2 * i + 1, 2 * i + 2, (2 * i + 3) % (2 * nbranches), AppendQuad(0, 2 * i + 1, 2 * i + 2, (2 * i + 3) % (2 * nbranches),
vbase); vbase);


p1 = rotmat * p1;
p2 = rotmat * p2;
p1 = rotmat * p1; uv1 = rotmat * uv1;
p2 = rotmat * p2; uv2 = rotmat * uv2;
} }
} }


@@ -1321,33 +1458,38 @@ void EasyMesh::AppendExpandedStar(int nbranches, float r1,
float r2, float extrar) float r2, float extrar)
{ {
int vbase = m_vert.Count(); int vbase = m_vert.Count();
float maxr = (float)max(max(r1, r2), max(r1 + extrar, r2 + extrar));


AddVertex(vec3(0.f, 0.f, 0.f));
AddVertex(vec3(0.f, 0.f, 0.f)); SetCurVertTexCoord(vec2(.5f, .5f));


mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f); mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f);
vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f), vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f),
p3(r1 + extrar, 0.f, 0.f), p4(r2 + extrar, 0.f, 0.f);; p3(r1 + extrar, 0.f, 0.f), p4(r2 + extrar, 0.f, 0.f);;
vec3 uv1(0.f, 0.f, -.5f * ((float)r1 / maxr)),
uv2(0.f, 0.f, -.5f * ((float)r2 / maxr)),
uv3(0.f, 0.f, -.5f * ((float)(r1 + extrar) / maxr)),
uv4(0.f, 0.f, -.5f * ((float)(r2 + extrar) / maxr));


p2 = rotmat * p2;
p4 = rotmat * p4;
p2 = rotmat * p2; uv2 = rotmat * uv2;
p4 = rotmat * p4; uv4 = rotmat * uv4;
rotmat = rotmat * rotmat; rotmat = rotmat * rotmat;


for (int i = 0; i < nbranches; i++) for (int i = 0; i < nbranches; i++)
{ {
AddVertex(p1);
AddVertex(p2);
AddVertex(p3); SetCurVertColor(m_color2);
AddVertex(p4); SetCurVertColor(m_color2);
AddVertex(p1); SetCurVertTexCoord(uv1.xz + vec2(.5f));
AddVertex(p2); SetCurVertTexCoord(uv2.xz + vec2(.5f));
AddVertex(p3); SetCurVertTexCoord(uv3.xz + vec2(.5f)); SetCurVertColor(m_color2);
AddVertex(p4); SetCurVertTexCoord(uv4.xz + vec2(.5f)); SetCurVertColor(m_color2);


int j = (i + 1) % nbranches; int j = (i + 1) % nbranches;
AppendQuad(0, 4 * i + 1, 4 * i + 2, 4 * j + 1, vbase); AppendQuad(0, 4 * i + 1, 4 * i + 2, 4 * j + 1, vbase);
AppendQuad(4 * i + 1, 4 * i + 3, 4 * i + 4, 4 * i + 2, vbase); AppendQuad(4 * i + 1, 4 * i + 3, 4 * i + 4, 4 * i + 2, vbase);
AppendQuad(4 * j + 1, 4 * i + 2, 4 * i + 4, 4 * j + 3, vbase); AppendQuad(4 * j + 1, 4 * i + 2, 4 * i + 4, 4 * j + 3, vbase);


p1 = rotmat * p1;
p2 = rotmat * p2;
p3 = rotmat * p3;
p4 = rotmat * p4;
p1 = rotmat * p1; uv1 = rotmat * uv1;
p2 = rotmat * p2; uv2 = rotmat * uv2;
p3 = rotmat * p3; uv3 = rotmat * uv3;
p4 = rotmat * p4; uv4 = rotmat * uv4;
} }
} }


@@ -1356,18 +1498,20 @@ void EasyMesh::AppendDisc(int nsides, float r, int fade)
{ {
int vbase = m_vert.Count(); int vbase = m_vert.Count();


AddVertex(vec3(0.f, 0.f, 0.f));
AddVertex(vec3(0.f, 0.f, 0.f)); SetCurVertTexCoord(vec2(.5f, .5f));


mat3 rotmat = mat3::rotate(360.0f / nsides, 0.f, 1.f, 0.f); mat3 rotmat = mat3::rotate(360.0f / nsides, 0.f, 1.f, 0.f);
vec3 p1(r, 0.f, 0.f); vec3 p1(r, 0.f, 0.f);
vec3 uv(.5f, .0f, .0f);


for (int i = 0; i < nsides; i++) for (int i = 0; i < nsides; i++)
{ {
AddVertex(p1);
AddVertex(p1); SetCurVertTexCoord(uv.xz + vec2(.5f, .5f));
if (fade) if (fade)
SetCurVertColor(m_color2); SetCurVertColor(m_color2);
AppendTriangle(0, i + 1, ((i + 1) % nsides) + 1, vbase); AppendTriangle(0, i + 1, ((i + 1) % nsides) + 1, vbase);
p1 = rotmat * p1; p1 = rotmat * p1;
uv = rotmat * uv;
} }
} }


@@ -1377,13 +1521,13 @@ void EasyMesh::AppendSimpleTriangle(float size, int fade)
mat3 m = mat3::rotate(120.f, 0.f, 1.f, 0.f); mat3 m = mat3::rotate(120.f, 0.f, 1.f, 0.f);
vec3 p(0.f, 0.f, size); vec3 p(0.f, 0.f, size);


AddVertex(p);
AddVertex(p); SetCurVertTexCoord(vec2(.5f, 0.133975f));
p = m * p; p = m * p;
AddVertex(p);
AddVertex(p); SetCurVertTexCoord(vec2(1.f, 1.f));
if (fade) if (fade)
SetCurVertColor(m_color2); SetCurVertColor(m_color2);
p = m * p; p = m * p;
AddVertex(p);
AddVertex(p); SetCurVertTexCoord(vec2(0.f, 1.f));
if (fade) if (fade)
SetCurVertColor(m_color2); SetCurVertColor(m_color2);


@@ -1399,16 +1543,16 @@ void EasyMesh::AppendSimpleQuad(float size, int fade)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void EasyMesh::AppendSimpleQuad(vec2 p1, vec2 p2, float z, int fade) void EasyMesh::AppendSimpleQuad(vec2 p1, vec2 p2, float z, int fade)
{ {
AddVertex(vec3(p2.x, z, -p1.y));
AddVertex(vec3(p2.x, z, -p2.y));
AddVertex(vec3(p1.x, z, -p2.y));
AddVertex(vec3(p2.x, z, -p1.y)); SetCurVertTexCoord(vec2(0.f, 1.f));
AddVertex(vec3(p2.x, z, -p2.y)); SetCurVertTexCoord(vec2(0.f, 0.f));
AddVertex(vec3(p1.x, z, -p2.y)); SetCurVertTexCoord(vec2(1.f, 0.f));
if (fade) if (fade)
SetCurVertColor(m_color2); SetCurVertColor(m_color2);
AddVertex(vec3(p1.x, z, -p1.y));
AddVertex(vec3(p1.x, z, -p1.y)); SetCurVertTexCoord(vec2(1.f, 1.f));
if (fade) if (fade)
SetCurVertColor(m_color2); SetCurVertColor(m_color2);


AppendQuad(3, 2, 1, 0, m_vert.Count() - 4);
AppendQuad(0, 1, 2, 3, m_vert.Count() - 4);
ComputeNormals(m_indices.Count() - 6, 6); ComputeNormals(m_indices.Count() - 6, 6);
} }


@@ -1430,6 +1574,7 @@ void EasyMesh::AppendCog(int nbsides, float h, float r10, float r20,


vec3 p[12]; vec3 p[12];


//Upper points
p[0] = vec3(r10, h * .5f, 0.f); p[0] = vec3(r10, h * .5f, 0.f);
p[1] = rotmat * p[0]; p[1] = rotmat * p[0];
p[2] = vec3(r1, h * .5f, 0.f); p[2] = vec3(r1, h * .5f, 0.f);
@@ -1437,6 +1582,7 @@ void EasyMesh::AppendCog(int nbsides, float h, float r10, float r20,
p[4] = smat1 * (rotmat * vec3(r1 + r12, h * .5f, 0.f)); p[4] = smat1 * (rotmat * vec3(r1 + r12, h * .5f, 0.f));
p[5] = smat2 * (rotmat * p[4]); p[5] = smat2 * (rotmat * p[4]);


//Lower points
p[6] = vec3(r20, h * -.5f, 0.f); p[6] = vec3(r20, h * -.5f, 0.f);
p[7] = rotmat * p[6]; p[7] = rotmat * p[6];
p[8] = vec3(r2, h * -.5f, 0.f); p[8] = vec3(r2, h * -.5f, 0.f);
@@ -1450,37 +1596,199 @@ void EasyMesh::AppendCog(int nbsides, float h, float r10, float r20,


rotmat = rotmat * rotmat; rotmat = rotmat * rotmat;


//UV base computation
float maxr = max(max(r1 + r12, r2 + r22), max(r10, r20));
float InLn = length(p[1] - p[0]);
float CogLn[8] = { .0f, .0f, .0f, .0f, .0f, .0f, .0f, .0f };
for (int i = 0; i < 3; i++)
{
for (int j = 0, k = 2; j < 8 && k < 12; j += 4, k += 6)
{
CogLn[j + i] = length(p[k + i + 1] - p[k + i]);
CogLn[j + 3] += CogLn[j + i];
if (i == 1) //Add 3to4 twice since it's automatically completed by +1 loop.
CogLn[j + 3] += CogLn[j + i];
}
}

//Choose the biggest cog length
int CogSrc = (CogLn[7] > CogLn[3])?(4):(0);
CogLn[3] = CogLn[CogSrc + 3];
for (int i = 0; i < 3; i++)
CogLn[i] = CogLn[CogSrc + i] / CogLn[CogSrc + 3];

//Calculate Cog Modifiers
vec2 InUV[2] = { vec2(.0f), vec2(.5f) };
vec2 CogUV[2] = { vec2(.0f), vec2(.5f) };
vec2 upadd = vec2(.25f, .75f);
vec2 lowadd = vec2(.75f, .75f);
{
if (h < InLn)
{
InUV[0].x = 1.0f;
InUV[0].y = h / InLn;
InUV[1].x = .0f;
InUV[1].y -= InUV[0].y * .5f;
}
else
{
InUV[0].x = InLn / h;
InUV[0].y = 1.0f;
InUV[1].x -= InUV[0].x * .5f;
InUV[1].y = .0f;
}
if (h < CogLn[3])
{
CogUV[0].x = 1.0f;
CogUV[0].y = h / CogLn[3];
CogUV[1].x = .0f;
CogUV[1].y -= CogUV[0].y * .5f;
}
else
{
CogUV[0].x = CogLn[3] / h;
CogUV[0].y = 1.0f;
CogUV[1].x -= CogUV[0].x * .5f;
CogUV[1].y = .0f;
}
if (InUV[0].x + CogUV[0].x < .5f)
{
InUV[1].x = .0f;
CogUV[1].x = .5f - CogUV[0].x;
upadd = vec2(.75f, .25f);
lowadd = vec2(.75f, .75f);
}
else if (InUV[0].y + CogUV[0].y < .5f)
{
InUV[1].y = .0f;
CogUV[1].y = .5f - CogUV[0].y;
}
else
{
InUV[0] *= .5f;
InUV[1] *= .5f;
CogUV[0] *= .5f;
CogUV[1] *= .5f;
InUV[1] += vec2(.5f, .0f);
}
}

//Build UV tab
vec2 uv[12]; float CogSz;
//Upper points
CogSz = 1.0f - CogLn[1];
uv[0] = vec2(0.f, 0.f) * InUV[0] + InUV[1];
uv[1] = vec2(1.f, 0.f) * InUV[0] + InUV[1];
uv[5] = vec2(CogSz, 0.f) * CogUV[0] + CogUV[1]; CogSz -= CogLn[2];
uv[4] = vec2(CogSz, 0.f) * CogUV[0] + CogUV[1]; CogSz -= CogLn[1];
uv[3] = vec2(CogSz, 0.f) * CogUV[0] + CogUV[1]; CogSz -= CogLn[0];
uv[2] = vec2(0.f, 0.f) * CogUV[0] + CogUV[1];

//Lower points
CogSz = 1.0f - CogLn[1];
uv[6] = vec2(0.f, 1.f) * InUV[0] + InUV[1];
uv[7] = vec2(1.f, 1.f) * InUV[0] + InUV[1];
uv[11] = vec2(CogSz, 1.f) * CogUV[0] + CogUV[1]; CogSz -= CogLn[2];
uv[10] = vec2(CogSz, 1.f) * CogUV[0] + CogUV[1]; CogSz -= CogLn[1];
uv[ 9] = vec2(CogSz, 1.f) * CogUV[0] + CogUV[1]; CogSz -= CogLn[0];
uv[ 8] = vec2(0.f, 1.f) * CogUV[0] + CogUV[1];

//Gear generation loop
for (int i = 0; i < nbsides; i++) for (int i = 0; i < nbsides; i++)
{ {
int j = 3 * 12 * i,
k = 3 * 12 * ((i + 1) % nbsides);

int q[] = { /* The top and bottom faces */
j, j, j, j,
j, j, j, j,
j, j, k, k,
k, k, j, j,
j, j, j, k,
k, j, j, j,
/* The inner side quads */
j, j, j, j,
j, k, k, j,
/* The outer side quads */
j, j, j, j,
j, j, j, j,
j, j, j, j,
k, j, j, k
};
int m[] = { /* The top and bottom faces */
0, 2, 3, 1,
7, 9, 8, 6,
1, 3, 2, 0,
6, 8, 9, 7,
3, 4, 5, 2,
8, 11, 10, 9,
/* The inner side quads */
0, 1, 7, 6,
1, 0, 6, 7,
/* The outer side quads */
3, 2, 8, 9,
4, 3, 9, 10,
5, 4, 10, 11,
2, 5, 11, 8
};
int a[] = { /* The top and bottom faces */
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
/* The inner side quads */
1, 1, 1, 1,
2, 2, 2, 2,
/* The outer side quads */
1, 1, 1, 1,
1, 2, 2, 1,
1, 2, 2, 1,
2, 2, 2, 2
};

/* Each vertex will share three faces, so three different /* Each vertex will share three faces, so three different
* normals, therefore we add each vertex three times. */ * normals, therefore we add each vertex three times. */
for (int n = 0; n < 3 * 12; n++) for (int n = 0; n < 3 * 12; n++)
{ {
AddVertex(p[n / 3]);
if (n / 3 >= 6)
int d = n / 3;
int m = d % 6;
AddVertex(p[d]);
if (n % 3 == 0) //Top-Bottom logic
{
vec2 tmp = (p[d].xz / maxr);
vec2 add;
if (d >= 6)
{
tmp *= -1.0f;
add = lowadd;
}
else
add = upadd;
SetCurVertTexCoord(tmp * vec2(.25f) + add);
}
else if (m == 0 || m == 1) //inner Logic
SetCurVertTexCoord(uv[d]);
else //Cog logic
{
if (m == 2 && n % 3 == 2)
SetCurVertTexCoord(vec2(1.f, (d == 2)?(0.f):(1.f)) * CogUV[0] + CogUV[1]);
else
SetCurVertTexCoord(uv[d]);
}
if (d >= 6)
SetCurVertColor(m_color2); SetCurVertColor(m_color2);
} }


int j = 3 * 12 * i, k = 3 * 12 * ((i + 1) % nbsides);

/* The top and bottom faces */
AppendQuad(j, j + 6, j + 9, j + 3, vbase);
AppendQuad(j + 21, j + 27, j + 24, j + 18, vbase);
AppendQuad(j + 3, j + 9, k + 6, k, vbase);
AppendQuad(k + 18, k + 24, j + 27, j + 21, vbase);
AppendQuad(j + 9, j + 12, j + 15, k + 6, vbase);
AppendQuad(k + 24, j + 33, j + 30, j + 27, vbase);

/* The inner side quads */
AppendQuad(j + 1, j + 4, j + 22, j + 19, vbase);
AppendQuad(j + 5, k + 2, k + 20, j + 23, vbase);

/* The outer side quads */
AppendQuad(j + 10, j + 7, j + 25, j + 28, vbase);
AppendQuad(j + 13, j + 11, j + 29, j + 31, vbase);
AppendQuad(j + 16, j + 14, j + 32, j + 34, vbase);
AppendQuad(k + 8, j + 17, j + 35, k + 26, vbase);

int l = -4;
while ((l += 4) < 48)
AppendQuad(q[l + 0] + m[l + 0] * 3 + a[l + 0],
q[l + 1] + m[l + 1] * 3 + a[l + 1],
q[l + 2] + m[l + 2] * 3 + a[l + 2],
q[l + 3] + m[l + 3] * 3 + a[l + 3],
vbase);
for (int n = 0; n < 12; n++) for (int n = 0; n < 12; n++)
p[n] = rotmat * p[n]; p[n] = rotmat * p[n];
} }


+ 169
- 8
src/easymesh/easymesh.h 查看文件

@@ -78,6 +78,21 @@ private:
Array<int> master_list; Array<int> master_list;
}; };


struct MeshBuildOperation
{
enum Value
{
Scale_Winding = 1 << 0,

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; }
};

class EasyMesh class EasyMesh
{ {
friend class EasyMeshParser; friend class EasyMeshParser;
@@ -98,21 +113,33 @@ private:
private: private:
void MeshCsg(CSGUsage csg_operation); void MeshCsg(CSGUsage csg_operation);
public: 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 CsgSubstract() { MeshCsg(CSGUsage::Substract); } void CsgSubstract() { MeshCsg(CSGUsage::Substract); }
/* [cmd:csgsl] Performs a Substract operation without keeping the mesh1 part */
void CsgSubstractLoss() { MeshCsg(CSGUsage::SubstractLoss); } void CsgSubstractLoss() { 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); }


public: public:
/* [cmd:[] from this point onward, any operation will not be performed on previous vertices */
void OpenBrace(); void OpenBrace();
/* [cmd:]] Merge current vertices with previous context */
void CloseBrace(); void CloseBrace();
/* [cmd:tsw] When activation, on negative-scaling, normal fixing will not occur */
void ToggleScaleWinding(); void ToggleScaleWinding();
/* [cmd:sc] Set vertices color */
void SetCurColor(vec4 const &color); void SetCurColor(vec4 const &color);
/* [cmd:scb] Set vertices color 2 */
void SetCurColor2(vec4 const &color); void SetCurColor2(vec4 const &color);


private: private:
//-------------------------------------------------------------------------
//Internal : Basic triangle/vertex operations
//-------------------------------------------------------------------------
void AddVertex(vec3 const &coord); void AddVertex(vec3 const &coord);
void AddDuplicateVertex(int i); void AddDuplicateVertex(int i);
void AppendQuad(int i1, int i2, int i3, int i4, int base); void AppendQuad(int i1, int i2, int i3, int i4, int base);
@@ -120,52 +147,183 @@ private:
void AppendTriangle(int i1, int i2, int i3, int base); void AppendTriangle(int i1, int i2, int i3, int base);
void AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base); void AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base);
void ComputeNormals(int start, int vcount); void ComputeNormals(int start, int vcount);
public:
public: //DEBUG
void ComputeTexCoord(float uv_scale, int uv_offset); void ComputeTexCoord(float uv_scale, int uv_offset);

//-------------------------------------------------------------------------
//Vertices operations
//-------------------------------------------------------------------------
void SetVertColor(vec4 const &color); void SetVertColor(vec4 const &color);
void SetTexCoordData(vec2 const &new_offset, vec2 const &new_scale);


void SetCurVertNormal(vec3 const &normal); void SetCurVertNormal(vec3 const &normal);
void SetCurVertColor(vec4 const &color); void SetCurVertColor(vec4 const &color);
void SetCurVertTexCoord(vec2 const &texcoord);


public: public:
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
//Mesh transform operations //Mesh transform operations
//------------------------------------------------------------------------- //-------------------------------------------------------------------------

/* [cmd:t/tx/ty/tz] Translate vertices
- v : Translation quantity.
*/
void Translate(vec3 const &v); void Translate(vec3 const &v);
void RotateX(float t);
void RotateY(float t);
void RotateZ(float t);
void Rotate(float t, vec3 const &axis);
/* 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 o2v *= (1.0 + rand(r))
- r : jitter maximum value.
*/
void RadialJitter(float r); void RadialJitter(float r);
//TODO : twist
//TODO : bend
//TODO : stretch
//TODO : shear
/* [cmd:tax] multiply y&z by (1.0 + (n * x + xoff))
- y : value of n for y.
- z : value of n for z.
- xoff : value of xoff.
*/
void TaperX(float y, float z, float xoff); void TaperX(float y, float z, float xoff);
/* [cmd:tay] multiply x&z by (1.0 + (n * y + yoff))
- x : value of n for x.
- z : value of n for z.
- yoff : value of yoff.
*/
void TaperY(float x, float z, float yoff); void TaperY(float x, float z, float yoff);
/* [cmd:taz] multiply x&y by (1.0 + (n * z + zoff))
- x : value of n for x.
- y : value of n for y.
- zoff : value of zoff.
*/
void TaperZ(float x, float y, float zoff); void TaperZ(float x, float y, float zoff);
/* [cmd:s/sx/sy/sz] Scale vertices
- s : scale quantity.
*/
void Scale(vec3 const &s); void Scale(vec3 const &s);
/* [cmd:mx] Mirror vertices through X-plane
Acts as an OpenBrace
*/
void MirrorX(); void MirrorX();
/* [cmd:my] Mirror vertices through Y-plane
Acts as an OpenBrace
*/
void MirrorY(); void MirrorY();
/* [cmd:mz] Mirror vertices through Z-plane
Acts as an OpenBrace
*/
void MirrorZ(); void MirrorZ();
/* [no-cmd] Duplicates vertices and scale duplicate
Acts as an OpenBrace
*/
void DupAndScale(vec3 const &s); void DupAndScale(vec3 const &s);
/* [cmd:ch] Performs a chamfer operation //TODO : Make it work.
- f : Chamfer quantity.
*/
void Chamfer(float f); void Chamfer(float f);


//------------------------------------------------------------------------- //-------------------------------------------------------------------------
//Mesh shape operations //Mesh shape operations
//------------------------------------------------------------------------- //-------------------------------------------------------------------------

/* [cmd:ac] Cylinder centered on (0,0,0) with BBox [-max(r1, r2), -.5*h, -max(r1, r2)][max(r1, r2), .5*h, max(r1, r2)]
- nbsides : Number of sides.
- h : Height of the cylinder.
- r1 : Lower radius. TODO:convert to diameter to be coherent with other funcs
- r2 : Upper radius. TODO:convert to diameter to be coherent with other funcs
- dualside : if (1) will also create inner sides : TOOD:TOREMOVE?? : needed ?
- smooth : if (1) will smooth normals : TOOD:TOREMOVE : smooth should be handled elsewhere
- close : if (1) will add discs to close the cylinder
*/
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, int close);
/* [cmd:asph] Sphere centered on (0,0,0) with BBox [-size][size]
- ndivisions : number of subdivisions each Sphere triangle will sustain.
- size : size of the Sphere.
*/
void AppendSphere(int ndivisions, float r);
/* [cmd:acap] Capsule centered on (0,0,0) with BBox [-r, -(r+h) ,-r][r, (r+h) ,r]
- ndivisions : number of subdivisions each Sphere triangle will sustain.
- h : Inner height.
- r : Radius. TODO:convert to diameter to be coherent with other funcs
*/
void AppendCapsule(int ndivisions, float h, float r); void AppendCapsule(int ndivisions, float h, float r);
void AppendSphere(int ndivisions, vec3 const &size);
/* [cmd:ato] Torus centered on (0,0,0) with BBox [-r2][r2]
- ndivisions : number of subdivisions of the torus.
- r1 : Inner radius. TODO:convert to diameter to be coherent with other funcs
- r2 : Outer radius. TODO:convert to diameter to be coherent with other funcs
*/
void AppendTorus(int ndivisions, float r1, float r2); void AppendTorus(int ndivisions, float r1, float r2);
/* [cmd:ab] Box centered on (0,0,0) with BBox [-.5 * size][.5 * size]
- size : size of the box.
- chamf : size of the chamfer.
- smooth : if (1) will smooth normals : TOOD:TOREMOVE : smooth should be handled elsewhere
*/
void AppendBox(vec3 const &size, float chamf = 0.f); void AppendBox(vec3 const &size, float chamf = 0.f);
//Same as AppendBox
void AppendSmoothChamfBox(vec3 const &size, float chamf); void AppendSmoothChamfBox(vec3 const &size, float chamf);
//Same as AppendBox
void AppendFlatChamfBox(vec3 const &size, float chamf); void AppendFlatChamfBox(vec3 const &size, float chamf);
//Same as AppendBox
void AppendBox(vec3 const &size, float chamf, bool smooth); 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(r1, r2)" radius.
- nbranches : Number of branches.
- r1 : Length of the branches.
- r2 : Length of the "branch" located between r1-branches.
- fade : if (1) in-between branches use Color2.
- fade2 : if (1) Star branches use Color2.
*/
void AppendStar(int nbranches, float r1, float r2, void AppendStar(int nbranches, float r1, float r2,
int fade = 0, int fade2 = 0); int fade = 0, int fade2 = 0);
/* [cmd:aes] Star centered on (0,0,0) contained within a disc of "max(max(r1, r2), max(r1 + extrar, r2 + extrar))" radius.
Expanded star branches use Color2.
- nbranches : Number of branches.
- r1 : Length of the branches.
- r2 : Length of the "branch" located between r1-branches.
- extrar : Extra length added to expand all branches.
*/
void AppendExpandedStar(int nbranches, float r1, float r2, float extrar); void AppendExpandedStar(int nbranches, float r1, float r2, float extrar);
/* [cmd:ad] Disc centered on (0,0,0) with BBox [-size][size]
- nbsides : Number of sides.
- r : Radius. TODO:convert to diameter to be coherent with other funcs
- fade : if (1) Outer vertices will use Color2
*/
void AppendDisc(int nsides, float r, int fade = 0); void AppendDisc(int nsides, float r, int fade = 0);
/* [cmd:at] Triangle centered on (0,0,0) contained within a disc of "size" radius.
- size : Size of vector : origin-TO-vertex.
- fade : if (1) 2nd & 3rd Vertices will use Color2
*/
void AppendSimpleTriangle(float size, int fade = 0); void AppendSimpleTriangle(float size, int fade = 0);
/* [cmd:aq] Quad centered on (0,0,0) contained within BBox [-size,0,-size][size,0,size]
- size : Size of quad.
- fade : if (1) 3rd & 4th Vertices will use Color2
*/
void AppendSimpleQuad(float size, int fade = 0); void AppendSimpleQuad(float size, int fade = 0);
private:
//complex version of above one
void AppendSimpleQuad(vec2 p1, vec2 p2, float z = 0.f, int fade = 0); void AppendSimpleQuad(vec2 p1, vec2 p2, float z = 0.f, int fade = 0);
public:
/* [cmd:acg] Gear centered on (0,0,0) contained within BBox [-max(r1,r2), -.5*h, -max(r1, r2)][max(r1, r2), .5*h, max(r1, r2)]
- h : Height of the Gear.
- r10 : Upper Inner radius.
- r20 : Lower Inner radius.
- r1 : Upper Outer radius.
- r2 : Lower Outer radius.
- r12 : Upper Cog radius.
- r22 : Lower Cog radius.
- sidemul : multiplier for the size of the cogs.
- offset : useless
*/
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);


@@ -201,6 +359,9 @@ private:
Array<int, int> m_cursors; Array<int, int> m_cursors;
//When this flag is up, negative scaling will not invert faces. //When this flag is up, negative scaling will not invert faces.
bool m_ignore_winding_on_scale; bool m_ignore_winding_on_scale;
//Texture coordinate modifiers.
vec2 m_texcoord_offset;
vec2 m_texcoord_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. */
struct struct


+ 39
- 1
src/easymesh/shinydebugUV.lolfx 查看文件

@@ -50,7 +50,45 @@ varying vec2 pass_TexCoord;


void main(void) void main(void)
{ {
gl_FragColor = vec4(mod(pass_TexCoord.x, 1.0f), 0.2, mod(pass_TexCoord.y, 1.0), 1.0) * length(normalize(pass_Color.xyz)) * length(normalize(pass_TNormal));
float mode = 0.0;
if (mode == 0.0)
{
gl_FragColor = vec4(mod(pass_TexCoord.x, 1.0f),
0.1,
mod(pass_TexCoord.y, 1.0), 1.0);
}
else
{
float col = ((mod(mode, 2.0) == 1)?(mod(pass_TexCoord.x, 1.0)):(mod(pass_TexCoord.y, 1.0)));
if (mode == 1 || mode == 2)
{
if (col > 1.0/3.0) gl_FragColor.r = 0.0;
else gl_FragColor.r = min(col, 1.0/3.0);
if (col > 2.0/3.0) gl_FragColor.g = 0.0;
else gl_FragColor.g = min(max(col, 1.0/3.0) - 1.0/3.0, 1.0/3.0);
gl_FragColor.b = min(max(col, 2.0/3.0) - 2.0/3.0, 1.0/3.0);
}
else if (mode == 3 || mode == 4)
{
if (col > 0.5) gl_FragColor.r = 0.0;
else gl_FragColor.r = min(col, 0.5);
gl_FragColor.g = min(max(col, 0.5) - 0.5, 0.5);
gl_FragColor.b = 0.1;
}
else if (mode == 5 || mode == 6)
{
gl_FragColor.r = col;
gl_FragColor.g = 0.1;
gl_FragColor.b = 0.1;
}
}

gl_FragColor.a = 1.0;
gl_FragColor *=
//= pass_Color *
length(normalize(pass_TexCoord)) *
length(normalize(pass_Color.xyz)) *
length(normalize(pass_TNormal));
} }


[vert.hlsl] [vert.hlsl]


+ 307
- 388
src/generated/easymesh-parser.cpp
文件差異過大導致無法顯示
查看文件


+ 66
- 38
src/generated/easymesh-parser.h 查看文件

@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 2.5. */
/* A Bison parser, made by GNU Bison 2.4.2. */


/* Skeleton interface for Bison LALR(1) parsers in C++ /* Skeleton interface for Bison LALR(1) parsers in C++
@@ -40,6 +40,20 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include "stack.hh" #include "stack.hh"


namespace lol {

/* Line 34 of lalr1.cc */
#line 49 "generated/easymesh-parser.h"
class position;
class location;

} // lol

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

#include "location.hh" #include "location.hh"


/* Enabling traces. */ /* Enabling traces. */
@@ -60,11 +74,30 @@
# define YYTOKEN_TABLE 0 # define YYTOKEN_TABLE 0
#endif #endif


/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
If N is 0, then set CURRENT to the empty location which ends
the previous symbol: RHS[0] (always defined). */

#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N) \
do { \
if (N) \
{ \
(Current).begin = (Rhs)[1].begin; \
(Current).end = (Rhs)[N].end; \
} \
else \
{ \
(Current).begin = (Current).end = (Rhs)[0].end; \
} \
} while (false)
#endif



namespace lol { namespace lol {


/* Line 35 of lalr1.cc */
#line 68 "generated/easymesh-parser.h"
/* Line 34 of lalr1.cc */
#line 101 "generated/easymesh-parser.h"


/// A Bison parser. /// A Bison parser.
class EasyMeshParser class EasyMeshParser
@@ -75,7 +108,7 @@ namespace lol {
union semantic_type union semantic_type
{ {


/* Line 35 of lalr1.cc */
/* Line 34 of lalr1.cc */
#line 36 "easymesh/easymesh-parser.y" #line 36 "easymesh/easymesh-parser.y"


float fval; float fval;
@@ -85,8 +118,8 @@ namespace lol {






/* Line 35 of lalr1.cc */
#line 90 "generated/easymesh-parser.h"
/* Line 34 of lalr1.cc */
#line 123 "generated/easymesh-parser.h"
}; };
#else #else
typedef YYSTYPE semantic_type; typedef YYSTYPE semantic_type;
@@ -122,25 +155,26 @@ namespace lol {
T_RADIALJITTER = 278, T_RADIALJITTER = 278,
T_CSGUNION = 279, T_CSGUNION = 279,
T_CSGSUBSTRACT = 280, T_CSGSUBSTRACT = 280,
T_CSGAND = 281,
T_CSGXOR = 282,
T_CHAMFER = 283,
T_CYLINDER = 284,
T_BOX = 285,
T_SMOOTHCHAMFBOX = 286,
T_FLATCHAMFBOX = 287,
T_SPHERE = 288,
T_CAPSULE = 289,
T_STAR = 290,
T_EXPANDEDSTAR = 291,
T_DISC = 292,
T_TRIANGLE = 293,
T_QUAD = 294,
T_COG = 295,
T_TORUS = 296,
T_ERROR = 297,
NUMBER = 298,
COLOR = 299
T_CSGSUBSTRACTLOSS = 281,
T_CSGAND = 282,
T_CSGXOR = 283,
T_CHAMFER = 284,
T_CYLINDER = 285,
T_BOX = 286,
T_SMOOTHCHAMFBOX = 287,
T_FLATCHAMFBOX = 288,
T_SPHERE = 289,
T_CAPSULE = 290,
T_STAR = 291,
T_EXPANDEDSTAR = 292,
T_DISC = 293,
T_TRIANGLE = 294,
T_QUAD = 295,
T_COG = 296,
T_TORUS = 297,
T_ERROR = 298,
NUMBER = 299,
COLOR = 300
}; };


}; };
@@ -214,14 +248,6 @@ namespace lol {
/// The location stack. /// The location stack.
location_stack_type yylocation_stack_; location_stack_type yylocation_stack_;


/// Whether the given \c yypact_ value indicates a defaulted state.
/// \param yyvalue the value to check
static bool yy_pact_value_is_default_ (int yyvalue);

/// Whether the given \c yytable_ value indicates a syntax error.
/// \param yyvalue the value to check
static bool yy_table_value_is_error_ (int yyvalue);

/// Internal symbol numbers. /// Internal symbol numbers.
typedef unsigned char token_number_type; typedef unsigned char token_number_type;
/* Tables. */ /* Tables. */
@@ -229,12 +255,12 @@ namespace lol {
static const signed char yypact_[]; static const signed char yypact_[];
static const signed char yypact_ninf_; static const signed char yypact_ninf_;


/// For a state, default reduction number.
/// For a state, default rule to reduce.
/// Unless\a yytable_ specifies something else to do. /// Unless\a yytable_ specifies something else to do.
/// Zero means the default is an error. /// Zero means the default is an error.
static const unsigned char yydefact_[]; static const unsigned char yydefact_[];


static const signed char yypgoto_[];
static const short int yypgoto_[];
static const signed char yydefgoto_[]; static const signed char yydefgoto_[];


/// What to do in a state. /// What to do in a state.
@@ -260,8 +286,10 @@ namespace lol {
static const char* const yytname_[]; static const char* const yytname_[];
#endif #endif


#if YYERROR_VERBOSE
/// Convert the symbol name \a n to a form suitable for a diagnostic. /// Convert the symbol name \a n to a form suitable for a diagnostic.
static std::string yytnamerr_ (const char *n);
virtual std::string yytnamerr_ (const char *n);
#endif


#if YYDEBUG #if YYDEBUG
/// A type to store symbol numbers and -1. /// A type to store symbol numbers and -1.
@@ -319,8 +347,8 @@ namespace lol {


} // lol } // lol


/* Line 35 of lalr1.cc */
#line 324 "generated/easymesh-parser.h"
/* Line 34 of lalr1.cc */
#line 352 "generated/easymesh-parser.h"








+ 113
- 108
src/generated/easymesh-scanner.cpp 查看文件

@@ -330,8 +330,8 @@ typedef unsigned char YY_CHAR;
*yy_cp = '\0'; \ *yy_cp = '\0'; \
(yy_c_buf_p) = yy_cp; (yy_c_buf_p) = yy_cp;


#define YY_NUM_RULES 51
#define YY_END_OF_BUFFER 52
#define YY_NUM_RULES 52
#define YY_END_OF_BUFFER 53
/* This struct is not used in this scanner, /* This struct is not used in this scanner,
but its presence is necessary. */ but its presence is necessary. */
struct yy_trans_info struct yy_trans_info
@@ -339,17 +339,17 @@ struct yy_trans_info
flex_int32_t yy_verify; flex_int32_t yy_verify;
flex_int32_t yy_nxt; flex_int32_t yy_nxt;
}; };
static yyconst flex_int16_t yy_accept[82] =
static yyconst flex_int16_t yy_accept[83] =
{ 0, { 0,
0, 0, 52, 50, 49, 48, 50, 50, 45, 50,
44, 46, 47, 50, 50, 50, 50, 17, 7, 0,
0, 44, 44, 0, 27, 28, 31, 0, 0, 34,
35, 38, 3, 0, 19, 20, 21, 22, 8, 9,
0, 0, 53, 51, 50, 49, 51, 51, 46, 51,
45, 47, 48, 51, 51, 51, 51, 17, 7, 0,
0, 45, 45, 0, 28, 29, 32, 0, 0, 35,
36, 39, 3, 0, 19, 20, 21, 22, 8, 9,
10, 1, 14, 15, 16, 0, 0, 4, 5, 6, 10, 1, 14, 15, 16, 0, 0, 4, 5, 6,
0, 0, 44, 0, 30, 32, 0, 0, 0, 39,
0, 2, 11, 12, 13, 18, 40, 29, 33, 36,
37, 25, 24, 23, 26, 41, 0, 42, 0, 43,
0
0, 0, 45, 0, 31, 33, 0, 0, 0, 40,
0, 2, 11, 12, 13, 18, 41, 30, 34, 37,
38, 26, 24, 23, 27, 42, 25, 0, 43, 0,
44, 0
} ; } ;


static yyconst flex_int32_t yy_ec[256] = static yyconst flex_int32_t yy_ec[256] =
@@ -365,9 +365,9 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
11, 1, 12, 1, 1, 1, 13, 14, 15, 16, 11, 1, 12, 1, 1, 1, 13, 14, 15, 16,


17, 18, 19, 20, 1, 21, 1, 1, 22, 1,
23, 24, 25, 26, 27, 28, 29, 1, 30, 31,
32, 33, 1, 1, 1, 1, 1, 1, 1, 1,
17, 18, 19, 20, 1, 21, 1, 22, 23, 1,
24, 25, 26, 27, 28, 29, 30, 1, 31, 32,
33, 34, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -384,78 +384,78 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1 1, 1, 1, 1, 1
} ; } ;


static yyconst flex_int32_t yy_meta[34] =
static yyconst flex_int32_t yy_meta[35] =
{ 0, { 0,
1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1
1, 1, 1, 1
} ; } ;


static yyconst flex_int16_t yy_base[90] =
static yyconst flex_int16_t yy_base[91] =
{ 0, { 0,
0, 0, 111, 112, 112, 112, 0, 27, 29, 102,
31, 112, 112, 35, 20, 11, 24, 39, 60, 0,
101, 51, 57, 70, 112, 64, 112, 81, 92, 112,
64, 83, 112, 86, 112, 112, 112, 112, 112, 112,
112, 90, 112, 112, 112, 49, 73, 112, 112, 112,
0, 93, 91, 73, 112, 112, 82, 81, 74, 112,
71, 112, 112, 112, 112, 112, 0, 112, 112, 112,
112, 112, 112, 112, 112, 0, 0, 0, 0, 112,
112, 88, 87, 84, 83, 67, 64, 62, 44
0, 0, 113, 114, 114, 114, 0, 28, 30, 104,
32, 114, 114, 36, 27, 11, 25, 41, 35, 0,
103, 69, 70, 76, 114, 47, 114, 82, 94, 114,
46, 84, 114, 88, 114, 114, 114, 114, 114, 114,
114, 92, 114, 114, 114, 56, 74, 114, 114, 114,
0, 96, 95, 76, 114, 114, 85, 83, 76, 114,
70, 114, 114, 114, 114, 114, 0, 114, 114, 114,
114, 114, 73, 114, 114, 0, 114, 0, 0, 0,
114, 114, 92, 91, 90, 89, 83, 70, 68, 39
} ; } ;


static yyconst flex_int16_t yy_def[90] =
static yyconst flex_int16_t yy_def[91] =
{ 0, { 0,
81, 1, 81, 81, 81, 81, 82, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 83,
81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
84, 81, 81, 81, 81, 81, 81, 81, 81, 81,
81, 81, 81, 81, 81, 81, 85, 81, 81, 81,
81, 81, 81, 81, 81, 86, 87, 88, 89, 81,
0, 81, 81, 81, 81, 81, 81, 81, 81
82, 1, 82, 82, 82, 82, 83, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82, 82, 84,
82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
85, 82, 82, 82, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 86, 82, 82, 82,
82, 82, 82, 82, 82, 87, 82, 88, 89, 90,
82, 0, 82, 82, 82, 82, 82, 82, 82, 82
} ; } ;


static yyconst flex_int16_t yy_nxt[146] =
static yyconst flex_int16_t yy_nxt[149] =
{ 0, { 0,
4, 5, 6, 7, 8, 9, 10, 11, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 4, 4,
12, 13, 14, 4, 15, 4, 4, 4, 4, 4, 12, 13, 14, 4, 15, 4, 4, 4, 4, 4,
4, 16, 4, 4, 4, 17, 18, 19, 4, 4,
4, 4, 4, 21, 22, 21, 22, 21, 22, 33,
24, 35, 36, 37, 38, 80, 34, 24, 25, 26,
27, 28, 29, 42, 39, 40, 41, 21, 22, 30,
24, 31, 32, 79, 23, 78, 24, 24, 77, 43,
44, 45, 46, 24, 52, 52, 54, 53, 58, 63,
64, 65, 55, 72, 76, 67, 47, 59, 51, 20,
48, 49, 50, 71, 70, 69, 68, 73, 53, 74,
53, 75, 66, 62, 61, 60, 57, 56, 23, 23,
81, 3, 81, 81, 81, 81, 81, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
81, 81, 81, 81, 81
4, 4, 16, 4, 4, 4, 17, 18, 19, 4,
4, 4, 4, 4, 21, 22, 21, 22, 21, 22,
81, 24, 35, 36, 37, 38, 33, 46, 24, 25,
26, 27, 28, 29, 34, 42, 39, 40, 41, 54,
58, 30, 47, 31, 32, 55, 48, 49, 50, 80,
59, 79, 43, 44, 45, 21, 22, 23, 24, 24,
52, 52, 72, 53, 78, 24, 24, 63, 64, 65,
76, 67, 51, 20, 77, 71, 70, 73, 69, 74,
68, 75, 53, 53, 66, 62, 61, 60, 57, 56,
23, 23, 82, 3, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82
} ; } ;


static yyconst flex_int16_t yy_chk[146] =
static yyconst flex_int16_t yy_chk[149] =
{ 0, { 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 8, 8, 9, 9, 11, 11, 15,
11, 16, 16, 16, 17, 89, 15, 11, 14, 14,
14, 14, 14, 18, 17, 17, 17, 22, 22, 14,
22, 14, 14, 88, 23, 87, 23, 22, 86, 18,
18, 18, 19, 23, 24, 24, 26, 24, 31, 46,
46, 46, 26, 61, 85, 84, 19, 31, 83, 82,
19, 19, 19, 59, 58, 57, 54, 61, 53, 61,
52, 61, 47, 42, 34, 32, 29, 28, 21, 10,
3, 81, 81, 81, 81, 81, 81, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
81, 81, 81, 81, 81
1, 1, 1, 1, 8, 8, 9, 9, 11, 11,
90, 11, 16, 16, 16, 17, 15, 19, 11, 14,
14, 14, 14, 14, 15, 18, 17, 17, 17, 26,
31, 14, 19, 14, 14, 26, 19, 19, 19, 89,
31, 88, 18, 18, 18, 22, 22, 23, 22, 23,
24, 24, 61, 24, 87, 22, 23, 46, 46, 46,
86, 85, 84, 83, 73, 59, 58, 61, 57, 61,
54, 61, 53, 52, 47, 42, 34, 32, 29, 28,
21, 10, 3, 82, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82
} ; } ;


/* The intent behind this definition is that it'll catch /* The intent behind this definition is that it'll catch
@@ -670,13 +670,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{ {
yy_current_state = (int) yy_def[yy_current_state]; yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 82 )
if ( yy_current_state >= 83 )
yy_c = yy_meta[(unsigned int) yy_c]; yy_c = yy_meta[(unsigned int) yy_c];
} }
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp; ++yy_cp;
} }
while ( yy_current_state != 81 );
while ( yy_current_state != 82 );
yy_cp = (yy_last_accepting_cpos); yy_cp = (yy_last_accepting_cpos);
yy_current_state = (yy_last_accepting_state); yy_current_state = (yy_last_accepting_state);


@@ -819,81 +819,86 @@ YY_RULE_SETUP
case 25: case 25:
YY_RULE_SETUP YY_RULE_SETUP
#line 77 "easymesh/easymesh-scanner.l" #line 77 "easymesh/easymesh-scanner.l"
{ return token::T_CSGAND; }
{ return token::T_CSGSUBSTRACTLOSS; }
YY_BREAK YY_BREAK
case 26: case 26:
YY_RULE_SETUP YY_RULE_SETUP
#line 78 "easymesh/easymesh-scanner.l" #line 78 "easymesh/easymesh-scanner.l"
{ return token::T_CSGXOR; }
{ return token::T_CSGAND; }
YY_BREAK YY_BREAK
case 27: case 27:
YY_RULE_SETUP YY_RULE_SETUP
#line 80 "easymesh/easymesh-scanner.l"
{ return token::T_BOX; }
#line 79 "easymesh/easymesh-scanner.l"
{ return token::T_CSGXOR; }
YY_BREAK YY_BREAK
case 28: case 28:
YY_RULE_SETUP YY_RULE_SETUP
#line 81 "easymesh/easymesh-scanner.l" #line 81 "easymesh/easymesh-scanner.l"
{ return token::T_CYLINDER; }
{ return token::T_BOX; }
YY_BREAK YY_BREAK
case 29: case 29:
YY_RULE_SETUP YY_RULE_SETUP
#line 82 "easymesh/easymesh-scanner.l" #line 82 "easymesh/easymesh-scanner.l"
{ return token::T_CAPSULE; }
{ return token::T_CYLINDER; }
YY_BREAK YY_BREAK
case 30: case 30:
YY_RULE_SETUP YY_RULE_SETUP
#line 83 "easymesh/easymesh-scanner.l" #line 83 "easymesh/easymesh-scanner.l"
{ return token::T_COG; }
{ return token::T_CAPSULE; }
YY_BREAK YY_BREAK
case 31: case 31:
YY_RULE_SETUP YY_RULE_SETUP
#line 84 "easymesh/easymesh-scanner.l" #line 84 "easymesh/easymesh-scanner.l"
{ return token::T_DISC; }
{ return token::T_COG; }
YY_BREAK YY_BREAK
case 32: case 32:
YY_RULE_SETUP YY_RULE_SETUP
#line 85 "easymesh/easymesh-scanner.l" #line 85 "easymesh/easymesh-scanner.l"
{ return token::T_EXPANDEDSTAR; }
{ return token::T_DISC; }
YY_BREAK YY_BREAK
case 33: case 33:
YY_RULE_SETUP YY_RULE_SETUP
#line 86 "easymesh/easymesh-scanner.l" #line 86 "easymesh/easymesh-scanner.l"
{ return token::T_FLATCHAMFBOX; }
{ return token::T_EXPANDEDSTAR; }
YY_BREAK YY_BREAK
case 34: case 34:
YY_RULE_SETUP YY_RULE_SETUP
#line 87 "easymesh/easymesh-scanner.l" #line 87 "easymesh/easymesh-scanner.l"
{ return token::T_QUAD; }
{ return token::T_FLATCHAMFBOX; }
YY_BREAK YY_BREAK
case 35: case 35:
YY_RULE_SETUP YY_RULE_SETUP
#line 88 "easymesh/easymesh-scanner.l" #line 88 "easymesh/easymesh-scanner.l"
{ return token::T_STAR; }
{ return token::T_QUAD; }
YY_BREAK YY_BREAK
case 36: case 36:
YY_RULE_SETUP YY_RULE_SETUP
#line 89 "easymesh/easymesh-scanner.l" #line 89 "easymesh/easymesh-scanner.l"
{ return token::T_SMOOTHCHAMFBOX; }
{ return token::T_STAR; }
YY_BREAK YY_BREAK
case 37: case 37:
YY_RULE_SETUP YY_RULE_SETUP
#line 90 "easymesh/easymesh-scanner.l" #line 90 "easymesh/easymesh-scanner.l"
{ return token::T_SPHERE; }
{ return token::T_SMOOTHCHAMFBOX; }
YY_BREAK YY_BREAK
case 38: case 38:
YY_RULE_SETUP YY_RULE_SETUP
#line 91 "easymesh/easymesh-scanner.l" #line 91 "easymesh/easymesh-scanner.l"
{ return token::T_TRIANGLE; }
{ return token::T_SPHERE; }
YY_BREAK YY_BREAK
case 39: case 39:
YY_RULE_SETUP YY_RULE_SETUP
#line 92 "easymesh/easymesh-scanner.l" #line 92 "easymesh/easymesh-scanner.l"
{ return token::T_TORUS; }
{ return token::T_TRIANGLE; }
YY_BREAK YY_BREAK
case 40: case 40:
YY_RULE_SETUP YY_RULE_SETUP
#line 94 "easymesh/easymesh-scanner.l"
#line 93 "easymesh/easymesh-scanner.l"
{ return token::T_TORUS; }
YY_BREAK
case 41:
YY_RULE_SETUP
#line 95 "easymesh/easymesh-scanner.l"
{ {
uint32_t tmp = std::strtol(yytext + 1, NULL, 16); uint32_t tmp = std::strtol(yytext + 1, NULL, 16);
yylval->u32val = 0x11000000u * (tmp >> 8) yylval->u32val = 0x11000000u * (tmp >> 8)
@@ -902,9 +907,9 @@ YY_RULE_SETUP
| 0x000000ffu; | 0x000000ffu;
return token::COLOR; } return token::COLOR; }
YY_BREAK YY_BREAK
case 41:
case 42:
YY_RULE_SETUP YY_RULE_SETUP
#line 101 "easymesh/easymesh-scanner.l"
#line 102 "easymesh/easymesh-scanner.l"
{ {
uint32_t tmp = std::strtol(yytext + 1, NULL, 16); uint32_t tmp = std::strtol(yytext + 1, NULL, 16);
yylval->u32val = 0x11000000u * (tmp >> 12) yylval->u32val = 0x11000000u * (tmp >> 12)
@@ -913,64 +918,64 @@ YY_RULE_SETUP
| 0x00000011u * (tmp & 0xf); | 0x00000011u * (tmp & 0xf);
return token::COLOR; } return token::COLOR; }
YY_BREAK YY_BREAK
case 42:
case 43:
YY_RULE_SETUP YY_RULE_SETUP
#line 108 "easymesh/easymesh-scanner.l"
#line 109 "easymesh/easymesh-scanner.l"
{ {
yylval->u32val = 0xffu yylval->u32val = 0xffu
| 0x100u * (uint32_t)std::strtol(yytext + 1, NULL, 16); | 0x100u * (uint32_t)std::strtol(yytext + 1, NULL, 16);
return token::COLOR; } return token::COLOR; }
YY_BREAK YY_BREAK
case 43:
case 44:
YY_RULE_SETUP YY_RULE_SETUP
#line 112 "easymesh/easymesh-scanner.l"
#line 113 "easymesh/easymesh-scanner.l"
{ {
yylval->u32val = (uint32_t)std::strtol(yytext + 1, NULL, 16); yylval->u32val = (uint32_t)std::strtol(yytext + 1, NULL, 16);
return token::COLOR; } return token::COLOR; }
YY_BREAK YY_BREAK
case 44:
case 45:
YY_RULE_SETUP YY_RULE_SETUP
#line 115 "easymesh/easymesh-scanner.l"
#line 116 "easymesh/easymesh-scanner.l"
{ {
yylval->fval = std::atof(yytext); return token::NUMBER; } yylval->fval = std::atof(yytext); return token::NUMBER; }
YY_BREAK YY_BREAK
case 45:
YY_RULE_SETUP
#line 117 "easymesh/easymesh-scanner.l"
{ return token_type('-'); }
YY_BREAK
case 46: case 46:
YY_RULE_SETUP YY_RULE_SETUP
#line 118 "easymesh/easymesh-scanner.l" #line 118 "easymesh/easymesh-scanner.l"
{ return token_type('['); }
{ return token_type('-'); }
YY_BREAK YY_BREAK
case 47: case 47:
YY_RULE_SETUP YY_RULE_SETUP
#line 119 "easymesh/easymesh-scanner.l" #line 119 "easymesh/easymesh-scanner.l"
{ return token_type(']'); }
{ return token_type('['); }
YY_BREAK YY_BREAK
case 48: case 48:
YY_RULE_SETUP YY_RULE_SETUP
#line 120 "easymesh/easymesh-scanner.l" #line 120 "easymesh/easymesh-scanner.l"
{ /* ignore this */ }
{ return token_type(']'); }
YY_BREAK YY_BREAK
case 49: case 49:
/* rule 49 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 121 "easymesh/easymesh-scanner.l" #line 121 "easymesh/easymesh-scanner.l"
{ /* ignore this */ } { /* ignore this */ }
YY_BREAK YY_BREAK
case 50: case 50:
/* rule 50 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 122 "easymesh/easymesh-scanner.l" #line 122 "easymesh/easymesh-scanner.l"
{ return token::T_ERROR; }
{ /* ignore this */ }
YY_BREAK YY_BREAK
case 51: case 51:
YY_RULE_SETUP YY_RULE_SETUP
#line 124 "easymesh/easymesh-scanner.l"
#line 123 "easymesh/easymesh-scanner.l"
{ return token::T_ERROR; }
YY_BREAK
case 52:
YY_RULE_SETUP
#line 125 "easymesh/easymesh-scanner.l"
ECHO; ECHO;
YY_BREAK YY_BREAK
#line 974 "generated/easymesh-scanner.cpp"
#line 979 "generated/easymesh-scanner.cpp"
case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(INITIAL):
yyterminate(); yyterminate();


@@ -1352,7 +1357,7 @@ int yyFlexLexer::yy_get_next_buffer()
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{ {
yy_current_state = (int) yy_def[yy_current_state]; yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 82 )
if ( yy_current_state >= 83 )
yy_c = yy_meta[(unsigned int) yy_c]; yy_c = yy_meta[(unsigned int) yy_c];
} }
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1380,11 +1385,11 @@ int yyFlexLexer::yy_get_next_buffer()
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{ {
yy_current_state = (int) yy_def[yy_current_state]; yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 82 )
if ( yy_current_state >= 83 )
yy_c = yy_meta[(unsigned int) yy_c]; yy_c = yy_meta[(unsigned int) yy_c];
} }
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_is_jam = (yy_current_state == 81);
yy_is_jam = (yy_current_state == 82);


return yy_is_jam ? 0 : yy_current_state; return yy_is_jam ? 0 : yy_current_state;
} }
@@ -1871,7 +1876,7 @@ void EasyMeshfree (void * ptr )


#define YYTABLES_NAME "yytables" #define YYTABLES_NAME "yytables"


#line 124 "easymesh/easymesh-scanner.l"
#line 125 "easymesh/easymesh-scanner.l"








+ 2
- 2
test/MeshViewer.cpp 查看文件

@@ -301,8 +301,8 @@ public:
m_meshes.Push(EasyMesh(), false, .0f, vec3(.0f)); m_meshes.Push(EasyMesh(), false, .0f, vec3(.0f));
if (!m_meshes.Last().m1.Compile(cmd.C())) if (!m_meshes.Last().m1.Compile(cmd.C()))
m_meshes.Pop(); m_meshes.Pop();
else
m_meshes.Last().m1.ComputeTexCoord(0.2f, 2);
//else
// m_meshes.Last().m1.ComputeTexCoord(0.2f, 2);
} }
} }
} }


+ 13
- 6
test/MeshViewerBuffer.txt 查看文件

@@ -1,11 +1,18 @@
[sc#88f ab 4 4 4]
//[sc#ff2 asph 2 4 4 4]
//[sc#ff2 acap 2 4 4]
//[sc#ff2 ac 12 4 4 4 0 0]
[sc#88f ab 4 4 4 tx 4 ab 4 4 4 tx -2 tax .4 .4 0]
//[sc#ff2 asph 2 4 tx 4 tax 1 1 0]
//[sc#ff2 acap 1 4 4]
//[sc#ff2 scb#ff2 ac 10 4 4 4 0 0 1]
//[sc#ff2 scb#ff2 ad 10 4 0]
//[sc#ff2 scb#ff2 ato 40 1 4]
//[sc#ff2 scb#2ff at 4 1]
//[sc#ff2 scb#2ff aq 4 0]
//[sc#ff2 scb#2ff aes 5 3 6 2]
//[sc#ff2 scb#2ff as 5 2 5 0 0]
//[sc#ff2 scb#2ff acg 2 10 .1 .1 .4 .4 .1 .1 0 1]
//[sc#ff2 asph 2 10 10 10] //[sc#ff2 asph 2 10 10 10]
//[sc#400 asph 2 10 10 10 t 2 2 2 csgs] //[sc#400 asph 2 10 10 10 t 2 2 2 csgs]
//[sc#88f afcb 10 10 10 .25 tx 0 sc 0.1]
//[sc#22f afcb 10 10 10 .25 t 2 2 2 csgs]
//[sc#88f afcb 10 10 10 .25 tx 0]
//[sc#fff afcb 10 10 10 .25 t 2 2 2]
//[sc#fff afcb 7 7 7 .25] //[sc#fff afcb 7 7 7 .25]
//[sc#ff2 afcb 7 7 7 .25 t 1 1 1] //[sc#ff2 afcb 7 7 7 .25 t 1 1 1]

Loading…
取消
儲存