示例#1
0
        /// <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;
            }
        }
示例#2
0
 public virtual void OnEnable()
 {
     m_State      = Loadm_State.Unloaded;
     m_ReadyState = Loadm_State.None;
     m_Root       = null;
     m_Data       = null;
     m_Coroutine  = null;
 }
示例#3
0
 //开始加载
 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;
     }
 }
示例#4
0
 //选择卸载或加载队列
 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);
     }
 }
示例#5
0
        /// <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;
            }
        }
示例#6
0
 /*开始加载*/
 public virtual void Load(UnityLODGroupFast data, ChildTreeRoot root)
 {
     //子类实现
 }
示例#7
0
 public virtual void Set(UnityLODGroupFast data, ChildTreeRoot root)
 {
     m_Data = data;
     m_Root = root;
 }
示例#8
0
        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));
                }
            }
        }
示例#9
0
        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;
            }
        }
示例#10
0
 /// <summary>
 ///节点卸载完毕
 /// </summary>
 public void Unloaded(LoadAssetBase loadAsset, UnityLODGroupFast fast)
 {
     s_LoadAssetPool.UnSpawn(loadAsset);
     m_LoadAsset.Remove(fast.GetInstanceID());
     //UnLoadCount++;
 }
示例#11
0
 /// <summary>
 ///节点实例化完毕
 /// </summary>
 public void Instantiated(LoadAssetBase loadAsset, UnityLODGroupFast fast)
 {
     m_LoadCount--;
 }
示例#12
0
        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());
                }
            }
        }