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;
- }
- }
- }
- }
|