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;
    }
    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;
    }
Example #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];
            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;
        }
    }
Example #4
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;
        }
    }