コード例 #1
0
        private static void MakeBatch(List <MeshSubsetCombineUtility.MeshInstance> meshes, List <MeshSubsetCombineUtility.SubMeshInstance> subsets, List <GameObject> subsetGOs, Transform staticBatchRootTransform, int batchIndex)
        {
            if (meshes.Count < 2)
            {
                return;
            }
            MeshSubsetCombineUtility.MeshInstance[]    meshes2 = meshes.ToArray();
            MeshSubsetCombineUtility.SubMeshInstance[] array   = subsets.ToArray();
            string text = "Combined Mesh";

            text = text + " (root: " + ((!(staticBatchRootTransform != null)) ? "scene" : staticBatchRootTransform.name) + ")";
            if (batchIndex > 0)
            {
                text = text + " " + (batchIndex + 1);
            }
            Mesh mesh = StaticBatchingUtility.InternalCombineVertices(meshes2, text);

            StaticBatchingUtility.InternalCombineIndices(array, mesh);
            int num = 0;

            for (int i = 0; i < array.Length; i++)
            {
                MeshSubsetCombineUtility.SubMeshInstance subMeshInstance = array[i];
                GameObject gameObject = subsetGOs[i];
                Mesh       sharedMesh = mesh;
                MeshFilter meshFilter = (MeshFilter)gameObject.GetComponent(typeof(MeshFilter));
                meshFilter.sharedMesh = sharedMesh;
                Renderer component = gameObject.GetComponent <Renderer>();
                component.SetSubsetIndex(subMeshInstance.subMeshIndex, num);
                component.staticBatchRootTransform = staticBatchRootTransform;
                component.enabled = false;
                component.enabled = true;
                MeshRenderer meshRenderer = component as MeshRenderer;
                if (meshRenderer != null)
                {
                    meshRenderer.additionalVertexStreams = null;
                }
                num++;
            }
        }
コード例 #2
0
        private static void MakeBatch(List <MeshSubsetCombineUtility.MeshInstance> meshes, List <MeshSubsetCombineUtility.SubMeshInstance> subsets, List <GameObject> subsetGOs, Transform staticBatchRootTransform, int batchIndex)
        {
            if (meshes.Count < 2)
            {
                return;
            }
            MeshSubsetCombineUtility.MeshInstance[]    array1 = meshes.ToArray();
            MeshSubsetCombineUtility.SubMeshInstance[] array2 = subsets.ToArray();
            string meshName = "Combined Mesh" + " (root: " + (!((Object)staticBatchRootTransform != (Object)null) ? "scene" : staticBatchRootTransform.name) + ")";

            if (batchIndex > 0)
            {
                meshName = meshName + " " + (object)(batchIndex + 1);
            }
            Mesh combinedMesh = StaticBatchingUtility.InternalCombineVertices(array1, meshName);

            StaticBatchingUtility.InternalCombineIndices(array2, combinedMesh);
            int subSetIndexForMaterial = 0;

            for (int index = 0; index < array2.Length; ++index)
            {
                MeshSubsetCombineUtility.SubMeshInstance subMeshInstance = array2[index];
                GameObject subsetGo = subsetGOs[index];
                Mesh       mesh     = combinedMesh;
                ((MeshFilter)subsetGo.GetComponent(typeof(MeshFilter))).sharedMesh = mesh;
                Renderer component = subsetGo.GetComponent <Renderer>();
                component.SetSubsetIndex(subMeshInstance.subMeshIndex, subSetIndexForMaterial);
                component.staticBatchRootTransform = staticBatchRootTransform;
                component.enabled = false;
                component.enabled = true;
                MeshRenderer meshRenderer = component as MeshRenderer;
                if ((Object)meshRenderer != (Object)null)
                {
                    meshRenderer.additionalVertexStreams = (Mesh)null;
                }
                ++subSetIndexForMaterial;
            }
        }
コード例 #3
0
        public static void CombineGameObjects(GameObject[] gos, GameObject staticBatchRoot, bool isEditorPostprocessScene)
        {
            Matrix4x4 lhs = Matrix4x4.identity;
            Transform staticBatchRootTransform = null;

            if (staticBatchRoot)
            {
                lhs = staticBatchRoot.transform.worldToLocalMatrix;
                staticBatchRootTransform = staticBatchRoot.transform;
            }
            int batchIndex = 0;
            int num        = 0;
            List <MeshSubsetCombineUtility.MeshContainer> list = new List <MeshSubsetCombineUtility.MeshContainer>();

            Array.Sort(gos, new InternalStaticBatchingUtility.SortGO());
            foreach (GameObject gameObject in gos)
            {
                MeshFilter meshFilter = gameObject.GetComponent(typeof(MeshFilter)) as MeshFilter;
                if (!(meshFilter == null))
                {
                    Mesh sharedMesh = meshFilter.sharedMesh;
                    if (!(sharedMesh == null) && (isEditorPostprocessScene || sharedMesh.canAccess))
                    {
                        Renderer component = meshFilter.GetComponent <Renderer>();
                        if (!(component == null) && component.enabled)
                        {
                            if (component.staticBatchIndex == 0)
                            {
                                Material[] array = component.sharedMaterials;
                                if (!array.Any((Material m) => m != null && m.shader != null && m.shader.disableBatching != DisableBatchingType.False))
                                {
                                    int vertexCount = sharedMesh.vertexCount;
                                    if (vertexCount != 0)
                                    {
                                        MeshRenderer meshRenderer = component as MeshRenderer;
                                        if (meshRenderer != null && meshRenderer.additionalVertexStreams != null)
                                        {
                                            if (vertexCount != meshRenderer.additionalVertexStreams.vertexCount)
                                            {
                                                goto IL_387;
                                            }
                                        }
                                        if (num + vertexCount > 64000)
                                        {
                                            InternalStaticBatchingUtility.MakeBatch(list, staticBatchRootTransform, batchIndex++);
                                            list.Clear();
                                            num = 0;
                                        }
                                        MeshSubsetCombineUtility.MeshInstance instance = default(MeshSubsetCombineUtility.MeshInstance);
                                        instance.meshInstanceID     = sharedMesh.GetInstanceID();
                                        instance.rendererInstanceID = component.GetInstanceID();
                                        if (meshRenderer != null && meshRenderer.additionalVertexStreams != null)
                                        {
                                            instance.additionalVertexStreamsMeshInstanceID = meshRenderer.additionalVertexStreams.GetInstanceID();
                                        }
                                        instance.transform                   = lhs * meshFilter.transform.localToWorldMatrix;
                                        instance.lightmapScaleOffset         = component.lightmapScaleOffset;
                                        instance.realtimeLightmapScaleOffset = component.realtimeLightmapScaleOffset;
                                        MeshSubsetCombineUtility.MeshContainer item = new MeshSubsetCombineUtility.MeshContainer
                                        {
                                            gameObject       = gameObject,
                                            instance         = instance,
                                            subMeshInstances = new List <MeshSubsetCombineUtility.SubMeshInstance>()
                                        };
                                        list.Add(item);
                                        if (array.Length > sharedMesh.subMeshCount)
                                        {
                                            Debug.LogWarning(string.Concat(new object[]
                                            {
                                                "Mesh '",
                                                sharedMesh.name,
                                                "' has more materials (",
                                                array.Length,
                                                ") than subsets (",
                                                sharedMesh.subMeshCount,
                                                ")"
                                            }), component);
                                            Material[] array2 = new Material[sharedMesh.subMeshCount];
                                            for (int j = 0; j < sharedMesh.subMeshCount; j++)
                                            {
                                                array2[j] = component.sharedMaterials[j];
                                            }
                                            component.sharedMaterials = array2;
                                            array = array2;
                                        }
                                        for (int k = 0; k < Math.Min(array.Length, sharedMesh.subMeshCount); k++)
                                        {
                                            MeshSubsetCombineUtility.SubMeshInstance item2 = default(MeshSubsetCombineUtility.SubMeshInstance);
                                            item2.meshInstanceID       = meshFilter.sharedMesh.GetInstanceID();
                                            item2.vertexOffset         = num;
                                            item2.subMeshIndex         = k;
                                            item2.gameObjectInstanceID = gameObject.GetInstanceID();
                                            item2.transform            = instance.transform;
                                            item.subMeshInstances.Add(item2);
                                        }
                                        num += sharedMesh.vertexCount;
                                    }
                                }
                            }
                        }
                    }
                }
                IL_387 :;
            }
            InternalStaticBatchingUtility.MakeBatch(list, staticBatchRootTransform, batchIndex);
        }
コード例 #4
0
        static public void CombineGameObjects(GameObject[] gos, UnityEngine.GameObject staticBatchRoot, bool isEditorPostprocessScene)
        {
            Matrix4x4 staticBatchInverseMatrix = Matrix4x4.identity;
            Transform staticBatchRootTransform = null;

            if (staticBatchRoot)
            {
                staticBatchInverseMatrix = staticBatchRoot.transform.worldToLocalMatrix;
                staticBatchRootTransform = staticBatchRoot.transform;
            }

            int batchIndex      = 0;
            int verticesInBatch = 0;
            List <MeshSubsetCombineUtility.MeshContainer> meshes = new List <MeshSubsetCombineUtility.MeshContainer>();

            Array.Sort(gos, new SortGO());

            foreach (GameObject go in gos)
            {
                MeshFilter filter = go.GetComponent(typeof(MeshFilter)) as MeshFilter;
                if (filter == null)
                {
                    continue;
                }

                Mesh instanceMesh = filter.sharedMesh;

                // reject if has no mesh or (mesh not readable and not called from Editor PostprocessScene.cs)
                // Editor is allowed to modify meshes even if they are marked as read-only e.g. Applicatiopn.LoadLevel() called from a script inside the editor player
                if (instanceMesh == null || (!isEditorPostprocessScene && !instanceMesh.canAccess))
                {
                    continue;
                }

                Renderer renderer = filter.GetComponent <Renderer>();

                // reject if has not renderer or renderer is disabled
                if (renderer == null || !renderer.enabled)
                {
                    continue;
                }

                // reject if already combined for static batching
                if (renderer.staticBatchIndex != 0)
                {
                    continue;
                }

                Material[] materials = renderer.sharedMaterials;

                // reject if any of the material's shader is using DisableBatching tag
                if (materials.Any(m => m != null && m.shader != null && m.shader.disableBatching != DisableBatchingType.False))
                {
                    continue;
                }

                int vertexCount = instanceMesh.vertexCount;
                // Use same tests as MeshCombiner::IsMeshBatchable to stay consistent with C++ code
                if (vertexCount == 0)
                {
                    continue;
                }

                MeshRenderer meshRenderer = renderer as MeshRenderer;
                if ((meshRenderer != null) && (meshRenderer.additionalVertexStreams != null))
                {
                    if (vertexCount != meshRenderer.additionalVertexStreams.vertexCount)
                    {
                        continue;
                    }
                }

                // check if we have enough space inside the current batch
                if (verticesInBatch + vertexCount > MaxVerticesInBatch)
                {
                    MakeBatch(meshes, staticBatchRootTransform, batchIndex++);
                    meshes.Clear();
                    verticesInBatch = 0;
                }

                MeshSubsetCombineUtility.MeshInstance instance = new MeshSubsetCombineUtility.MeshInstance();
                instance.meshInstanceID     = instanceMesh.GetInstanceID();
                instance.rendererInstanceID = renderer.GetInstanceID();
                if (meshRenderer != null && meshRenderer.additionalVertexStreams != null)
                {
                    instance.additionalVertexStreamsMeshInstanceID = meshRenderer.additionalVertexStreams.GetInstanceID();
                }

                instance.transform                   = staticBatchInverseMatrix * filter.transform.localToWorldMatrix;
                instance.lightmapScaleOffset         = renderer.lightmapScaleOffset;
                instance.realtimeLightmapScaleOffset = renderer.realtimeLightmapScaleOffset;

                MeshSubsetCombineUtility.MeshContainer mesh = new MeshSubsetCombineUtility.MeshContainer();
                mesh.gameObject       = go;
                mesh.instance         = instance;
                mesh.subMeshInstances = new List <MeshSubsetCombineUtility.SubMeshInstance>();

                //;;Debug.Log("New static mesh (" + go.name + ")verts: " + instanceMesh.vertexCount +
                //  ", tris: " + instanceMesh.triangles.Length +
                //  ", materials: " + renderer.sharedMaterials.Length +
                //  ", subs: " + instanceMesh.subMeshCount
                //  );

                meshes.Add(mesh);

                if (materials.Length > instanceMesh.subMeshCount)
                {
                    Debug.LogWarning("Mesh '" + instanceMesh.name + "' has more materials (" + materials.Length + ") than subsets (" + instanceMesh.subMeshCount + ")", renderer);
                    // extra materials don't have a meaning and it screws the rendering as Unity
                    // tries to render with those extra materials.
                    Material[] newMats = new Material[instanceMesh.subMeshCount];
                    for (int i = 0; i < instanceMesh.subMeshCount; ++i)
                    {
                        newMats[i] = renderer.sharedMaterials[i];
                    }
                    renderer.sharedMaterials = newMats;
                    materials = newMats;
                }

                for (int m = 0; m < System.Math.Min(materials.Length, instanceMesh.subMeshCount); ++m)
                {
                    //;;Debug.Log("   new subset : " + m + ", tris " + instanceMesh.GetTriangles(m).Length);
                    MeshSubsetCombineUtility.SubMeshInstance subMeshInstance = new MeshSubsetCombineUtility.SubMeshInstance();
                    subMeshInstance.meshInstanceID       = filter.sharedMesh.GetInstanceID();
                    subMeshInstance.vertexOffset         = verticesInBatch;
                    subMeshInstance.subMeshIndex         = m;
                    subMeshInstance.gameObjectInstanceID = go.GetInstanceID();
                    subMeshInstance.transform            = instance.transform;
                    mesh.subMeshInstances.Add(subMeshInstance);
                }
                verticesInBatch += instanceMesh.vertexCount;
            }

            MakeBatch(meshes, staticBatchRootTransform, batchIndex);
        }
コード例 #5
0
        public static void CombineGameObjects(GameObject[] gos, GameObject staticBatchRoot, bool isEditorPostprocessScene)
        {
            Matrix4x4 lhs = Matrix4x4.identity;
            Transform staticBatchRootTransform = null;

            if ((bool)staticBatchRoot)
            {
                lhs = staticBatchRoot.transform.worldToLocalMatrix;
                staticBatchRootTransform = staticBatchRoot.transform;
            }
            int num  = 0;
            int num2 = 0;
            List <MeshSubsetCombineUtility.MeshInstance>    list  = new List <MeshSubsetCombineUtility.MeshInstance>();
            List <MeshSubsetCombineUtility.SubMeshInstance> list2 = new List <MeshSubsetCombineUtility.SubMeshInstance>();
            List <GameObject> list3 = new List <GameObject>();

            Array.Sort(gos, new SortGO());
            foreach (GameObject gameObject in gos)
            {
                MeshFilter meshFilter = gameObject.GetComponent(typeof(MeshFilter)) as MeshFilter;
                if (meshFilter == null)
                {
                    continue;
                }
                Mesh sharedMesh = meshFilter.sharedMesh;
                if (sharedMesh == null || (!isEditorPostprocessScene && !sharedMesh.canAccess))
                {
                    continue;
                }
                Renderer component = meshFilter.GetComponent <Renderer>();
                if (component == null || !component.enabled || component.staticBatchIndex != 0)
                {
                    continue;
                }
                Material[] array = meshFilter.GetComponent <Renderer>().sharedMaterials;
                if (array.Any((Material m) => m != null && m.shader != null && m.shader.disableBatching != DisableBatchingType.False))
                {
                    continue;
                }
                if (num2 + meshFilter.sharedMesh.vertexCount > 64000)
                {
                    MakeBatch(list, list2, list3, staticBatchRootTransform, num++);
                    list.Clear();
                    list2.Clear();
                    list3.Clear();
                    num2 = 0;
                }
                MeshSubsetCombineUtility.MeshInstance item = default(MeshSubsetCombineUtility.MeshInstance);
                item.meshInstanceID     = sharedMesh.GetInstanceID();
                item.rendererInstanceID = component.GetInstanceID();
                MeshRenderer meshRenderer = component as MeshRenderer;
                if (meshRenderer != null && meshRenderer.additionalVertexStreams != null)
                {
                    item.additionalVertexStreamsMeshInstanceID = meshRenderer.additionalVertexStreams.GetInstanceID();
                }
                item.transform                   = lhs * meshFilter.transform.localToWorldMatrix;
                item.lightmapScaleOffset         = component.lightmapScaleOffset;
                item.realtimeLightmapScaleOffset = component.realtimeLightmapScaleOffset;
                list.Add(item);
                if (array.Length > sharedMesh.subMeshCount)
                {
                    Debug.LogWarning("Mesh has more materials (" + array.Length + ") than subsets (" + sharedMesh.subMeshCount + ")", meshFilter.GetComponent <Renderer>());
                    Material[] array2 = new Material[sharedMesh.subMeshCount];
                    for (int j = 0; j < sharedMesh.subMeshCount; j++)
                    {
                        array2[j] = meshFilter.GetComponent <Renderer>().sharedMaterials[j];
                    }
                    meshFilter.GetComponent <Renderer>().sharedMaterials = array2;
                    array = array2;
                }
                for (int k = 0; k < Math.Min(array.Length, sharedMesh.subMeshCount); k++)
                {
                    MeshSubsetCombineUtility.SubMeshInstance item2 = default(MeshSubsetCombineUtility.SubMeshInstance);
                    item2.meshInstanceID       = meshFilter.sharedMesh.GetInstanceID();
                    item2.vertexOffset         = num2;
                    item2.subMeshIndex         = k;
                    item2.gameObjectInstanceID = gameObject.GetInstanceID();
                    item2.transform            = item.transform;
                    list2.Add(item2);
                    list3.Add(gameObject);
                }
                num2 += sharedMesh.vertexCount;
            }
            MakeBatch(list, list2, list3, staticBatchRootTransform, num);
        }