Exemple #1
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;
            }
        }
Exemple #2
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());
                }
            }
        }