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.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; }