// Use this for initialization
    void Start()
    {
        TriMesh = new TriangleNet.Mesh();
        /*_mesh.Triangulate("Assets/Plugins/Data/superior.poly");*/

        var geometry = FileReader.ReadPolyFile("Assets/Plugins/Data/superior.poly");

        TriMesh.behavior.Quality  = true;
        TriMesh.behavior.MinAngle = 33.8f;
        TriMesh.Triangulate(geometry);
        //TriMesh.Refine(true);
        // Get mesh statistics.
        var statistic = new Statistic();

        statistic.Update(TriMesh, 1);

        // Refine by setting a custom maximum area constraint.
        TriMesh.Refine(statistic.LargestArea / 4);
        TriMesh.Smooth();

        Debug.Log(string.Format("width {0:0.00}, height {1:0.00}; min {2:0.00}, {3:0.00}; max {4:0.00}, {5:0.00}",
                                TriMesh.Bounds.Width, TriMesh.Bounds.Height,
                                TriMesh.Bounds.Xmin, TriMesh.Bounds.Ymin,
                                TriMesh.Bounds.Xmax, TriMesh.Bounds.Ymax));

        OnRender(TriMesh);
    }
    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;
    }
Exemplo n.º 3
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;
        }
    }