예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #4
0
 public static Mesh TriangulateFaces(this IVertexSource vertexSource,
                                     CachedTesselator teselatedSource = null,
                                     Mesh meshToAddTo = null,
                                     double zHeight   = 0)
 {
     return(TriangulateFaces(vertexSource.Vertices(), teselatedSource, meshToAddTo, zHeight));
 }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        public static Mesh TriangulateFaces(IVertexSource vertexSource)
        {
            CachedTesselator teselatedSource = new CachedTesselator();

            return(TriangulateFaces(vertexSource, teselatedSource));
        }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }