| @@ -147,14 +147,16 @@ transform_command: | |||
| primitive_command: | |||
| T_CYLINDER args6 { mc.m_mesh.AppendCylinder((int)$2.f0, $2.f1, | |||
| $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_SMOOTHCHAMFBOX args4 { mc.m_mesh.AppendSmoothChamfBox(vec3($2.f0, $2.f1, | |||
| $2.f2), $2.f3); } | |||
| | T_FLATCHAMFBOX args4 { mc.m_mesh.AppendFlatChamfBox(vec3($2.f0, $2.f1, | |||
| $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_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, | |||
| @@ -47,7 +47,8 @@ namespace lol | |||
| //----------------------------------------------------------------------------- | |||
| 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); | |||
| } | |||
| @@ -478,7 +479,7 @@ void EasyMesh::MeshCsg(CSGUsage csg_operation) | |||
| //csgs : CSGSubstractLoss() -> m0_Outside | |||
| (csg_operation == CSGUsage::SubstractLoss && | |||
| ((mesh_id == 0 && tri_list[k].m1 == LEAF_BACK) || mesh_id == 1)) || | |||
| //csga : CSGAnd() -> Inside + Inside | |||
| //csga : CSGAnd() -> m0_Inside + m1_Inside | |||
| (csg_operation == CSGUsage::And && tri_list[k].m1 == LEAF_FRONT)) | |||
| { | |||
| triangle_to_kill.Push(tri_idx); | |||
| @@ -487,7 +488,7 @@ void EasyMesh::MeshCsg(CSGUsage csg_operation) | |||
| //Triangle Invert Test | |||
| if (//csgs : CSGSubstract() -> m0_Outside + m1_Inside-inverted | |||
| (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)) | |||
| { | |||
| //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 ! | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| 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 v_dir = normalize(cross(m_vert[m_indices[cur_tri]].m2, v01)); | |||
| 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 | |||
| 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. | |||
| for (int j = 0; j < 3; j++) | |||
| { | |||
| #if 0 | |||
| #if 1 | |||
| //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); | |||
| #else | |||
| @@ -787,6 +787,17 @@ void EasyMesh::ComputeTexCoord(float uv_scale, int uv_offset) | |||
| } | |||
| 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; | |||
| for (int j = 0; j < tri_done.Count(); j++) | |||
| if (cur_tri == tri_done[j]) | |||
| @@ -794,6 +805,7 @@ void EasyMesh::ComputeTexCoord(float uv_scale, int uv_offset) | |||
| if (!tri_present) | |||
| tri_done << cur_tri; | |||
| tri_check.Remove(0); | |||
| */ | |||
| } | |||
| 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; | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| 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) | |||
| { | |||
| @@ -832,6 +851,15 @@ void EasyMesh::SetCurVertColor(vec4 const &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) | |||
| { | |||
| @@ -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++) | |||
| { | |||
| 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! */ | |||
| 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++) | |||
| { | |||
| 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++) | |||
| { | |||
| 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, | |||
| 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(); | |||
| 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; | |||
| 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 */ | |||
| if (r2 != .0f) | |||
| @@ -1000,8 +1037,8 @@ void EasyMesh::AppendCylinder(int nsides, float h, float r1, float r2, | |||
| * means duplicating the vertices again... */ | |||
| 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); | |||
| 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); | |||
| } | |||
| p1 = rotmat * p1; | |||
| p2 = rotmat * p2; | |||
| p1 = rotmat * p1; uv1 += uvadd; | |||
| p2 = rotmat * p2; uv2 += uvadd; | |||
| 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); | |||
| 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; | |||
| } | |||
| 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(); | |||
| Array<vec3> vertices; | |||
| float uv_h = 0; | |||
| float uv_r = 0; | |||
| /* FIXME: we don't know how to handle even-divided capsules, so we | |||
| * force the count to be odd. */ | |||
| if (h) | |||
| { | |||
| 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 | |||
| * 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] + vc, | |||
| p[0] + vb + vc }; | |||
| vec2 uv[4]; | |||
| /* FIXME: when we normalise here, we get a volume that is slightly | |||
| * smaller than the sphere of radius 1, since we are not using | |||
| * the midradius. */ | |||
| 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) | |||
| { | |||
| 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 */ | |||
| 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++; | |||
| @@ -1127,15 +1236,6 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float r) | |||
| 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) | |||
| { | |||
| @@ -1151,16 +1251,22 @@ void EasyMesh::AppendTorus(int ndivisions, float r1, float r2) | |||
| { | |||
| int i2 = (i + di) % nidiv; | |||
| 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 z = 0.0f; | |||
| //Center circle | |||
| float ca = (float)lol::cos(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 z2 = z * ca + x * sa; | |||
| 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); | |||
| @@ -1202,35 +1308,62 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth) | |||
| vec3 d = size * 0.5f; | |||
| //Side vertices | |||
| AddVertex(vec3(-d.x, -d.y, -d.z - chamf)); | |||
| SetCurVertTexCoord(vec2(0.f, .5f)); | |||
| AddVertex(vec3(-d.x, +d.y, -d.z - chamf)); | |||
| SetCurVertTexCoord(vec2(0.f, 0.f)); | |||
| AddVertex(vec3(+d.x, +d.y, -d.z - chamf)); | |||
| SetCurVertTexCoord(vec2(.5f, 0.f)); | |||
| AddVertex(vec3(+d.x, -d.y, -d.z - chamf)); | |||
| SetCurVertTexCoord(vec2(.5f, .5f)); | |||
| AddVertex(vec3(-d.x - chamf, -d.y, +d.z)); | |||
| SetCurVertTexCoord(vec2(.5f, 0.5f)); | |||
| AddVertex(vec3(-d.x - chamf, +d.y, +d.z)); | |||
| SetCurVertTexCoord(vec2(.5f, 0.f)); | |||
| AddVertex(vec3(-d.x - chamf, +d.y, -d.z)); | |||
| SetCurVertTexCoord(vec2(1.f, 0.f)); | |||
| AddVertex(vec3(-d.x - chamf, -d.y, -d.z)); | |||
| SetCurVertTexCoord(vec2(1.f, .5f)); | |||
| AddVertex(vec3(+d.x, -d.y, +d.z + chamf)); | |||
| SetCurVertTexCoord(vec2(0.f, .5f)); | |||
| AddVertex(vec3(+d.x, +d.y, +d.z + chamf)); | |||
| SetCurVertTexCoord(vec2(0.f, 0.f)); | |||
| AddVertex(vec3(-d.x, +d.y, +d.z + chamf)); | |||
| SetCurVertTexCoord(vec2(.5f, 0.f)); | |||
| AddVertex(vec3(-d.x, -d.y, +d.z + chamf)); | |||
| SetCurVertTexCoord(vec2(.5f, .5f)); | |||
| AddVertex(vec3(+d.x + chamf, -d.y, -d.z)); | |||
| SetCurVertTexCoord(vec2(.5f, .5f)); | |||
| AddVertex(vec3(+d.x + chamf, +d.y, -d.z)); | |||
| SetCurVertTexCoord(vec2(.5f, .0f)); | |||
| AddVertex(vec3(+d.x + chamf, +d.y, +d.z)); | |||
| SetCurVertTexCoord(vec2(1.f, .0f)); | |||
| 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)); | |||
| SetCurVertTexCoord(vec2(0.f, 1.f)); | |||
| AddVertex(vec3(-d.x, -d.y - chamf, -d.z)); | |||
| SetCurVertTexCoord(vec2(0.f, .5f)); | |||
| AddVertex(vec3(+d.x, -d.y - chamf, -d.z)); | |||
| SetCurVertTexCoord(vec2(.5f, .5f)); | |||
| 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)); | |||
| SetCurVertTexCoord(vec2(0.f, 1.f)); | |||
| AddVertex(vec3(-d.x, +d.y + chamf, +d.z)); | |||
| SetCurVertTexCoord(vec2(0.f, .5f)); | |||
| AddVertex(vec3(+d.x, +d.y + chamf, +d.z)); | |||
| SetCurVertTexCoord(vec2(.5f, .5f)); | |||
| AddVertex(vec3(+d.x, +d.y + chamf, -d.z)); | |||
| SetCurVertTexCoord(vec2(.5f, 1.f)); | |||
| /* The 6 quads on each side of the box */ | |||
| 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, | |||
| 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(); | |||
| 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); | |||
| 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; | |||
| for (int i = 0; i < nbranches; i++) | |||
| { | |||
| AddVertex(p1); | |||
| AddVertex(p1); SetCurVertTexCoord(uv1.xz + vec2(.5f)); | |||
| if (fade2) | |||
| SetCurVertColor(m_color2); | |||
| AddVertex(p2); | |||
| AddVertex(p2); SetCurVertTexCoord(uv2.xz + vec2(.5f)); | |||
| if (fade) | |||
| SetCurVertColor(m_color2); | |||
| AppendQuad(0, 2 * i + 1, 2 * i + 2, (2 * i + 3) % (2 * nbranches), | |||
| 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) | |||
| { | |||
| 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); | |||
| 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);; | |||
| 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; | |||
| 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; | |||
| 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 * 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(); | |||
| 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); | |||
| vec3 p1(r, 0.f, 0.f); | |||
| vec3 uv(.5f, .0f, .0f); | |||
| for (int i = 0; i < nsides; i++) | |||
| { | |||
| AddVertex(p1); | |||
| AddVertex(p1); SetCurVertTexCoord(uv.xz + vec2(.5f, .5f)); | |||
| if (fade) | |||
| SetCurVertColor(m_color2); | |||
| AppendTriangle(0, i + 1, ((i + 1) % nsides) + 1, vbase); | |||
| 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); | |||
| vec3 p(0.f, 0.f, size); | |||
| AddVertex(p); | |||
| AddVertex(p); SetCurVertTexCoord(vec2(.5f, 0.133975f)); | |||
| p = m * p; | |||
| AddVertex(p); | |||
| AddVertex(p); SetCurVertTexCoord(vec2(1.f, 1.f)); | |||
| if (fade) | |||
| SetCurVertColor(m_color2); | |||
| p = m * p; | |||
| AddVertex(p); | |||
| AddVertex(p); SetCurVertTexCoord(vec2(0.f, 1.f)); | |||
| if (fade) | |||
| 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) | |||
| { | |||
| 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) | |||
| 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) | |||
| 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); | |||
| } | |||
| @@ -1430,6 +1574,7 @@ void EasyMesh::AppendCog(int nbsides, float h, float r10, float r20, | |||
| vec3 p[12]; | |||
| //Upper points | |||
| p[0] = vec3(r10, h * .5f, 0.f); | |||
| p[1] = rotmat * p[0]; | |||
| 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[5] = smat2 * (rotmat * p[4]); | |||
| //Lower points | |||
| p[6] = vec3(r20, h * -.5f, 0.f); | |||
| p[7] = rotmat * p[6]; | |||
| 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; | |||
| //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++) | |||
| { | |||
| 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 | |||
| * normals, therefore we add each vertex three times. */ | |||
| 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); | |||
| } | |||
| 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++) | |||
| p[n] = rotmat * p[n]; | |||
| } | |||
| @@ -78,6 +78,21 @@ private: | |||
| 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 | |||
| { | |||
| friend class EasyMeshParser; | |||
| @@ -98,21 +113,33 @@ private: | |||
| private: | |||
| void MeshCsg(CSGUsage csg_operation); | |||
| public: | |||
| /* [cmd:csgu] Performs a Union operation as (mesh0_Outside + mesh1_Outside) */ | |||
| void CsgUnion() { MeshCsg(CSGUsage::Union); } | |||
| /* [cmd:csgs] Performs a Substract operation as (mesh0_Outside + mesh1_Inside-inverted) */ | |||
| void CsgSubstract() { MeshCsg(CSGUsage::Substract); } | |||
| /* [cmd:csgsl] Performs a Substract operation without keeping the mesh1 part */ | |||
| void CsgSubstractLoss() { MeshCsg(CSGUsage::SubstractLoss); } | |||
| /* [cmd:csga] Performs an And operation as (mesh0_Inside + mesh1_Inside) */ | |||
| void CsgAnd() { MeshCsg(CSGUsage::And); } | |||
| /* [cmd:csgx] Performs a Xor operation as (m0_Outside/m0_Inside-inverted + m1_Outside/m1_Inside-inverted) */ | |||
| void CsgXor() { MeshCsg(CSGUsage::Xor); } | |||
| public: | |||
| /* [cmd:[] from this point onward, any operation will not be performed on previous vertices */ | |||
| void OpenBrace(); | |||
| /* [cmd:]] Merge current vertices with previous context */ | |||
| void CloseBrace(); | |||
| /* [cmd:tsw] When activation, on negative-scaling, normal fixing will not occur */ | |||
| void ToggleScaleWinding(); | |||
| /* [cmd:sc] Set vertices color */ | |||
| void SetCurColor(vec4 const &color); | |||
| /* [cmd:scb] Set vertices color 2 */ | |||
| void SetCurColor2(vec4 const &color); | |||
| private: | |||
| //------------------------------------------------------------------------- | |||
| //Internal : Basic triangle/vertex operations | |||
| //------------------------------------------------------------------------- | |||
| void AddVertex(vec3 const &coord); | |||
| void AddDuplicateVertex(int i); | |||
| 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 AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base); | |||
| void ComputeNormals(int start, int vcount); | |||
| public: | |||
| public: //DEBUG | |||
| void ComputeTexCoord(float uv_scale, int uv_offset); | |||
| //------------------------------------------------------------------------- | |||
| //Vertices operations | |||
| //------------------------------------------------------------------------- | |||
| void SetVertColor(vec4 const &color); | |||
| void SetTexCoordData(vec2 const &new_offset, vec2 const &new_scale); | |||
| void SetCurVertNormal(vec3 const &normal); | |||
| void SetCurVertColor(vec4 const &color); | |||
| void SetCurVertTexCoord(vec2 const &texcoord); | |||
| public: | |||
| //------------------------------------------------------------------------- | |||
| //Mesh transform operations | |||
| //------------------------------------------------------------------------- | |||
| /* [cmd:t/tx/ty/tz] Translate vertices | |||
| - v : Translation quantity. | |||
| */ | |||
| 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); | |||
| //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); | |||
| /* [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); | |||
| /* [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); | |||
| /* [cmd:s/sx/sy/sz] Scale vertices | |||
| - s : scale quantity. | |||
| */ | |||
| void Scale(vec3 const &s); | |||
| /* [cmd:mx] Mirror vertices through X-plane | |||
| Acts as an OpenBrace | |||
| */ | |||
| void MirrorX(); | |||
| /* [cmd:my] Mirror vertices through Y-plane | |||
| Acts as an OpenBrace | |||
| */ | |||
| void MirrorY(); | |||
| /* [cmd:mz] Mirror vertices through Z-plane | |||
| Acts as an OpenBrace | |||
| */ | |||
| void MirrorZ(); | |||
| /* [no-cmd] Duplicates vertices and scale duplicate | |||
| Acts as an OpenBrace | |||
| */ | |||
| void DupAndScale(vec3 const &s); | |||
| /* [cmd:ch] Performs a chamfer operation //TODO : Make it work. | |||
| - f : Chamfer quantity. | |||
| */ | |||
| void Chamfer(float f); | |||
| //------------------------------------------------------------------------- | |||
| //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, | |||
| 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 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); | |||
| /* [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); | |||
| //Same as AppendBox | |||
| void AppendSmoothChamfBox(vec3 const &size, float chamf); | |||
| //Same as AppendBox | |||
| void AppendFlatChamfBox(vec3 const &size, float chamf); | |||
| //Same as AppendBox | |||
| void AppendBox(vec3 const &size, float chamf, bool smooth); | |||
| /* [cmd:as] | |||
| Append a Star centered on (0,0,0) contained within a disc of "max(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, | |||
| 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); | |||
| /* [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); | |||
| /* [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); | |||
| /* [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); | |||
| private: | |||
| //complex version of above one | |||
| 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, | |||
| float r2, float r12, float r22, float sidemul, int offset); | |||
| @@ -201,6 +359,9 @@ private: | |||
| Array<int, int> m_cursors; | |||
| //When this flag is up, negative scaling will not invert faces. | |||
| 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. */ | |||
| struct | |||
| @@ -50,7 +50,45 @@ varying vec2 pass_TexCoord; | |||
| 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] | |||
| @@ -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++ | |||
| @@ -40,6 +40,20 @@ | |||
| #include <string> | |||
| #include <iostream> | |||
| #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" | |||
| /* Enabling traces. */ | |||
| @@ -60,11 +74,30 @@ | |||
| # define YYTOKEN_TABLE 0 | |||
| #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 { | |||
| /* 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. | |||
| class EasyMeshParser | |||
| @@ -75,7 +108,7 @@ namespace lol { | |||
| union semantic_type | |||
| { | |||
| /* Line 35 of lalr1.cc */ | |||
| /* Line 34 of lalr1.cc */ | |||
| #line 36 "easymesh/easymesh-parser.y" | |||
| 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 | |||
| typedef YYSTYPE semantic_type; | |||
| @@ -122,25 +155,26 @@ namespace lol { | |||
| T_RADIALJITTER = 278, | |||
| T_CSGUNION = 279, | |||
| 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. | |||
| 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. | |||
| typedef unsigned char token_number_type; | |||
| /* Tables. */ | |||
| @@ -229,12 +255,12 @@ namespace lol { | |||
| static const signed char yypact_[]; | |||
| 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. | |||
| /// Zero means the default is an error. | |||
| static const unsigned char yydefact_[]; | |||
| static const signed char yypgoto_[]; | |||
| static const short int yypgoto_[]; | |||
| static const signed char yydefgoto_[]; | |||
| /// What to do in a state. | |||
| @@ -260,8 +286,10 @@ namespace lol { | |||
| static const char* const yytname_[]; | |||
| #endif | |||
| #if YYERROR_VERBOSE | |||
| /// 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 | |||
| /// A type to store symbol numbers and -1. | |||
| @@ -319,8 +347,8 @@ namespace lol { | |||
| } // lol | |||
| /* Line 35 of lalr1.cc */ | |||
| #line 324 "generated/easymesh-parser.h" | |||
| /* Line 34 of lalr1.cc */ | |||
| #line 352 "generated/easymesh-parser.h" | |||
| @@ -330,8 +330,8 @@ typedef unsigned char YY_CHAR; | |||
| *yy_cp = '\0'; \ | |||
| (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, | |||
| but its presence is necessary. */ | |||
| struct yy_trans_info | |||
| @@ -339,17 +339,17 @@ struct yy_trans_info | |||
| flex_int32_t yy_verify; | |||
| flex_int32_t yy_nxt; | |||
| }; | |||
| static yyconst flex_int16_t yy_accept[82] = | |||
| static yyconst flex_int16_t yy_accept[83] = | |||
| { 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, | |||
| 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] = | |||
| @@ -365,9 +365,9 @@ static yyconst flex_int32_t yy_ec[256] = | |||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||
| 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, | |||
| @@ -384,78 +384,78 @@ static yyconst flex_int32_t yy_ec[256] = | |||
| 1, 1, 1, 1, 1 | |||
| } ; | |||
| static yyconst flex_int32_t yy_meta[34] = | |||
| static yyconst flex_int32_t yy_meta[35] = | |||
| { 0, | |||
| 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, | |||
| 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 | |||
| } ; | |||
| static yyconst flex_int16_t yy_base[90] = | |||
| static yyconst flex_int16_t yy_base[91] = | |||
| { 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, | |||
| 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, | |||
| 4, 5, 6, 7, 8, 9, 10, 11, 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, | |||
| 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 | |||
| @@ -670,13 +670,13 @@ yy_match: | |||
| while ( yy_chk[yy_base[yy_current_state] + yy_c] != 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_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; | |||
| ++yy_cp; | |||
| } | |||
| while ( yy_current_state != 81 ); | |||
| while ( yy_current_state != 82 ); | |||
| yy_cp = (yy_last_accepting_cpos); | |||
| yy_current_state = (yy_last_accepting_state); | |||
| @@ -819,81 +819,86 @@ YY_RULE_SETUP | |||
| case 25: | |||
| YY_RULE_SETUP | |||
| #line 77 "easymesh/easymesh-scanner.l" | |||
| { return token::T_CSGAND; } | |||
| { return token::T_CSGSUBSTRACTLOSS; } | |||
| YY_BREAK | |||
| case 26: | |||
| YY_RULE_SETUP | |||
| #line 78 "easymesh/easymesh-scanner.l" | |||
| { return token::T_CSGXOR; } | |||
| { return token::T_CSGAND; } | |||
| YY_BREAK | |||
| case 27: | |||
| 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 | |||
| case 28: | |||
| YY_RULE_SETUP | |||
| #line 81 "easymesh/easymesh-scanner.l" | |||
| { return token::T_CYLINDER; } | |||
| { return token::T_BOX; } | |||
| YY_BREAK | |||
| case 29: | |||
| YY_RULE_SETUP | |||
| #line 82 "easymesh/easymesh-scanner.l" | |||
| { return token::T_CAPSULE; } | |||
| { return token::T_CYLINDER; } | |||
| YY_BREAK | |||
| case 30: | |||
| YY_RULE_SETUP | |||
| #line 83 "easymesh/easymesh-scanner.l" | |||
| { return token::T_COG; } | |||
| { return token::T_CAPSULE; } | |||
| YY_BREAK | |||
| case 31: | |||
| YY_RULE_SETUP | |||
| #line 84 "easymesh/easymesh-scanner.l" | |||
| { return token::T_DISC; } | |||
| { return token::T_COG; } | |||
| YY_BREAK | |||
| case 32: | |||
| YY_RULE_SETUP | |||
| #line 85 "easymesh/easymesh-scanner.l" | |||
| { return token::T_EXPANDEDSTAR; } | |||
| { return token::T_DISC; } | |||
| YY_BREAK | |||
| case 33: | |||
| YY_RULE_SETUP | |||
| #line 86 "easymesh/easymesh-scanner.l" | |||
| { return token::T_FLATCHAMFBOX; } | |||
| { return token::T_EXPANDEDSTAR; } | |||
| YY_BREAK | |||
| case 34: | |||
| YY_RULE_SETUP | |||
| #line 87 "easymesh/easymesh-scanner.l" | |||
| { return token::T_QUAD; } | |||
| { return token::T_FLATCHAMFBOX; } | |||
| YY_BREAK | |||
| case 35: | |||
| YY_RULE_SETUP | |||
| #line 88 "easymesh/easymesh-scanner.l" | |||
| { return token::T_STAR; } | |||
| { return token::T_QUAD; } | |||
| YY_BREAK | |||
| case 36: | |||
| YY_RULE_SETUP | |||
| #line 89 "easymesh/easymesh-scanner.l" | |||
| { return token::T_SMOOTHCHAMFBOX; } | |||
| { return token::T_STAR; } | |||
| YY_BREAK | |||
| case 37: | |||
| YY_RULE_SETUP | |||
| #line 90 "easymesh/easymesh-scanner.l" | |||
| { return token::T_SPHERE; } | |||
| { return token::T_SMOOTHCHAMFBOX; } | |||
| YY_BREAK | |||
| case 38: | |||
| YY_RULE_SETUP | |||
| #line 91 "easymesh/easymesh-scanner.l" | |||
| { return token::T_TRIANGLE; } | |||
| { return token::T_SPHERE; } | |||
| YY_BREAK | |||
| case 39: | |||
| YY_RULE_SETUP | |||
| #line 92 "easymesh/easymesh-scanner.l" | |||
| { return token::T_TORUS; } | |||
| { return token::T_TRIANGLE; } | |||
| YY_BREAK | |||
| case 40: | |||
| 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); | |||
| yylval->u32val = 0x11000000u * (tmp >> 8) | |||
| @@ -902,9 +907,9 @@ YY_RULE_SETUP | |||
| | 0x000000ffu; | |||
| return token::COLOR; } | |||
| YY_BREAK | |||
| case 41: | |||
| case 42: | |||
| YY_RULE_SETUP | |||
| #line 101 "easymesh/easymesh-scanner.l" | |||
| #line 102 "easymesh/easymesh-scanner.l" | |||
| { | |||
| uint32_t tmp = std::strtol(yytext + 1, NULL, 16); | |||
| yylval->u32val = 0x11000000u * (tmp >> 12) | |||
| @@ -913,64 +918,64 @@ YY_RULE_SETUP | |||
| | 0x00000011u * (tmp & 0xf); | |||
| return token::COLOR; } | |||
| YY_BREAK | |||
| case 42: | |||
| case 43: | |||
| YY_RULE_SETUP | |||
| #line 108 "easymesh/easymesh-scanner.l" | |||
| #line 109 "easymesh/easymesh-scanner.l" | |||
| { | |||
| yylval->u32val = 0xffu | |||
| | 0x100u * (uint32_t)std::strtol(yytext + 1, NULL, 16); | |||
| return token::COLOR; } | |||
| YY_BREAK | |||
| case 43: | |||
| case 44: | |||
| 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); | |||
| return token::COLOR; } | |||
| YY_BREAK | |||
| case 44: | |||
| case 45: | |||
| YY_RULE_SETUP | |||
| #line 115 "easymesh/easymesh-scanner.l" | |||
| #line 116 "easymesh/easymesh-scanner.l" | |||
| { | |||
| yylval->fval = std::atof(yytext); return token::NUMBER; } | |||
| YY_BREAK | |||
| case 45: | |||
| YY_RULE_SETUP | |||
| #line 117 "easymesh/easymesh-scanner.l" | |||
| { return token_type('-'); } | |||
| YY_BREAK | |||
| case 46: | |||
| YY_RULE_SETUP | |||
| #line 118 "easymesh/easymesh-scanner.l" | |||
| { return token_type('['); } | |||
| { return token_type('-'); } | |||
| YY_BREAK | |||
| case 47: | |||
| YY_RULE_SETUP | |||
| #line 119 "easymesh/easymesh-scanner.l" | |||
| { return token_type(']'); } | |||
| { return token_type('['); } | |||
| YY_BREAK | |||
| case 48: | |||
| YY_RULE_SETUP | |||
| #line 120 "easymesh/easymesh-scanner.l" | |||
| { /* ignore this */ } | |||
| { return token_type(']'); } | |||
| YY_BREAK | |||
| case 49: | |||
| /* rule 49 can match eol */ | |||
| YY_RULE_SETUP | |||
| #line 121 "easymesh/easymesh-scanner.l" | |||
| { /* ignore this */ } | |||
| YY_BREAK | |||
| case 50: | |||
| /* rule 50 can match eol */ | |||
| YY_RULE_SETUP | |||
| #line 122 "easymesh/easymesh-scanner.l" | |||
| { return token::T_ERROR; } | |||
| { /* ignore this */ } | |||
| YY_BREAK | |||
| case 51: | |||
| 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; | |||
| YY_BREAK | |||
| #line 974 "generated/easymesh-scanner.cpp" | |||
| #line 979 "generated/easymesh-scanner.cpp" | |||
| case YY_STATE_EOF(INITIAL): | |||
| yyterminate(); | |||
| @@ -1352,7 +1357,7 @@ int yyFlexLexer::yy_get_next_buffer() | |||
| while ( yy_chk[yy_base[yy_current_state] + yy_c] != 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_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 ) | |||
| { | |||
| 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_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; | |||
| } | |||
| @@ -1871,7 +1876,7 @@ void EasyMeshfree (void * ptr ) | |||
| #define YYTABLES_NAME "yytables" | |||
| #line 124 "easymesh/easymesh-scanner.l" | |||
| #line 125 "easymesh/easymesh-scanner.l" | |||
| @@ -301,8 +301,8 @@ public: | |||
| m_meshes.Push(EasyMesh(), false, .0f, vec3(.0f)); | |||
| if (!m_meshes.Last().m1.Compile(cmd.C())) | |||
| m_meshes.Pop(); | |||
| else | |||
| m_meshes.Last().m1.ComputeTexCoord(0.2f, 2); | |||
| //else | |||
| // m_meshes.Last().m1.ComputeTexCoord(0.2f, 2); | |||
| } | |||
| } | |||
| } | |||
| @@ -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#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#ff2 afcb 7 7 7 .25 t 1 1 1] | |||