AddSegment() public method

Adds a segment to the geometry.
public AddSegment ( int p0, int p1 ) : void
p0 int First endpoint.
p1 int Second endpoint.
return void
示例#1
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;
        }
        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);
        }
示例#3
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;
        }
示例#4
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);
        }
    }
示例#5
0
文件: Slice.cs 项目: JackTing/PathCAM
        /// <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;
                    }
                }
            }
        }
示例#6
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);
					}
				}
			}
		}
示例#7
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);
					}
				}
			}
		}
    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);
    }
示例#9
0
        public override InputGeometry Generate(double param0, double param1, double param2)
        {
            int numPoints = GetParamValueInt(1, param1);

            InputGeometry input = new InputGeometry(numPoints + 4);

            double x, y, step = 2 * Math.PI / numPoints;

            double r = GetParamValueInt(2, param2);

            // Generate circle
            for (int i = 0; i < numPoints; i++)
            {
                x = r * Math.Cos(i * step);
                y = r * Math.Sin(i * step);

                input.AddPoint(x, y, 2);
                input.AddSegment(i, (i + 1) % numPoints, 2);
            }

            numPoints = input.Count;

            int numPointsB = GetParamValueInt(0, param0);

            // Box sides are 100 units long
            step = 100.0 / numPointsB;

            // Left box boundary points
            for (int i = 0; i < numPointsB; i++)
            {
                input.AddPoint(-50, -50 + i * step, 1);
            }

            // Top box boundary points
            for (int i = 0; i < numPointsB; i++)
            {
                input.AddPoint(-50 + i * step, 50, 1);
            }

            // Right box boundary points
            for (int i = 0; i < numPointsB; i++)
            {
                input.AddPoint(50, 50 - i * step, 1);
            }

            // Bottom box boundary points
            for (int i = 0; i < numPointsB; i++)
            {
                input.AddPoint(50 - i * step, -50, 1);
            }

            // Add box segments
            for (int i = numPoints; i < input.Count - 1; i++)
            {
                input.AddSegment(i, i + 1, 1);
            }

            // Add last segments which closes the box
            input.AddSegment(input.Count - 1, numPoints, 1);

            // Add hole
            input.AddHole(0, 0);

            return input;
        }
        static void SearchTree(InputGeometry inputGeometry, ref int pointIndex, PolyNode node)
        {
            foreach (PolyNode childNode in node.Childs)
            {
                int startIndex = pointIndex;

                foreach (Vector2 point in childNode.Contour)
                {
                    inputGeometry.AddPoint(point.X, point.Y);
                    if (pointIndex > startIndex) inputGeometry.AddSegment(pointIndex - 1, pointIndex);
                    pointIndex++;
                }
                inputGeometry.AddSegment(pointIndex - 1, startIndex);

                if (childNode.IsHole)
                {
                    for (int i = 0, j = childNode.Contour.Count - 1, k = childNode.Contour.Count - 2; i < childNode.Contour.Count; k = j, j = i, i++)
                    {
                        Vector2 a1 = childNode.Contour[k];
                        Vector2 a2 = childNode.Contour[j];
                        Vector2 a3 = childNode.Contour[i];
                        
                        if (Vector2.VectorProduct(a2 - a1, a3 - a1) < 0)
                        {
                            Vector2 c = (a1 + a3) / 2;
                            Vector2 d = a2 - c;
                            float x = c.Length * 2;
                            Vector2 hole;
                            do
                            {
                                x /= 2;
                                hole = c + (1 - x) * d;
                            } while (!IsInside(childNode, hole));
                            x /= 512;
                            hole = c + (1 - x) * d;
                            inputGeometry.AddHole(hole.X, hole.Y);
                            break;
                        }
                    }
                    
                }

                SearchTree(inputGeometry, ref pointIndex, childNode);
            }
        }
    public void CreateSubdividedMesh(Vector2[] vertsToCopy, Transform transform, int smoothLevel)
    {
        Sprite spr = transform.GetComponent<SpriteRenderer>().sprite;
        Rect rec = spr.rect;
        Vector3 bound = transform.GetComponent<Renderer>().bounds.max- transform.GetComponent<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();
        if(smoothLevel>0)
            triangleNetMesh.behavior.MinAngle = 10;

        triangleNetMesh.Triangulate(geometry);
        if (smoothLevel > 0)
        {
            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;
    }
示例#12
0
		public static PolyGisLayer CreateFromContour(Game engine, DVector2[] lonLatRad, Color color)
		{
			var triangulator = new TriangleNet.Mesh();
			triangulator.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
			
			InputGeometry ig = new InputGeometry();

			ig.AddPoint(lonLatRad[0].X, lonLatRad[0].Y);
			for (int v = 1; v < lonLatRad.Length; v++) {
				ig.AddPoint(lonLatRad[v].X, lonLatRad[v].Y);
				ig.AddSegment(v-1, v);
			}
			ig.AddSegment(lonLatRad.Length - 1, 0);
			
			triangulator.Triangulate(ig);

			if (triangulator.Vertices.Count != lonLatRad.Length) {
				Log.Warning("Vertices count not match");
				return null;
			}


			var points = new List<Gis.GeoPoint>();
			foreach (var pp in triangulator.Vertices) {
				points.Add(new Gis.GeoPoint {
					Lon		= pp.X,
					Lat		= pp.Y,
					Color	= color
				});
			}


			var indeces = new List<int>();
			foreach (var tr in triangulator.Triangles) {
				indeces.Add(tr.P0);
				indeces.Add(tr.P1);
				indeces.Add(tr.P2);
			}


			return new PolyGisLayer(engine, points.ToArray(), indeces.ToArray(), true) {
				Flags = (int)(PolyFlags.NO_DEPTH | PolyFlags.DRAW_TEXTURED | PolyFlags.CULL_NONE | PolyFlags.VERTEX_SHADER | PolyFlags.PIXEL_SHADER | PolyFlags.USE_PALETTE_COLOR) 
			};
		}
    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;
		}
    }
    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;
    }
示例#15
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();
    }
示例#16
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;
        }
    }
示例#17
0
        void SearchTree(InputGeometry inputGeometry, ref int pointIndex, PolyNode node)
        {
            foreach (PolyNode childNode in node.Childs)
            {
                int startIndex = pointIndex;

                foreach (ControlPoint point in childNode.Contour)
                {
                    inputGeometry.AddPoint(point.X, point.Y);
                    if (pointIndex > startIndex) inputGeometry.AddSegment(pointIndex - 1, pointIndex);
                    pointIndex++;
                }
                inputGeometry.AddSegment(pointIndex - 1, startIndex);

                if (childNode.IsHole)
                {
                    for (int i = 0, j = childNode.Contour.Count - 1, k = childNode.Contour.Count - 2; i < childNode.Contour.Count; k = j, j = i, i++)
                    {
                        ControlPoint a1 = childNode.Contour[k];
                        ControlPoint a2 = childNode.Contour[j];
                        ControlPoint a3 = childNode.Contour[i];

                        if (ControlPoint.VectorProduct(a2 - a1, a3 - a1) < 0)
                        {
                            ControlPoint c = ((a1 + a3) / 2) - a2;
                            double x = 2;
                            ControlPoint hole;
                            do
                            {
                                x /= 2;
                                hole = a2 + (c * x);
                            } while (!IsInside(childNode, hole));

                            inputGeometry.AddHole(hole.X, hole.Y);
                            break;
                        }
                    }
                }

                SearchTree(inputGeometry, ref pointIndex, childNode);
            }
        }
示例#18
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;
        }
示例#19
0
        void InitBuildingsOSM()
        {
            var osm = Game.GetService<LayerService>().OpenStreetMapSource;

            List<GeoVert> lines = new List<GeoVert>();
            List<GeoVert> simple = new List<GeoVert>();

            var nodes = osm.allNodes;
            int k = 0;
            foreach (var way in osm.allWays) {
                if (!way.Value.isBuilding) continue;

                var centerMerc = way.Value.BBox.Center();
                float width		= (way.Value.BBox.Maximum - way.Value.BBox.Minimum).X * 10000.0f;
                float length	= (way.Value.BBox.Maximum - way.Value.BBox.Minimum).Y * 10000.0f;
                double lon, lat;
                GeoHelper.TileToWorldPos(centerMerc.X, centerMerc.Y, 0, out lon, out lat);

                simple.Add(new GeoVert {
                        Lon			= DMathUtil.DegreesToRadians(lon),
                        Lat			= DMathUtil.DegreesToRadians(lat),
                        Color		= Color.White,
                        Position	= Vector3.Zero,
                        Tex			= new Vector4(width, length, 0, 0)
                    });

                List<DVector2> buildingVertices = new List<DVector2>();
                for (int i = 0; i < way.Value.nodeRef.Length - 1; i++) {
                    var nInds = way.Value.nodeRef;

                    lines.Add(new GeoVert {
                            Lon			= DMathUtil.DegreesToRadians(nodes[nInds[i]].Longitude),
                            Lat			= DMathUtil.DegreesToRadians(nodes[nInds[i]].Latitude),
                            Position	= new Vector3(1.0f, 0.0f, 0.0f),
                            Color		= Color.Yellow,
                            Tex			= Vector4.Zero
                        });

                    lines.Add(new GeoVert {
                            Lon			= DMathUtil.DegreesToRadians(nodes[nInds[i+1]].Longitude),
                            Lat			= DMathUtil.DegreesToRadians(nodes[nInds[i+1]].Latitude),
                            Position	= new Vector3(1.0f, 0.0f, 0.0f),
                            Color		= Color.Yellow,
                            Tex			= Vector4.Zero
                        });

                    buildingVertices.Add(new DVector2(nodes[nInds[i]].Longitude, nodes[nInds[i]].Latitude));
                }
                buildingVertices.Add(new DVector2(nodes[way.Value.nodeRef[way.Value.nodeRef.Length - 1]].Longitude, nodes[way.Value.nodeRef[way.Value.nodeRef.Length - 1]].Latitude));

                /////////////////////////////////////////

                var mesh = new Mesh();
                mesh.Behavior.Quality	= false;
                mesh.Behavior.MinAngle	= 25;
                mesh.Behavior.Convex	= false;

                var ig = new InputGeometry();

                ig.AddPoint(buildingVertices[0].X, buildingVertices[0].Y);
                for (int v = 1; v < buildingVertices.Count; v++) {
                    ig.AddPoint(buildingVertices[v].X, buildingVertices[v].Y);
                    ig.AddSegment(v - 1, v);
                }
                ig.AddSegment(buildingVertices.Count - 1, 0);

                mesh.Triangulate(ig);

                int n = mesh.Vertices.Count;

                mesh.Renumber();

                buildings = new GeoVert[mesh.Triangles.Count*3];

                int ind = 0;
                foreach (var triangle in mesh.Triangles) {
                    buildings[ind++] = new GeoVert {
                        Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P0).X),
                        Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P0).Y),
                        Position = new Vector3(0.1f, 0.0f, 0.0f),
                        Color = Color.Green,
                        Tex = Vector4.Zero
                    };
                    buildings[ind++] = new GeoVert {
                        Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P1).X),
                        Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P1).Y),
                        Position = new Vector3(0.1f, 0.0f, 0.0f),
                        Color = Color.Green,
                        Tex = Vector4.Zero
                    };
                    buildings[ind++] = new GeoVert {
                        Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P2).X),
                        Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P2).Y),
                        Position = new Vector3(0.1f, 0.0f, 0.0f),
                        Color = Color.Green,
                        Tex = Vector4.Zero
                    };
                }

                /////////////////////////////////////////

                k++;
                if (k >= 1) break;
            }

            simpleBuildings		= simple.ToArray();
            contourBuildings	= lines.ToArray();

            contourBuildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof (GeoVert), contourBuildings.Length);
            contourBuildingsVB.SetData(contourBuildings, 0, contourBuildings.Length);

            simpleBuildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), simpleBuildings.Length);
            simpleBuildingsVB.SetData(simpleBuildings, 0, simpleBuildings.Length);

            buildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), buildings.Length);
            buildingsVB.SetData(buildings, 0, buildings.Length);
        }
示例#20
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;
        }
    }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="contour"></param>
        void AddMunicipalDivision(string name, List<DVector2> contour)
        {
            if (municipalDivisions.ContainsKey(name)) return;

            var mesh = new TriangleNet.Mesh();
            mesh.Behavior.Quality = true;
            mesh.Behavior.MinAngle = 25;
            mesh.Behavior.Convex = false;

            var ig = new InputGeometry();

            ig.AddPoint(contour[0].X, contour[0].Y);
            for (int v = 1; v < contour.Count; v++) {
                ig.AddPoint(contour[v].X, contour[v].Y);
                ig.AddSegment(v - 1, v);
            }
            ig.AddSegment(contour.Count - 1, 0);

            mesh.Triangulate(ig);

            int n = mesh.Vertices.Count;

            mesh.Renumber();

            // Vertices
            var moVerts = new GeoVert[n];
            int i = 0;
            foreach (var pt in mesh.Vertices) {
                moVerts[i] = new GeoVert {
                    Lon			= pt.X * Math.PI / 180.0,
                    Lat			= pt.Y * Math.PI / 180.0,
                    Position	= Vector3.Zero,
                    Tex			= Vector4.Zero,
                    Color		= Color.White
                };

                i++;
            }

            // Triangles
            var triangles = new int[3 * mesh.Triangles.Count];
            i = 0;
            foreach (var tri in mesh.Triangles) {
                triangles[i * 3 + 0] = tri.P0;
                triangles[i * 3 + 1] = tri.P1;
                triangles[i * 3 + 2] = tri.P2;
                i++;
            }

            // Contour vertices
            var contourVerts = new GeoVert[contour.Count*2];

            contourVerts[1] = new GeoVert {
                Lon			= contour[0].X * Math.PI / 180.0,
                Lat			= contour[0].Y * Math.PI / 180.0,
                Position	= Vector3.Zero,
                Tex			= Vector4.Zero,
                Color		= Color.Red
            };

            for (int j = 1; j < contour.Count; j++) {
                contourVerts[2*j+1] = new GeoVert {
                    Lon			= contour[j].X * Math.PI / 180.0,
                    Lat			= contour[j].Y * Math.PI / 180.0,
                    Position	= Vector3.Zero,
                    Tex			= Vector4.Zero,
                    Color		= Color.Red
                };
                contourVerts[2*j] = contourVerts[2*(j - 1) + 1];
            }

            contourVerts[0] = contourVerts[contourVerts.Length-1];

            // Create buffers
            var vb		= new VertexBuffer(Game.GraphicsDevice, typeof (GeoVert), moVerts.Length);
            var inds	= new IndexBuffer(Game.GraphicsDevice, triangles.Length);
            var cont	= new VertexBuffer(Game.GraphicsDevice, typeof (GeoVert), contourVerts.Length);

            vb.SetData(moVerts, 0, moVerts.Length);
            inds.SetData(triangles, 0, triangles.Length);
            cont.SetData(contourVerts, 0, contourVerts.Length);

            municipalDivisions.Add(name, new MD {
                    Contour		= cont,
                    Indeces		= inds,
                    Vertices	= vb,
                    Value		= r.NextFloat(0.0f, 1.0f)
                });
        }
    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;
    }
示例#23
0
        private void ReadSegments(InputGeometry geometry, Dictionary<string, object> segments, int count)
        {
            ArrayList data = segments["data"] as ArrayList;

            ArrayList markers = null;

            if (segments.ContainsKey("markers"))
            {
                markers = segments["markers"] as ArrayList;
            }

            if (data != null)
            {
                int mark, n = data.Count;

                if (n % 2 != 0)
                {
                    throw new Exception("JSON format error (segments).");
                }

                int p0, p1;

                for (int i = 0; i < n; i += 2)
                {
                    mark = 0;

                    if (markers != null && markers.Count == n)
                    {
                        mark = int.Parse(markers[i / 2].ToString());
                    }

                    p0 = int.Parse(data[i].ToString());
                    p1 = int.Parse(data[i + 1].ToString());

                    if (p0 < 0 || p0 >= count || p1 < 0 || p1 >= count)
                    {
                        throw new Exception("JSON format error (segment index).");
                    }

                    geometry.AddSegment(p0, p1, mark);
                }
            }
        }