public static void RandomiseTriangleOrder(Mesh mesh) { var OldTriangles = new List <int> (mesh.triangles); var NewTriangles = new List <int> (); using (var Progress = new ScopedProgressBar("Randomising triangle order")) { var OriginalTriangleCount = OldTriangles.Count; // move a random set of indexes to the new list while (OldTriangles.Count > 0) { var TriangleIndex = Random.Range(0, OldTriangles.Count); TriangleIndex -= TriangleIndex % 3; if (TriangleIndex % 3 != 0) { throw new System.Exception("Picked triangle index not at triangle start"); } NewTriangles.Add(OldTriangles [TriangleIndex + 0]); NewTriangles.Add(OldTriangles [TriangleIndex + 1]); NewTriangles.Add(OldTriangles [TriangleIndex + 2]); OldTriangles.RemoveRange(TriangleIndex, 3); Progress.SetProgress("Shuffling", NewTriangles.Count, OriginalTriangleCount, 100); } } mesh.triangles = NewTriangles.ToArray(); }
static public List <Vector2> ExtractPoints(Texture Image) { // find the middle of the white pixels var Texture2 = SaveTextureToPng.GetTexture2D(Image, false); var Pixels = Texture2.GetPixels(); var MatchColour = Color.white; System.Func <Color, Color, float> GetColourMatchScore = (Source, Match) => { var Distance = Source.GetHSVDistance(Match); return(1 - Distance); }; System.Func <int, int, float> GetWhiteScore = (x, y) => { var i = x + y * Texture2.width; var Colour = Pixels[i]; return(GetColourMatchScore(Colour, MatchColour)); }; float?BestScore = null; int BestX = 0, BestY = 0; using (var Progress = new ScopedProgressBar("Extracting pixel scores")) { var NotifyRate = 1; var maxi = Texture2.height * Texture2.width; for (int y = 0; y < Texture2.height; y++) { for (int x = 0; x < Texture2.width; x++) { var i = x + y * Texture2.width; if (x == 0) { Progress.SetProgress("Extracting pixels", i, maxi, NotifyRate); } var Score = GetWhiteScore(x, y); if (!BestScore.HasValue || Score > BestScore.Value && Score > 0) { BestScore = Score; BestX = x; BestY = y; } } } } // convert best to uv var Bestu = BestX / (float)Texture2.width; var Bestv = BestY / (float)Texture2.height; var Points = new List <Vector2>(); Points.Add(new Vector2(Bestu, Bestv)); return(Points); }
public static void SetMeshUV0ToTriangleIndex(Mesh mesh) { var m = mesh; var TriangleIndexes = m.triangles; #if UNITY_EDITOR if (TriangleIndexes.Length != m.vertexCount) { var DialogResult = EditorUtility.DisplayDialog("Error", "Assigning triangle indexes to attributes probably won't work as expected for meshes sharing vertexes.", "Continue", "Cancel"); if (!DialogResult) { throw new System.Exception("Aborted assignment of UV triangle indexes"); } } #endif using (var Progress = new ScopedProgressBar("Setting UVs")) { var Uvs = new Vector2[m.vertexCount]; { var v2 = new Vector2(); // avoid allocs for (int t = 0; t < TriangleIndexes.Length; t += 3) { if (t % 100 == 0) { Progress.SetProgress("Setting UV of triangle", t / 3, TriangleIndexes.Length / 3); } for (int i = 0; i < 3; i++) { var iv = TriangleIndexes [t + i]; v2.x = t / 3; v2.y = i; Uvs [iv] = v2; } } } m.uv = Uvs; m.UploadMeshData(true); #if UNTIY_EDITOR AssetDatabase.SaveAssets(); #endif } }
public static void SetMeshUV2ToRandomPerTriangle(MenuCommand menuCommand) { var mf = menuCommand.context as MeshFilter; var m = mf.sharedMesh; var TriangleIndexes = m.triangles; if (TriangleIndexes.Length != m.vertexCount) { var DialogResult = EditorUtility.DisplayDialog("Error", "Assigning triangle indexes to attributes probably won't work as expected for meshes sharing vertexes.", "Continue", "Cancel"); if (!DialogResult) { throw new System.Exception("Aborted assignment of UV triangle indexes"); } } using (var Progress = new ScopedProgressBar("Setting UVs")) { var Uvs = new Vector3[m.vertexCount]; { var random3 = new Vector3(0, 0, 0); for (int t = 0; t < TriangleIndexes.Length; t += 3) { Progress.SetProgress("Setting UV of triangle", t / 3, TriangleIndexes.Length / 3, 100); float tTime = t / (float)TriangleIndexes.Length; random3.x = Mathf.PerlinNoise(tTime, 0.0f); random3.y = Mathf.PerlinNoise(0.0f, tTime); random3.z = Random.Range(0.0f, 1.0f); Uvs [TriangleIndexes [t + 0]] = random3; Uvs [TriangleIndexes [t + 1]] = random3; Uvs [TriangleIndexes [t + 2]] = random3; } } m.SetUVs(2, new List <Vector3>(Uvs)); m.UploadMeshData(true); AssetDatabase.SaveAssets(); } }
public static void SetMeshUV1ToTriangleBarycentricCoords(MenuCommand menuCommand) { var mf = menuCommand.context as MeshFilter; var m = mf.sharedMesh; var TriangleIndexes = m.triangles; if (TriangleIndexes.Length != m.vertexCount) { var DialogResult = EditorUtility.DisplayDialog("Error", "Assigning triangle indexes to attributes probably won't work as expected for meshes sharing vertexes.", "Continue", "Cancel"); if (!DialogResult) { throw new System.Exception("Aborted assignment of UV triangle indexes"); } } using (var Progress = new ScopedProgressBar("Setting UVs")) { var Uvs = new Vector3[m.vertexCount]; { var barya = new Vector3(1, 0, 0); var baryb = new Vector3(0, 1, 0); var baryc = new Vector3(0, 0, 1); for (int t = 0; t < TriangleIndexes.Length; t += 3) { Progress.SetProgress("Setting UV of triangle", t / 3, TriangleIndexes.Length / 3, 100); Uvs [TriangleIndexes [t + 0]] = barya; Uvs [TriangleIndexes [t + 1]] = baryb; Uvs [TriangleIndexes [t + 2]] = baryc; } } m.SetUVs(1, new List <Vector3>(Uvs)); m.UploadMeshData(true); AssetDatabase.SaveAssets(); } }
public static void UnshareTrianglesOfMesh(ref Mesh mesh) { var OldTriangles = mesh.triangles; var OldPositions = mesh.vertices; var OldNormals = mesh.normals; var OldUv1s = mesh.uv; var OldUv2s = mesh.uv2; var OldUv3s = mesh.uv3; var OldColourfs = mesh.colors; var OldColour32s = mesh.colors32; List <Vector3> NewPositons = NullIfEmpty(OldPositions) != null ? new List <Vector3> () : null; List <Vector3> NewNormals = NullIfEmpty(OldNormals) != null ? new List <Vector3> () : null; List <Vector2> NewUv1s = NullIfEmpty(OldUv1s) != null ? new List <Vector2> () : null; List <Vector2> NewUv2s = NullIfEmpty(OldUv2s) != null ? new List <Vector2> () : null; List <Vector2> NewUv3s = NullIfEmpty(OldUv3s) != null ? new List <Vector2> () : null; List <Color> NewColourfs = NullIfEmpty(OldColourfs) != null ? new List <Color> () : null; List <Color32> NewColour32s = NullIfEmpty(OldColour32s) != null ? new List <Color32> () : null; List <int> TriangleIndexes = new List <int> (); bool PromptShown = false; System.Func <Vertex, Vertex, Vertex, bool> PushTriangle = (a, b, c) => { // hit limits if (TriangleIndexes.Count >= 65000 && !PromptShown) { #if UNITY_EDITOR var DialogResult = EditorUtility.DisplayDialogComplex("Error", "Hit vertex limit with " + (TriangleIndexes.Count / 3) + " triangles (" + TriangleIndexes.Count + " vertexes.", "Stop Here", "Abort", "Overflow"); #else var DialogResult = 1; #endif PromptShown = true; // stop if (DialogResult == 0) { return(false); } else if (DialogResult == 2) // continue/overflow { } else if (DialogResult == 1) // abort { throw new System.Exception("Aborted export"); } else { throw new System.Exception("unknown dialog result " + DialogResult); } } if (NewPositons != null) { NewPositons.Add(a.position); NewPositons.Add(b.position); NewPositons.Add(c.position); } if (NewNormals != null) { NewNormals.Add(a.normal); NewNormals.Add(b.normal); NewNormals.Add(c.normal); } if (NewUv1s != null) { NewUv1s.Add(a.uv1); NewUv1s.Add(b.uv1); NewUv1s.Add(c.uv1); } if (NewUv2s != null) { NewUv2s.Add(a.uv2); NewUv2s.Add(b.uv2); NewUv2s.Add(c.uv2); } if (NewUv3s != null) { NewUv3s.Add(a.uv3); NewUv3s.Add(b.uv3); NewUv3s.Add(c.uv3); } if (NewColourfs != null) { NewColourfs.Add(a.colourf); NewColourfs.Add(b.colourf); NewColourfs.Add(c.colourf); } if (NewColour32s != null) { NewColour32s.Add(a.colour32); NewColour32s.Add(b.colour32); NewColour32s.Add(c.colour32); } TriangleIndexes.Add(TriangleIndexes.Count); TriangleIndexes.Add(TriangleIndexes.Count); TriangleIndexes.Add(TriangleIndexes.Count); return(true); }; using (var Progress = new ScopedProgressBar("Splitting mesh")) { var va = new Vertex(); var vb = new Vertex(); var vc = new Vertex(); for (int t = 0; t < OldTriangles.Length; t += 3) { Progress.SetProgress("Adding triangle", t / 3, OldTriangles.Length / 3, 100); var ia = OldTriangles [t]; var ib = OldTriangles [t + 1]; var ic = OldTriangles [t + 2]; SafeSet(ref va.position, OldPositions, ia); SafeSet(ref vb.position, OldPositions, ib); SafeSet(ref vc.position, OldPositions, ic); SafeSet(ref va.normal, OldNormals, ia); SafeSet(ref vb.normal, OldNormals, ib); SafeSet(ref vc.normal, OldNormals, ic); SafeSet(ref va.uv1, OldUv1s, ia); SafeSet(ref vb.uv1, OldUv1s, ib); SafeSet(ref vc.uv1, OldUv1s, ic); SafeSet(ref va.uv2, OldUv2s, ia); SafeSet(ref vb.uv2, OldUv2s, ib); SafeSet(ref vc.uv2, OldUv2s, ic); SafeSet(ref va.uv3, OldUv3s, ia); SafeSet(ref vb.uv3, OldUv3s, ib); SafeSet(ref vc.uv3, OldUv3s, ic); SafeSet(ref va.colourf, OldColourfs, ia); SafeSet(ref vb.colourf, OldColourfs, ib); SafeSet(ref vc.colourf, OldColourfs, ic); SafeSet(ref va.colour32, OldColour32s, ia); SafeSet(ref vb.colour32, OldColour32s, ib); SafeSet(ref vc.colour32, OldColour32s, ic); if (!PushTriangle(va, vb, vc)) { break; } } } var OldBounds = mesh.bounds; mesh.Clear(); if (NewPositons != null) { mesh.SetVertices(NewPositons); } if (NewNormals != null) { mesh.SetNormals(NewNormals); } if (NewUv1s != null) { mesh.SetUVs(0, NewUv1s); } if (NewUv2s != null) { mesh.SetUVs(1, NewUv2s); } if (NewUv3s != null) { mesh.SetUVs(1, NewUv3s); } if (NewColourfs != null) { mesh.SetColors(NewColourfs); } if (NewColour32s != null) { mesh.SetColors(NewColour32s); } if (TriangleIndexes != null) { mesh.SetIndices(TriangleIndexes.ToArray(), MeshTopology.Triangles, 0); } mesh.bounds = OldBounds; mesh.UploadMeshData(false); }