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); }
public static void CombineGameObjects(GameObject[] gos, GameObject staticBatchRoot, bool isEditorPostprocessScene) { Matrix4x4 matrix4x4 = Matrix4x4.identity; Transform staticBatchRootTransform = (Transform) null; if ((bool) ((Object) staticBatchRoot)) { matrix4x4 = staticBatchRoot.transform.worldToLocalMatrix; staticBatchRootTransform = staticBatchRoot.transform; } int batchIndex = 0; int num = 0; List<MeshSubsetCombineUtility.MeshInstance> meshes = new List<MeshSubsetCombineUtility.MeshInstance>(); List<MeshSubsetCombineUtility.SubMeshInstance> subsets = new List<MeshSubsetCombineUtility.SubMeshInstance>(); List<GameObject> subsetGOs = new List<GameObject>(); Array.Sort((Array) gos, (IComparer) new InternalStaticBatchingUtility.SortGO()); foreach (GameObject go in gos) { MeshFilter component1 = go.GetComponent(typeof (MeshFilter)) as MeshFilter; if (!((Object) component1 == (Object) null)) { Mesh sharedMesh = component1.sharedMesh; if (!((Object) sharedMesh == (Object) null) && (isEditorPostprocessScene || sharedMesh.canAccess)) { Renderer component2 = component1.GetComponent<Renderer>(); if (!((Object) component2 == (Object) null) && component2.enabled && component2.staticBatchIndex == 0) { Material[] materialArray1 = component1.GetComponent<Renderer>().sharedMaterials; if (!((IEnumerable<Material>) materialArray1).Any<Material>((Func<Material, bool>) (m => { if ((Object) m != (Object) null && (Object) m.shader != (Object) null) return m.shader.disableBatching != DisableBatchingType.False; return false; }))) { int vertexCount = sharedMesh.vertexCount; if (vertexCount != 0) { MeshRenderer meshRenderer = component2 as MeshRenderer; if (!((Object) meshRenderer != (Object) null) || !((Object) meshRenderer.additionalVertexStreams != (Object) null) || vertexCount == meshRenderer.additionalVertexStreams.vertexCount) { if (num + vertexCount > 64000) { InternalStaticBatchingUtility.MakeBatch(meshes, subsets, subsetGOs, staticBatchRootTransform, batchIndex++); meshes.Clear(); subsets.Clear(); subsetGOs.Clear(); num = 0; } MeshSubsetCombineUtility.MeshInstance meshInstance = new MeshSubsetCombineUtility.MeshInstance(); meshInstance.meshInstanceID = sharedMesh.GetInstanceID(); meshInstance.rendererInstanceID = component2.GetInstanceID(); if ((Object) meshRenderer != (Object) null && (Object) meshRenderer.additionalVertexStreams != (Object) null) meshInstance.additionalVertexStreamsMeshInstanceID = meshRenderer.additionalVertexStreams.GetInstanceID(); meshInstance.transform = matrix4x4 * component1.transform.localToWorldMatrix; meshInstance.lightmapScaleOffset = component2.lightmapScaleOffset; meshInstance.realtimeLightmapScaleOffset = component2.realtimeLightmapScaleOffset; meshes.Add(meshInstance); if (materialArray1.Length > sharedMesh.subMeshCount) { Debug.LogWarning((object) ("Mesh has more materials (" + (object) materialArray1.Length + ") than subsets (" + (object) sharedMesh.subMeshCount + ")"), (Object) component1.GetComponent<Renderer>()); Material[] materialArray2 = new Material[sharedMesh.subMeshCount]; for (int index = 0; index < sharedMesh.subMeshCount; ++index) materialArray2[index] = component1.GetComponent<Renderer>().sharedMaterials[index]; component1.GetComponent<Renderer>().sharedMaterials = materialArray2; materialArray1 = materialArray2; } for (int index = 0; index < Math.Min(materialArray1.Length, sharedMesh.subMeshCount); ++index) { subsets.Add(new MeshSubsetCombineUtility.SubMeshInstance() { meshInstanceID = component1.sharedMesh.GetInstanceID(), vertexOffset = num, subMeshIndex = index, gameObjectInstanceID = go.GetInstanceID(), transform = meshInstance.transform }); subsetGOs.Add(go); } num += sharedMesh.vertexCount; } } } } } } } InternalStaticBatchingUtility.MakeBatch(meshes, subsets, subsetGOs, staticBatchRootTransform, batchIndex); }
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); }
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); }
public static void Combine(GameObject[] gos, GameObject staticBatchRoot) { Matrix4x4 lhs = Matrix4x4.identity; Transform staticBatchRootTransform = null; if (staticBatchRoot) { lhs = staticBatchRoot.transform.worldToLocalMatrix; staticBatchRootTransform = staticBatchRoot.transform; } int batchIndex = 0; int num = 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 InternalStaticBatchingUtility.SortGO()); for (int i = 0; i < gos.Length; i++) { GameObject gameObject = gos[i]; MeshFilter meshFilter = gameObject.GetComponent(typeof(MeshFilter)) as MeshFilter; if (!(meshFilter == null)) { Mesh sharedMesh = meshFilter.sharedMesh; if (!(sharedMesh == null) && sharedMesh.canAccess) { Renderer component = meshFilter.GetComponent <Renderer>(); if (!(component == null) && component.enabled) { if (component.staticBatchIndex == 0) { Material[] array = meshFilter.GetComponent <Renderer>().sharedMaterials; if (!array.Any((Material m) => m != null && m.shader != null && m.shader.disableBatching != DisableBatchingType.False)) { if (num + meshFilter.sharedMesh.vertexCount > 64000) { InternalStaticBatchingUtility.MakeBatch(list, list2, list3, staticBatchRootTransform, batchIndex++); list.Clear(); list2.Clear(); list3.Clear(); num = 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(string.Concat(new object[] { "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++) { list2.Add(new MeshSubsetCombineUtility.SubMeshInstance { meshInstanceID = meshFilter.sharedMesh.GetInstanceID(), vertexOffset = num, subMeshIndex = k, gameObjectInstanceID = gameObject.GetInstanceID(), transform = item.transform }); list3.Add(gameObject); } num += sharedMesh.vertexCount; } } } } } } InternalStaticBatchingUtility.MakeBatch(list, list2, list3, staticBatchRootTransform, batchIndex); }
public static void CombineGameObjects(GameObject[] gos, GameObject staticBatchRoot, bool isEditorPostprocessScene) { Matrix4x4 matrix4x4 = Matrix4x4.identity; Transform staticBatchRootTransform = (Transform)null; if ((bool)((Object)staticBatchRoot)) { matrix4x4 = staticBatchRoot.transform.worldToLocalMatrix; staticBatchRootTransform = staticBatchRoot.transform; } int batchIndex = 0; int num = 0; List <MeshSubsetCombineUtility.MeshInstance> meshes = new List <MeshSubsetCombineUtility.MeshInstance>(); List <MeshSubsetCombineUtility.SubMeshInstance> subsets = new List <MeshSubsetCombineUtility.SubMeshInstance>(); List <GameObject> subsetGOs = new List <GameObject>(); Array.Sort((Array)gos, (IComparer) new InternalStaticBatchingUtility.SortGO()); foreach (GameObject go in gos) { MeshFilter component1 = go.GetComponent(typeof(MeshFilter)) as MeshFilter; if (!((Object)component1 == (Object)null)) { Mesh sharedMesh = component1.sharedMesh; if (!((Object)sharedMesh == (Object)null) && (isEditorPostprocessScene || sharedMesh.canAccess)) { Renderer component2 = component1.GetComponent <Renderer>(); if (!((Object)component2 == (Object)null) && component2.enabled && component2.staticBatchIndex == 0) { Material[] materialArray1 = component1.GetComponent <Renderer>().sharedMaterials; if (!((IEnumerable <Material>)materialArray1).Any <Material>((Func <Material, bool>)(m => { if ((Object)m != (Object)null && (Object)m.shader != (Object)null) { return(m.shader.disableBatching != DisableBatchingType.False); } return(false); }))) { int vertexCount = sharedMesh.vertexCount; if (vertexCount != 0) { MeshRenderer meshRenderer = component2 as MeshRenderer; if (!((Object)meshRenderer != (Object)null) || !((Object)meshRenderer.additionalVertexStreams != (Object)null) || vertexCount == meshRenderer.additionalVertexStreams.vertexCount) { if (num + vertexCount > 64000) { InternalStaticBatchingUtility.MakeBatch(meshes, subsets, subsetGOs, staticBatchRootTransform, batchIndex++); meshes.Clear(); subsets.Clear(); subsetGOs.Clear(); num = 0; } MeshSubsetCombineUtility.MeshInstance meshInstance = new MeshSubsetCombineUtility.MeshInstance(); meshInstance.meshInstanceID = sharedMesh.GetInstanceID(); meshInstance.rendererInstanceID = component2.GetInstanceID(); if ((Object)meshRenderer != (Object)null && (Object)meshRenderer.additionalVertexStreams != (Object)null) { meshInstance.additionalVertexStreamsMeshInstanceID = meshRenderer.additionalVertexStreams.GetInstanceID(); } meshInstance.transform = matrix4x4 * component1.transform.localToWorldMatrix; meshInstance.lightmapScaleOffset = component2.lightmapScaleOffset; meshInstance.realtimeLightmapScaleOffset = component2.realtimeLightmapScaleOffset; meshes.Add(meshInstance); if (materialArray1.Length > sharedMesh.subMeshCount) { Debug.LogWarning((object)("Mesh has more materials (" + (object)materialArray1.Length + ") than subsets (" + (object)sharedMesh.subMeshCount + ")"), (Object)component1.GetComponent <Renderer>()); Material[] materialArray2 = new Material[sharedMesh.subMeshCount]; for (int index = 0; index < sharedMesh.subMeshCount; ++index) { materialArray2[index] = component1.GetComponent <Renderer>().sharedMaterials[index]; } component1.GetComponent <Renderer>().sharedMaterials = materialArray2; materialArray1 = materialArray2; } for (int index = 0; index < Math.Min(materialArray1.Length, sharedMesh.subMeshCount); ++index) { subsets.Add(new MeshSubsetCombineUtility.SubMeshInstance() { meshInstanceID = component1.sharedMesh.GetInstanceID(), vertexOffset = num, subMeshIndex = index, gameObjectInstanceID = go.GetInstanceID(), transform = meshInstance.transform }); subsetGOs.Add(go); } num += sharedMesh.vertexCount; } } } } } } } InternalStaticBatchingUtility.MakeBatch(meshes, subsets, subsetGOs, staticBatchRootTransform, batchIndex); }