public static Mesh GetBounds(IEnumerable <GameObject> objs, Matrix4x4 worldToLocal) { var hasMesh = objs.Where(o => o.GetComponent <MeshFilter>()).Where(o => o.GetComponent <MeshFilter>().sharedMesh != null); var vertices = hasMesh.SelectMany(m => m.GetComponent <MeshFilter>().sharedMesh.vertices.Select(v => m.transform.localToWorldMatrix.MultiplyPoint3x4(v))); var flattened = from v in vertices select new Vector3(v.x, 0, v.z); var distinct = flattened.Distinct(); var extremes = vertices.Aggregate( new { min = Mathf.Infinity, max = Mathf.NegativeInfinity }, (curr, v) => new { min = v.y <curr.min?v.y : curr.min, max = v.y> curr.max ? v.y : curr.max }); var convex = ConvexHullAlgorithms.GrahamScan(distinct.ToList()); //Actually switching dimension order here, shouldn't matter (No Loss Of Generality); int[] triangulated = (new Triangulator(convex.Select(v => new Vector2(v.x, v.z)))).Triangulate(); var verts = new List <Vector3>(); var uvs = new List <Vector2>(); var tris = new List <int>(); verts.InsertRange(0, convex.Select(v => new Vector3(v.x, extremes.min, v.z))); var distances = Functional.Zip(verts, verts.Skip(1), ((v1, v2) => Vector2.Distance(v1, v2))); var distancesNormalized = (from d in distances select d / distances.Sum()).ToList(); for (int i = 0; i < verts.Count; i++) { //Totally ghetto UV mapping algorithm //NOT diffeomorphic to texture domain //NO CONTINUOUS FIRST DERIVATIVE //NORMALS MAY CRY //#YOLO if (i == 0) { uvs.Add(new Vector2(0, 0.25f)); } else { uvs.Add(new Vector2(distancesNormalized[i - 1], 0.25f)); } } tris.InsertRange(0, triangulated); var increment = verts.Count; verts.InsertRange(increment, convex.Select(v => new Vector3(v.x, extremes.max, v.z))); var buffer = uvs.Select(v => v + new Vector2(0, 0.5f)).ToList(); uvs.InsertRange(increment, buffer); tris.InsertRange(tris.Count, triangulated.Select(i => i + increment)); for (int i = 0; i < convex.Count - 1; i++) { //convex is sorted counterclockwise looking from above y, //So clockwise from outside would mean going i => i + increment => i + 1 tris.Add(i); tris.Add(i + increment); tris.Add(i + 1); tris.Add(i + increment); tris.Add(i + increment + 1); tris.Add(i + 1); } var outputMesh = new Mesh(); outputMesh.vertices = verts.Select(v => worldToLocal.MultiplyPoint3x4(v)).ToArray(); outputMesh.uv = uvs.ToArray(); outputMesh.triangles = tris.ToArray(); outputMesh.RecalculateNormals(); outputMesh.RecalculateBounds(); return(outputMesh); }
public void RecalculateBounds() { Transform[] transforms = (Transform[])GetComponentsInChildren <Transform>(); GetComponent <MeshFilter>().sharedMesh = ConvexHullAlgorithms.GetBounds(transforms.Select(x => x.gameObject), transform.worldToLocalMatrix); GetComponent <MeshCollider>().sharedMesh = GetComponent <MeshFilter>().sharedMesh; }