using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using Unity.HLODSystem.Utils; namespace Unity.HLODSystem { public static partial class CreateUtils { private class MeshRendererCalculator { private bool m_isCalculated = false; private List m_meshSetters = new List(); private List m_meshRenderers = new List(); private List m_lodGroups = new List(); private List m_resultMeshRenderers = new List(); public List ResultMeshRenderers { get { return m_resultMeshRenderers; } } public MeshRendererCalculator(List targetGameObjects) { for (int oi = 0; oi < targetGameObjects.Count; ++oi) { var target = targetGameObjects[oi]; m_meshSetters.AddRange(target.GetComponentsInChildren()); m_meshRenderers.AddRange(target.GetComponentsInChildren()); m_lodGroups.AddRange(target.GetComponentsInChildren()); } RemoveDisabled(m_meshSetters); RemoveDisabled(m_lodGroups); RemoveDisabled(m_meshRenderers); } public void Calculate(float minObjectSize, int level) { if (m_isCalculated == true) return; for (int si = 0; si < m_meshSetters.Count; ++si) { AddResultFromMeshSetters(m_meshSetters[si], minObjectSize, level); } for (int gi = 0; gi < m_lodGroups.Count; ++gi) { LODGroup lodGroup = m_lodGroups[gi]; LOD[] lods = lodGroup.GetLODs(); for (int li = 0; li < lods.Length; ++li) { Renderer[] lodRenderers = lods[li].renderers; //Remove every mesh renderer which is registered to the LODGroup. for (int ri = 0; ri < lodRenderers.Length; ++ri) { MeshRenderer mr = lodRenderers[ri] as MeshRenderer; if (mr == null) continue; m_meshRenderers.Remove(mr); } } AddReusltFromLODGroup(lodGroup, minObjectSize); } for (int mi = 0; mi < m_meshRenderers.Count; ++mi) { MeshRenderer mr = m_meshRenderers[mi]; float max = Mathf.Max(mr.bounds.size.x, mr.bounds.size.y, mr.bounds.size.z); if (max < minObjectSize) continue; m_resultMeshRenderers.Add(mr); } m_isCalculated = true; } private void AddResultFromMeshSetters(HLODMeshSetter setter, float minObjectSize, int level) { var group = setter.FindGroup(level); //If group is null, there is no MeshSetting for current level. if (group == null) return; m_resultMeshRenderers.AddRange(group.MeshRenderers); RemoveUnderMeshSetters(setter); } private void AddReusltFromLODGroup(LODGroup lodGroup, float minObjectSize) { LOD[] lods = lodGroup.GetLODs(); Renderer[] renderers = lods.Last().renderers; for (int ri = 0; ri < renderers.Length; ++ri) { MeshRenderer mr = renderers[ri] as MeshRenderer; if (mr == null) continue; if (mr.gameObject.activeInHierarchy == false || mr.enabled == false) continue; float max = Mathf.Max(mr.bounds.size.x, mr.bounds.size.y, mr.bounds.size.z); if (max < minObjectSize) continue; m_resultMeshRenderers.Add(mr); } } private void RemoveUnderMeshSetters(HLODMeshSetter setter) { m_lodGroups.RemoveAll(setter.GetComponentsInChildren()); m_meshRenderers.RemoveAll(setter.GetComponentsInChildren()); } //enabled is not Component variable. //So we can not make this to Generic function. private void RemoveDisabled(List componentList) { for (int i = 0; i < componentList.Count; ++i) { if (componentList[i].enabled == true && componentList[i].gameObject.activeInHierarchy == true) { continue; } int backIndex = componentList.Count - 1; componentList[i] = componentList[backIndex]; componentList.RemoveAt(backIndex); i -= 1; } } private void RemoveDisabled(List componentList) { for (int i = 0; i < componentList.Count; ++i) { if (componentList[i].enabled == true && componentList[i].gameObject.activeInHierarchy == true) { continue; } int backIndex = componentList.Count - 1; componentList[i] = componentList[backIndex]; componentList.RemoveAt(backIndex); i -= 1; } } private void RemoveDisabled(List componentList) { for (int i = 0; i < componentList.Count; ++i) { if (componentList[i].enabled == true && componentList[i].gameObject.activeInHierarchy == true) { continue; } int backIndex = componentList.Count - 1; componentList[i] = componentList[backIndex]; componentList.RemoveAt(backIndex); i -= 1; } } } public static List GetMeshRenderers(List gameObjects, float minObjectSize, int level) { MeshRendererCalculator calculator = new MeshRendererCalculator(gameObjects); calculator.Calculate(minObjectSize, level); return calculator.ResultMeshRenderers; } public static List GetMeshRenderers(GameObject gameObject, float minObjectSize, int level) { List tmpList = new List(); tmpList.Add(gameObject); MeshRendererCalculator calculator = new MeshRendererCalculator(tmpList); calculator.Calculate(minObjectSize, level); return calculator.ResultMeshRenderers; } } }