예제 #1
0
        static Box UVBox(MeshExtended extended, float gap)
        {
            // find the minimum and maximum values for X and Y.
            Vector2[] uvs  = extended.UVs;
            float     xMin = Mathf.Infinity;
            float     xMax = -Mathf.Infinity;
            float     yMin = Mathf.Infinity;
            float     yMax = -Mathf.Infinity;

            foreach (Vector2 v2 in uvs)
            {
                if (v2.x < xMin)
                {
                    xMin = v2.x;
                }
                if (v2.x > xMax)
                {
                    xMax = v2.x;
                }
                if (v2.y < yMin)
                {
                    yMin = v2.y;
                }
                if (v2.y > yMax)
                {
                    yMax = v2.y;
                }
            }

            // calculate the with and height plus a small gap definded by the user.
            float wid = xMax - xMin + gap;
            float hgt = yMax - yMin + gap;

            // calculate the box size base on the 3D size.
            Vector3 size = extended.Size;
            float   sid  = size.x * size.y * size.z;

            return(new Box {
                Height = hgt, Width = wid, Side = sid, Extended = extended, ShiftX = xMin, ShiftY = yMin
            });
        }
        /// <summary>
        /// Combines the meshes of mesh filter.
        /// </summary>
        /// <param name="filters"></param>
        /// <param name="weld">Should mesh vertices be welded?</param>
        /// <param name="gap">Padding between packed UV isalnds.</param>
        /// <returns></returns>
        public static Mesh Combine(MeshFilter[] filters, bool weld, float gap)
        {
            if (filters.Length == 0)
            {
                Debug.LogError("Mesh list is empty.");
                return(null);
            }

            // the root transform is used as base to translate local space to world space and back.
            Transform root = filters[0].transform;

            // Get extended data from each meh.
            int meshCount = filters.Length;

            MeshExtended[] extended = new MeshExtended[meshCount];
            for (int m = 0; m < meshCount; m++)
            {
                MeshFilter filter = filters[m];
                extended[m] = new MeshExtended();
                // The Mesh Extender take care of translating vertex positions to world space and back.
                // also calculates the required box size for the UVs
                extended[m].Prepare(filter.sharedMesh, weld, root, filter.GetComponent <Transform>(), MeshExtended.SizeMethod.WorldScale);
            }

            // After all meshes have been welded we can procedd to Pack the UV's
            List <UVPacker.Box> boxes = UVPacker.Pack(extended, gap);

            // Prepare a new mesh.
            Mesh           combined         = new Mesh();
            List <Vector3> combinedVertices = new List <Vector3>();
            List <Vector2> combinedUVs      = new List <Vector2>();
            List <Vector3> combinedNormals  = new List <Vector3>();
            List <int>     combinedTris     = new List <int>();
            int            triOffset        = 0;

            // once welded and with the UVs packed we can just add items to lists.
            for (int meshIndex = 0; meshIndex < meshCount; meshIndex++)
            {
                MeshExtended extmesh     = boxes[meshIndex].Extended;
                Vector3[]    vertices    = extmesh.Vertices;
                Vector2[]    uvs         = boxes[meshIndex].PackedUVs;
                Vector3[]    normals     = extmesh.Normals;
                int[]        triangles   = extmesh.Triangles;
                int          vertexCount = vertices.Length;
                int          triCount    = triangles.Length;

                for (int v = 0; v < vertexCount; v++)
                {
                    combinedVertices.Add(vertices[v]);
                    combinedUVs.Add(uvs[v]);
                    combinedNormals.Add(normals[v]);
                }

                for (int t = 0; t < triCount; t++)
                {
                    combinedTris.Add(triangles[t] + triOffset);
                }
                triOffset = combinedVertices.Count;
            }

            // with all the UVs merged we can make the final adjustments.
            UVPacker.AdjustSpace(combinedUVs);

            // and finally create the new mesh.
            combined.SetVertices(combinedVertices);
            combined.SetUVs(0, combinedUVs);
            combined.SetNormals(combinedNormals);
            combined.SetTriangles(combinedTris, 0);
            combined.RecalculateTangents();

            return(combined);
        }