The input geometry which will be triangulated. May represent a pointset or a planar straight line graph.
Пример #1
1
    public Mesh CreateMeshFromPoints(bool combine)
    {
        if (spriteRenderer != null && points.Length > 2) {

            int pointNum = points.Length;
            if (combine && combineMesh != null) {
                pointNum = points.Length + combineMesh.vertices.Length;
            }

            //Create triangle.NET geometry
            TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(pointNum);

            geometry.AddPolygon(points);

            if (combine && combineMesh != null) {
                geometry.AddPolygon(combineMesh.vertices.Select(x => (Vector2)x).ToArray());
            }

            //Triangulate
            TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh();

            triangleMesh.Triangulate(geometry);

            //transform vertices
            points = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] vertices = new Vector3[triangleMesh.Vertices.Count];
            Vector3[] normals = new Vector3[triangleMesh.Vertices.Count];

            int n = 0;
            foreach(TriangleNet.Data.Vertex v in triangleMesh.Vertices)
            {

                points[n] = new Vector2((float)v.X, (float)v.Y);
                vertices[n] = new Vector3((float)v.X, (float)v.Y, 0);
                normals[n]=new Vector3(0,0,-1);

                n++;
            }

            //transform triangles
            int[] triangles = triangleMesh.Triangles.ToUnityMeshTriangleIndices();

            mesh.Clear();
            mesh = new Mesh();
            mesh.vertices = vertices;
            mesh.triangles = triangles;
            mesh.uv = genUV(mesh.vertices);
            mesh.normals = normals;

            return mesh;
        }
        else {
            return null;
        }
    }
Пример #2
0
        public override InputGeometry Generate(double param0, double param1, double param2)
        {
            // Number of points on the outer circle
            int n = GetParamValueInt(0, param0);
            int count, npoints;

            double radius = GetParamValueInt(1, param1);

            // Step size on the outer circle
            double h = 2 * Math.PI * radius / n;

            // Current radius and step size
            double r, dphi;

            InputGeometry input = new InputGeometry(n + 1);

            // Inner cirlce (radius = 1)
            r = 1;
            npoints = (int)(2 * Math.PI * r / h);
            dphi = 2 * Math.PI / npoints;
            for (int i = 0; i < npoints; i++)
            {
                input.AddPoint(r * Math.Cos(i * dphi), r * Math.Sin(i * dphi), 1);
                input.AddSegment(i, (i + 1) % npoints, 1);
            }

            count = input.Count;

            // Center cirlce
            r = (radius + 1) / 2.0;
            npoints = (int)(2 * Math.PI * r / h);
            dphi = 2 * Math.PI / npoints;
            for (int i = 0; i < npoints; i++)
            {
                input.AddPoint(r * Math.Cos(i * dphi), r * Math.Sin(i * dphi), 2);
                input.AddSegment(count + i, count + (i + 1) % npoints, 2);
            }

            count = input.Count;

            // Outer cirlce
            r = radius;
            npoints = (int)(2 * Math.PI * r / h);
            dphi = 2 * Math.PI / npoints;
            for (int i = 0; i < npoints; i++)
            {
                input.AddPoint(r * Math.Cos(i * dphi), r * Math.Sin(i * dphi), 3);
                input.AddSegment(count + i, count + (i + 1) % npoints, 3);
            }

            input.AddHole(0, 0);

            // Regions: |++++++|++++++|---|
            //          r             1   0

            input.AddRegion((r + 3.0) / 4.0, 0, 1);
            input.AddRegion((3 * r + 1.0) / 4.0, 0, 2);

            return input;
        }
Пример #3
0
 public void HandleMeshImport(InputGeometry geometry, Mesh mesh)
 {
     // Previous mesh stats
     lbNumVert2.Text = "-";
     lbNumTri2.Text = "-";
     lbNumSeg2.Text = "-";
 }
Пример #4
0
    public Mesh CreateMeshFromPoints(bool combine)
    {
        if (spriteRenderer != null && points.Length > 2)
        {
            int pointNum = points.Length;
            if (combine && combineMesh != null)
            {
                pointNum = points.Length + combineMesh.vertices.Length;
            }

            //Create triangle.NET geometry
            TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(pointNum);


            geometry.AddPolygon(points);


            if (combine && combineMesh != null)
            {
                geometry.AddPolygon(combineMesh.vertices.Select(x => (Vector2)x).ToArray());
            }

            //Triangulate
            TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh();

            triangleMesh.Triangulate(geometry);

            //transform vertices
            points = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] vertices = new Vector3[triangleMesh.Vertices.Count];
            Vector2[] uvs      = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] normals  = new Vector3[triangleMesh.Vertices.Count];

            int n = 0;
            foreach (TriangleNet.Data.Vertex v in triangleMesh.Vertices)
            {
                points[n]   = new Vector2((float)v.X, (float)v.Y);
                vertices[n] = new Vector3((float)v.X, (float)v.Y, 0);
                normals[n]  = new Vector3(0, 0, -1);

                n++;
            }

            //transform triangles
            int[] triangles = triangleMesh.Triangles.ToUnityMeshTriangleIndices();

            mesh.Clear();
            mesh           = new Mesh();
            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            mesh.uv        = genUV(mesh.vertices);
            mesh.normals   = normals;

            return(mesh);
        }
        else
        {
            return(null);
        }
    }
Пример #5
0
        /// <summary>
        /// Rebuild the input geometry.
        /// </summary>
        private InputGeometry Rebuild()
        {
            InputGeometry geometry = new InputGeometry(mesh.vertices.Count);

            foreach (var vertex in mesh.vertices.Values)
            {
                geometry.AddPoint(vertex.x, vertex.y, vertex.mark);
            }

            foreach (var segment in mesh.subsegs.Values)
            {
                geometry.AddSegment(segment.P0, segment.P1, segment.Boundary);
            }

            foreach (var hole in mesh.holes)
            {
                geometry.AddHole(hole.x, hole.y);
            }

            foreach (var region in mesh.regions)
            {
                geometry.AddRegion(region.point.x, region.point.y, region.id);
            }

            return geometry;
        }
        /// <summary>
        /// Add a polygon ring to the geometry and make it a hole.
        /// </summary>
        /// <remarks>
        /// WARNING: This works for convex polygons, but not for non-convex regions in general.
        /// </remarks>
        /// <param name="points">List of points which make up the hole.</param>
        /// <param name="mark">Common boundary mark for all segments of the hole.</param>
        public static void AddRingAsHole(this InputGeometry geometry, IEnumerable<TriangleNet.Geometry.Point> points, int mark = 0)
        {
            // Save the current number of points.
            int N = geometry.Count;
            int m = 0;

            foreach (var pt in points)
            {
                geometry.AddPoint(pt.X, pt.Y, pt.Boundary, pt.Attributes);
                m++;
            }

            for (int i = 0; i < m; i++)
            {
                geometry.AddSegment(N + i, N + ((i + 1) % m), mark);
            }

            //a lényeg az hogy kell egy a lyukon lévő pont,hogy jelezze hogy az egy lyuk poligon... a legegyszerübb trükk a következő, az egybefüggő (akár konkáv) poligont háromszögesítem, ezzel nincs gond, ezután kiválasztok egy testzőleges háromszöget, és veszem annak a középpontját..ez már tuti hogy a nagy poligon belső pontja
            TriangleNetMesh mesh = new TriangleNetMesh();
            var inputGeometry = new InputGeometry();
            inputGeometry.AddRing(points);
            mesh.Triangulate(inputGeometry);
            var firstTriangle = new List<Triangle>(mesh.Triangles)[0];

            double x = 0.0;
            double y = 0.0;
            for (int iii = 0; iii < 3; iii++)
            {
                var vertex = firstTriangle.GetVertex(iii);
                x += vertex.X;
                y += vertex.Y;
            }

            geometry.AddHole(x / 3, y / 3);
        }
Пример #7
0
    public WaterSurfacePolygon(List<Point> points)
    {
        mesh = new TriangleNet.Mesh();
        mesh.Behavior.Quality = true;

        this.points = points;

        triangleNormals = new List<Point>();
        trianglePlaneEquationDs = new List<double>();

        InputGeometry geomtery = new InputGeometry();

        for (int i = 0; i < points.Count; i++)
        {
            Point p = points[i];

            if (i == 0)
            {
                minX = maxX = p.X;
                minY = maxY = p.Y;
                minZ = maxZ = p.Z;
            }
            else
            {
                minX = Math.Min(p.X, minX);
                maxX = Math.Max(p.X, maxX);
                minY = Math.Min(p.Y, minY);
                maxY = Math.Max(p.Y, maxY);
                minZ = Math.Min(p.Z, minZ);
                maxZ = Math.Max(p.Z, maxZ);
            }

            geomtery.AddPoint(p.X, p.Y, 0, p.Z);

            //add segments
            if (i > 0)
            {
                geomtery.AddSegment(i - 1, i, 0);
            }

            if (i == points.Count - 1)
            {
                geomtery.AddSegment(i, 0, 0);
            }
        }

        mesh.Triangulate(geomtery);
        triangles = new List<TriangleNet.Data.Triangle>();

        foreach (TriangleNet.Data.Triangle tr in mesh.Triangles)
        {
            if (tr.P0 < points.Count && tr.P1 < points.Count && tr.P2 < points.Count)
            {
                triangles.Add(tr);
            }
        }

        calculateNormalsAndDs();
    }
Пример #8
0
 public static void Write(InputGeometry geometry, string filename)
 {
     using (StreamWriter writer = new StreamWriter(filename))
     {
         WritePoints(writer, geometry.Points, geometry.Count);
         WriteSegments(writer, geometry.Segments);
         WriteHoles(writer, geometry.Holes);
     }
 }
        private static Mesh buildMesh(Dictionary<Point, Color> pointIndex)
        {
            InputGeometry g = new InputGeometry();
            foreach (var value in pointIndex)
            {
                g.AddPoint(value.Key.X, value.Key.Y);
            }

            Mesh m = new Mesh();
            m.Triangulate(g);
            return m;
        }
Пример #10
0
        /// <summary>
        /// Reads a mesh from .node, .poly or .ele files.
        /// </summary>
        public static void Read(string filename, out InputGeometry geometry, out List<ITriangle> triangles)
        {
            triangles = null;

            FileReader.Read(filename, out geometry);

            //string path = Path.ChangeExtension(filename, ".ele");

            //if (File.Exists(path) && geometry != null)
            //{
            //    triangles = FileReader.ReadEleFile(path);
            //}
        }
Пример #11
0
    private Mesh TriangulateMesh()
    {
        if (verts.Count > 2)
        {
            var tnMesh = new TriangleNet.Mesh();
            var input  = new TriangleNet.Geometry.InputGeometry();

            var localVertices = verts.Select(v => spriteRenderer.transform.InverseTransformPoint(v.position)).ToArray();

            for (int i = 0; i < verts.Count; i++)
            {
                verts[i].index = i;
                input.AddPoint(verts[i].position.x, verts[i].position.y);
            }

            foreach (var seg in segments)
            {
                if (!seg.IsDeleted())
                {
                    input.AddSegment(seg.first.index, seg.second.index);
                }
            }

            foreach (var hole in holes)
            {
                input.AddHole(hole.x, hole.y);
            }

            tnMesh.Triangulate(input);

            try {
                Mesh mesh = new Mesh();
                mesh.vertices  = localVertices;
                mesh.triangles = tnMesh.Triangles.ToUnityMeshTriangleIndices();
                mesh.uv        = genUV(mesh.vertices);
                mesh.RecalculateBounds();
                mesh.RecalculateNormals();
                return(mesh);
            }
            catch {
                Debug.LogError("Mesh topology was wrong. Make sure you dont have intersecting edges.");
                throw;
            }
        }
        else
        {
            return(null);
        }
    }
Пример #12
0
        /// <summary>
        /// Reads geometry information from .node or .poly files.
        /// </summary>
        public static void Read(string filename, out InputGeometry geometry)
        {
            geometry = null;

            //string path = Path.ChangeExtension(filename, ".poly");

            //if (File.Exists(path))
            //{
            //    geometry = FileReader.ReadPolyFile(path);
            //}
            //else
            //{
            //    path = Path.ChangeExtension(filename, ".node");
            //    geometry = FileReader.ReadNodeFile(path);
            //}
        }
Пример #13
0
        /// <summary>
        /// Reads geometry information from .node or .poly files.
        /// </summary>
        public static void Read(string filename, out InputGeometry geometry)
        {
            geometry = null;

            string path = Path.ChangeExtension(filename, ".poly");

            if (File.Exists(path))
            {
                geometry = FileReader.ReadPolyFile(path);
            }
            else
            {
                path = Path.ChangeExtension(filename, ".node");
                geometry = FileReader.ReadNodeFile(path);
            }
        }
        private static InputGeometry GetGeometryFor(IEnumerable <Vector2> circuit)
        {
            var result = new TriangleNet.Geometry.InputGeometry(circuit.Count());

            foreach (var v in circuit)
            {
                result.AddPoint(v.x, v.y);
            }

            for (int i = 0; i < result.Count - 1; i++)
            {
                result.AddSegment(i, i + 1, 1);
            }

            result.AddSegment(result.Count - 1, 0, 1);

            return(result);
        }
Пример #15
0
        /// <summary>
        /// Copy input geometry data.
        /// </summary>
        public void SetInputGeometry(InputGeometry data)
        {
            // Clear unused buffers
            this.Segments = null;
            this.Triangles = null;
            this.MeshEdges = null;
            this.VoronoiPoints = null;
            this.VoronoiEdges = null;

            int n = data.Count;
            int i = 0;

            this.NumberOfRegions = data.Regions.Count;
            this.NumberOfInputPoints = n;

            // Copy points
            this.Points = new float[2 * n];
            foreach (var pt in data.Points)
            {
                this.Points[2 * i] = (float)pt.X;
                this.Points[2 * i + 1] = (float)pt.Y;
                i++;
            }

            // Copy segments
            n = data.Segments.Count;
            if (n > 0)
            {
                var segments = new List<uint>(2 * n);
                foreach (var seg in data.Segments)
                {
                    segments.Add((uint)seg.P0);
                    segments.Add((uint)seg.P1);
                }
                this.Segments = segments.ToArray();
            }

            this.Bounds = new BoundingBox(
                (float)data.Bounds.Xmin,
                (float)data.Bounds.Xmax,
                (float)data.Bounds.Ymin,
                (float)data.Bounds.Ymax);
        }
Пример #16
0
        public override InputGeometry Generate(double param0, double param1, double param2)
        {
            int n = GetParamValueInt(0, param0);
            int m = n / 2;

            InputGeometry input = new InputGeometry(n + 1);

            double ro, r = 10;
            double step = 2 * Math.PI / m;

            // Inner ring
            for (int i = 0; i < m; i++)
            {
                input.AddPoint(r * Math.Cos(i * step), r * Math.Sin(i * step));
                input.AddSegment(i, (i + 1) % m);
            }

            r = 1.5 * r;

            step = 2 * Math.PI / n;
            double offset = step / 2;

            // Outer ring
            for (int i = 0; i < n; i++)
            {
                ro = r;

                if (i % 2 == 0)
                {
                    ro = r + r * Util.Random.NextDouble() * (param1 / 100);
                }

                input.AddPoint(ro * Math.Cos(i * step + offset), ro * Math.Sin(i * step + offset));
                input.AddSegment(m + i, m + ((i + 1) % n));
            }

            input.AddHole(0, 0);

            return input;
        }
Пример #17
0
        public override InputGeometry Generate(double param0, double param1, double param2)
        {
            int numPoints = GetParamValueInt(0, param0);
            numPoints = (numPoints / 10) * 10;

            if (numPoints < 5)
            {
                numPoints = 5;
            }

            double exp = (param1 + 10) / 100;

            InputGeometry input = new InputGeometry(numPoints);

            int i = 0, cNum = 2 * (int)Math.Floor(Math.Sqrt(numPoints));

            double r, phi, radius = 100, step = 2 * Math.PI / cNum;

            // Distrubute points equally on circle border
            for (; i < cNum; i++)
            {
                // Add a little error
                r = Util.Random.NextDouble();

                input.AddPoint((radius + r) * Math.Cos(i * step),
                    (radius + r) * Math.Sin(i * step));
            }

            for (; i < numPoints; i++)
            {
                // Use sqrt(rand) to get normal distribution right.
                r = Math.Pow(Util.Random.NextDouble(), exp) * radius;
                phi = Util.Random.NextDouble() * Math.PI * 2;

                input.AddPoint(r * Math.Cos(phi), r * Math.Sin(phi));
            }

            return input;
        }
Пример #18
0
        public override InputGeometry Generate(double param0, double param1, double param2)
        {
            int numPoints = GetParamValueInt(0, param0);
            numPoints = (numPoints / 10) * 10;

            if (numPoints < 5)
            {
                numPoints = 5;
            }

            InputGeometry input = new InputGeometry(numPoints);

            int width = GetParamValueInt(1, param1);
            int height = GetParamValueInt(2, param2);

            for (int i = 0; i < numPoints; i++)
            {
                input.AddPoint(Util.Random.NextDouble() * width,
                        Util.Random.NextDouble() * height);
            }

            return input;
        }
Пример #19
0
        /// <summary>
        /// Read vertex information of the given line.
        /// </summary>
        /// <param name="data">The input geometry.</param>
        /// <param name="index">The current vertex index.</param>
        /// <param name="line">The current line.</param>
        /// <param name="attributes">Number of point attributes</param>
        /// <param name="marks">Number of point markers (0 or 1)</param>
        static void ReadVertex(InputGeometry data, int index, string[] line, int attributes, int marks)
        {
            float x = float.Parse(line[1], nfi);
            float y = float.Parse(line[2], nfi);
            int mark = 0;
            float[] attribs = attributes == 0 ? null : new float[attributes];

            // Read the vertex attributes.
            for (int j = 0; j < attributes; j++)
            {
                if (line.Length > 3 + j)
                {
                    attribs[j] = float.Parse(line[3 + j]);
                }
            }

            // Read a vertex marker.
            if (marks > 0 && line.Length > 3 + attributes)
            {
                mark = int.Parse(line[3 + attributes]);
            }

            data.AddPoint(x, y, mark, attribs);
        }
Пример #20
0
        /// <summary>
        /// Read the vertices from memory.
        /// </summary>
        /// <param name="data">The input data.</param>
        private void TransferNodes(InputGeometry data)
        {
            List<Vertex> points = data.points;

            this.invertices = points.Count;
            this.mesh_dim = 2;

            if (this.invertices < 3)
            {
                logger.Error("Input must have at least three input vertices.", "MeshReader.TransferNodes()");
                throw new Exception("Input must have at least three input vertices.");
            }

            this.nextras = points[0].attributes == null ? 0 : points[0].attributes.Length;

            foreach (Vertex vertex in points)
            {
                vertex.hash = this.hash_vtx++;
                vertex.id = vertex.hash;

                this.vertices.Add(vertex.hash, vertex);
            }

            this.bounds = data.Bounds;
        }
Пример #21
0
        /// <summary>
        /// Reconstructs a mesh from raw input data.
        /// </summary>
        public void Load(InputGeometry input, List<ITriangle> triangles)
        {
            if (input == null || triangles == null)
            {
                throw new ArgumentException("Invalid input (argument is null).");
            }

            // Clear all data structures / reset hash seeds
            this.ResetData();

            if (input.HasSegments)
            {
                behavior.Poly = true;

                this.holes.AddRange(input.Holes);
            }

            //if (input.EdgeMarkers != null)
            //{
            //    behavior.UseBoundaryMarkers = true;
            //}

            //if (input.TriangleAreas != null)
            //{
            //    behavior.VarArea = true;
            //}

            // TODO: remove
            if (!behavior.Poly)
            {
                // Be careful not to allocate space for element area constraints that
                // will never be assigned any value (other than the default -1.0).
                behavior.VarArea = false;

                // Be careful not to add an extra attribute to each element unless the
                // input supports it (PSLG in, but not refining a preexisting mesh).
                behavior.useRegions = false;
            }

            behavior.useRegions = input.Regions.Count > 0;

            TransferNodes(input);

            // Read and reconstruct a mesh.
            hullsize = DataReader.Reconstruct(this, input, triangles.ToArray());

            // Calculate the number of edges.
            edges = (3 * triangles.Count + hullsize) / 2;
        }
Пример #22
0
        /// <summary>
        /// Create the segments of a triangulation, including PSLG segments and edges 
        /// on the convex hull.
        /// </summary>
        /// <param name="segmentlist"></param>
        /// <param name="segmentmarkerlist"></param>
        /// <param name="numberofsegments"></param>
        private void FormSkeleton(InputGeometry input)
        {
            Vertex endpoint1, endpoint2;
            int end1, end2;
            int boundmarker;

            this.insegments = 0;

            if (behavior.Poly)
            {
                // If the input vertices are collinear, there is no triangulation,
                // so don't try to insert segments.
                if (triangles.Count == 0)
                {
                    return;
                }

                // If segments are to be inserted, compute a mapping
                // from vertices to triangles.
                if (input.HasSegments)
                {
                    MakeVertexMap();
                }

                boundmarker = 0;

                // Read and insert the segments.
                foreach (var seg in input.segments)
                {
                    this.insegments++;

                    end1 = seg.P0;
                    end2 = seg.P1;
                    boundmarker = seg.Boundary;

                    if ((end1 < 0) || (end1 >= invertices))
                    {
                        if (Behavior.Verbose)
                        {
                            logger.Warning("Invalid first endpoint of segment.", "Mesh.FormSkeleton().1");
                        }
                    }
                    else if ((end2 < 0) || (end2 >= invertices))
                    {
                        if (Behavior.Verbose)
                        {
                            logger.Warning("Invalid second endpoint of segment.", "Mesh.FormSkeleton().2");
                        }
                    }
                    else
                    {
                        // TODO: Is using the vertex ID reliable???
                        // It should be. The ID gets appropriately set in TransferNodes().

                        // Find the vertices numbered 'end1' and 'end2'.
                        endpoint1 = vertices[end1];
                        endpoint2 = vertices[end2];
                        if ((endpoint1.x == endpoint2.x) && (endpoint1.y == endpoint2.y))
                        {
                            if (Behavior.Verbose)
                            {
                                logger.Warning("Endpoints of segments are coincident.", "Mesh.FormSkeleton()");
                            }
                        }
                        else
                        {
                            InsertSegment(endpoint1, endpoint2, boundmarker);
                        }
                    }
                }
            }

            if (behavior.Convex || !behavior.Poly)
            {
                // Enclose the convex hull with subsegments.
                MarkHull();
            }
        }
Пример #23
0
        private void RecalculateVertices()
        {
            if (points.Count < 2)
            {
                return;
            }

            vertexPositionColorArray = null;

            var lineColor = Color.Red;

            #region clipper
            List<IntPoint> clipperPath = new List<IntPoint>(points.Count);
            foreach (var point in points)
            {
                clipperPath.Add(new IntPoint(point.X * ClipperScale, point.Y * ClipperScale));
            }

            List<List<IntPoint>> clipperSolution = new List<List<IntPoint>>();
            ClipperOffset clipperOffset = new ClipperOffset();

            clipperOffset.AddPath(clipperPath, JoinType.jtRound, EndType.etOpenRound);
            clipperOffset.Execute(ref clipperSolution, lineThickness / 2.0f * ClipperScale);
            #endregion

            #region triangle.net
            InputGeometry InputGeometry = new InputGeometry();
            Mesh TriangleMesh = new Mesh();

            for (int iii = 0; iii < clipperSolution.Count; iii++)
            {
                var trianglePath = clipperSolution[iii].Select(p => new TrianglePoint(p.X / (float)ClipperScale, p.Y / (float)ClipperScale)).ToList();

                if (iii == 0)
                {
                    InputGeometry.AddRing(trianglePath);
                }
                else
                {
                    InputGeometry.AddRingAsHole(trianglePath);
                }
            }
            #endregion

            if (InputGeometry.Count > 0)
            {
                TriangleMesh.Triangulate(InputGeometry);

                vertexPositionColorArray = TriangleMesh.GetTriangleList().Select(v => new VertexPositionColor(new Vector3((float)v.X, (float)v.Y, 0.0f), lineColor)).ToArray();

                vertexBuffer = new VertexBuffer(GraphicsDevice, VertexPositionColor.VertexDeclaration, vertexPositionColorArray.Length, BufferUsage.WriteOnly);
                vertexBuffer.SetData<VertexPositionColor>(vertexPositionColorArray);
            }
        }
Пример #24
0
    public void SubdivideMesh(int divisions)
    {
        if (spriteRenderer != null && points.Length > 2)
        {
            // Unparent the skin temporarily before adding the mesh
            Transform polygonParent = spriteRenderer.transform.parent;
            spriteRenderer.transform.parent = null;

            // Reset the rotation before creating the mesh so the UV's will align properly
            Quaternion localRotation = spriteRenderer.transform.localRotation;
            spriteRenderer.transform.localRotation = Quaternion.identity;

            // Reset the scale before creating the mesh so the UV's will align properly
            Vector3 localScale = spriteRenderer.transform.localScale;
            spriteRenderer.transform.localScale = Vector3.one;

            //Create triangle.NET geometry
            TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(points.Length);

            //Add vertices
            foreach (Vector2 point in points)
            {
                geometry.AddPoint(point.x, point.y);
            }

            int N   = geometry.Count;
            int end = 0;
            //Add vertices
            foreach (Vector2 point in points)
            {
                geometry.AddPoint(point.x, point.y);
                end++;
            }

            for (int i = 0; i < end; i++)
            {
                geometry.AddSegment(N + i, N + ((i + 1) % end));
            }

            //Triangulate and subdivide the mesh
            TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh();

            if (divisions > 0)
            {
                triangleMesh.behavior.MinAngle = 10;
            }

            triangleMesh.Triangulate(geometry);
            if (divisions > 0)
            {
                if (divisions > 1)
                {
                    triangleMesh.Refine(true);
                }
                TriangleNet.Tools.Statistic stat = new TriangleNet.Tools.Statistic();
                stat.Update(triangleMesh, 1);
                // Refine by area
                if (divisions > 2)
                {
                    triangleMesh.Refine(stat.LargestArea / 8);
                }

                try {
                    triangleMesh.Smooth();
                } catch {
                    //Debug.Log("Cannot subdivide");
                }
                triangleMesh.Renumber();
            }

            //transform vertices
            points = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] vertices = new Vector3[triangleMesh.Vertices.Count];
            Vector2[] uvs      = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] normals  = new Vector3[triangleMesh.Vertices.Count];

            int n = 0;
            foreach (TriangleNet.Data.Vertex v in triangleMesh.Vertices)
            {
                points[n]   = new Vector2((float)v.X, (float)v.Y);
                vertices[n] = new Vector3((float)v.X, (float)v.Y, 0);
                normals[n]  = new Vector3(0, 0, -1);
                n++;
            }

            //transform triangles
            int[] triangles = new int[triangleMesh.Triangles.Count * 3];
            n = 0;
            foreach (TriangleNet.Data.Triangle t in triangleMesh.Triangles)
            {
                triangles[n++] = t.P1;
                triangles[n++] = t.P0;
                triangles[n++] = t.P2;
            }

            mesh.Clear();
            mesh           = new Mesh();
            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            mesh.uv        = genUV(mesh.vertices);
            mesh.normals   = normals;
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();

            // Reset the rotations of the object
            spriteRenderer.transform.localRotation = localRotation;
            spriteRenderer.transform.localScale    = localScale;
            spriteRenderer.transform.parent        = polygonParent;

            meshCreated = true;
        }
    }
Пример #25
0
        /// <summary>
        /// Get a list of triangles which will fill the area described by the slice
        /// </summary>
        public IEnumerable<Triangle> Triangles()
        {
            TriangleNet.Behavior behavior = new TriangleNet.Behavior();
            behavior.ConformingDelaunay = true;

            foreach (var poly in IndividualPolygons())
            {
                PolyNode node = polyTree.GetFirst();
                InputGeometry geometry = new InputGeometry();
                while (node != null)
                {
                    var offset = geometry.Points.Count();
                    var index = 0;
                    foreach (IntPoint point in node.Contour)
                    {
                        geometry.AddPoint(point.X, point.Y);
                        if (index > 0)
                        {
                            geometry.AddSegment(index - 1 + offset, index + offset);
                        }
                        index++;
                    }
                    geometry.AddSegment(index - 1 + offset, offset);

                    if (node.IsHole)
                    {
                        // To describe a hole, AddHole must be called with a location inside the hole.
                        IntPoint last = new IntPoint(0, 0);
                        bool lastKnown = false;
                        double longest = 0;
                        IntPoint longestAlong = new IntPoint(0, 0);
                        IntPoint from = new IntPoint(0, 0);
                        foreach (IntPoint point in node.Contour)
                        {
                            if (lastKnown)
                            {
                                IntPoint along = new IntPoint(point.X - last.X, point.Y - last.Y);
                                double length = Math.Sqrt(along.X * along.X + along.Y * along.Y);
                                if (length > longest)
                                {
                                    longest = length;
                                    longestAlong = along;
                                    from = last;
                                }
                            }
                            last = point;
                            lastKnown = true;
                        }
                        if (longest > 0)
                        {
                            double perpendicularX = ((double)longestAlong.Y * (double)scale * 0.001d) / longest;
                            double perpendicularY = -((double)longestAlong.X * (double)scale * 0.001d) / longest;
                            geometry.AddHole(perpendicularX + from.X + longestAlong.X / 2.0d,
                                perpendicularY + from.Y + longestAlong.Y / 2.0d);
                        }
                        else
                        {
                        }
                    }
                    node = node.GetNext();
                }

                if (geometry.Points.Count() > 0)
                {
                    var mesh = new TriangleNet.Mesh(behavior);
                    mesh.Triangulate(geometry);
                    mesh.Renumber();
                    foreach (Triangle t in this.GetMeshTriangles(mesh))
                    {
                        yield return t;
                    }
                }
            }
        }
Пример #26
0
		public static void Tessellate(List<Vector2> vertices, List<IndexedEdge> indexedEdges, List<Hole> holes, List<int> indices, float tessellationAmount)
		{
			if(tessellationAmount <= 0f)
			{
				return;
			}
			
			indices.Clear();
			
			if(vertices.Count >= 3)
			{
				InputGeometry inputGeometry = new InputGeometry(vertices.Count);
				
				for(int i = 0; i < vertices.Count; ++i)
				{
					Vector2 vertex = vertices[i];
					inputGeometry.AddPoint(vertex.x,vertex.y);
				}
				
				for(int i = 0; i < indexedEdges.Count; ++i)
				{
					IndexedEdge edge = indexedEdges[i];
					inputGeometry.AddSegment(edge.index1,edge.index2);
				}
				
				for(int i = 0; i < holes.Count; ++i)
				{
					Vector2 hole = holes[i].vertex;
					inputGeometry.AddHole(hole.x,hole.y);
				}
				
				TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh();
				TriangleNet.Tools.Statistic statistic = new TriangleNet.Tools.Statistic();
				
				triangleMesh.Triangulate(inputGeometry);
				
				triangleMesh.Behavior.MinAngle = 20.0;
				triangleMesh.Behavior.SteinerPoints = -1;
				triangleMesh.Refine(true);
				
				statistic.Update(triangleMesh,1);
				
				triangleMesh.Refine(statistic.LargestArea / tessellationAmount);
				triangleMesh.Renumber();
				
				vertices.Clear();
				indexedEdges.Clear();
				
				foreach(TriangleNet.Data.Vertex vertex in triangleMesh.Vertices)
				{
					vertices.Add(new Vector2((float)vertex.X,(float)vertex.Y));
				}
				
				foreach(TriangleNet.Data.Segment segment in triangleMesh.Segments)
				{
					indexedEdges.Add(new IndexedEdge(segment.P0,segment.P1));
				}
				
				foreach (TriangleNet.Data.Triangle triangle in triangleMesh.Triangles)
				{
					if(triangle.P0 >= 0 && triangle.P0 < vertices.Count &&
					   triangle.P0 >= 0 && triangle.P1 < vertices.Count &&
					   triangle.P0 >= 0 && triangle.P2 < vertices.Count)
					{
						indices.Add(triangle.P0);
						indices.Add(triangle.P2);
						indices.Add(triangle.P1);
					}
				}
			}
		}
Пример #27
0
        void frmGenerator_InputGenerated(object sender, EventArgs e)
        {
            this.input = sender as InputGeometry;

            if (input != null)
            {
                settings.CurrentFile = "tmp-" + DateTime.Now.ToString("HH-mm-ss");
                HandleNewInput();
            }
        }
Пример #28
0
    public Mesh TriangulateMesh(Vector3[] Vertices)
    {
        if (Vertices.Length < 3)
        {
            return(null);
        }

        geometry = new InputGeometry();

        foreach (Vector3 Vert in Vertices)
        {
            geometry.AddPoint(Vert.x, Vert.y);
        }

        List <Point> points = new List <Point>();

        for (float offsetX = -distance; offsetX < distance; offsetX += boxDistance)
        {
            for (float offsetY = -verticalDistance; offsetY < verticalDistance; offsetY += boxDistance)
            {
                Vector2 offset = new Vector2(offsetX, offsetY) + Vector2.one * boxDistance * 0.5f;

                float radians = Random.Range(0, 2 * Mathf.PI);
                float length  = Random.Range(0, circleDistance);

                Vector2 pos = new Vector2(Mathf.Cos(radians), Mathf.Sin(radians)) * length;
                pos += offset;
            }
        }

        meshRepresentation = new TriangleNet.Mesh();
        meshRepresentation.Triangulate(geometry);

        //generate mesh based on triangulation

        Dictionary <int, float> zOffsets = new Dictionary <int, float>();

        foreach (KeyValuePair <int, TriangleNet.Data.Vertex> pair in meshRepresentation.vertices)
        {
            zOffsets.Add(pair.Key, Random.Range(-zOffset, zOffset));
        }

        int            triangleIndex   = 0;
        List <Vector3> vertices        = new List <Vector3>(meshRepresentation.triangles.Count * 3);
        List <int>     triangleIndices = new List <int>(meshRepresentation.triangles.Count * 3);

        foreach (KeyValuePair <int, TriangleNet.Data.Triangle> pair in meshRepresentation.triangles)
        {
            TriangleNet.Data.Triangle triangle = pair.Value;

            TriangleNet.Data.Vertex vertex0 = triangle.GetVertex(0);
            TriangleNet.Data.Vertex vertex1 = triangle.GetVertex(1);
            TriangleNet.Data.Vertex vertex2 = triangle.GetVertex(2);

            Vector3 p0 = new Vector3(vertex0.x, vertex0.y, zOffsets[vertex0.id]);
            Vector3 p1 = new Vector3(vertex1.x, vertex1.y, zOffsets[vertex1.id]);
            Vector3 p2 = new Vector3(vertex2.x, vertex2.y, zOffsets[vertex2.id]);

            vertices.Add(p0);
            vertices.Add(p1);
            vertices.Add(p2);

            triangleIndices.Add(triangleIndex + 2);
            triangleIndices.Add(triangleIndex + 1);
            triangleIndices.Add(triangleIndex);

            triangleIndex += 3;
        }

        mesh           = new Mesh();
        mesh.name      = "Triangulated Terrain";
        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangleIndices.ToArray();

        return(mesh);
    }
Пример #29
0
        public static List<SampleTri> BuildMesh(Dictionary<Point, Pixel> pointIndex)
        {
            InputGeometry g = new InputGeometry();
            foreach (var value in pointIndex)
            {
                g.AddPoint(value.Key.X, value.Key.Y);
            }

            Mesh m = new Mesh();
            m.Triangulate(g);

            List<SampleTri> sampleMesh = new List<SampleTri>();

            Dictionary<ITriangle, SampleTri> table = new Dictionary<ITriangle, SampleTri>();

            Dictionary<Point, Sample> sampleTable = new Dictionary<Point, Sample>();

            foreach (var mTri in m.Triangles)
            {
                SampleTri tri = new SampleTri(mTri);

                for (int i = 0; i < 3; i++)
                    tri.TriangleNeighbours.Add(mTri.GetNeighbor(i));

                sampleMesh.Add(tri);
                table.Add(mTri, tri);

                if (sampleTable.ContainsKey(tri.U.Point))
                    tri.U = sampleTable[tri.U.Point];
                else
                    sampleTable[tri.U.Point] = tri.U;

                if (sampleTable.ContainsKey(tri.V.Point))
                    tri.V = sampleTable[tri.V.Point];
                else
                    sampleTable[tri.V.Point] = tri.V;

                if (sampleTable.ContainsKey(tri.W.Point))
                    tri.W = sampleTable[tri.W.Point];
                else
                    sampleTable[tri.W.Point] = tri.W;
            }

            foreach (var tri in sampleMesh)
            {
                foreach (var triangleNeighbour in tri.TriangleNeighbours)
                {
                    if (triangleNeighbour != null)
                        tri.SampleTriNeighbours.Add(table[triangleNeighbour]);
                }
                tri.U.Triangles.Add(tri);
                tri.V.Triangles.Add(tri);
                tri.W.Triangles.Add(tri);

                tri.U.Color = pointIndex[tri.U.Point];
                tri.V.Color = pointIndex[tri.V.Point];
                tri.W.Color = pointIndex[tri.W.Point];

                tri.CenterColor = tri.U.Color;
            }

            return sampleMesh;
        }
Пример #30
0
        /// <summary>
        /// Triangulate given input data.
        /// </summary>
        /// <param name="input"></param>
        public void Triangulate(InputGeometry input)
        {
            ResetData();

            behavior.Poly = input.HasSegments;
            //behavior.useSegments = input.HasSegments;

            //if (input.EdgeMarkers != null)
            //{
            //    behavior.UseBoundaryMarkers = true;
            //}

            // TODO: remove
            if (!behavior.Poly)
            {
                // Be careful not to allocate space for element area constraints that
                // will never be assigned any value (other than the default -1.0).
                behavior.VarArea = false;

                // Be careful not to add an extra attribute to each element unless the
                // input supports it (PSLG in, but not refining a preexisting mesh).
                behavior.useRegions = false;
            }

            behavior.useRegions = input.Regions.Count > 0;

            steinerleft = behavior.SteinerPoints;

            TransferNodes(input);

            hullsize = Delaunay(); // Triangulate the vertices.

            // Ensure that no vertex can be mistaken for a triangular bounding
            // box vertex in insertvertex().
            infvertex1 = null;
            infvertex2 = null;
            infvertex3 = null;

            if (behavior.useSegments)
            {
                // Segments will be introduced next.
                checksegments = true;

                // Insert PSLG segments and/or convex hull segments.
                FormSkeleton(input);
            }

            if (behavior.Poly && (triangles.Count > 0))
            {
                // Copy holes
                foreach (var item in input.holes)
                {
                    holes.Add(item);
                }

                // Copy regions
                foreach (var item in input.regions)
                {
                    regions.Add(item);
                }

                //dummytri.neighbors[2].triangle = dummytri;

                // Carve out holes and concavities.
                Carver c = new Carver(this);
                c.CarveHoles();
            }
            else
            {
                // Without a PSLG, there can be no holes or regional attributes
                // or area constraints. The following are set to zero to avoid
                // an accidental free() later.
                //
                // TODO: -
                holes.Clear();
                regions.Clear();
            }

            if (behavior.Quality && (triangles.Count > 0))
            {
                quality.EnforceQuality(); // Enforce angle and area constraints.
            }

            // Calculate the number of edges.
            edges = (3 * triangles.Count + hullsize) / 2;
        }
Пример #31
0
 private void WriteGeometry(InputGeometry geometry)
 {
     stream.WriteLine("#!G{0}", this.iteration++);
 }
Пример #32
0
    public void SubdivideMesh(int divisions)
    {
        if (spriteRenderer != null && points.Length > 2) {
            // Unparent the skin temporarily before adding the mesh
            Transform polygonParent = spriteRenderer.transform.parent;
            spriteRenderer.transform.parent = null;

            // Reset the rotation before creating the mesh so the UV's will align properly
            Quaternion localRotation = spriteRenderer.transform.localRotation;
            spriteRenderer.transform.localRotation = Quaternion.identity;

            // Reset the scale before creating the mesh so the UV's will align properly
            Vector3 localScale = spriteRenderer.transform.localScale;
            spriteRenderer.transform.localScale = Vector3.one;

            //Create triangle.NET geometry
            TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(points.Length);

            //Add vertices
            foreach (Vector2 point in points) {
                geometry.AddPoint(point.x,point.y);
            }

            int N = geometry.Count;
            int end = 0;
            //Add vertices
            foreach (Vector2 point in points) {
                geometry.AddPoint(point.x,point.y);
                end++;
            }

            for (int i = 0; i < end; i++) {
                geometry.AddSegment(N + i, N + ((i + 1) % end));
            }

            //Triangulate and subdivide the mesh
            TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh();

            if (divisions > 0) {
                triangleMesh.behavior.MinAngle = 10;
            }

            triangleMesh.Triangulate(geometry);
            if (divisions > 0) {
                if (divisions > 1) triangleMesh.Refine(true);
                TriangleNet.Tools.Statistic stat = new TriangleNet.Tools.Statistic();
                stat.Update(triangleMesh, 1);
                // Refine by area
                if (divisions > 2) triangleMesh.Refine (stat.LargestArea / 8);

                try {
                    triangleMesh.Smooth();
                } catch {
                    //Debug.Log("Cannot subdivide");
                }
                triangleMesh.Renumber();
            }

            //transform vertices
            points = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] vertices = new Vector3[triangleMesh.Vertices.Count];
            Vector3[] normals = new Vector3[triangleMesh.Vertices.Count];

            int n = 0;
            foreach(TriangleNet.Data.Vertex v in triangleMesh.Vertices) {

                points[n] = new Vector2((float)v.X, (float)v.Y);
                vertices[n] = new Vector3((float)v.X, (float)v.Y, 0);
                normals[n] = new Vector3(0, 0, -1);
                n++;
            }

            //transform triangles
            int[] triangles = new int[triangleMesh.Triangles.Count*3];
            n = 0;
            foreach (TriangleNet.Data.Triangle t in triangleMesh.Triangles) {
                triangles[n++] = t.P1;
                triangles[n++] = t.P0;
                triangles[n++] = t.P2;
            }

            mesh.Clear();
            mesh = new Mesh();
            mesh.vertices = vertices;
            mesh.triangles = triangles;
            mesh.uv = genUV(mesh.vertices);
            mesh.normals = normals;
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();

            // Reset the rotations of the object
            spriteRenderer.transform.localRotation = localRotation;
            spriteRenderer.transform.localScale = localScale;
            spriteRenderer.transform.parent = polygonParent;

            meshCreated = true;
        }
    }
    public void CreateSubdividedMesh(Vector2[] vertsToCopy, Transform transform, int smoothLevel)
    {
        Sprite          spr             = transform.GetComponent <SpriteRenderer>().sprite;
        Rect            rec             = spr.rect;
        Vector3         bound           = transform.renderer.bounds.max - transform.renderer.bounds.min;
        TextureImporter textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(spr)) as TextureImporter;

        //Create triangle.NET geometry
        TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(vertsToCopy.Length);

        //Add vertices
        foreach (Vector2 p in vertsToCopy)
        {
            geometry.AddPoint(p.x, p.y);
        }
        //Add segments
        for (int i = 0; i < vertsToCopy.Length - 1; i++)
        {
            geometry.AddSegment(i, i + 1);
        }
        geometry.AddSegment(vertsToCopy.Length - 1, 0);

        //Triangulate, refine and smooth
        TriangleNet.Mesh triangleNetMesh = new TriangleNet.Mesh();
        triangleNetMesh.behavior.MinAngle = 10;
        triangleNetMesh.Triangulate(geometry);
        if (smoothLevel > 1)
        {
            triangleNetMesh.Refine(true);
        }
        TriangleNet.Tools.Statistic statistic = new TriangleNet.Tools.Statistic();
        statistic.Update(triangleNetMesh, 1);
        // Refine by setting a custom maximum area constraint.
        if (smoothLevel > 2)
        {
            triangleNetMesh.Refine(statistic.LargestArea / 8);
        }

        try
        {
            triangleNetMesh.Smooth();
        }
        catch
        {
            //Debug.LogWarning("unable to smooth");
        }
        triangleNetMesh.Renumber();

        //transform vertices
        Vector3[] vertices = new Vector3[triangleNetMesh.Vertices.Count];
        Vector2[] uvs      = new Vector2[triangleNetMesh.Vertices.Count];
        Vector3[] normals  = new Vector3[triangleNetMesh.Vertices.Count];

        int idx = 0;

        foreach (TriangleNet.Data.Vertex v in triangleNetMesh.Vertices)
        {
            vertices[idx] = new Vector3((float)v.X, (float)v.Y, 0);
            normals[idx]  = new Vector3(0, 0, -1);


            Vector2 newUv = new Vector2(((float)v.X / bound.x) + 0.5f, ((float)v.Y / bound.y) + 0.5f);

            newUv.x *= rec.width / spr.texture.width;
            newUv.y *= rec.height / spr.texture.height;
            //Debug.Log(spr.textureRectOffset);
            newUv.x += (rec.x) / spr.texture.width;
            newUv.y += (rec.y) / spr.texture.height;

            SpriteMetaData[] smdArray = textureImporter.spritesheet;
            Vector2          pivot    = new Vector2(.0f, .0f);;

            for (int i = 0; i < smdArray.Length; i++)
            {
                if (smdArray[i].name == spr.name)
                {
                    switch (smdArray[i].alignment)
                    {
                    case (0):
                        smdArray[i].pivot = Vector2.zero;
                        break;

                    case (1):
                        smdArray[i].pivot = new Vector2(0f, 1f) - new Vector2(.5f, .5f);
                        break;

                    case (2):
                        smdArray[i].pivot = new Vector2(0.5f, 1f) - new Vector2(.5f, .5f);
                        break;

                    case (3):
                        smdArray[i].pivot = new Vector2(1f, 1f) - new Vector2(.5f, .5f);
                        break;

                    case (4):
                        smdArray[i].pivot = new Vector2(0f, .5f) - new Vector2(.5f, .5f);
                        break;

                    case (5):
                        smdArray[i].pivot = new Vector2(1f, .5f) - new Vector2(.5f, .5f);
                        break;

                    case (6):
                        smdArray[i].pivot = new Vector2(0f, 0f) - new Vector2(.5f, .5f);
                        break;

                    case (7):
                        smdArray[i].pivot = new Vector2(0.5f, 0f) - new Vector2(.5f, .5f);
                        break;

                    case (8):
                        smdArray[i].pivot = new Vector2(1f, 0f) - new Vector2(.5f, .5f);
                        break;

                    case (9):
                        smdArray[i].pivot -= new Vector2(.5f, .5f);
                        break;
                    }
                    pivot = smdArray[i].pivot;
                }
            }
            if (textureImporter.spriteImportMode == SpriteImportMode.Single)
            {
                pivot = textureImporter.spritePivot - new Vector2(.5f, .5f);
            }
            newUv.x += ((pivot.x) * rec.width) / spr.texture.width;
            newUv.y += ((pivot.y) * rec.height) / spr.texture.height;


            uvs[idx] = newUv;
            idx++;
        }

        //transform triangles
        int[] triangles = new int[triangleNetMesh.Triangles.Count * 3];
        idx = 0;
        foreach (TriangleNet.Data.Triangle t in triangleNetMesh.Triangles)
        {
            triangles[idx++] = t.P1;
            triangles[idx++] = t.P0;
            triangles[idx++] = t.P2;
        }

        finalVertices  = vertices;
        finalTriangles = triangles;
        finalUvs       = uvs;
        finalNormals   = normals;
    }
Пример #34
0
    private void CreateMesh()
    {
        Sprite sprite = spriteRenderer.sprite;

        Rect bounds = GetBounds(polygon);

        TriangleNet.Mesh tnMesh = new TriangleNet.Mesh();
        TriangleNet.Geometry.InputGeometry input = new TriangleNet.Geometry.InputGeometry();

        input.AddPolygon(polygon);

        tnMesh.Triangulate(input);

        Mesh mesh = new Mesh();
        mesh.vertices = tnMesh.Vertices.Select(p => new Vector3((float)p.X, (float)p.Y, 0)).ToArray();

        // Not sure about winding
        // If there is an interesting error, It is probably because of cw/ccw windings
        int[] tris = tnMesh.Triangles.ToUnityMeshTriangleIndices();
        mesh.triangles = tris;

        List<Vector2> uv = new List<Vector2>();

        Vector3 lower = new Vector3(bounds.x, bounds.y);
        Vector3 size = new Vector3(bounds.xMax, bounds.yMax) - lower;

        Rect uv_bounds = new Rect(sprite.rect.x / sprite.texture.width, sprite.rect.y / sprite.texture.height, sprite.rect.width / sprite.texture.width, sprite.rect.height / sprite.texture.height);

        float scalex = sprite.bounds.size.x / bounds.width;
        float scaley = sprite.bounds.size.y / bounds.height;

        Vector3[] scaled = mesh.vertices;

        for (int i = 0; i < mesh.vertices.Length; i++) {
            Vector3 v = scaled[i];
            Vector3 rel = v - lower;
            uv.Add(new Vector2(rel.x / size.x * uv_bounds.width, rel.y / size.y * uv_bounds.height) + new Vector2(uv_bounds.x, uv_bounds.y));

            scaled[i] = new Vector3(v.x * scalex, v.y * scaley, v.z) - ((Vector3)bounds.center * scalex) + sprite.bounds.center;
        }

        mesh.MarkDynamic();
            mesh.vertices = scaled;
        mesh.uv = uv.ToArray();
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();

        //GameObject go = new GameObject();
        //MeshFilter mf = go.AddComponent<MeshFilter>();
        //mf.sharedMesh = mesh;
        //MeshRenderer mr = go.AddComponent<MeshRenderer>();
        //mr.sharedMaterial = spriteRenderer.sharedMaterial;

        // Check if the Meshes directory exists, if not, create it.
        DirectoryInfo meshDir = new DirectoryInfo("Assets/Meshes");
        if (Directory.Exists(meshDir.FullName) == false)
        {
            Directory.CreateDirectory(meshDir.FullName);
        }
        ScriptableObjectUtility.CreateAsset(mesh, "Meshes/" + spriteRenderer.gameObject.name + ".Mesh");
    }
    public Mesh CreateMeshFromVerts(Vector3[] vertsToCopy, Mesh mesh, List <int> pathSplitIds, Transform SpriteGO = null)
    {
        Sprite          spr             = new Sprite();
        Rect            rec             = new Rect();
        Vector3         bound           = Vector3.zero;
        TextureImporter textureImporter = new TextureImporter();

        if (SpriteGO != null && SpriteGO.GetComponent <SpriteRenderer>() && SpriteGO.GetComponent <SpriteRenderer>().sprite)
        {
            spr             = SpriteGO.GetComponent <SpriteRenderer>().sprite;
            rec             = spr.rect;
            bound           = SpriteGO.GetComponent <Renderer>().bounds.max - SpriteGO.GetComponent <Renderer>().bounds.min;
            textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(spr)) as TextureImporter;
        }

        //Create triangle.NET geometry
        TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(vertsToCopy.Length);

        //Add vertices
        foreach (Vector3 p in vertsToCopy)
        {
            geometry.AddPoint(p.x, p.y);
        }
        //Add segments
        int prevEnd = 0;

        for (int i = 0; i < vertsToCopy.Length - 1; i++)
        {
            if (!pathSplitIds.Contains(i + 1))
            {
                geometry.AddSegment(i, i + 1);
                //Debug.Log ("joining " + i + " to " + (i + 1));
            }
            else
            {
                geometry.AddSegment(i, prevEnd);
                prevEnd = i + 1;
            }
        }
        if (pathSplitIds.Count <= 1)
        {
            //Debug.Log ("joining " + (vertsToCopy.Length - 1) + " to 0");
            geometry.AddSegment(vertsToCopy.Length - 1, 0);
        }


        //Triangulate, refine and smooth
        TriangleNet.Mesh triangleNetMesh = new TriangleNet.Mesh();

        triangleNetMesh.Triangulate(geometry);

        //transform vertices
        Vector3[] vertices = new Vector3[triangleNetMesh.Vertices.Count];
        Vector2[] uvs      = new Vector2[triangleNetMesh.Vertices.Count];
        Vector3[] normals  = new Vector3[triangleNetMesh.Vertices.Count];

        int idx = 0;

        foreach (TriangleNet.Data.Vertex v in triangleNetMesh.Vertices)
        {
            vertices[idx] = new Vector3((float)v.X, (float)v.Y, 0);
            normals[idx]  = new Vector3(0, 0, -1);

            if (SpriteGO != null && SpriteGO.GetComponent <SpriteRenderer>())
            {
                Vector2 newUv = new Vector2(((float)v.X / bound.x) + 0.5f, ((float)v.Y / bound.y) + 0.5f);

                newUv.x *= rec.width / spr.texture.width;
                newUv.y *= rec.height / spr.texture.height;
                //Debug.Log(spr.textureRectOffset);
                newUv.x += (rec.x) / spr.texture.width;
                newUv.y += (rec.y) / spr.texture.height;

                SpriteMetaData[] smdArray = textureImporter.spritesheet;
                Vector2          pivot    = new Vector2(.0f, .0f);
                ;

                for (int i = 0; i < smdArray.Length; i++)
                {
                    if (smdArray [i].name == spr.name)
                    {
                        switch (smdArray [i].alignment)
                        {
                        case (0):
                            smdArray [i].pivot = Vector2.zero;
                            break;

                        case (1):
                            smdArray [i].pivot = new Vector2(0f, 1f) - new Vector2(.5f, .5f);
                            break;

                        case (2):
                            smdArray [i].pivot = new Vector2(0.5f, 1f) - new Vector2(.5f, .5f);
                            break;

                        case (3):
                            smdArray [i].pivot = new Vector2(1f, 1f) - new Vector2(.5f, .5f);
                            break;

                        case (4):
                            smdArray [i].pivot = new Vector2(0f, .5f) - new Vector2(.5f, .5f);
                            break;

                        case (5):
                            smdArray [i].pivot = new Vector2(1f, .5f) - new Vector2(.5f, .5f);
                            break;

                        case (6):
                            smdArray [i].pivot = new Vector2(0f, 0f) - new Vector2(.5f, .5f);
                            break;

                        case (7):
                            smdArray [i].pivot = new Vector2(0.5f, 0f) - new Vector2(.5f, .5f);
                            break;

                        case (8):
                            smdArray [i].pivot = new Vector2(1f, 0f) - new Vector2(.5f, .5f);
                            break;

                        case (9):
                            smdArray [i].pivot -= new Vector2(.5f, .5f);
                            break;
                        }
                        pivot = smdArray [i].pivot;
                    }
                }
                if (textureImporter.spriteImportMode == SpriteImportMode.Single)
                {
                    pivot = textureImporter.spritePivot - new Vector2(.5f, .5f);
                }
                newUv.x += ((pivot.x) * rec.width) / spr.texture.width;
                newUv.y += ((pivot.y) * rec.height) / spr.texture.height;


                uvs [idx] = newUv;
            }


            idx++;
        }

        //transform triangles
        int[] triangles = new int[triangleNetMesh.Triangles.Count * 3];
        idx = 0;
        foreach (TriangleNet.Data.Triangle t in triangleNetMesh.Triangles)
        {
            triangles[idx++] = t.P1;
            triangles[idx++] = t.P0;
            triangles[idx++] = t.P2;
        }

        mesh.vertices  = vertices;
        mesh.triangles = triangles;
        mesh.uv        = uvs;
        mesh.normals   = normals;

        return(mesh);
    }
Пример #36
0
    private void CreateMesh()
    {
        Sprite sprite = spriteRenderer.sprite;

        Rect bounds = GetBounds(polygon);

        TriangleNet.Mesh tnMesh = new TriangleNet.Mesh();
        TriangleNet.Geometry.InputGeometry input = new TriangleNet.Geometry.InputGeometry();

        input.AddPolygon(polygon);

        tnMesh.Triangulate(input);

        Mesh mesh = new Mesh();

        mesh.vertices = tnMesh.Vertices.Select(p => new Vector3((float)p.X, (float)p.Y, 0)).ToArray();

        // Not sure about winding
        // If there is an interesting error, It is probably because of cw/ccw windings
        int[] tris = tnMesh.Triangles.ToUnityMeshTriangleIndices();
        mesh.triangles = tris;

        List <Vector2> uv = new List <Vector2>();

        Vector3 lower = new Vector3(bounds.x, bounds.y);
        Vector3 size  = new Vector3(bounds.xMax, bounds.yMax) - lower;

        Rect uv_bounds = new Rect(sprite.rect.x / sprite.texture.width, sprite.rect.y / sprite.texture.height, sprite.rect.width / sprite.texture.width, sprite.rect.height / sprite.texture.height);

        float scalex = sprite.bounds.size.x / bounds.width;
        float scaley = sprite.bounds.size.y / bounds.height;

        Vector3[] scaled = mesh.vertices;

        for (int i = 0; i < mesh.vertices.Length; i++)
        {
            Vector3 v   = scaled[i];
            Vector3 rel = v - lower;
            uv.Add(new Vector2(rel.x / size.x * uv_bounds.width, rel.y / size.y * uv_bounds.height) + new Vector2(uv_bounds.x, uv_bounds.y));

            scaled[i] = new Vector3(v.x * scalex, v.y * scaley, v.z) - ((Vector3)bounds.center * scalex) + sprite.bounds.center;
        }

        mesh.MarkDynamic();
        mesh.vertices = scaled;
        mesh.uv       = uv.ToArray();
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
        mesh.Optimize();

        //GameObject go = new GameObject();
        //MeshFilter mf = go.AddComponent<MeshFilter>();
        //mf.sharedMesh = mesh;
        //MeshRenderer mr = go.AddComponent<MeshRenderer>();
        //mr.sharedMaterial = spriteRenderer.sharedMaterial;

        // Check if the Meshes directory exists, if not, create it.
        DirectoryInfo meshDir = new DirectoryInfo("Assets/Meshes");

        if (Directory.Exists(meshDir.FullName) == false)
        {
            Directory.CreateDirectory(meshDir.FullName);
        }
        ScriptableObjectUtility.CreateAsset(mesh, "Meshes/" + spriteRenderer.gameObject.name + ".Mesh");
    }
Пример #37
0
        private bool Open(string filename)
        {
            if (FileProcessor.ContainsMeshData(filename))
            {
                if (DarkMessageBox.Show("Import mesh", Settings.ImportString,
                    "Do you want to import the mesh?", MessageBoxButtons.YesNo) == DialogResult.OK)
                {
                    input = null;
                    mesh = FileProcessor.Import(filename);

                    if (mesh != null)
                    {
                        statisticView.UpdateStatistic(mesh);

                        // Update settings
                        settings.CurrentFile = Path.GetFileName(filename);

                        HandleMeshImport();
                        btnSmooth.Enabled = true; // TODO: Remove
                    }
                    // else Message

                    return true;
                }
            }

            input = FileProcessor.Read(filename);

            if (input != null)
            {
                // Update settings
                settings.CurrentFile = Path.GetFileName(filename);

                HandleNewInput();
            }
            // else Message

            return true;
        }
Пример #38
0
		public static void Triangulate(List<Vector2> vertices, List<IndexedEdge> edges, List<Hole> holes,ref List<int> indices)
		{
			indices.Clear();
			
			if(vertices.Count >= 3)
			{
				InputGeometry inputGeometry = new InputGeometry(vertices.Count);
				
				for(int i = 0; i < vertices.Count; ++i)
				{
					Vector2 position = vertices[i];
					inputGeometry.AddPoint(position.x,position.y);
				}
				
				for(int i = 0; i < edges.Count; ++i)
				{
					IndexedEdge edge = edges[i];
					inputGeometry.AddSegment(edge.index1,edge.index2);
				}
				
				for(int i = 0; i < holes.Count; ++i)
				{
					Vector2 hole = holes[i].vertex;
					inputGeometry.AddHole(hole.x,hole.y);
				}
				
				TriangleNet.Mesh trangleMesh = new TriangleNet.Mesh();
				
				trangleMesh.Triangulate(inputGeometry);
				
				foreach (TriangleNet.Data.Triangle triangle in trangleMesh.Triangles)
				{
					if(triangle.P0 >= 0 && triangle.P0 < vertices.Count &&
					   triangle.P0 >= 0 && triangle.P1 < vertices.Count &&
					   triangle.P0 >= 0 && triangle.P2 < vertices.Count)
					{
						indices.Add(triangle.P0);
						indices.Add(triangle.P2);
						indices.Add(triangle.P1);
					}
				}
			}
		}