| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 | /************************************************************************* *  Copyright © 2018-2023 Liwen All rights reserved. *------------------------------------------------------------------------ *  File         :  LoadPagedLodFromFileManager.cs *  Description  :  Load root tile file and initialize child lod config. *------------------------------------------------------------------------ *  Author       :  Liwen *  Version      :  1.0.0 *  Date         :  1/5/2019 *  Description  :  Initial development version. *************************************************************************/using System.Collections;using System.Collections.Generic;using UnityEngine;using System.IO;using System;using UnityEngine.EventSystems;using UnityEngine.Scripting;using System.Runtime.InteropServices;using System.Runtime.Serialization.Formatters.Binary;namespace AIPagedLod{    [System.Serializable]    public class LoadPagedLodFromFileConfig    {        /////////////////////////////editor parameter///////////////////////        public string mDataName = string.Empty;        public string mDataPath = string.Empty;        public int mStartLevel = -1;        //public int mMeshLayer = -1;        public int mLoadPagedLodCount = 6;        public bool mLoadStartLevelFlag = false;        public int mStartLoadLevel = 17;        public bool mIsDaJiangData = false;        public bool mIsGenerateCollider = false;        /////////////////////////////runtime parameter///////////////////////        public bool mIsUpdate = true;        public string mBaseUrl;    }    public class LoadPagedLodFromFileManager : MonoBehaviour    {        public LoadPagedLodFromFileConfig mConfig = new LoadPagedLodFromFileConfig();        public List<PagedLod> mPagedLodList = null;        public static Vector3 mCameraPosition = Vector3.zero;        private void Start()        {        }        void InitPagedLodList()        {            mPagedLodList = new List<PagedLod>(GetComponentsInChildren<PagedLod>(true));            for (int i = 0; i < mPagedLodList.Count; ++i)            {#if  !UNITY_WEBGL && UNITY_ANDROID                if (PagedLodConfig.mInstance.mTileDataType == TileDataType.B3DM)                {                    mPagedLodList[i].LoadTileSetJsonFile();                }#endif                mPagedLodList[i].mIsRootTile = true;                mPagedLodList[i].RecaculateBounds();                mPagedLodList[i].InitBasicInfoDictFromList();            }        }        public string GetDataPath()        {            if (PagedLodConfig.mInstance != null && PagedLodConfig.mInstance.mDataPathDict.ContainsKey(mConfig.mDataName))            {                return PagedLodConfig.mInstance.mDataPathDict[mConfig.mDataName].mDataPath;            }            string dataPath = mConfig.mDataPath;            if(!Directory.Exists(dataPath)) //数据路径不存在则停止更新            {                mConfig.mIsUpdate = false;            }            return dataPath;        }        void Update()        {            if (mConfig.mIsUpdate)            {                if (mPagedLodList.Count == 0)                {                    InitPagedLodList();                }                UpdatePagedLod(mPagedLodList);            }        }        private void LateUpdate()        {            if (Input.GetKeyDown(KeyCode.Escape))            {                Application.Quit();            }        }        public static int SortLodByDistance(PagedLod left, PagedLod right)        {            if(left.mIsVisiable && right.mIsVisiable)            {                float d1 = Vector3.Distance(left.mWorldCenter, mCameraPosition);                float d2 = Vector3.Distance(right.mWorldCenter, mCameraPosition);                if (d1 < d2)                    return 1;                else if (d1 > d2)                    return -1;                else                    return 0;            }            else            {                //根据是否可见                    if (left.mIsVisiable && !right.mIsVisiable)                    return 1;                else if (!right.mIsVisiable && right.mIsVisiable)                    return -1;                else                    return 0;            }        }        public static void UpdatePagedLod(List<PagedLod> pagedLodList)        {            mCameraPosition = Camera.main.transform.position;            if (!PagedLodUpdateController.IsUpdateEnabled()) return;#if UNITY_WEBGL || UNITY_ANDROID            pagedLodList.Sort(SortLodByDistance);            TraverseUpdateDepthFirst(pagedLodList);#else            PagedLodThreadPool.RunAsync(() =>            {                pagedLodList.Sort(SortLodByDistance);                PagedLodThreadPool.QueueOnMainThread(() =>                {                    TraverseUpdateDepthFirst(pagedLodList);                });            });#endif        }        public static void TraverseUpdateBreadthFirst(List<PagedLod> pagedLodList)        {            Queue<PagedLod> tileQueue = new Queue<PagedLod>();            for (int i = 0; i < pagedLodList.Count; ++i)            {                tileQueue.Enqueue(pagedLodList[i]);            }            while (tileQueue.Count > 0)            {                PagedLod currentTile = tileQueue.Dequeue();                bool isUpdateChild = currentTile.UpdatePagedLod();                if (isUpdateChild)                {                    for (int i = 0; i < currentTile.mChildTileList.Count; ++i)                    {                        PagedLod childPagedLod = currentTile.mChildTileList[i].mPagedLod;                        if (childPagedLod != null)                        {                            tileQueue.Enqueue(childPagedLod);                        }                    }                }            }        }        //深度优先遍历四叉树        public static void TraverseUpdateDepthFirst(List<PagedLod> pagedLodList)        {            Stack<PagedLod> tileStack =new Stack<PagedLod>();            for (int i = 0; i < pagedLodList.Count; ++i)            {                tileStack.Push(pagedLodList[i]);            }            while (tileStack.Count > 0)            {                PagedLod currentTile = tileStack.Pop();                bool isUpdateChild = currentTile.UpdatePagedLod();                if (isUpdateChild)                {                    for (int i = 0; i < currentTile.mChildTileList.Count; ++i)                    {                        PagedLod childPagedLod = currentTile.mChildTileList[i].mPagedLod;                        if (childPagedLod != null)                        {                            tileStack.Push(childPagedLod);                        }                    }                }            }        }        public static int GetTileFileLevel(string tileDirName, string tileFileName)        {            string tileFileBaseName = tileFileName.Replace(PagedLodConfig.mInstance.GetFileSufix(), "");            if (tileFileBaseName == tileDirName) return -1;            string tempTileDirName = tileDirName + "_";            if (tileFileBaseName.Contains(tempTileDirName))            {                string strLevel = tileFileBaseName.Replace(tempTileDirName, "");                strLevel = strLevel.Replace("L", "");                string[] tempArray = strLevel.Split('_');                if (tempArray.Length > 0)                {                    return int.Parse(tempArray[0]);                }            }            return -1;        }        public static int GetDataStartLevel(string dataPath)        {#if !UNITY_WEBGL && !UNITY_ANDROID            if (!Directory.Exists(dataPath)) return 0;            DirectoryInfo dataDir = new DirectoryInfo(dataPath);            List<DirectoryInfo> dirInfos = new List<DirectoryInfo>(dataDir.GetDirectories());            foreach (var tileDir in dirInfos)            {                foreach (var fileInfo in tileDir.GetFiles("*"+ PagedLodConfig.mInstance.GetFileSufix()))                {                    int level = GetTileFileLevel(tileDir.Name, fileInfo.Name);                    if (level > 0)                    {                        return level - 1;                    }                }            }#endif            return -1;        }        //编辑器初始化加载数据        //运行时初始化加载数据        public static PagedLod LoadPagedLod(PagedLodFileLoader loader,Transform parent)        {            GameObject tileObj = new GameObject();            tileObj.name = loader.mTileName;            tileObj.transform.SetParent(parent);            tileObj.transform.localPosition = Vector3.zero;            tileObj.transform.localRotation = Quaternion.identity;            tileObj.transform.localScale = Vector3.one;            PagedLod pagedLod = tileObj.AddComponent<PagedLod>();            pagedLod.mSelfLevel = loader.mLevel;            pagedLod.mTileDirPath = loader.mTileDirPath;            pagedLod.LoadRenderNode(loader);                     return pagedLod;        }        public static void GenerateColliderObject(PagedLod pagedLod)        {            GameObject tileCollider = new GameObject("TileCollider");            tileCollider.transform.SetParent(pagedLod.transform);            tileCollider.transform.localPosition = Vector3.zero;            tileCollider.transform.localRotation = Quaternion.identity;            tileCollider.transform.localScale = Vector3.one;            MeshFilter[] meshFilters = pagedLod.GetComponentsInChildren<MeshFilter>();            for (int i = 0; i < meshFilters.Length; ++i)            {                GameObject meshColliderObj = new GameObject("MeshCollider");                meshColliderObj.transform.SetParent(tileCollider.transform);                meshColliderObj.transform.localPosition = Vector3.zero;                meshColliderObj.transform.localRotation = Quaternion.identity;                meshColliderObj.transform.localScale = Vector3.one;                MeshCollider meshCollider = meshColliderObj.AddComponent<MeshCollider>();                meshCollider.sharedMesh = meshFilters[i].sharedMesh;                meshColliderObj.layer = PagedLodConfig.mInstance == null ? 8 : PagedLodConfig.mInstance.mMeshLayer;            }        }    }}
 |