Beispiel #1
0
    /// <summary>
    /// Clear the merged meshes, reverting back to the state prior to the Merge() call.
    /// </summary>

    public void Clear()
    {
        for (int i = 0, imax = mDisabledGO.Count; i < imax; ++i)
        {
            GameObject go = mDisabledGO[i];
            if (go)
            {
                TWTools.SetActive(go, true);
            }
        }

        for (int i = 0, imax = mDisabledRen.Count; i < imax; ++i)
        {
            Renderer ren = mDisabledRen[i];
            if (ren)
            {
                ren.enabled = true;
            }
        }

        mDisabledGO.Clear();
        mDisabledRen.Clear();

        if (mRen != null)
        {
            mRen.enabled = false;
        }
    }
Beispiel #2
0
    /// <summary>
    /// Clear the merged meshes and release all memory.
    /// </summary>

    public void Release()
    {
        Clear();

        TWTools.Destroy(mRen);
        TWTools.Destroy(mFilter);
        TWTools.Destroy(mMesh);

        mFilter = null;
        mMesh   = null;
        mRen    = null;
    }
Beispiel #3
0
    /// <summary>
    /// Merge all meshes
    /// </summary>

    public void Merge(bool immediate)
    {
        if (!immediate)
        {
            mMerge  = true;
            enabled = true;
            return;
        }

        mMerge  = false;
        mName   = name;
        mFilter = GetComponent <MeshFilter>();
        mTrans  = transform;

        Clear();
        MeshFilter[] filters = GetComponentsInChildren <MeshFilter>();
        if (filters.Length == 0 || (mFilter != null && filters.Length == 1))
        {
            return;
        }

        GameObject go  = gameObject;
        Matrix4x4  w2l = go.transform.worldToLocalMatrix;

        int vertexCount = 0;
        int indexCount  = 0;
        int normCount   = 0;
        int tanCount    = 0;
        int colCount    = 0;
        int uv1Count    = 0;
        int uv2Count    = 0;

        // First we need to calculate the number of vertices, normals, etc
        foreach (MeshFilter filter in filters)
        {
            if (filter == mFilter)
            {
                continue;
            }

            if (filter.gameObject.isStatic)
            {
                Debug.LogError("MergeMeshes can't merge objects marked as static", filter.gameObject);
                continue;
            }

            Mesh mesh = filter.sharedMesh;

            // Assume the first material if none was specified
            if (material == null)
            {
                material = filter.renderer.sharedMaterial;
            }

            // Vertex colors and indices must always be present
            vertexCount += mesh.vertexCount;
            indexCount  += mesh.triangles.Length;

            // Other components are optional
            if (mesh.normals != null)
            {
                normCount += mesh.normals.Length;
            }
            if (mesh.tangents != null)
            {
                tanCount += mesh.tangents.Length;
            }
            if (mesh.colors != null)
            {
                colCount += mesh.colors.Length;
            }
            if (mesh.uv != null)
            {
                uv1Count += mesh.uv.Length;
            }
            if (mesh.uv2 != null)
            {
                uv2Count += mesh.uv2.Length;
            }
        }

        if (vertexCount == 0)
        {
            Debug.LogWarning("Unable to find any non-static objects to merge", this);
            return;
        }

        Vector3[] verts   = new Vector3[vertexCount];
        int[]     indices = new int[indexCount];

        Vector2[] uv1   = (uv1Count == vertexCount) ? new Vector2[vertexCount] : null;
        Vector2[] uv2   = (uv2Count == vertexCount) ? new Vector2[vertexCount] : null;
        Vector3[] norms = (normCount == vertexCount) ? new Vector3[vertexCount] : null;
        Vector4[] tans  = (tanCount == vertexCount) ? new Vector4[vertexCount] : null;
        Color[]   cols  = (colCount == vertexCount) ? new Color[vertexCount] : null;

        int meshOffset   = 0;
        int indexOffset  = 0;
        int vertexOffset = 0;

        // Run through each filter again
        foreach (MeshFilter filter in filters)
        {
            if (filter == mFilter || filter.gameObject.isStatic)
            {
                continue;
            }

            Mesh mesh = filter.sharedMesh;
            if (mesh.vertexCount == 0)
            {
                continue;
            }

            // Matrix that will transform from relative-to-mesh to world space coordinates
            Matrix4x4 l2w = filter.transform.localToWorldMatrix;

            // Disable this renderer
            Renderer ren = filter.renderer;

            // If we are not destroying renderers, add this renderer to the list
            if (afterMerging != PostMerge.DestroyRenderers)
            {
                ren.enabled = false;
                mDisabledRen.Add(ren);
            }

            // Disable the game object
            if (afterMerging == PostMerge.DisableGameObjects)
            {
                GameObject root  = filter.gameObject;
                Transform  trans = root.transform;

                // Find the object's root (rigidbody)
                while (trans != mTrans)
                {
                    if (trans.rigidbody != null)
                    {
                        root = trans.gameObject;
                        break;
                    }
                    trans = trans.parent;
                }
                mDisabledGO.Add(root);
                TWTools.SetActive(root, false);
            }

            Vector3[] mv = mesh.vertices;
            Vector3[] mn = (norms != null) ? mesh.normals : null;
            Vector4[] mt = (tans != null) ? mesh.tangents : null;
            Vector2[] u1 = (uv1 != null) ? mesh.uv : null;
            Vector2[] u2 = (uv2 != null) ? mesh.uv2 : null;
            Color[]   mc = (cols != null) ? mesh.colors : null;
            int[]     mi = mesh.triangles;

            // Copy all vertices, tangents, normals, etc
            for (int i = 0, imax = mv.Length; i < imax; ++i)
            {
                verts[vertexOffset] = w2l.MultiplyPoint3x4(l2w.MultiplyPoint3x4(mv[i]));

                if (norms != null)
                {
                    norms[vertexOffset] = w2l.MultiplyVector(l2w.MultiplyVector(mn[i]));
                }
                if (cols != null)
                {
                    cols[vertexOffset] = mc[i];
                }
                if (uv1 != null)
                {
                    uv1[vertexOffset] = u1[i];
                }
                if (uv2 != null)
                {
                    uv2[vertexOffset] = u2[i];
                }

                if (tans != null)
                {
                    Vector4 tan4 = mt[i];
                    Vector3 tan3 = new Vector3(tan4.x, tan4.y, tan4.z);
                    tan3               = w2l.MultiplyVector(l2w.MultiplyVector(tan3));
                    tan4.x             = tan3.x;
                    tan4.y             = tan3.y;
                    tan4.z             = tan3.z;
                    tans[vertexOffset] = tan4;
                }
                ++vertexOffset;
            }

            // Copy over the indices
            for (int i = 0, imax = mi.Length; i < imax; ++i)
            {
                indices[indexOffset++] = meshOffset + mi[i];
            }
            meshOffset = vertexOffset;

            // Destroy the game object if needed
            if (afterMerging == PostMerge.DestroyGameObjects)
            {
                Destroy(filter.gameObject);
            }
            else if (afterMerging == PostMerge.DestroyRenderers)
            {
                Destroy(ren);
            }
        }

        // If objects get destroyed, there is no point in keeping the original filters
        if (afterMerging == PostMerge.DestroyGameObjects)
        {
            filters = null;
            mDisabledGO.Clear();
        }

        if (verts.Length > 0)
        {
            // Create a temporary mesh
            if (mMesh == null)
            {
                mMesh           = new Mesh();
                mMesh.hideFlags = HideFlags.DontSave;
            }
            else
            {
                mMesh.Clear();
            }

            mMesh.name      = mName;
            mMesh.vertices  = verts;
            mMesh.normals   = norms;
            mMesh.tangents  = tans;
            mMesh.colors    = cols;
            mMesh.uv        = uv1;
            mMesh.uv2       = uv2;
            mMesh.triangles = indices;
            mMesh.RecalculateBounds();

            // Add a mesh filter
            if (mFilter == null)
            {
                mFilter      = go.AddComponent <MeshFilter>();
                mFilter.mesh = mMesh;
            }

            // Add a mesh renderer
            if (mRen == null)
            {
                mRen = go.AddComponent <MeshRenderer>();
            }
            mRen.sharedMaterial = material;
            mRen.enabled        = true;

            // Just for clarity, show the number of triangles in the name of the game object
            go.name = mName + " (" + (indices.Length / 3) + " tri)";
        }
        else
        {
            Release();
        }
        enabled = false;
        //BroadcastMessage("OnMergedMeshes", SendMessageOptions.DontRequireReceiver);
    }