public static Mesh TriangulateFaces(this IVertexSource vertexSource, CachedTesselator teselatedSource = null) { if (teselatedSource == null) { teselatedSource = new CachedTesselator(); } VertexSourceToTesselator.SendShapeToTesselator(teselatedSource, vertexSource); Mesh mesh = new Mesh(); int numIndicies = teselatedSource.IndicesCache.Count; // turn the tessellation output into mesh faces for (int i = 0; i < numIndicies; i += 3) { Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position; Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position; Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position; if (v0 == v1 || v1 == v2 || v2 == v0) { continue; } mesh.CreateFace(new Vector3[] { new Vector3(v0, 0), new Vector3(v1, 0), new Vector3(v2, 0) }); } return(mesh); }
private static Mesh TriangulateFaces(IVertexSource vertexSource, CachedTesselator teselatedSource) { VertexSourceToTesselator.SendShapeToTesselator(teselatedSource, vertexSource); Mesh teselatedMesh = new Mesh(); int numIndicies = teselatedSource.IndicesCache.Count; // turn the tessellation output into mesh faces for (int i = 0; i < numIndicies; i += 3) { Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position; Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position; Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position; if (v0 == v1 || v1 == v2 || v2 == v0) { continue; } IVertex topVertex0 = teselatedMesh.CreateVertex(new Vector3(v0, 0)); IVertex topVertex1 = teselatedMesh.CreateVertex(new Vector3(v1, 0)); IVertex topVertex2 = teselatedMesh.CreateVertex(new Vector3(v2, 0)); teselatedMesh.CreateFace(new IVertex[] { topVertex0, topVertex1, topVertex2 }); } return(teselatedMesh); }
private static Mesh TriangulateFaces(IVertexSource vertexSource, CachedTesselator teselatedSource) { VertexSourceToTesselator.SendShapeToTesselator(teselatedSource, vertexSource); Mesh extrudedVertexSource = new Mesh(); int numIndicies = teselatedSource.IndicesCache.Count; // build the top first so it will render first when we are translucent for (int i = 0; i < numIndicies; i += 3) { Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position; Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position; Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position; if (v0 == v1 || v1 == v2 || v2 == v0) { continue; } Vertex topVertex0 = extrudedVertexSource.CreateVertex(new Vector3(v0, 0)); Vertex topVertex1 = extrudedVertexSource.CreateVertex(new Vector3(v1, 0)); Vertex topVertex2 = extrudedVertexSource.CreateVertex(new Vector3(v2, 0)); extrudedVertexSource.CreateFace(new Vertex[] { topVertex0, topVertex1, topVertex2 }); } return(extrudedVertexSource); }
public static Mesh TriangulateFaces(this IVertexSource vertexSource, CachedTesselator teselatedSource = null, Mesh meshToAddTo = null, double zHeight = 0) { return(TriangulateFaces(vertexSource.Vertices(), teselatedSource, meshToAddTo, zHeight)); }
public static Mesh TriangulateFaces(this IEnumerable <VertexData> vertexSource, CachedTesselator teselatedSource = null, Mesh meshToAddTo = null, double zHeight = 0) { if (teselatedSource == null) { teselatedSource = new CachedTesselator(); } VertexSourceToTesselator.SendShapeToTesselator(teselatedSource, vertexSource); if (meshToAddTo == null) { meshToAddTo = new Mesh(); } int numIndicies = teselatedSource.IndicesCache.Count; // turn the tessellation output into mesh faces for (int i = 0; i < numIndicies; i += 3) { Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position; Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position; Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position; if (v0 == v1 || v1 == v2 || v2 == v0) { continue; } meshToAddTo.CreateFace(new Vector3[] { new Vector3(v0, zHeight), new Vector3(v1, zHeight), new Vector3(v2, zHeight) }); } return(meshToAddTo); }
public static Mesh TriangulateFaces(this IEnumerable <VertexData> vertexSource, CachedTesselator teselatedSource = null, Mesh meshToAddTo = null, double zHeight = 0, Matrix4X4?inMatrix = null) { bool isIdentity = inMatrix == null || inMatrix.Value == Matrix4X4.Identity; if (teselatedSource == null) { teselatedSource = new CachedTesselator(); } VertexSourceToTesselator.SendShapeToTesselator(teselatedSource, vertexSource); if (meshToAddTo == null) { meshToAddTo = new Mesh(); } int numIndicies = teselatedSource.IndicesCache.Count; // turn the tessellation output into mesh faces for (int i = 0; i < numIndicies; i += 3) { Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position; Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position; Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position; if (v0 == v1 || v1 == v2 || v2 == v0) { continue; } if (!isIdentity) { var matrix = inMatrix.Value; meshToAddTo.CreateFace(new Vector3[] { new Vector3(v0, zHeight).Transform(matrix), new Vector3(v1, zHeight).Transform(matrix), new Vector3(v2, zHeight).Transform(matrix) }); } else { meshToAddTo.CreateFace(new Vector3[] { new Vector3(v0, zHeight), new Vector3(v1, zHeight), new Vector3(v2, zHeight) }); } } return(meshToAddTo); }
public static Mesh Revolve(IVertexSource source, int angleSteps = 30, double angleStart = 0, double angleEnd = MathHelper.Tau) { angleSteps = Math.Max(angleSteps, 3); angleStart = MathHelper.Range0ToTau(angleStart); angleEnd = MathHelper.Range0ToTau(angleEnd); // convert to clipper polygons and scale so we can ensure good shapes Polygons polygons = source.CreatePolygons(); // ensure good winding and consistent shapes // clip against x=0 left and right // mirror left material across the origin // union mirrored left with right material // convert the data back to PathStorage VertexStorage cleanedPath = polygons.CreateVertexStorage(); Mesh mesh = new Mesh(); var hasStartAndEndFaces = angleStart > 0.000001; hasStartAndEndFaces |= angleEnd < MathHelper.Tau - 0.000001; // check if we need to make closing faces if (hasStartAndEndFaces) { // make a face for the start CachedTesselator teselatedSource = new CachedTesselator(); Mesh extrudedVertexSource = TriangulateFaces(source, teselatedSource); extrudedVertexSource.Transform(Matrix4X4.CreateRotationX(MathHelper.Tau / 4)); extrudedVertexSource.Transform(Matrix4X4.CreateRotationZ(angleStart)); mesh.CopyFaces(extrudedVertexSource); } // make the outside shell double angleDelta = (angleEnd - angleStart) / angleSteps; double currentAngle = angleStart; if (!hasStartAndEndFaces) { angleSteps--; } for (int i = 0; i < angleSteps; i++) { AddRevolveStrip(cleanedPath, mesh, currentAngle, currentAngle + angleDelta); currentAngle += angleDelta; } if (!hasStartAndEndFaces) { if (((angleEnd - angleStart) < .0000001 || (angleEnd - MathHelper.Tau - angleStart) < .0000001) && (angleEnd - currentAngle) > .0000001) { // make sure we close the shape exactly AddRevolveStrip(cleanedPath, mesh, currentAngle, angleStart); } } else // add the end face { // make a face for the end CachedTesselator teselatedSource = new CachedTesselator(); Mesh extrudedVertexSource = TriangulateFaces(source, teselatedSource); extrudedVertexSource.Transform(Matrix4X4.CreateRotationX(MathHelper.Tau / 4)); extrudedVertexSource.Transform(Matrix4X4.CreateRotationZ(currentAngle)); extrudedVertexSource.ReverseFaceEdges(); mesh.CopyFaces(extrudedVertexSource); } // return the completed mesh return(mesh); }
public static Mesh TriangulateFaces(IVertexSource vertexSource) { CachedTesselator teselatedSource = new CachedTesselator(); return(TriangulateFaces(vertexSource, teselatedSource)); }
public static Mesh Extrude(IVertexSource vertexSource, double zHeight) { CachedTesselator teselatedSource = new CachedTesselator(); Mesh extrudedVertexSource = TriangulateFaces(vertexSource, teselatedSource); int numIndicies = teselatedSource.IndicesCache.Count; extrudedVertexSource.Translate(new Vector3(0, 0, zHeight)); // then the outside edge for (int i = 0; i < numIndicies; i += 3) { Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position; Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position; Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position; if (v0 == v1 || v1 == v2 || v2 == v0) { continue; } IVertex bottomVertex0 = extrudedVertexSource.CreateVertex(new Vector3(v0, 0)); IVertex bottomVertex1 = extrudedVertexSource.CreateVertex(new Vector3(v1, 0)); IVertex bottomVertex2 = extrudedVertexSource.CreateVertex(new Vector3(v2, 0)); IVertex topVertex0 = extrudedVertexSource.CreateVertex(new Vector3(v0, zHeight)); IVertex topVertex1 = extrudedVertexSource.CreateVertex(new Vector3(v1, zHeight)); IVertex topVertex2 = extrudedVertexSource.CreateVertex(new Vector3(v2, zHeight)); if (teselatedSource.IndicesCache[i + 0].IsEdge) { extrudedVertexSource.CreateFace(new IVertex[] { bottomVertex0, bottomVertex1, topVertex1, topVertex0 }); } if (teselatedSource.IndicesCache[i + 1].IsEdge) { extrudedVertexSource.CreateFace(new IVertex[] { bottomVertex1, bottomVertex2, topVertex2, topVertex1 }); } if (teselatedSource.IndicesCache[i + 2].IsEdge) { extrudedVertexSource.CreateFace(new IVertex[] { bottomVertex2, bottomVertex0, topVertex0, topVertex2 }); } } // then the bottom for (int i = 0; i < numIndicies; i += 3) { Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position; Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position; Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position; if (v0 == v1 || v1 == v2 || v2 == v0) { continue; } IVertex bottomVertex0 = extrudedVertexSource.CreateVertex(new Vector3(v0, 0)); IVertex bottomVertex1 = extrudedVertexSource.CreateVertex(new Vector3(v1, 0)); IVertex bottomVertex2 = extrudedVertexSource.CreateVertex(new Vector3(v2, 0)); extrudedVertexSource.CreateFace(new IVertex[] { bottomVertex2, bottomVertex1, bottomVertex0 }); } return(extrudedVertexSource); }
public static Mesh Extrude(this IVertexSource vertexSource, double zHeight) { Polygons polygons = vertexSource.CreatePolygons(); // ensure good winding and consistent shapes polygons = polygons.GetCorrectedWinding(); // convert the data back to PathStorage vertexSource = polygons.CreateVertexStorage(); CachedTesselator teselatedSource = new CachedTesselator(); Mesh mesh = vertexSource.TriangulateFaces(teselatedSource); int numIndicies = teselatedSource.IndicesCache.Count; mesh.Translate(new Vector3(0, 0, zHeight)); // then the outside edge for (int i = 0; i < numIndicies; i += 3) { Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position; Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position; Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position; if (v0 == v1 || v1 == v2 || v2 == v0) { continue; } var bottomVertex0 = new Vector3(v0, 0); var bottomVertex1 = new Vector3(v1, 0); var bottomVertex2 = new Vector3(v2, 0); var topVertex0 = new Vector3(v0, zHeight); var topVertex1 = new Vector3(v1, zHeight); var topVertex2 = new Vector3(v2, zHeight); if (teselatedSource.IndicesCache[i + 0].IsEdge) { mesh.CreateFace(new Vector3[] { bottomVertex0, bottomVertex1, topVertex1, topVertex0 }); } if (teselatedSource.IndicesCache[i + 1].IsEdge) { mesh.CreateFace(new Vector3[] { bottomVertex1, bottomVertex2, topVertex2, topVertex1 }); } if (teselatedSource.IndicesCache[i + 2].IsEdge) { mesh.CreateFace(new Vector3[] { bottomVertex2, bottomVertex0, topVertex0, topVertex2 }); } } // then the bottom for (int i = 0; i < numIndicies; i += 3) { Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position; Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position; Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position; if (v0 == v1 || v1 == v2 || v2 == v0) { continue; } mesh.CreateFace(new Vector3[] { new Vector3(v2, 0), new Vector3(v1, 0), new Vector3(v0, 0) }); } mesh.CleanAndMerge(); return(mesh); }