/// Usually rendering with triangle strips is faster. /// However when combining objects with very low triangle counts, it can be faster to use triangles. /// Best is to try out which value is faster in practice. /// This option has a far longer preprocessing time at startup but leads to better runtime performance. public static void CombineMeshFilters(MeshFilter[] mf, Transform t, bool generateTriangleStrips) { MeshFilter[] filters = mf; Matrix4x4 myTransform = t.worldToLocalMatrix; Hashtable materialToMesh= new Hashtable(); for (int i=0;i<filters.Length;i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].GetComponent<Renderer>(); pb_MeshCombineUtility.MeshInstance instance = new pb_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); } } curRenderer.enabled = false; } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; pb_MeshCombineUtility.MeshInstance[] instances = (pb_MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(pb_MeshCombineUtility.MeshInstance)); // We have a maximum of one material, so just attach the mesh to our own game object if (materialToMesh.Count == 1) { // Make sure we have a mesh filter & renderer if (t.GetComponent(typeof(MeshFilter)) == null) t.gameObject.AddComponent(typeof(MeshFilter)); if (!t.GetComponent("MeshRenderer")) t.gameObject.AddComponent<MeshRenderer>(); MeshFilter filter = (MeshFilter)t.GetComponent(typeof(MeshFilter)); filter.mesh = pb_MeshCombineUtility.Combine(instances, generateTriangleStrips); t.GetComponent<Renderer>().material = (Material)de.Key; t.GetComponent<Renderer>().enabled = true; } // We have multiple materials to take care of, build one mesh / gameobject for each material // and parent it to this object else { GameObject go = new GameObject("Combined mesh"); go.transform.parent = t.transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent<MeshRenderer>(); go.GetComponent<Renderer>().material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.mesh = pb_MeshCombineUtility.Combine(instances, generateTriangleStrips); } } }
/// Usually rendering with triangle strips is faster. /// However when combining objects with very low triangle counts, it can be faster to use triangles. /// Best is to try out which value is faster in practice. /// This option has a far longer preprocessing time at startup but leads to better runtime performance. public static void CombineMeshFilters(MeshFilter[] mf, Transform t, bool generateTriangleStrips) { MeshFilter[] filters = mf; Matrix4x4 myTransform = t.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); for (int i = 0; i < filters.Length; i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].GetComponent <Renderer>(); pb_MeshCombineUtility.MeshInstance instance = new pb_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); } } curRenderer.enabled = false; } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; pb_MeshCombineUtility.MeshInstance[] instances = (pb_MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(pb_MeshCombineUtility.MeshInstance)); // We have a maximum of one material, so just attach the mesh to our own game object if (materialToMesh.Count == 1) { // Make sure we have a mesh filter & renderer if (t.GetComponent(typeof(MeshFilter)) == null) { t.gameObject.AddComponent(typeof(MeshFilter)); } if (!t.GetComponent("MeshRenderer")) { t.gameObject.AddComponent <MeshRenderer>(); } MeshFilter filter = (MeshFilter)t.GetComponent(typeof(MeshFilter)); filter.mesh = pb_MeshCombineUtility.Combine(instances, generateTriangleStrips); t.GetComponent <Renderer>().material = (Material)de.Key; t.GetComponent <Renderer>().enabled = true; } // We have multiple materials to take care of, build one mesh / gameobject for each material // and parent it to this object else { GameObject go = new GameObject("Combined mesh"); go.transform.parent = t.transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent <MeshRenderer>(); go.GetComponent <Renderer>().material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.mesh = pb_MeshCombineUtility.Combine(instances, generateTriangleStrips); } } }