/// <summary> ///卸载 /// </summary> public void AddUnLoadAsset(UnityLODGroupFast fast) { int id = fast.GetInstanceID(); LoadAssetBase loadAsset = null; fast.SetEnableApply(); if (!m_LoadAsset.TryGetValue(id, out loadAsset)) { return; } switch (loadAsset.State) { case Loadm_State.Loading: m_LoadCount--; loadAsset.UnLoad(); break; case Loadm_State.Instantiated: if (!m_ImmediateUnLoad) //不等待 { loadAsset.UnLoad(); break; } m_UnLoadCount++; loadAsset.ReadyState = Loadm_State.Unloaded; break; case Loadm_State.Unloaded: case Loadm_State.UnLoading: break; } }
public virtual void OnEnable() { m_State = Loadm_State.Unloaded; m_ReadyState = Loadm_State.None; m_Root = null; m_Data = null; m_Coroutine = null; }
//开始加载 public override void Load(UnityLODGroupFast data, ChildTreeRoot root) { if (m_State == Loadm_State.Unloaded) { m_Data = data; m_Root = root; Addressables.InstantiateAsync(m_Data._assetPath).Completed += OnAssetInstantiated; m_State = Loadm_State.Loading; } else if (m_State == Loadm_State.UnLoading) { m_State = Loadm_State.Loading; } }
//选择卸载或加载队列 static void ChoiceQueue(LODVolume node, UnityLODGroupFast fast) { if (node.childTreeRoot == null) { node.childTreeRoot = node.gameObject.AddComponent <ChildTreeRoot>(); } if (fast.EnabledVirtual) { node.childTreeRoot.AddLoadAsset(fast); } else { node.childTreeRoot.AddUnLoadAsset(fast); } }
/// <summary> ///加载 /// </summary> public void AddLoadAsset(UnityLODGroupFast fast) { int id = fast.GetInstanceID(); LoadAssetBase loadAsset = null; fast.SetEnableApply(); if (!m_LoadAsset.TryGetValue(id, out loadAsset)) { loadAsset = s_LoadAssetPool.Spawn(); m_LoadAsset.Add(id, loadAsset); } //要准备卸载,把状态改变回来 if (loadAsset.ReadyState == Loadm_State.Unloaded) { m_UnLoadCount--; } loadAsset.ReadyState = Loadm_State.None; switch (loadAsset.State) { case Loadm_State.Instantiated: loadAsset.StopCoroutines(); break; case Loadm_State.Loading: break; case Loadm_State.Unloaded: m_LoadCount++; loadAsset.Load(fast, this); break; case Loadm_State.UnLoading: m_LoadCount++; loadAsset.StopCoroutines(); loadAsset.Load(null, null); break; } }
/*开始加载*/ public virtual void Load(UnityLODGroupFast data, ChildTreeRoot root) { //子类实现 }
public virtual void Set(UnityLODGroupFast data, ChildTreeRoot root) { m_Data = data; m_Root = root; }
public IEnumerator AddLodGroup(UnityLODGroupFast lodGroup) { if (!this) { yield break; } if (!lodGroup) { yield break; } if (lodGroups.Count == 0 && Mathf.Approximately(bounds.size.magnitude, 0f)) { Renderer[] rds = lodGroup.GetLODs()[0].renderers; var targetBounds = bounds; foreach (var r in rds) { targetBounds.Encapsulate(r.bounds); } bounds = GetCuboidBounds(targetBounds); transform.position = bounds.min; } // Each LODVolume maintains it's own list of renderers, which includes renderers in children nodes if (WithinBounds(lodGroup._lodGroup, bounds)) { var lodGroupsRef = lodGroups.Select(l => l._lodGroup); if (!lodGroupsRef.Contains(lodGroup._lodGroup)) { lodGroups.Add(lodGroup); } /*当自己维护的节点大于k_VolumeSplitRendererCount个时,就开始分割子节点*/ if (transform.childCount == 0) { if (GetRenderersCount() > m_CurrHLODGenerate.m_BVHDivide.m_VolumeSplitRendererCount) { yield return(SplitLodGroup()); } else { yield return(SetDirty()); } } else { foreach (Transform child in transform) { if (!lodGroup) { yield break; } var lodVolume = child.GetComponent <LODVolume>(); if (WithinBounds(lodGroup._lodGroup, lodVolume.bounds)) { yield return(lodVolume.AddLodGroup(lodGroup)); break; } yield return(null); } } } else if (!transform.parent || !transform.parent.GetComponent <LODVolume>()) { if (transform.childCount == 0 && lodGroups.Count < m_CurrHLODGenerate.m_BVHDivide.m_VolumeSplitRendererCount) { bounds.Encapsulate(lodGroup.bounds); bounds = GetCuboidBounds(bounds); var lodGroupsRef = lodGroups.Select(l => l._lodGroup); if (!lodGroupsRef.Contains(lodGroup._lodGroup)) { lodGroups.Add(lodGroup); } yield return(SetDirty()); } else { // Expand and then try to add at the larger bounds var targetBounds = bounds; targetBounds.Encapsulate(lodGroup.bounds); targetBounds = GetCuboidBounds(targetBounds); yield return(Grow(targetBounds)); yield return(transform.parent.GetComponent <LODVolume>().AddLodGroup(lodGroup)); } } }
public IEnumerator GenerateHLODInstancing(bool propagateUpwards = true, int treeHeight = 2, GameObject hlods = null) { if (ChildDeep() <= treeHeight) { HashSet <Renderer> hlodRenderers = new HashSet <Renderer>(); Renderer[] renderers = GetAllRendererByLodGroups(); foreach (var r in renderers) { var mr = r as MeshRenderer; if (mr) { //hlodRenderers.Add(mr); // Use the coarsest LOD if it exists var mrLODGroup = mr.GetComponentInParent <LODGroup>(); if (mrLODGroup) { var mrLODs = mrLODGroup.GetLODs(); var maxLOD = mrLODGroup.lodCount - 1; var mrLOD = mrLODs[maxLOD]; foreach (var lr in mrLOD.renderers) { if (lr && lr.GetComponent <MeshFilter>()) { hlodRenderers.Add(lr); } } } else if (mr.GetComponent <MeshFilter>()) { hlodRenderers.Add(mr); } } yield return(null); } var lodRenderers = new List <Renderer>(); CleanupHLOD(); GameObject hlodRoot = new GameObject(transform.name); hlodRoot.transform.parent = hlods.transform; var parent = hlodRoot.transform; foreach (var r in hlodRenderers) { var rendererTransform = r.transform; var child = new GameObject(r.name, typeof(MeshFilter), typeof(MeshRenderer)); var childTransform = child.transform; childTransform.SetPositionAndRotation(rendererTransform.position, rendererTransform.rotation); childTransform.localScale = rendererTransform.lossyScale; childTransform.SetParent(parent, true); var mr = child.GetComponent <MeshRenderer>(); EditorUtility.CopySerialized(r.GetComponent <MeshFilter>(), child.GetComponent <MeshFilter>()); EditorUtility.CopySerialized(r.GetComponent <MeshRenderer>(), mr); lodRenderers.Add(mr); } LOD lod = new LOD(); var lodGroup = hlodRoot.GetComponent <LODGroup>(); if (!lodGroup) { lodGroup = hlodRoot.AddComponent <LODGroup>(); } lodGroup.enabled = false; UnityLODGroupFast lodGroupFast = ScriptableObject.CreateInstance <UnityLODGroupFast>(); lodGroupFast.Init(lodGroup, hlodRoot); this.combined = lodGroupFast; EditorUtility.DisplayProgressBar("合并网格和贴图", name, 0.8f); var batcher = (IBatcher)Activator.CreateInstance(ObjectUtils.batcherType); yield return(batcher.Batch(m_CurrHLODGenerate, this)); lod.renderers = hlodRoot.GetComponentsInChildren <Renderer>(false); lodGroup.SetLODs(new LOD[] { lod }); //lodGroup.size += 5;//lod屏幕占比偏差 if (propagateUpwards) { var lodVolumeParent = transform.parent; var parentLODVolume = lodVolumeParent ? lodVolumeParent.GetComponentInParent <LODVolume>() : null; if (parentLODVolume) { yield return(parentLODVolume.GenerateHLODInstancing()); } } hlodRoot.GetComponent <MeshRenderer>().enabled = false; } }
/// <summary> ///节点卸载完毕 /// </summary> public void Unloaded(LoadAssetBase loadAsset, UnityLODGroupFast fast) { s_LoadAssetPool.UnSpawn(loadAsset); m_LoadAsset.Remove(fast.GetInstanceID()); //UnLoadCount++; }
/// <summary> ///节点实例化完毕 /// </summary> public void Instantiated(LoadAssetBase loadAsset, UnityLODGroupFast fast) { m_LoadCount--; }
IEnumerator UpdateOctreeByLodGroup(GameObject[] gameObjects = null) { if (gameObjects == null || gameObjects.Count() < 1) { yield break; } if (!m_RootVolume) { if (m_CreateRootVolumeForScene == SceneManager.GetActiveScene().name) { #if UNITY_EDITOR m_RootVolume = LODVolume.Create(m_CurrHLODGenerate); #endif } else { yield break; } } var lodGroups = m_FoundLODGroups; lodGroups.Clear(); foreach (var objRoot in gameObjects) { LODGroup [] childGroups = objRoot.GetComponentsInChildren <LODGroup>(); lodGroups.AddRange(childGroups); } // Remove any renderers that should not be there (e.g. HLODs) lodGroups.RemoveAll(r => m_ExcludedLODGroups.Contains(r) ); lodGroups.RemoveAll(l => { if (l) { // Check against previous collection if (m_ExcludedLODGroups.Contains(l)) { return(false); } var rds = l.GetLODs()[0].renderers; foreach (var r in rds) { if (r == null) { return(false); } var mf = r.GetComponent <MeshFilter>(); if (!mf || (mf.sharedMesh && mf.sharedMesh.GetTopology(0) != MeshTopology.Triangles)) { m_ExcludedLODGroups.Add(l); return(true); } #if UNITY_EDITOR //根据包围盒直径进行剔除不需要计算的模型 if (m_CurrHLODGenerate.m_BVHDivide.m_Cull) { bool result = m_CurrHLODGenerate.m_BVHDivide.CullByMesh(r.transform); if (result) { m_ExcludedLODGroups.Add(l); return(true); } } #endif } } return(false); }); var existingLODGroups = m_ExistingLODGroups; existingLODGroups.Clear(); existingLODGroups.UnionWith(m_RootVolume.lodGroups.Select(l => l._lodGroup)); var removed = m_RemovedLODGroups; removed.Clear(); removed.UnionWith(m_ExistingLODGroups); removed.ExceptWith(lodGroups); var added = m_AddedLODGroups; added.Clear(); added.UnionWith(lodGroups); added.ExceptWith(existingLODGroups); int count = 1; foreach (var l in removed) { if (existingLODGroups.Contains(l)) { #if UNITY_EDITOR yield return(m_RootVolume.RemoveLodGroup(l)); #endif // Check if the BVH shrunk yield return(SetRootLODVolume()); } } count = 1; foreach (var l in added) { EditorUtility.DisplayProgressBar("网格划分", l.name, (float)count++ / added.Count); if (!existingLODGroups.Contains(l)) { UnityLODGroupFast lodGroupFast = CreateInstance <UnityLODGroupFast>(); #if UNITY_EDITOR lodGroupFast.Init(l, l.gameObject); //UnityLODGroupFast lodGroupFast = new UnityLODGroupFast(l, l.gameObject); yield return(m_RootVolume.AddLodGroup(lodGroupFast)); #endif l.transform.hasChanged = false; // Check if the BVH grew yield return(SetRootLODVolume()); } } }