Esempio n. 1
0
    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);
    }
Esempio n. 2
0
 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;
 }