PagedLod.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. /*************************************************************************
  2. * Copyright © 2018-2023 Liwen All rights reserved.
  3. *------------------------------------------------------------------------
  4. * File : PagedLod.cs
  5. * Description : update lod with cameradistance
  6. *------------------------------------------------------------------------
  7. * Author : Liwen
  8. * Version : 1.0.0
  9. * Date : 1/5/2019
  10. * Description : Initial development version.
  11. *************************************************************************/
  12. using System.Collections;
  13. using System.Collections.Generic;
  14. using UnityEngine;
  15. using System.IO;
  16. using System.Runtime.InteropServices;
  17. using System;
  18. using System.Text;
  19. using System.Text.RegularExpressions;
  20. using LitJson;
  21. namespace AIPagedLod
  22. {
  23. [System.Serializable]
  24. public class PagedLodInfo
  25. {
  26. public string mFileName = string.Empty;
  27. public PagedLod mPagedLod = null;
  28. public bool mIsBasicInfoLoaded = false;
  29. public bool mIsDownloaded = false;
  30. public PagedLodRangeInfo mRangeValue = new PagedLodRangeInfo();
  31. }
  32. public class PagedLodLoaderInfo
  33. {
  34. public int mIndex = 0;
  35. public PagedLodFileLoader mLoader = null;
  36. }
  37. [System.Serializable]
  38. public class B3dmBasicInfo
  39. {
  40. public Vector3 mCenter;
  41. public Vector3 mExtents;
  42. public float mGeometricError;
  43. public string mContent;
  44. public Bounds mBounds;
  45. public List<B3dmBasicInfo> mChildrenList = new List<B3dmBasicInfo>();
  46. }
  47. public class PagedLod : MonoBehaviour
  48. {
  49. public List<PagedLodInfo> mChildTileList = new List<PagedLodInfo>();
  50. //初始化加载时赋值
  51. public int mSelfLevel = 0;
  52. public bool mIsRootTile = false;
  53. public string mTileDirPath;
  54. //osgb文件属性
  55. public float mPixelValue;
  56. public float mLoadChildPixelValue;
  57. //固有基本属性
  58. public float mOsgbBoundRadius; //缩放变化后需要重新求取,osgb库中求得,暂时不用
  59. public Bounds mOsgbBounds;
  60. //根据固有属性计算
  61. public Vector3 mWorldCenter = Vector3.zero; //相对于父节点的局部中心坐标,仅在根节点中使用,位置变化后需要重新求取
  62. public List<Vector3> mBoundsVertexList = new List<Vector3>();//位置及缩放变化后需要重新求取
  63. public List<MeshRenderer> mMeshRenderers = new List<MeshRenderer>(); //根节点拥有,用于计算瓦片是否可见
  64. public GameObject mRenderNode = null;
  65. public bool mIsRenderNodeLoaded = false;
  66. public bool mIsRenderNodeMeshLoaded = false;//Mesh网格节点是否加载
  67. //每帧计算
  68. public bool mIsVisiable = true;
  69. private int mVisiableFrameNumber = 0;
  70. private int mInRangeFrameNumber = 0;
  71. private LoadPagedLodFromFileManager mManager = null;
  72. private Camera mMainCamera = null;
  73. //b3dm专有
  74. public PagedLod mRootPagedLod = null;
  75. public Dictionary<string, B3dmBasicInfo> mBasicInfoDict = new Dictionary<string, B3dmBasicInfo>();//根节点拥有
  76. public List<B3dmBasicInfo> mBasicInfoList = new List<B3dmBasicInfo>();//根节点拥有
  77. public B3dmBasicInfo mBasicInfo = new B3dmBasicInfo();
  78. public float mScreenSpaceError = 0.0f;
  79. public static int mMaxLoadLevel = 0;
  80. private LoadPagedLodFromFileManager GetLodManager()
  81. {
  82. if (mManager == null)
  83. {
  84. mManager = transform.GetComponentInParent<LoadPagedLodFromFileManager>();
  85. }
  86. return mManager;
  87. }
  88. string GetDataPath()
  89. {
  90. return GetLodManager().GetDataPath() + "\\" + mTileDirPath;
  91. }
  92. public void InitBasicInfoDictFromList()
  93. {
  94. if (mBasicInfoDict.Count == 0)
  95. {
  96. for (int i = 0; i < mBasicInfoList.Count; ++i)
  97. {
  98. mBasicInfoDict.Add(mBasicInfoList[i].mContent, mBasicInfoList[i]);
  99. }
  100. }
  101. }
  102. void ResetLod()
  103. {
  104. mChildTileList.Clear();
  105. mMeshRenderers.Clear();
  106. mVisiableFrameNumber = 0;
  107. mInRangeFrameNumber = 0;
  108. mSelfLevel = 0;
  109. mManager = null;
  110. mRootPagedLod = null;
  111. mBasicInfoDict.Clear();
  112. mIsRenderNodeLoaded = false;
  113. mIsRenderNodeMeshLoaded = false;
  114. }
  115. #region UpdateTileVisiableStatus-----------------------
  116. void UpdateTileVisiableStatus()
  117. {
  118. mIsVisiable = true;
  119. if (mIsRootTile)
  120. {
  121. GetTileVisiableStatus();
  122. }
  123. }
  124. void GetTileVisiableStatus()
  125. {
  126. if (mMeshRenderers.Count == 0)
  127. {
  128. mIsVisiable = true;
  129. return;
  130. }
  131. if (mMainCamera == null) mMainCamera = Camera.main;
  132. Plane[] planes = GeometryUtility.CalculateFrustumPlanes(mMainCamera);
  133. for (int i = 0; i < mMeshRenderers.Count; ++i)
  134. {
  135. if (GeometryUtility.TestPlanesAABB(planes, mMeshRenderers[i].bounds))
  136. {
  137. mIsVisiable = true;
  138. return;
  139. }
  140. }
  141. mIsVisiable = false;
  142. }
  143. void UpdateInvisiableTiles()
  144. {
  145. if (!mRenderNode.activeSelf)
  146. mRenderNode.SetActive(true);
  147. if (!mIsRenderNodeLoaded)
  148. {
  149. LoadTileRenderNode();
  150. }
  151. if (Time.frameCount - mVisiableFrameNumber > PagedLodConfig.mInstance.mExpiryFrames)
  152. {
  153. if (mChildTileList.Count != 0 && mChildTileList[0].mPagedLod != null)
  154. {
  155. CollectChildTiles();
  156. }
  157. }
  158. else
  159. {
  160. if (mChildTileList.Count != 0 && mChildTileList[0].mPagedLod != null && mChildTileList[0].mPagedLod.gameObject.activeSelf)
  161. {
  162. SetChildTilesActive(false);
  163. }
  164. }
  165. }
  166. #endregion UpdateTileVisiableStatus
  167. #region CollectChildTiles-----------------------------
  168. public void CollectChildTiles()
  169. {
  170. for (int i = 0; i < mChildTileList.Count; ++i)
  171. {
  172. PagedLod childLod = mChildTileList[i].mPagedLod;
  173. if (childLod != null)
  174. {
  175. PagedLod[] childPagedlods = childLod.transform.GetComponentsInChildren<PagedLod>(true);
  176. for (int j = 0; j < childPagedlods.Length; ++j)
  177. {
  178. #if UNITY_WEBGL
  179. GameObject.Destroy(childPagedlods[j].gameObject);
  180. PagedLodConfig.mInstance.mCollectCount++;
  181. #else
  182. childPagedlods[j].ResetLod();
  183. MeshRenderer[] renderers = childPagedlods[j].gameObject.GetComponentsInChildren<MeshRenderer>(true);
  184. for (int m = 0; m < renderers.Length; ++m)
  185. {
  186. MeshPool.mInstance.PushMeshObject(renderers[m].gameObject);
  187. }
  188. TileObjectPool.mInstance.PushTileObject(childPagedlods[j].gameObject);
  189. #endif
  190. }
  191. }
  192. mChildTileList[i].mPagedLod = null;
  193. mChildTileList[i].mIsBasicInfoLoaded = false;
  194. #if UNITY_WEBGL
  195. if (PagedLodConfig.mInstance.mCollectCount >= 100)
  196. {
  197. StartCoroutine(DestoryTiles());
  198. PagedLodConfig.mInstance.mCollectCount = 0;
  199. //Debug.Log("-------------------UnloadUnusedAssets");
  200. }
  201. #endif
  202. }
  203. }
  204. IEnumerator DestoryTiles()
  205. {
  206. yield return new WaitForSeconds(0.1f);
  207. Resources.UnloadUnusedAssets();//卸载未占用的asset资源
  208. System.GC.Collect();//回收内存
  209. }
  210. #endregion
  211. public bool UpdatePagedLod()
  212. {
  213. mMaxLoadLevel = (int)MathF.Max(mMaxLoadLevel,mSelfLevel);
  214. //RecaculateBounds();
  215. UpdateTileVisiableStatus();
  216. if (!mIsVisiable) //不可见,则回收瓦片
  217. {
  218. UpdateInvisiableTiles();
  219. return false;
  220. }
  221. else
  222. {
  223. mVisiableFrameNumber = Time.frameCount;
  224. bool isLoadChildTile = false;
  225. if (PagedLodConfig.mInstance.mTileDataType == TileDataType.OSGB)
  226. {
  227. mPixelValue = GetPixelValue();//瓦片所占像素大小
  228. isLoadChildTile = mPixelValue > mLoadChildPixelValue;
  229. }
  230. else
  231. {
  232. mScreenSpaceError = GetScreenSpaceError();
  233. isLoadChildTile = mScreenSpaceError > PagedLodConfig.mInstance.mMaxSSE;
  234. }
  235. if (isLoadChildTile)
  236. {
  237. #if UNITY_WEBGL || UNITY_ANDROID
  238. LoadChildTilePagedLodFromUrl();
  239. #else
  240. if (PagedLodConfig.mInstance.mIsLoadFromUrl)
  241. LoadChildTilePagedLodFromUrl();
  242. else
  243. LoadChildTilePagedLod();
  244. #endif
  245. if (mRenderNode != null )
  246. {
  247. if (mRenderNode.activeSelf)
  248. {
  249. if(IsChildTilesLoaded())
  250. {
  251. mRenderNode.SetActive(false);
  252. }
  253. }
  254. //else
  255. //{
  256. // mRenderNode.SetActive(true);
  257. //}
  258. }
  259. return true;
  260. }
  261. else //回收子瓦片
  262. {
  263. UpdateCollectChildTiles();
  264. return false;
  265. }
  266. }
  267. }
  268. #region LoadB3dmFile--------------------------------------
  269. void LoadSelfRenderNodeFromUrl()
  270. {
  271. if (DownloadFileManager.mInstance.CanDownload())
  272. {
  273. mIsRenderNodeLoaded = true;
  274. DownloadFileManager.mInstance.StartDownloadTileFile(this,GetLodManager().mConfig.mBaseUrl);
  275. }
  276. }
  277. void LoadChildTilePagedLodFromUrl()
  278. {
  279. if (!DownloadFileManager.mInstance.CanDownload()) return;
  280. for (int i = 0; i < mChildTileList.Count; ++i)
  281. {
  282. if (mChildTileList[i].mPagedLod != null)
  283. {
  284. mChildTileList[i].mPagedLod.gameObject.SetActive(true);
  285. }
  286. else
  287. {
  288. if (!mChildTileList[i].mIsBasicInfoLoaded)
  289. {
  290. PagedLodInfo pagedLodInfo = mChildTileList[i];
  291. B3dmFileLoader pagedLodLoader = new B3dmFileLoader();
  292. pagedLodLoader.mTileName = pagedLodInfo.mFileName.Replace(PagedLodConfig.mInstance.GetFileSufix(), "");
  293. pagedLodInfo.mIsBasicInfoLoaded = true;
  294. LoadTilePagedLod(pagedLodInfo, pagedLodLoader);
  295. break;
  296. }
  297. }
  298. }
  299. }
  300. #endregion LoadB3dmFile
  301. #region LoadSelfRenderNode--------------------------------------
  302. void UpdateCollectChildTiles()
  303. {
  304. if (!mIsRenderNodeLoaded)
  305. {
  306. LoadTileRenderNode();
  307. }
  308. else
  309. {
  310. if (mRenderNode != null && !mRenderNode.activeSelf)
  311. {
  312. mRenderNode.SetActive(true);
  313. }
  314. }
  315. //if (mIsRenderNodeLoaded && mRenderNode != null && mRenderNode.activeSelf)
  316. if (mIsRenderNodeMeshLoaded)
  317. {
  318. if (Time.frameCount - mInRangeFrameNumber > PagedLodConfig.mInstance.mExpiryFrames)
  319. {
  320. CollectChildTiles();
  321. }
  322. else
  323. {
  324. SetChildTilesActive(false);
  325. }
  326. }
  327. }
  328. void LoadTileRenderNode()
  329. {
  330. #if UNITY_WEBGL || UNITY_ANDROID
  331. LoadSelfRenderNodeFromUrl();
  332. #else
  333. if (PagedLodConfig.mInstance.mIsLoadFromUrl)
  334. LoadSelfRenderNodeFromUrl();
  335. else
  336. LoadSelfRenderNode();
  337. #endif
  338. }
  339. PagedLodFileLoader GetSelfRenderNodeLoader()
  340. {
  341. PagedLodFileLoader pagedLodLoader = null;
  342. string fileFullPath = GetDataPath() + "/" + gameObject.name + PagedLodConfig.mInstance.GetFileSufix();
  343. fileFullPath = System.Text.RegularExpressions.Regex.Replace(fileFullPath, @"\p{C}+", "");
  344. if (File.Exists(fileFullPath))
  345. {
  346. pagedLodLoader = PagedLodFileLoader.GetFileLoader(fileFullPath);
  347. pagedLodLoader.mIsDaJiangData = GetLodManager().mConfig.mIsDaJiangData;
  348. }
  349. return pagedLodLoader;
  350. }
  351. void LoadSelfRenderNode()
  352. {
  353. if (!PagedLodThreadPool.IsQueueWorkItem()) return;
  354. PagedLodFileLoader pagedLodLoader = GetSelfRenderNodeLoader();
  355. if (pagedLodLoader == null) return;
  356. mIsRenderNodeLoaded = true;
  357. PagedLod targetPagedLod = this;
  358. PagedLodThreadPool.RunAsync(() =>
  359. {
  360. pagedLodLoader.LoadObjectMeshInfo();
  361. PagedLodThreadPool.QueueOnMainThread(() =>
  362. {
  363. if (GetLodManager() != null)
  364. {
  365. if (targetPagedLod != null)
  366. {
  367. LoadTileAsyncManager.mInstance.StartLoadRenderNode(targetPagedLod, pagedLodLoader);
  368. }
  369. else
  370. {
  371. Debug.Log("targetPagedLod is null ************* ");
  372. }
  373. }
  374. else
  375. {
  376. pagedLodLoader.Dispose();
  377. pagedLodLoader = null;
  378. }
  379. });
  380. });
  381. }
  382. #endregion
  383. #region LoadChildTilePagedLod------------------------------------
  384. List<PagedLodLoaderInfo> GetNeedLoadChildTile()
  385. {
  386. List<PagedLodLoaderInfo> loaderList = new List<PagedLodLoaderInfo>();
  387. for (int i = 0; i < mChildTileList.Count; ++i)
  388. {
  389. if (mChildTileList[i].mPagedLod != null)
  390. {
  391. mChildTileList[i].mPagedLod.gameObject.SetActive(true);
  392. }
  393. else
  394. {
  395. if (!mChildTileList[i].mIsBasicInfoLoaded)
  396. {
  397. PagedLodInfo pagedLodInfo = mChildTileList[i];
  398. string fileFullPath = GetDataPath() + "/" + mChildTileList[i].mFileName;
  399. fileFullPath = System.Text.RegularExpressions.Regex.Replace(fileFullPath, @"\p{C}+", "");
  400. if (File.Exists(fileFullPath))
  401. {
  402. PagedLodLoaderInfo info = new PagedLodLoaderInfo();
  403. PagedLodFileLoader pagedLodLoader = PagedLodFileLoader.GetFileLoader(fileFullPath);
  404. pagedLodLoader.mIsDaJiangData = GetLodManager().mConfig.mIsDaJiangData;
  405. FileInfo fileInfo = new FileInfo(pagedLodLoader.mFileName);
  406. pagedLodLoader.mTileName = fileInfo.Name.Replace(PagedLodConfig.mInstance.GetFileSufix(), "");
  407. pagedLodInfo.mIsBasicInfoLoaded = true;
  408. info.mLoader = pagedLodLoader;
  409. info.mIndex = i;
  410. loaderList.Add(info);
  411. }
  412. }
  413. }
  414. }
  415. return loaderList;
  416. }
  417. void LoadChildTilePagedLod()
  418. {
  419. if (!PagedLodThreadPool.IsQueueWorkItem()) return;
  420. List<PagedLodLoaderInfo> loaderList = GetNeedLoadChildTile();
  421. PagedLod targetPagedLod = this;
  422. PagedLodThreadPool.RunAsync(() =>
  423. {
  424. for (int i = 0; i < loaderList.Count; ++i)
  425. {
  426. if (loaderList[i].mLoader != null)
  427. {
  428. loaderList[i].mLoader.LoadObjectBasicInfo();
  429. }
  430. }
  431. PagedLodThreadPool.QueueOnMainThread(() =>
  432. {
  433. if (GetLodManager() != null && targetPagedLod != null)
  434. {
  435. for (int i = 0; i < loaderList.Count; ++i)
  436. {
  437. if (loaderList[i].mLoader != null)
  438. {
  439. LoadTileAsyncManager.mInstance.StartLoadChildTile(targetPagedLod,
  440. loaderList[i].mLoader, mChildTileList[loaderList[i].mIndex]);
  441. }
  442. }
  443. }
  444. else
  445. {
  446. for (int i = 0; i < loaderList.Count; ++i)
  447. {
  448. if (loaderList[i].mLoader != null)
  449. {
  450. loaderList[i].mLoader.Dispose();
  451. loaderList[i].mLoader = null;
  452. }
  453. }
  454. }
  455. });
  456. });
  457. }
  458. #endregion
  459. //运行时调用
  460. public void LoadTilePagedLod(PagedLodInfo info, PagedLodFileLoader pagedLodLoader)
  461. {
  462. GameObject tileObj = TileObjectPool.mInstance.GetTileObject();
  463. PagedLod pagedLod = null;
  464. if (tileObj == null)
  465. {
  466. tileObj = new GameObject();
  467. pagedLod = tileObj.AddComponent<PagedLod>();
  468. }
  469. else
  470. {
  471. tileObj.SetActive(true);
  472. pagedLod = tileObj.GetComponent<PagedLod>();
  473. }
  474. info.mPagedLod = pagedLod;
  475. tileObj.name = pagedLodLoader.mTileName;
  476. tileObj.transform.SetParent(transform);
  477. tileObj.transform.localPosition = Vector3.zero;
  478. tileObj.transform.localRotation = Quaternion.identity;
  479. tileObj.transform.localScale = Vector3.one;
  480. pagedLod.mSelfLevel = mSelfLevel + 1;
  481. pagedLod.mTileDirPath = mTileDirPath;
  482. if(mIsRootTile)
  483. {
  484. pagedLod.mRootPagedLod = this;
  485. }
  486. else
  487. {
  488. pagedLod.mRootPagedLod = mRootPagedLod;
  489. }
  490. if(PagedLodConfig.mInstance.mTileDataType == TileDataType.OSGB)
  491. {
  492. pagedLod.LoadOsgbBasicInfo(pagedLodLoader);
  493. }
  494. else
  495. {
  496. pagedLod.mBasicInfo = pagedLod.mRootPagedLod.GetTileBasicInfo(tileObj.name);
  497. pagedLod.LoadB3dmBasicInfo(pagedLodLoader);
  498. }
  499. }
  500. public void LoadOsgbBasicInfo(PagedLodFileLoader pagedLodLoader)
  501. {
  502. OsgbFileLoader osgbFileLoader = pagedLodLoader as OsgbFileLoader;
  503. Vector3 center = GetLodManager().transform.TransformPoint(osgbFileLoader.mBoundsCenter);
  504. Vector3 min = GetLodManager().transform.TransformPoint(osgbFileLoader.mBoundsBoxMin);
  505. Vector3 max = GetLodManager().transform.TransformPoint(osgbFileLoader.mBoundsBoxMax);
  506. mOsgbBoundRadius = osgbFileLoader.mBoundRadius;
  507. mOsgbBounds.min = min;
  508. mOsgbBounds.max = max;
  509. //mWorldCenter = new Vector3(center.x, -center.y, center.z);
  510. mWorldCenter = new Vector3(center.x, -center.z, -center.y);
  511. InitOsgbChildFiles(this, pagedLodLoader);
  512. GetBoundsVertexList();
  513. }
  514. public void LoadB3dmBasicInfo(PagedLodFileLoader pagedLodLoader)
  515. {
  516. mOsgbBounds = mBasicInfo.mBounds;
  517. mWorldCenter = GetLodManager().transform.TransformPoint(mOsgbBounds.center);
  518. mOsgbBoundRadius = mOsgbBounds.extents.magnitude;
  519. InitB3dmChildFiles(this, pagedLodLoader);
  520. GetBoundsVertexList();
  521. }
  522. public void RecaculateBounds()
  523. {
  524. Vector3 center = Vector3.zero;
  525. if (mMeshRenderers.Count != 0)
  526. {
  527. Bounds bounds = new Bounds(center, Vector3.zero);
  528. foreach (Renderer mr in mMeshRenderers)
  529. {
  530. if (bounds.size == Vector3.zero)
  531. {
  532. bounds = mr.bounds;
  533. }
  534. else
  535. {
  536. bounds.Encapsulate(mr.bounds);
  537. }
  538. }
  539. mOsgbBounds = bounds;
  540. mOsgbBoundRadius = Vector3.Distance(bounds.center, bounds.max);
  541. mWorldCenter = bounds.center;
  542. GetBoundsVertexList();
  543. }
  544. }
  545. private void InitOsgbChildFiles(PagedLod pagedLod, PagedLodFileLoader pagedLodLoader)
  546. {
  547. OsgbFileLoader osgbFileLoader = pagedLodLoader as OsgbFileLoader;
  548. pagedLod.mChildTileList.Clear();
  549. float minPixelValue = float.MaxValue;
  550. for (int i = 0; i < osgbFileLoader.mChildFiles.Count; ++i)
  551. {
  552. PagedLodInfo info = new PagedLodInfo();
  553. string fileFullPath = pagedLod.GetDataPath() + "\\" + osgbFileLoader.mChildFiles[i];
  554. fileFullPath = System.Text.RegularExpressions.Regex.Replace(fileFullPath, @"\p{C}+", "");
  555. info.mFileName = osgbFileLoader.mChildFiles[i];
  556. info.mRangeValue = osgbFileLoader.mChildRangeValues[i];
  557. pagedLod.mChildTileList.Add(info);
  558. minPixelValue = Mathf.Min(minPixelValue, info.mRangeValue.mChildMinValue);
  559. }
  560. pagedLod.mLoadChildPixelValue = minPixelValue;
  561. }
  562. private void InitB3dmChildFiles(PagedLod pagedLod, PagedLodFileLoader pagedLodLoader)
  563. {
  564. pagedLod.mChildTileList.Clear();
  565. for (int i = 0; i < pagedLod.mBasicInfo.mChildrenList.Count; ++i)
  566. {
  567. B3dmBasicInfo childBasicInfo = pagedLod.mBasicInfo.mChildrenList[i];
  568. PagedLodInfo info = new PagedLodInfo();
  569. info.mFileName = childBasicInfo.mContent + PagedLodConfig.mInstance.GetFileSufix();
  570. pagedLod.mChildTileList.Add(info);
  571. }
  572. }
  573. public void LoadRenderNode(PagedLodFileLoader pagedLodLoader)
  574. {
  575. if (mRenderNode == null)
  576. {
  577. mRenderNode = new GameObject("RenderNode");
  578. mRenderNode.transform.SetParent(transform);
  579. mRenderNode.transform.localPosition = Vector3.zero;
  580. mRenderNode.transform.localRotation = Quaternion.identity;
  581. mRenderNode.transform.localScale = Vector3.one;
  582. }
  583. else
  584. {
  585. mRenderNode.SetActive(true);
  586. }
  587. pagedLodLoader.BuildObjectForThread(mRenderNode);
  588. transform.localScale = Vector3.one;
  589. mIsRenderNodeMeshLoaded = true;
  590. GetMeshRenders();
  591. RecaculateBounds();
  592. }
  593. public void GetMeshRenders()
  594. {
  595. mMeshRenderers = new List<MeshRenderer>(gameObject.GetComponentsInChildren<MeshRenderer>());
  596. }
  597. public void GetBoundsVertexList()
  598. {
  599. Vector3 center = mWorldCenter;
  600. var targetBoundsExtents = mOsgbBounds.extents; //得到目标物包围盒范围:extents
  601. List<Vector3> vertexList = new List<Vector3>();
  602. float x = targetBoundsExtents.x;
  603. float y = targetBoundsExtents.y;
  604. float z = targetBoundsExtents.z;
  605. vertexList.Add(center);
  606. vertexList.Add(center + new Vector3(x, y, z));
  607. vertexList.Add(center + new Vector3(x, -y, z));
  608. vertexList.Add(center + new Vector3(x, y, -z));
  609. vertexList.Add(center + new Vector3(x, -y, -z));
  610. vertexList.Add(center + new Vector3(-x, y, z));
  611. vertexList.Add(center + new Vector3(-x, -y, z));
  612. vertexList.Add(center + new Vector3(-x, y, -z));
  613. vertexList.Add(center + new Vector3(-x, -y, -z));
  614. mBoundsVertexList = vertexList;
  615. }
  616. public bool IsChildTilesLoaded()
  617. {
  618. if (mIsVisiable)
  619. {
  620. for (int i = 0; i < mChildTileList.Count; ++i)
  621. {
  622. if (mChildTileList[i].mPagedLod != null)
  623. {
  624. if (!mChildTileList[i].mPagedLod.gameObject.activeSelf) return false;
  625. bool flag = mChildTileList[i].mPagedLod.IsRenderNodeLoaded();
  626. if (!flag)
  627. {
  628. return false;
  629. }
  630. }
  631. else
  632. {
  633. return false;
  634. }
  635. }
  636. }
  637. return true;
  638. }
  639. public bool IsRenderNodeLoaded()
  640. {
  641. bool isLoadChildTile = false;
  642. if (PagedLodConfig.mInstance.mTileDataType == TileDataType.OSGB)
  643. {
  644. mPixelValue = GetPixelValue();//瓦片所占像素大小
  645. isLoadChildTile = mPixelValue > mLoadChildPixelValue;
  646. }
  647. else
  648. {
  649. mScreenSpaceError = GetScreenSpaceError();
  650. isLoadChildTile = mScreenSpaceError > PagedLodConfig.mInstance.mMaxSSE;
  651. }
  652. if (isLoadChildTile)
  653. {
  654. return IsChildTilesLoaded();
  655. }
  656. else
  657. {
  658. return mIsRenderNodeMeshLoaded;
  659. //return mIsRenderNodeLoaded && mRenderNode != null && mRenderNode.activeSelf;
  660. }
  661. }
  662. void SetChildTilesActive(bool flag)
  663. {
  664. for (int i = 0; i < mChildTileList.Count; ++i)
  665. {
  666. PagedLod childTile = mChildTileList[i].mPagedLod;
  667. if (childTile != null && childTile.gameObject.activeSelf != flag)
  668. {
  669. childTile.gameObject.SetActive(flag);
  670. }
  671. }
  672. }
  673. float GetMinCameraDistance()
  674. {
  675. if (mMainCamera == null) mMainCamera = Camera.main;
  676. float distance = float.MaxValue;
  677. for (int i = 0; i < mBoundsVertexList.Count; ++i)
  678. {
  679. float d = Vector3.Distance(mMainCamera.transform.position, mBoundsVertexList[i]);
  680. distance = Mathf.Min(distance, d);
  681. }
  682. return distance;
  683. }
  684. public float mDistance = 0.0f;
  685. float GetPixelValue()
  686. {
  687. if (mWorldCenter == Vector3.zero) return float.MinValue;
  688. Vector3 center = mWorldCenter;
  689. if (mMainCamera == null)
  690. {
  691. mMainCamera = Camera.main;
  692. }
  693. float distance = GetMinCameraDistance();
  694. mDistance = distance;
  695. float slope = Mathf.Tan(mMainCamera.fieldOfView * Mathf.Deg2Rad * 0.5f);
  696. int pixelHeight = 1300;/*mMainCamera.pixelHeight*/;
  697. float projFactor = (0.5f * pixelHeight) / (slope * distance);
  698. float pixelValue = mOsgbBoundRadius * projFactor;
  699. return pixelValue;
  700. }
  701. public bool IsMaxLevelTile()//最高级没有子节点
  702. {
  703. if (mRenderNode != null)
  704. {
  705. return mChildTileList.Count == 0;
  706. }
  707. return false;
  708. }
  709. #region B3DM file Load-------------------------
  710. float GetScreenSpaceError()
  711. {
  712. if (mWorldCenter == Vector3.zero) return float.MinValue;
  713. Vector3 center = mWorldCenter;
  714. if (mMainCamera == null)
  715. {
  716. mMainCamera = Camera.main;
  717. }
  718. float distance = Vector3.Distance(mMainCamera.transform.position, mWorldCenter); //GetMinCameraDistance();
  719. mDistance = distance;
  720. float slope = Mathf.Tan(mMainCamera.fieldOfView * Mathf.Deg2Rad * 0.5f);
  721. int pixelHeight = 1300;/*mMainCamera.pixelHeight*/;
  722. float es = (mBasicInfo.mGeometricError * pixelHeight) / (distance * 2.0f * slope);
  723. return es;
  724. }
  725. //根节点调用,加载瓦片结构组织
  726. public void LoadTileSetJsonFile()
  727. {
  728. if (mBasicInfoDict.Count == 0)
  729. {
  730. string tileSetJsonPath = GetDataPath() + "/tileset.json";
  731. string jsonText = System.IO.File.ReadAllText(tileSetJsonPath);
  732. B3dmBasicInfo rootTileInfo = null;
  733. mBasicInfoDict = LoadTileSetJsonText(jsonText, ref rootTileInfo);
  734. mBasicInfoList = new List<B3dmBasicInfo>(mBasicInfoDict.Values);
  735. //mBasicInfo = rootTileInfo;
  736. mBasicInfo = GetTileBasicInfo(gameObject.name);
  737. }
  738. }
  739. public static Dictionary<string, B3dmBasicInfo> LoadTileSetJsonText(string jsonText,ref B3dmBasicInfo rootTileInfo)
  740. {
  741. JsonData resultJson = JsonMapper.ToObject(jsonText);
  742. JsonData root = resultJson["root"];
  743. Dictionary<string, B3dmBasicInfo> basicInfoDict = new Dictionary<string, B3dmBasicInfo>();
  744. TraverseLoadTileBasicInfo(root, ref basicInfoDict,ref rootTileInfo);
  745. return basicInfoDict;
  746. }
  747. static void TraverseLoadTileBasicInfo(JsonData tileJson, ref Dictionary<string, B3dmBasicInfo> basicInfoDict, ref B3dmBasicInfo rootTileInfo)
  748. {
  749. B3dmBasicInfo info = LoadTileBasicInfo(tileJson);
  750. if(rootTileInfo == null)
  751. {
  752. rootTileInfo = info;
  753. }
  754. if (tileJson.Keys.Contains("children"))
  755. {
  756. JsonData children = tileJson["children"];
  757. for (int i = 0; i < children.Count; ++i)
  758. {
  759. B3dmBasicInfo childInfo = LoadTileBasicInfo(children[i]);
  760. info.mChildrenList.Add(childInfo);
  761. TraverseLoadTileBasicInfo(children[i], ref basicInfoDict,ref rootTileInfo);
  762. }
  763. }
  764. basicInfoDict.Add(info.mContent, info);
  765. }
  766. public static B3dmBasicInfo LoadTileBasicInfo(JsonData tileJson)
  767. {
  768. JsonData boundingVolume = tileJson["boundingVolume"];
  769. JsonData box = boundingVolume["box"];
  770. float centerX = float.Parse(box[0].ToString());
  771. float centerY = float.Parse(box[1].ToString());
  772. float centerZ = float.Parse(box[2].ToString());
  773. float extentX = float.Parse(box[3].ToString());
  774. float extentY = float.Parse(box[7].ToString());
  775. float extentZ = float.Parse(box[11].ToString());
  776. B3dmBasicInfo info = new B3dmBasicInfo();
  777. info.mCenter = new Vector3(centerX, centerZ, centerY);
  778. info.mExtents = new Vector3(extentX, extentZ, extentY);
  779. Bounds bounds = new Bounds();
  780. bounds.center = info.mCenter;
  781. bounds.extents = info.mExtents;
  782. info.mBounds = bounds;
  783. if (tileJson.Keys.Contains("content"))
  784. {
  785. info.mContent = tileJson["content"]["uri"].ToString();
  786. info.mContent = info.mContent.Replace("./", "");
  787. info.mContent = info.mContent.Replace(PagedLodConfig.mInstance.GetFileSufix(), "");
  788. }
  789. info.mGeometricError = float.Parse(tileJson["geometricError"].ToString());
  790. return info;
  791. }
  792. public B3dmBasicInfo GetTileBasicInfo(string tileName)
  793. {
  794. if (mBasicInfoDict.ContainsKey(tileName))
  795. {
  796. return mBasicInfoDict[tileName];
  797. }
  798. return null;
  799. }
  800. #endregion B3DM file Load
  801. }
  802. }