/// <summary>
    /// Combines selected gameobjects that have meshfilters to the lowest possible meshcount.
    /// </summary>
    private void Combine()
    {
        GameObject GO_Parent = Selection.gameObjects[0];
        GameObject[] oldGameObjects = Selection.gameObjects;
        Vector3 oldPosition = new Vector3(GO_Parent.transform.position.x, GO_Parent.transform.position.y, GO_Parent.transform.position.z);

        //		oldPositions.Clear();
        //		oldRotations.Clear();
        //		oldPositions = StoreOriginalPositions(oldGameObjects);
        //		oldRotations = StoreOriginalQuaternions(oldGameObjects);

        Component[] filters = GetMeshFilters();
        Matrix4x4 myTransform = GO_Parent.transform.worldToLocalMatrix;
        Hashtable materialToMesh = new Hashtable();

        for (int i = 0; i < filters.Length; i++)
        {
            MeshFilter filter = (MeshFilter)filters[i];
            Renderer curRenderer = filters[i].GetComponent<Renderer>();
            QT_MeshCombineUtility.MeshInstance instance = new QT_MeshCombineUtility.MeshInstance();
            instance.mesh = filter.sharedMesh;
            if (curRenderer != null && curRenderer.enabled && instance.mesh != null)
            {
                instance.transform = myTransform * filter.transform.localToWorldMatrix;

                Material[] materials = curRenderer.sharedMaterials;
                for (int m = 0; m < materials.Length; m++)
                {
                    instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1);

                    ArrayList objects = (ArrayList)materialToMesh[materials[m]];
                    if (objects != null)
                        objects.Add(instance);
                    else
                    {
                        objects = new ArrayList();
                        objects.Add(instance);
                        materialToMesh.Add(materials[m], objects);
                    }
                }
            }
        }

        int nameCount = 1; //used for multimesh naming.

        //for each material found
        foreach (DictionaryEntry de in materialToMesh)
        {
            ArrayList elements = (ArrayList)de.Value;
            QT_MeshCombineUtility.MeshInstance[] instances = (QT_MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(QT_MeshCombineUtility.MeshInstance));

            GameObject go = new GameObject("Combined Mesh");
            if (keepLayer)
                go.layer = GO_Parent.layer;
            // transforms should be zeroed out, then reset when we place the new object em.
            go.transform.localScale = Vector3.one;
            go.transform.localRotation = GO_Parent.transform.localRotation;
            go.transform.localPosition = Vector3.zero;
            go.transform.position = Vector3.zero;
            go.AddComponent(typeof(MeshFilter));
            go.AddComponent<MeshRenderer>();
            go.GetComponent<Renderer>().material = (Material)de.Key;
            MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter));
            filter.sharedMesh = QT_MeshCombineUtility.Combine(instances, false);
          //  filter.GetComponent<Renderer>().receiveShadows = receiveShadows;
           // filter.GetComponent<Renderer>().castShadows = castShadows;
            go.isStatic = isStatic;
            if (isLightmapped)
                Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh);
            if (addMeshCollider)
                go.AddComponent<MeshCollider>();
            //add the new object to our list.
            newObjects.Add(go);

        }

        if (destroyAfterOptimized)
        {
            for (int x = 0; x < oldGameObjects.Length; x++)
                DestroyImmediate(oldGameObjects[x]);
        }

        //if we found unique materials, make sure we name the GO's properly.
        if (newObjects.Count > 1)
        {
            for (int x = 0; x < newObjects.Count; x++)
            {
                if (x > 0)
                    newObjects[x].name = newName + nameCount;
                else
                    newObjects[0].name = newName;
                nameCount++;
                newObjects[x].transform.position = oldPosition;
            }
        }
        else
        {
            newObjects[0].name = newName;
            newObjects[0].transform.position = oldPosition;
        }

        if (createParentGO)
        {
            GameObject p = new GameObject(newName);
            p.transform.position = oldPosition;
            foreach (GameObject g in newObjects)
                g.transform.parent = p.transform;
        }
    }
Beispiel #2
0
    /// <summary>
    /// Combines selected gameobjects that have meshfilters to the lowest possible meshcount.
    /// </summary>
    private void Combine()
    {
        GameObject GO_Parent = Selection.gameObjects[0];

        GameObject[] oldGameObjects = Selection.gameObjects;
        Vector3      oldPosition    = new Vector3(GO_Parent.transform.position.x, GO_Parent.transform.position.y, GO_Parent.transform.position.z);

        //		oldPositions.Clear();
        //		oldRotations.Clear();
        //		oldPositions = StoreOriginalPositions(oldGameObjects);
        //		oldRotations = StoreOriginalQuaternions(oldGameObjects);

        Component[] filters        = GetMeshFilters();
        Matrix4x4   myTransform    = GO_Parent.transform.worldToLocalMatrix;
        Hashtable   materialToMesh = new Hashtable();

        for (int i = 0; i < filters.Length; i++)
        {
            MeshFilter filter      = (MeshFilter)filters[i];
            Renderer   curRenderer = filters[i].GetComponent <Renderer>();
            QT_MeshCombineUtility.MeshInstance instance = new QT_MeshCombineUtility.MeshInstance();
            instance.mesh = filter.sharedMesh;
            if (curRenderer != null && curRenderer.enabled && instance.mesh != null)
            {
                instance.transform = myTransform * filter.transform.localToWorldMatrix;

                Material[] materials = curRenderer.sharedMaterials;
                for (int m = 0; m < materials.Length; m++)
                {
                    instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1);

                    ArrayList objects = (ArrayList)materialToMesh[materials[m]];
                    if (objects != null)
                    {
                        objects.Add(instance);
                    }
                    else
                    {
                        objects = new ArrayList();
                        objects.Add(instance);
                        materialToMesh.Add(materials[m], objects);
                    }
                }
            }
        }

        int nameCount = 1; //used for multimesh naming.

        //for each material found
        foreach (DictionaryEntry de in materialToMesh)
        {
            ArrayList elements = (ArrayList)de.Value;
            QT_MeshCombineUtility.MeshInstance[] instances = (QT_MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(QT_MeshCombineUtility.MeshInstance));

            GameObject go = new GameObject("Combined Mesh");
            if (keepLayer)
            {
                go.layer = GO_Parent.layer;
            }
            // transforms should be zeroed out, then reset when we place the new object em.
            go.transform.localScale    = Vector3.one;
            go.transform.localRotation = GO_Parent.transform.localRotation;
            go.transform.localPosition = Vector3.zero;
            go.transform.position      = Vector3.zero;
            go.AddComponent(typeof(MeshFilter));
            go.AddComponent <MeshRenderer>();
            go.GetComponent <Renderer>().material = (Material)de.Key;
            MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter));
            filter.sharedMesh = QT_MeshCombineUtility.Combine(instances, false);
            //  filter.GetComponent<Renderer>().receiveShadows = receiveShadows;
            // filter.GetComponent<Renderer>().castShadows = castShadows;
            go.isStatic = isStatic;
            if (isLightmapped)
            {
                Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh);
            }
            if (addMeshCollider)
            {
                go.AddComponent <MeshCollider>();
            }
            //add the new object to our list.
            newObjects.Add(go);
        }


        if (destroyAfterOptimized)
        {
            for (int x = 0; x < oldGameObjects.Length; x++)
            {
                DestroyImmediate(oldGameObjects[x]);
            }
        }

        //if we found unique materials, make sure we name the GO's properly.
        if (newObjects.Count > 1)
        {
            for (int x = 0; x < newObjects.Count; x++)
            {
                if (x > 0)
                {
                    newObjects[x].name = newName + nameCount;
                }
                else
                {
                    newObjects[0].name = newName;
                }
                nameCount++;
                newObjects[x].transform.position = oldPosition;
            }
        }
        else
        {
            newObjects[0].name = newName;
            newObjects[0].transform.position = oldPosition;
        }

        if (createParentGO)
        {
            GameObject p = new GameObject(newName);
            p.transform.position = oldPosition;
            foreach (GameObject g in newObjects)
            {
                g.transform.parent = p.transform;
            }
        }
    }