Advertisement
Guest User

Untitled

a guest
Jan 21st, 2018
232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.69 KB | None | 0 0
  1. #include "StdAfx.h"
  2. #include "../eterlib/Camera.h"
  3. #include "../PRTerrainLib/StdAfx.h"
  4.  
  5. #include "MapOutdoor.h"
  6. #include "TerrainPatch.h"
  7. #include "AreaTerrain.h"
  8. #include "TerrainQuadtree.h"
  9. #include "ActorInstance.h"
  10.  
  11. // 2004.08.17.myevan.std::vector ¸¦ »çżëÇŇ °ćżě ¸Ţ¸đ¸® Á˘±Ůżˇ żŔ·ˇ°É·Á ˝şĹĂÂĘŔ¸·Î °č»ęÇϵµ·Ď ĽöÁ¤
  12. class PCBlocker_CDynamicSphereInstanceVector
  13. {
  14. public:
  15. typedef CDynamicSphereInstance* Iterator;
  16.  
  17. enum
  18. {
  19. SIZE = 4,
  20. };
  21.  
  22. public:
  23. PCBlocker_CDynamicSphereInstanceVector()
  24. {
  25. }
  26. ~PCBlocker_CDynamicSphereInstanceVector()
  27. {
  28. }
  29.  
  30. Iterator Begin()
  31. {
  32. return m_aDSI+0;
  33. }
  34. Iterator End()
  35. {
  36. return m_aDSI+4;
  37. }
  38.  
  39. private:
  40. CDynamicSphereInstance m_aDSI[4];
  41. };
  42.  
  43.  
  44.  
  45.  
  46. bool CMapOutdoor::Update(float fX, float fY, float fZ)
  47. {
  48. D3DXVECTOR3 v3Player(fX, fY, fZ);
  49.  
  50. m_v3Player=v3Player;
  51.  
  52.  
  53. DWORD t1=ELTimer_GetMSec();
  54.  
  55. int ix, iy;
  56. PR_FLOAT_TO_INT(fX, ix);
  57. if ( fY < 0 )
  58. fY = -fY;
  59. PR_FLOAT_TO_INT(fY, iy);
  60.  
  61. short sCoordX = MINMAX(0, ix / CTerrainImpl::TERRAIN_XSIZE, m_sTerrainCountX - 1);
  62. short sCoordY = MINMAX(0, iy / CTerrainImpl::TERRAIN_YSIZE, m_sTerrainCountY - 1);
  63. #ifdef __PERFORMANCE_CHECKER__
  64. DWORD t2=ELTimer_GetMSec();
  65. #endif
  66.  
  67. bool bNeedInit = (m_PrevCoordinate.m_sTerrainCoordX == -1 || m_PrevCoordinate.m_sTerrainCoordY == -1);
  68.  
  69. if ( bNeedInit ||
  70. (m_CurCoordinate.m_sTerrainCoordX/LOAD_SIZE_WIDTH) != (sCoordX/LOAD_SIZE_WIDTH) ||
  71. (m_CurCoordinate.m_sTerrainCoordY/LOAD_SIZE_WIDTH) != (sCoordY/LOAD_SIZE_WIDTH) )
  72. {
  73. if (bNeedInit)
  74. {
  75. m_PrevCoordinate.m_sTerrainCoordX = sCoordX;
  76. m_PrevCoordinate.m_sTerrainCoordY = sCoordY;
  77. }
  78. else
  79. {
  80. m_PrevCoordinate.m_sTerrainCoordX = m_CurCoordinate.m_sTerrainCoordX;
  81. m_PrevCoordinate.m_sTerrainCoordY = m_CurCoordinate.m_sTerrainCoordY;
  82. }
  83.  
  84. m_CurCoordinate.m_sTerrainCoordX = sCoordX;
  85. m_CurCoordinate.m_sTerrainCoordY = sCoordY;
  86. m_lCurCoordStartX = sCoordX * CTerrainImpl::TERRAIN_XSIZE;
  87. m_lCurCoordStartY = sCoordY * CTerrainImpl::TERRAIN_YSIZE;
  88.  
  89. WORD wCellCoordX = (ix % CTerrainImpl::TERRAIN_XSIZE) / CTerrainImpl::CELLSCALE;
  90. WORD wCellCoordY = (iy % CTerrainImpl::TERRAIN_YSIZE) / CTerrainImpl::CELLSCALE;
  91.  
  92. short sReferenceCoordMinX, sReferenceCoordMaxX, sReferenceCoordMinY, sReferenceCoordMaxY;
  93. sReferenceCoordMinX = max(m_CurCoordinate.m_sTerrainCoordX - LOAD_SIZE_WIDTH, 0);
  94. sReferenceCoordMaxX = min(m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH, m_sTerrainCountX - 1);
  95. sReferenceCoordMinY = max(m_CurCoordinate.m_sTerrainCoordY - LOAD_SIZE_WIDTH, 0);
  96. sReferenceCoordMaxY = min(m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH, m_sTerrainCountY - 1);
  97.  
  98. for (WORD usY = sReferenceCoordMinY; usY <=sReferenceCoordMaxY; ++usY)
  99. {
  100. for (WORD usX = sReferenceCoordMinX; usX <= sReferenceCoordMaxX; ++usX)
  101. {
  102. LoadTerrain(usX, usY, wCellCoordX, wCellCoordY);
  103. LoadArea(usX, usY, wCellCoordX, wCellCoordY);
  104. }
  105. }
  106.  
  107. AssignTerrainPtr();
  108. m_lOldReadX = -1;
  109.  
  110. Tracenf("Update::Load spent %d ms\n", ELTimer_GetMSec() - t1);
  111. }
  112. #ifdef __PERFORMANCE_CHECKER__
  113. DWORD t3=ELTimer_GetMSec();
  114. #endif
  115. CSpeedTreeForestDirectX8::Instance().UpdateSystem(CTimer::Instance().GetCurrentSecond());
  116. #ifdef __PERFORMANCE_CHECKER__
  117. DWORD t4=ELTimer_GetMSec();
  118. #endif
  119. __UpdateGarvage();
  120. #ifdef __PERFORMANCE_CHECKER__
  121. DWORD t5=ELTimer_GetMSec();
  122. #endif
  123. UpdateTerrain(fX, fY);
  124. #ifdef __PERFORMANCE_CHECKER__
  125. DWORD t6=ELTimer_GetMSec();
  126. #endif
  127. __UpdateArea(v3Player);
  128. #ifdef __PERFORMANCE_CHECKER__
  129. DWORD t7=ELTimer_GetMSec();
  130. #endif
  131. UpdateSky();
  132. #ifdef __PERFORMANCE_CHECKER__
  133. DWORD t8=ELTimer_GetMSec();
  134. #endif
  135. __HeightCache_Update();
  136.  
  137. #ifdef __PERFORMANCE_CHECKER__
  138. {
  139. static FILE* fp=fopen("perf_outdoor_update.txt", "w");
  140.  
  141. if (t8-t1>5)
  142. {
  143. fprintf(fp, "OD.Total %d (Time %f)\n", t3-t1, ELTimer_GetMSec()/1000.0f);
  144. fprintf(fp, "OD.INIT %d\n", t2-t1);
  145. fprintf(fp, "OD.LOAD %d\n", t3-t2);
  146. fprintf(fp, "OD.TREE %d\n", t4-t3);
  147. fprintf(fp, "OD.GVG %d\n", t5-t4);
  148. fprintf(fp, "OD.TRN %d\n", t6-t5);
  149. fprintf(fp, "OD.AREA %d\n", t7-t6);
  150. fprintf(fp, "OD.SKY %d\n", t8-t7);
  151. fflush(fp);
  152. }
  153. }
  154. #endif
  155.  
  156. return true;
  157. }
  158.  
  159. void CMapOutdoor::UpdateSky()
  160. {
  161. m_SkyBox.Update();
  162. }
  163.  
  164. struct FGetShadowReceiverFromCollisionData
  165. {
  166. bool m_bCollide;
  167. std::vector<CGraphicObjectInstance *>* m_pkVct_pkShadowReceiver;
  168. CDynamicSphereInstance * m_pdsi;
  169. FGetShadowReceiverFromCollisionData(CDynamicSphereInstance * pdsi, std::vector<CGraphicObjectInstance *>* pkVct_pkShadowReceiver) : m_pdsi(pdsi), m_bCollide(false)
  170. {
  171. m_pkVct_pkShadowReceiver=pkVct_pkShadowReceiver;
  172. m_pkVct_pkShadowReceiver->clear();
  173. }
  174. void operator () (CGraphicObjectInstance * pInstance)
  175. {
  176. if (!pInstance)
  177. return;
  178.  
  179. if (TREE_OBJECT == pInstance->GetType() || ACTOR_OBJECT == pInstance->GetType() || EFFECT_OBJECT == pInstance->GetType())
  180. return;
  181. if (pInstance->CollisionDynamicSphere(*m_pdsi))
  182. {
  183. m_pkVct_pkShadowReceiver->push_back(pInstance);
  184. m_bCollide = true;
  185. }
  186. }
  187. };
  188.  
  189.  
  190.  
  191. struct FPCBlockerDistanceSort
  192. {
  193. D3DXVECTOR3 m_v3Eye;
  194. FPCBlockerDistanceSort(D3DXVECTOR3 & v3Eye) : m_v3Eye(v3Eye) { }
  195.  
  196. bool operator () (CGraphicObjectInstance * plhs, CGraphicObjectInstance * prhs) const
  197. {
  198. return D3DXVec3LengthSq(&(plhs->GetPosition() - m_v3Eye)) > D3DXVec3LengthSq(&(prhs->GetPosition() - m_v3Eye));
  199. }
  200. };
  201.  
  202. void CMapOutdoor::UpdateAroundAmbience(float fX, float fY, float fZ)
  203. {
  204. for (int i = 0; i < AROUND_AREA_NUM; ++i)
  205. {
  206. CArea * pArea;
  207. if (GetAreaPointer(i, &pArea))
  208. pArea->UpdateAroundAmbience(fX, fY, fZ);
  209. }
  210. }
  211.  
  212. void CMapOutdoor::__UpdateArea(D3DXVECTOR3& v3Player)
  213. {
  214. #ifdef WORLD_EDITOR
  215. __NEW_WorldEditor_UpdateArea();
  216. #else
  217. __Game_UpdateArea(v3Player);
  218. #endif
  219. }
  220.  
  221. void CMapOutdoor::__Game_UpdateArea(D3DXVECTOR3& v3Player)
  222. {
  223. #ifdef __PERFORMANCE_CHECKER__
  224. DWORD t1=timeGetTime();
  225. #endif
  226. m_PCBlockerVector.clear();
  227. m_ShadowReceiverVector.clear();
  228. #ifdef __PERFORMANCE_CHECKER__
  229. DWORD t2=timeGetTime();
  230. #endif
  231. CCameraManager& rCmrMgr=CCameraManager::Instance();
  232. CCamera * pCamera = rCmrMgr.GetCurrentCamera();
  233. if (!pCamera)
  234. return;
  235.  
  236. float fDistance = pCamera->GetDistance();
  237.  
  238. D3DXVECTOR3 v3View= pCamera->GetView();
  239. D3DXVECTOR3 v3Target = pCamera->GetTarget();
  240. D3DXVECTOR3 v3Eye= pCamera->GetEye();
  241.  
  242. D3DXVECTOR3 v3Light = D3DXVECTOR3(1.732f, 1.0f, -3.464f); // şűŔÇ ąćÇâ
  243. v3Light *= 50.0f / D3DXVec3Length(&v3Light);
  244.  
  245. /*
  246. if (v3Target!=v3Player)
  247. {
  248. printf("%.2f %.2f %.2f -> target(%.2f %.2f %.2f) player(%.2f %.2f %.2f)\n",
  249. v3Eye.x, v3Eye.y, v3Eye.z,
  250. v3Target.x, v3Target.y, v3Target.z,
  251. v3Player.x, v3Player.y, v3Player.z
  252. );
  253. }
  254. */
  255. #ifdef __PERFORMANCE_CHECKER__
  256. DWORD t3=timeGetTime();
  257. #endif
  258. __CollectShadowReceiver(v3Player, v3Light);
  259. #ifdef __PERFORMANCE_CHECKER__
  260. DWORD t4=timeGetTime();
  261. #endif
  262. __CollectCollisionPCBlocker(v3Eye, v3Player, fDistance);
  263. #ifdef __PERFORMANCE_CHECKER__
  264. DWORD t5=timeGetTime();
  265. #endif
  266. __CollectCollisionShadowReceiver(v3Player, v3Light);
  267. #ifdef __PERFORMANCE_CHECKER__
  268. DWORD t6=timeGetTime();
  269. #endif
  270. __UpdateAroundAreaList();
  271.  
  272. #ifdef __PERFORMANCE_CHECKER__
  273. DWORD t7=timeGetTime();
  274. {
  275. static FILE* fp=fopen("perf_area_update.txt", "w");
  276.  
  277. if (t7-t1>5)
  278. {
  279. fprintf(fp, "UA.Total %d (Time %f)\n", t3-t1, ELTimer_GetMSec()/1000.0f);
  280. fprintf(fp, "UA.Clear %d\n", t2-t1);
  281. fprintf(fp, "UA.Vector %d\n", t3-t2);
  282. fprintf(fp, "UA.Shadow %d\n", t4-t3);
  283. fprintf(fp, "UA.Blocker %d\n", t5-t4);
  284. fprintf(fp, "UA.ColliShadow %d\n", t6-t5);
  285. fprintf(fp, "UA.Area %d\n", t7-t6);
  286. fflush(fp);
  287. }
  288. }
  289. #endif
  290. }
  291. #ifdef WORLD_EDITOR
  292. void CMapOutdoor::__NEW_WorldEditor_UpdateArea()
  293. {
  294. m_PCBlockerVector.clear();
  295. m_ShadowReceiverVector.clear();
  296. __UpdateAroundAreaList();
  297.  
  298. }
  299. #endif
  300. void CMapOutdoor::__UpdateAroundAreaList()
  301. {
  302. #ifdef __PERFORMANCE_CHECKER__
  303. DWORD ft1=timeGetTime();
  304. #endif
  305. DWORD at[AROUND_AREA_NUM];
  306. for (int i = 0; i < AROUND_AREA_NUM; ++i)
  307. {
  308. DWORD t1=timeGetTime();
  309. CArea * pArea;
  310. if (GetAreaPointer(i, &pArea))
  311. pArea->Update();
  312. DWORD t2=timeGetTime();
  313.  
  314. at[i]=t2-t1;
  315. }
  316. #ifdef __PERFORMANCE_CHECKER__
  317. DWORD ft2=timeGetTime();
  318. if (ft2-ft1>5)
  319. {
  320. for (int i=0; i<AROUND_AREA_NUM; ++i)
  321. Tracef("Area %d %d\n", i, at[i]);
  322. }
  323. #endif
  324. }
  325.  
  326.  
  327. struct FGetShadowReceiverFromHeightData
  328. {
  329. enum
  330. {
  331. COLLECT_MAX = 100,
  332. };
  333.  
  334. DWORD m_dwCollectOverCount;
  335. DWORD m_dwCollectCount;
  336. DWORD m_dwCheckCount;
  337. bool m_bReceiverFound;
  338. float m_fFromX, m_fFromY, m_fToX, m_fToY;
  339. float m_fReturnHeight;
  340.  
  341. CGraphicObjectInstance* m_apkShadowReceiver[COLLECT_MAX];
  342.  
  343. FGetShadowReceiverFromHeightData(float fFromX, float fFromY, float fToX, float fToY) :
  344. m_fFromX(fFromX), m_fFromY(fFromY), m_fToX(fToX), m_fToY(fToY), m_bReceiverFound(false)
  345. {
  346. m_dwCheckCount=0;
  347. m_dwCollectOverCount=0;
  348. m_dwCollectCount=0;
  349. }
  350.  
  351. CGraphicObjectInstance* GetCollectItem(UINT uIndex)
  352. {
  353. if (uIndex>=m_dwCollectCount)
  354. return NULL;
  355.  
  356. return m_apkShadowReceiver[uIndex];
  357. }
  358.  
  359. UINT GetCollectCount()
  360. {
  361. return m_dwCollectCount;
  362. }
  363.  
  364. void operator () (CGraphicObjectInstance * pInstance)
  365. {
  366. m_dwCheckCount++;
  367.  
  368. if (!pInstance)
  369. return;
  370.  
  371. if (m_fFromY < 0)
  372. m_fFromY = -m_fFromY;
  373. if (m_fToY < 0)
  374. m_fToY = -m_fToY;
  375. if (pInstance->GetObjectHeight(m_fFromX, m_fFromY, &m_fReturnHeight) ||
  376. pInstance->GetObjectHeight(m_fToX, m_fToY, &m_fReturnHeight))
  377. {
  378. if (m_dwCollectCount<COLLECT_MAX)
  379. m_apkShadowReceiver[m_dwCollectCount++]=pInstance;
  380. else
  381. m_dwCollectOverCount++;
  382.  
  383. m_bReceiverFound = true;
  384. }
  385. }
  386. };
  387.  
  388.  
  389. void CMapOutdoor::__CollectShadowReceiver(D3DXVECTOR3& v3Target, D3DXVECTOR3& v3Light)
  390. {
  391. CDynamicSphereInstance s;
  392. s.v3LastPosition = v3Target + v3Light;
  393. s.v3Position = s.v3LastPosition + v3Light;
  394. s.fRadius = 50.0f;
  395.  
  396. Vector3d aVector3d;
  397. aVector3d.Set(v3Target.x, v3Target.y, v3Target.z);
  398.  
  399. CCullingManager & rkCullingMgr = CCullingManager::Instance();
  400.  
  401. #ifdef __PERFORMANCE_CHECKER__
  402. DWORD t1=ELTimer_GetMSec();
  403. #endif
  404.  
  405. FGetShadowReceiverFromHeightData kGetShadowReceiverFromHeightData(v3Target.x, v3Target.y, s.v3Position.x, s.v3Position.y);
  406. rkCullingMgr.ForInRange(aVector3d, 10.0f, &kGetShadowReceiverFromHeightData);
  407.  
  408. #ifdef __PERFORMANCE_CHECKER__
  409. DWORD t2=ELTimer_GetMSec();
  410. #endif
  411.  
  412. if (kGetShadowReceiverFromHeightData.m_bReceiverFound)
  413. {
  414. for (UINT i=0; i<kGetShadowReceiverFromHeightData.GetCollectCount(); ++i)
  415. {
  416. CGraphicObjectInstance * pObjInstEach = kGetShadowReceiverFromHeightData.GetCollectItem(i);
  417. if (!__IsInShadowReceiverList(pObjInstEach))
  418. m_ShadowReceiverVector.push_back(pObjInstEach);
  419. }
  420. }
  421.  
  422. #ifdef __PERFORMANCE_CHECKER__
  423. static FILE* fp=fopen("perf_shadow_collect.txt", "w");
  424. DWORD t3=ELTimer_GetMSec();
  425.  
  426. if (t3-t1>5)
  427. {
  428. fprintf(fp, "SC.Total %d (Time %f)\n", t3-t1, ELTimer_GetMSec()/1000.0f);
  429. fprintf(fp, "SC.Find %d\n", t2-t1);
  430. fprintf(fp, "SC.Push %d\n", t3-t2);
  431. fprintf(fp, "SC.Count (Collect %d, Over %d, Check %d)\n",
  432. kGetShadowReceiverFromHeightData.m_dwCollectCount,
  433. kGetShadowReceiverFromHeightData.m_dwCollectOverCount,
  434. kGetShadowReceiverFromHeightData.m_dwCheckCount);
  435. fflush(fp);
  436. }
  437. #endif
  438. }
  439.  
  440.  
  441. struct PCBlocker_SInstanceList
  442. {
  443. typedef CGraphicObjectInstance* Item;
  444. typedef Item* Iterator;
  445.  
  446. enum
  447. {
  448. CAPACITY = 512,
  449. };
  450.  
  451. DWORD m_dwInstCount;
  452. DWORD m_dwBlockerCount;
  453. DWORD m_dwBlockerOverCount;
  454.  
  455. Item m_apkPCBlocker[CAPACITY];
  456.  
  457. PCBlocker_CDynamicSphereInstanceVector* m_pkDSIVector;
  458.  
  459. CCamera * m_pCamera;
  460. D3DXVECTOR2 m_v2View;
  461. D3DXVECTOR2 m_v2Target;
  462.  
  463. PCBlocker_SInstanceList(PCBlocker_CDynamicSphereInstanceVector* pkDSIVector)
  464. {
  465. m_pCamera = CCameraManager::Instance().GetCurrentCamera();
  466. if (!m_pCamera)
  467. return;
  468.  
  469. D3DXVECTOR3 m_v3View = m_pCamera->GetView();
  470. D3DXVECTOR3 m_v3Target = m_pCamera->GetTarget();
  471.  
  472. m_v2View.x = m_v3View.x;
  473. m_v2View.y = m_v3View.y;
  474.  
  475. m_v2Target.x = m_v3Target.x;
  476. m_v2Target.y = m_v3Target.y;
  477.  
  478. m_pkDSIVector=pkDSIVector;
  479. m_dwBlockerCount=0;
  480. m_dwBlockerOverCount=0;
  481. m_dwInstCount=0;
  482. }
  483. ~PCBlocker_SInstanceList()
  484. {
  485. #ifdef _DEBUG
  486. __DEBUG_ShowInstanceMaxCount();
  487. #endif
  488. }
  489. void __DEBUG_ShowInstanceMaxCount()
  490. {
  491. static DWORD s_dwInstMaxCount=0;
  492. if (s_dwInstMaxCount<m_dwInstCount)
  493. {
  494. s_dwInstMaxCount=m_dwInstCount;
  495. //Tracenf("PCBlocker MaxInstanceCount %d", m_dwInstCount);
  496. }
  497. }
  498.  
  499. Iterator Begin()
  500. {
  501. return m_apkPCBlocker;
  502. }
  503. Iterator End()
  504. {
  505. return m_apkPCBlocker+m_dwBlockerCount;
  506. }
  507.  
  508. DWORD Size()
  509. {
  510. return m_dwBlockerCount;
  511. }
  512.  
  513. bool IsEmpty()
  514. {
  515. if (m_dwBlockerCount>0)
  516. return false;
  517.  
  518. return true;
  519. }
  520.  
  521. void __AppendPCBlocker(CGraphicObjectInstance * pInstance)
  522. {
  523. if (m_dwBlockerCount<CAPACITY)
  524. m_apkPCBlocker[m_dwBlockerCount++]=pInstance;
  525. else
  526. m_dwBlockerOverCount++;
  527. }
  528.  
  529. void __AppendObject(CGraphicObjectInstance * pInstance)
  530. {
  531. D3DXVECTOR3 v3Center;
  532. float fRadius;
  533. pInstance->GetBoundingSphere(v3Center, fRadius);
  534.  
  535. D3DXVECTOR2 v2TargetToCenter;
  536. v2TargetToCenter.x = v3Center.x - m_v2Target.x;
  537. v2TargetToCenter.y = v3Center.y - m_v2Target.y;
  538. if (D3DXVec2Dot(&m_v2View, &v2TargetToCenter) <= 0)
  539. {
  540. __AppendPCBlocker(pInstance);
  541. return;
  542. }
  543. }
  544.  
  545. void operator () (CGraphicObjectInstance * pInstance)
  546. {
  547. if (!m_pCamera)
  548. return;
  549.  
  550. if (!pInstance)
  551. return;
  552.  
  553. ++m_dwInstCount;
  554.  
  555. PCBlocker_CDynamicSphereInstanceVector::Iterator i;
  556.  
  557. for (i=m_pkDSIVector->Begin(); i!=m_pkDSIVector->End(); ++i)
  558. {
  559. CDynamicSphereInstance& rkDSI = *i;
  560. if (pInstance->CollisionDynamicSphere(rkDSI) )
  561. {
  562. if (TREE_OBJECT == pInstance->GetType())
  563. {
  564. __AppendPCBlocker(pInstance);
  565. return;
  566. }
  567. else if (THING_OBJECT == pInstance->GetType())
  568. {
  569. __AppendObject(pInstance);
  570. }
  571. else if (ACTOR_OBJECT == pInstance->GetType())
  572. {
  573. if (((CActorInstance *)pInstance)->IsBuilding())
  574. {
  575. __AppendObject(pInstance);
  576. }
  577. }
  578. }
  579. }
  580. }
  581. };
  582.  
  583.  
  584. void CMapOutdoor::__CollectCollisionPCBlocker(D3DXVECTOR3& v3Eye, D3DXVECTOR3& v3Target, float fDistance)
  585. {
  586. #ifdef __PERFORMANCE_CHECKER__
  587. DWORD t1=timeGetTime();
  588. #endif
  589.  
  590. Vector3d v3dRayStart;
  591. v3dRayStart.Set(v3Eye.x, v3Eye.y, v3Eye.z);
  592. #ifdef __PERFORMANCE_CHECKER__
  593. DWORD t2=timeGetTime();
  594. #endif
  595.  
  596. PCBlocker_CDynamicSphereInstanceVector aDynamicSphereInstanceVector;
  597. {
  598. CDynamicSphereInstance* pkDSI=aDynamicSphereInstanceVector.Begin();
  599. pkDSI->fRadius = fDistance * 0.5f;
  600. pkDSI->v3LastPosition = v3Eye;
  601. pkDSI->v3Position = v3Eye + 0.5f * (v3Target - v3Eye);
  602. ++pkDSI;
  603.  
  604. pkDSI->fRadius = fDistance * 0.5f;
  605. pkDSI->v3LastPosition = v3Eye + 0.5f * (v3Target - v3Eye);
  606. pkDSI->v3Position = v3Target;
  607. ++pkDSI;
  608.  
  609. pkDSI->fRadius = fDistance * 0.5f;
  610. pkDSI->v3LastPosition = v3Target;
  611. pkDSI->v3Position = v3Eye + 0.5f * (v3Target - v3Eye);
  612. ++pkDSI;
  613.  
  614. pkDSI->fRadius = fDistance * 0.5f;
  615. pkDSI->v3LastPosition = v3Eye + 0.5f * (v3Target - v3Eye);
  616. pkDSI->v3Position = v3Eye;
  617. ++pkDSI;
  618. }
  619. #ifdef __PERFORMANCE_CHECKER__
  620. DWORD t3=timeGetTime();
  621. #endif
  622. CCullingManager & rkCullingMgr = CCullingManager::Instance();
  623.  
  624. PCBlocker_SInstanceList kPCBlockerList(&aDynamicSphereInstanceVector);
  625. RangeTester<PCBlocker_SInstanceList> kPCBlockerRangeTester(&kPCBlockerList);
  626. rkCullingMgr.RangeTest(v3dRayStart, fDistance, &kPCBlockerRangeTester);
  627. #ifdef __PERFORMANCE_CHECKER__
  628. DWORD t4=timeGetTime();
  629. #endif
  630.  
  631. if (!kPCBlockerList.IsEmpty())
  632. {
  633. PCBlocker_SInstanceList::Iterator i;
  634.  
  635. for (i=kPCBlockerList.Begin(); i!=kPCBlockerList.End(); ++i)
  636. {
  637. CGraphicObjectInstance * pObjInstEach = *i;
  638.  
  639. if (!pObjInstEach)
  640. continue;
  641.  
  642. if (TREE_OBJECT == pObjInstEach->GetType() && !m_bTransparentTree)
  643. continue;
  644.  
  645. if (!__IsInShadowReceiverList(pObjInstEach))
  646. if (!__IsInPCBlockerList(pObjInstEach))
  647. m_PCBlockerVector.push_back(pObjInstEach);
  648. }
  649. }
  650. #ifdef __PERFORMANCE_CHECKER__
  651. DWORD t5=timeGetTime();
  652. #endif
  653. std::sort(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), FPCBlockerDistanceSort(v3Eye));
  654.  
  655. #ifdef __PERFORMANCE_CHECKER__
  656. DWORD t6=timeGetTime();
  657.  
  658. static FILE* fp=fopen("perf_pbc_collect.txt", "w");
  659.  
  660. if (t3-t1>5)
  661. {
  662. fprintf(fp, "PBC.Total %d (Time %f)\n", t3-t1, ELTimer_GetMSec()/1000.0f);
  663. fprintf(fp, "PBC.INIT %d\n", t2-t1);
  664. fprintf(fp, "PBC.SET %d\n", t3-t2);
  665. fprintf(fp, "PBC.CALC %d\n", t4-t2);
  666. fprintf(fp, "PBC.PUSH %d\n", t5-t2);
  667. fprintf(fp, "PBC.SORT %d (%d)\n", t6-t2, m_PCBlockerVector.size());
  668. fprintf(fp, "PBC.Count (Collect %d, Over %d, Check %d)\n",
  669. kPCBlockerList.m_dwBlockerCount,
  670. kPCBlockerList.m_dwBlockerOverCount,
  671. kPCBlockerList.m_dwInstCount);
  672. fflush(fp);
  673. }
  674. #endif
  675. }
  676.  
  677. void CMapOutdoor::__CollectCollisionShadowReceiver(D3DXVECTOR3& v3Target, D3DXVECTOR3& v3Light)
  678. {
  679. CDynamicSphereInstance s;
  680. s.fRadius = 50.0f;
  681. s.v3LastPosition = v3Target + v3Light;
  682. s.v3Position = s.v3LastPosition + v3Light;
  683.  
  684. Vector3d aVector3d;
  685. aVector3d.Set(v3Target.x, v3Target.y, v3Target.z);
  686.  
  687. CCullingManager & rkCullingMgr = CCullingManager::Instance();
  688.  
  689. std::vector<CGraphicObjectInstance *> kVct_pkShadowReceiver;
  690. FGetShadowReceiverFromCollisionData kGetShadowReceiverFromCollisionData(&s, &kVct_pkShadowReceiver);
  691. rkCullingMgr.ForInRange(aVector3d, 100.0f, &kGetShadowReceiverFromCollisionData);
  692. if (!kGetShadowReceiverFromCollisionData.m_bCollide)
  693. return;
  694.  
  695. std::vector<CGraphicObjectInstance * >::iterator i;
  696. for ( i = kVct_pkShadowReceiver.begin(); i != kVct_pkShadowReceiver.end(); ++i)
  697. {
  698. CGraphicObjectInstance * pObjInstEach = *i;
  699. if (!__IsInPCBlockerList(pObjInstEach))
  700. if (!__IsInShadowReceiverList(pObjInstEach))
  701. m_ShadowReceiverVector.push_back(pObjInstEach);
  702. }
  703. }
  704.  
  705. bool CMapOutdoor::__IsInShadowReceiverList(CGraphicObjectInstance* pkObjInstTest)
  706. {
  707. if (m_ShadowReceiverVector.end() == std::find(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), pkObjInstTest))
  708. return false;
  709.  
  710. return true;
  711. }
  712.  
  713. bool CMapOutdoor::__IsInPCBlockerList(CGraphicObjectInstance* pkObjInstTest)
  714. {
  715. if (m_PCBlockerVector.end() == std::find(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), pkObjInstTest))
  716. return false;
  717.  
  718. return true;
  719. }
  720.  
  721. // Updates the position of the terrain
  722. void CMapOutdoor::UpdateTerrain(float fX, float fY)
  723. {
  724. if (fY < 0)
  725. fY = -fY;
  726.  
  727. int sx, sy;
  728. PR_FLOAT_TO_INT(fX, sx);
  729. PR_FLOAT_TO_INT(fY, sy);
  730.  
  731. long lDivider = (CTerrainImpl::CELLSCALE * TERRAIN_PATCHSIZE);
  732.  
  733. m_lCenterX = (sx - m_lCurCoordStartX) / lDivider;
  734. m_lCenterY = (sy - m_lCurCoordStartY) / lDivider;
  735.  
  736. if ((m_lCenterX != m_lOldReadX) || (m_lCenterY != m_lOldReadY))
  737. {
  738. long lRealCenterX = m_lCenterX * TERRAIN_PATCHSIZE;
  739. long lRealCenterY = m_lCenterY * TERRAIN_PATCHSIZE;
  740. m_lOldReadX = m_lCenterX;
  741. m_lOldReadY = m_lCenterY;
  742.  
  743. ConvertTerrainToTnL(lRealCenterX, lRealCenterY);
  744. UpdateAreaList(lRealCenterX, lRealCenterY);
  745. //Tracef("»çżëÇĎ´Â Area, Terrain : (%d, %d), Áöżď Area, Terrain : (%d, %d)\n",
  746. // m_AreaVector.size(), m_TerrainVector.size(), m_AreaDeleteVector.size(), m_TerrainDeleteVector.size());
  747. }
  748. }
  749.  
  750. void CMapOutdoor::FPushTerrainToDeleteVector::operator () (CTerrain * pTerrain)
  751. {
  752. TTerrainPtrVectorIterator aIterator = std::find(m_ReturnTerrainVector.begin(), m_ReturnTerrainVector.end(), pTerrain);
  753. if (aIterator != m_ReturnTerrainVector.end())
  754. return;
  755.  
  756. WORD wReferenceCoordX = m_CurCoordinate.m_sTerrainCoordX;
  757. WORD wReferenceCoordY = m_CurCoordinate.m_sTerrainCoordY;
  758.  
  759. WORD wCoordX, wCoordY;
  760. pTerrain->GetCoordinate(&wCoordX, &wCoordY);
  761.  
  762.  
  763. switch(m_eLRDeleteDir)
  764. {
  765. case DELETE_LEFT:
  766. if (wCoordX < wReferenceCoordX - LOAD_SIZE_WIDTH)
  767. m_ReturnTerrainVector.push_back(pTerrain);
  768. break;
  769. case DELETE_RIGHT:
  770. if (wCoordX > wReferenceCoordX + LOAD_SIZE_WIDTH)
  771. m_ReturnTerrainVector.push_back(pTerrain);
  772. break;
  773. }
  774.  
  775. aIterator = std::find(m_ReturnTerrainVector.begin(), m_ReturnTerrainVector.end(), pTerrain);
  776. if (aIterator != m_ReturnTerrainVector.end())
  777. return;
  778.  
  779. switch(m_eTBDeleteDir)
  780. {
  781. case DELETE_TOP:
  782. if (wCoordY < wReferenceCoordY - LOAD_SIZE_WIDTH)
  783. m_ReturnTerrainVector.push_back(pTerrain);
  784. break;
  785. case DELETE_BOTTOM:
  786. if (wCoordY > wReferenceCoordY + LOAD_SIZE_WIDTH)
  787. m_ReturnTerrainVector.push_back(pTerrain);
  788. break;
  789. }
  790. }
  791.  
  792. void CMapOutdoor::FPushAreaToDeleteVector::operator () (CArea * pArea)
  793. {
  794. TAreaPtrVectorIterator aIterator = std::find(m_ReturnAreaVector.begin(), m_ReturnAreaVector.end(), pArea);
  795. if (aIterator != m_ReturnAreaVector.end())
  796. return;
  797.  
  798. WORD wReferenceCoordX = m_CurCoordinate.m_sTerrainCoordX;
  799. WORD wReferenceCoordY = m_CurCoordinate.m_sTerrainCoordY;
  800.  
  801. WORD wCoordX, wCoordY;
  802. pArea->GetCoordinate(&wCoordX, &wCoordY);
  803.  
  804. switch(m_eLRDeleteDir)
  805. {
  806. case DELETE_LEFT:
  807. if (wCoordX < wReferenceCoordX - LOAD_SIZE_WIDTH)
  808. m_ReturnAreaVector.push_back(pArea);
  809. break;
  810. case DELETE_RIGHT:
  811. if (wCoordX > wReferenceCoordX + LOAD_SIZE_WIDTH)
  812. m_ReturnAreaVector.push_back(pArea);
  813. break;
  814. }
  815.  
  816. aIterator = std::find(m_ReturnAreaVector.begin(), m_ReturnAreaVector.end(), pArea);
  817. if (aIterator != m_ReturnAreaVector.end())
  818. return;
  819.  
  820. switch(m_eTBDeleteDir)
  821. {
  822. case DELETE_TOP:
  823. if (wCoordY < wReferenceCoordY - LOAD_SIZE_WIDTH)
  824. m_ReturnAreaVector.push_back(pArea);
  825. break;
  826. case DELETE_BOTTOM:
  827. if (wCoordY > wReferenceCoordY + LOAD_SIZE_WIDTH)
  828. m_ReturnAreaVector.push_back(pArea);
  829. break;
  830. }
  831. }
  832.  
  833. void CMapOutdoor::__ClearGarvage()
  834. {
  835. std::for_each(m_TerrainDeleteVector.begin(), m_TerrainDeleteVector.end(), CTerrain::Delete);
  836. m_TerrainDeleteVector.clear();
  837.  
  838. std::for_each(m_AreaDeleteVector.begin(), m_AreaDeleteVector.end(), CArea::Delete);
  839. m_AreaDeleteVector.clear();
  840. }
  841.  
  842. void CMapOutdoor::__UpdateGarvage()
  843. {
  844. const DWORD dwTerrainEraseInterval = 1000 * 60;
  845. static DWORD dwEraseTime = ELTimer_GetMSec();
  846.  
  847. if (!m_TerrainDeleteVector.empty())
  848. {
  849. if (ELTimer_GetMSec() - dwEraseTime <= dwTerrainEraseInterval)
  850. return;
  851. TTerrainPtrVectorIterator aTerrainPtrDeleteItertor = m_TerrainDeleteVector.begin();
  852. CTerrain * pTerrain = *aTerrainPtrDeleteItertor;
  853. CTerrain::Delete(pTerrain);
  854.  
  855. aTerrainPtrDeleteItertor = m_TerrainDeleteVector.erase(aTerrainPtrDeleteItertor);
  856. dwEraseTime = ELTimer_GetMSec();
  857. Trace("Delete Terrain \n");
  858. return;
  859. }
  860.  
  861. if (!m_AreaDeleteVector.empty())
  862. {
  863. if (ELTimer_GetMSec() - dwEraseTime <= dwTerrainEraseInterval)
  864. return;
  865. TAreaPtrVectorIterator aAreaPtrDeleteItertor = m_AreaDeleteVector.begin();
  866.  
  867. CArea * pArea = *aAreaPtrDeleteItertor;
  868. CArea::Delete(pArea);
  869.  
  870. aAreaPtrDeleteItertor = m_AreaDeleteVector.erase(aAreaPtrDeleteItertor);
  871. dwEraseTime = ELTimer_GetMSec();
  872. Trace("Delete Area \n");
  873. return;
  874. }
  875. }
  876.  
  877. void CMapOutdoor::UpdateAreaList(long lCenterX, long lCenterY)
  878. {
  879. if (m_TerrainVector.size() <= AROUND_AREA_NUM && m_AreaVector.size() <= AROUND_AREA_NUM)
  880. return;
  881.  
  882. __ClearGarvage();
  883.  
  884. FPushToDeleteVector::EDeleteDir eDeleteLRDir, eDeleteTBDir;
  885.  
  886. if (lCenterX > CTerrainImpl::XSIZE / 2)
  887. eDeleteLRDir = FPushToDeleteVector::DELETE_LEFT;
  888. else
  889. eDeleteLRDir = FPushToDeleteVector::DELETE_RIGHT;
  890. if (lCenterY > CTerrainImpl::YSIZE / 2)
  891. eDeleteTBDir = FPushToDeleteVector::DELETE_TOP;
  892. else
  893. eDeleteTBDir = FPushToDeleteVector::DELETE_BOTTOM;
  894.  
  895. FPushTerrainToDeleteVector &rPushTerrainToDeleteVector = std::for_each(m_TerrainVector.begin(), m_TerrainVector.end(),
  896. FPushTerrainToDeleteVector(eDeleteLRDir, eDeleteTBDir, m_CurCoordinate));
  897. FPushAreaToDeleteVector &rPushAreaToDeleteVector = std::for_each(m_AreaVector.begin(), m_AreaVector.end(),
  898. FPushAreaToDeleteVector(eDeleteLRDir, eDeleteTBDir, m_CurCoordinate));
  899.  
  900. if (!rPushTerrainToDeleteVector.m_ReturnTerrainVector.empty())
  901. {
  902. m_TerrainDeleteVector.resize(rPushTerrainToDeleteVector.m_ReturnTerrainVector.size());
  903. std::copy(rPushTerrainToDeleteVector.m_ReturnTerrainVector.begin(), rPushTerrainToDeleteVector.m_ReturnTerrainVector.end(), m_TerrainDeleteVector.begin());
  904.  
  905. for (DWORD dwIndex = 0; dwIndex < rPushTerrainToDeleteVector.m_ReturnTerrainVector.size(); ++dwIndex)
  906. {
  907. bool isDel=false;
  908. TTerrainPtrVectorIterator aTerrainPtrItertor = m_TerrainVector.begin();
  909. while(aTerrainPtrItertor != m_TerrainVector.end())
  910. {
  911. CTerrain * pTerrain = *aTerrainPtrItertor;
  912. if (pTerrain == rPushTerrainToDeleteVector.m_ReturnTerrainVector[dwIndex])
  913. {
  914. aTerrainPtrItertor = m_TerrainVector.erase(aTerrainPtrItertor);
  915. isDel=true;
  916. }
  917. else
  918. ++aTerrainPtrItertor;
  919. }
  920. }
  921. }
  922. if (!rPushAreaToDeleteVector.m_ReturnAreaVector.empty())
  923. {
  924. m_AreaDeleteVector.resize(rPushAreaToDeleteVector.m_ReturnAreaVector.size());
  925. std::copy(rPushAreaToDeleteVector.m_ReturnAreaVector.begin(), rPushAreaToDeleteVector.m_ReturnAreaVector.end(), m_AreaDeleteVector.begin());
  926.  
  927. for (DWORD dwIndex = 0; dwIndex < rPushAreaToDeleteVector.m_ReturnAreaVector.size(); ++dwIndex)
  928. {
  929. TAreaPtrVectorIterator aAreaPtrItertor = m_AreaVector.begin();
  930. while(aAreaPtrItertor != m_AreaVector.end())
  931. {
  932. CArea * pArea = *aAreaPtrItertor;
  933. if (pArea == rPushAreaToDeleteVector.m_ReturnAreaVector[dwIndex])
  934. aAreaPtrItertor = m_AreaVector.erase(aAreaPtrItertor);
  935. else
  936. ++aAreaPtrItertor;
  937. }
  938. }
  939. }
  940. }
  941.  
  942. void CMapOutdoor::ConvertTerrainToTnL(long lx, long ly)
  943. {
  944. assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::ConvertTerrainToTnL");
  945.  
  946. for (long i = 0; i < m_wPatchCount * m_wPatchCount; i++)
  947. m_pTerrainPatchProxyList[i].SetUsed(false);
  948.  
  949. lx -= m_lViewRadius; /* Move to the top left corner of the */
  950. ly -= m_lViewRadius; /* input rectangle */
  951.  
  952. long diameter = m_lViewRadius * 2;
  953.  
  954. long x0 = lx / TERRAIN_PATCHSIZE;
  955. long y0 = ly / TERRAIN_PATCHSIZE;
  956. long x1 = ( lx + diameter - 1 ) / TERRAIN_PATCHSIZE;
  957. long y1 = ( ly + diameter - 1 ) / TERRAIN_PATCHSIZE;
  958.  
  959. long xw = x1 - x0 + 1; /* Figure out how many patches are needed */
  960. long yw = y1 - y0 + 1;
  961.  
  962. long ex = lx + diameter;
  963. long ey = ly + diameter;
  964.  
  965. y0 = ly;
  966. for (long yp = 0; yp < yw; yp++)
  967. {
  968. x0 = lx;
  969. y1 = (y0 / TERRAIN_PATCHSIZE + 1) * TERRAIN_PATCHSIZE;
  970. if (y1 > ey)
  971. y1 = ey;
  972. for (long xp = 0; xp < xw; xp++)
  973. {
  974. x1 = (x0 / TERRAIN_PATCHSIZE + 1) * TERRAIN_PATCHSIZE;
  975. if (x1 > ex)
  976. x1 = ex;
  977. AssignPatch(yp * m_wPatchCount + xp, x0, y0, x1, y1);
  978. x0 = x1;
  979. }
  980. y0 = y1;
  981. }
  982. UpdateQuadTreeHeights(m_pRootNode);
  983. }
  984.  
  985. void CMapOutdoor::AssignPatch(long lPatchNum, long x0, long y0, long x1, long y1)
  986. {
  987. assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::AssignPatch");
  988.  
  989. CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[lPatchNum];
  990.  
  991. if (y0 < 0 && y1 <= 0)
  992. {
  993. if (x0 < 0 && x1 <= 0)
  994. {
  995. pTerrainPatchProxy->SetTerrainNum(0);
  996. x0 += CTerrainImpl::XSIZE;
  997. x1 += CTerrainImpl::XSIZE;
  998. }
  999. else if (x0 >= CTerrainImpl::XSIZE && x1 > CTerrainImpl::XSIZE)
  1000. {
  1001. pTerrainPatchProxy->SetTerrainNum(2);
  1002. x0 -= CTerrainImpl::XSIZE;
  1003. x1 -= CTerrainImpl::XSIZE;
  1004. }
  1005. else
  1006. pTerrainPatchProxy->SetTerrainNum(1);
  1007.  
  1008. y0 += CTerrainImpl::YSIZE;
  1009. y1 += CTerrainImpl::YSIZE;
  1010. }
  1011. else if (y0 >= CTerrainImpl::YSIZE && y1 > CTerrainImpl::YSIZE)
  1012. {
  1013. if (x0 < 0 && x1 <= 0)
  1014. {
  1015. pTerrainPatchProxy->SetTerrainNum(6);
  1016. x0 += CTerrainImpl::XSIZE;
  1017. x1 += CTerrainImpl::XSIZE;
  1018. }
  1019. else if (x0 >= CTerrainImpl::XSIZE && x1 > CTerrainImpl::XSIZE)
  1020. {
  1021. pTerrainPatchProxy->SetTerrainNum(8);
  1022. x0 -= CTerrainImpl::XSIZE;
  1023. x1 -= CTerrainImpl::XSIZE;
  1024. }
  1025. else
  1026. pTerrainPatchProxy->SetTerrainNum(7);
  1027.  
  1028. y0 -= CTerrainImpl::YSIZE;
  1029. y1 -= CTerrainImpl::YSIZE;
  1030. }
  1031. else
  1032. {
  1033. if (x0 < 0 && x1 <= 0)
  1034. {
  1035. pTerrainPatchProxy->SetTerrainNum(3);
  1036. x0 += CTerrainImpl::XSIZE;
  1037. x1 += CTerrainImpl::XSIZE;
  1038. }
  1039. else if (x0 >= CTerrainImpl::XSIZE && x1 > CTerrainImpl::XSIZE)
  1040. {
  1041. pTerrainPatchProxy->SetTerrainNum(5);
  1042. x0 -= CTerrainImpl::XSIZE;
  1043. x1 -= CTerrainImpl::XSIZE;
  1044. }
  1045. else
  1046. pTerrainPatchProxy->SetTerrainNum(4);
  1047. }
  1048.  
  1049. CTerrain * pTerrain;
  1050. if (!GetTerrainPointer(pTerrainPatchProxy->GetTerrainNum(), &pTerrain))
  1051. return;
  1052.  
  1053. BYTE byPatchNumX, byPatchNumY;
  1054. byPatchNumX = x0 / CTerrainImpl::PATCH_XSIZE;
  1055. byPatchNumY = y0 / CTerrainImpl::PATCH_YSIZE;
  1056.  
  1057. CTerrainPatch * pTerrainPatch = pTerrain->GetTerrainPatchPtr(byPatchNumX, byPatchNumY);
  1058. if (!pTerrainPatch)
  1059. return;
  1060.  
  1061. pTerrainPatchProxy->SetPatchNum(byPatchNumY * CTerrainImpl::PATCH_XCOUNT + byPatchNumX);
  1062. pTerrainPatchProxy->SetTerrainPatch(pTerrainPatch);
  1063. pTerrainPatchProxy->SetUsed(true);
  1064. }
  1065.  
  1066. void CMapOutdoor::UpdateQuadTreeHeights(CTerrainQuadtreeNode *Node)
  1067. {
  1068. // Inserted by levites
  1069. assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::UpdateQuadTreeHeights");
  1070. if (!m_pTerrainPatchProxyList)
  1071. return;
  1072.  
  1073. float minx, maxx, miny, maxy, minz, maxz;
  1074. minx = maxx = miny = maxy = minz = maxz = 0;
  1075.  
  1076. if (m_pTerrainPatchProxyList[Node->PatchNum].isUsed())
  1077. {
  1078. minx = m_pTerrainPatchProxyList[Node->PatchNum].GetMinX();
  1079. maxx = m_pTerrainPatchProxyList[Node->PatchNum].GetMaxX();
  1080. miny = m_pTerrainPatchProxyList[Node->PatchNum].GetMinY();
  1081. maxy = m_pTerrainPatchProxyList[Node->PatchNum].GetMaxY();
  1082. minz = m_pTerrainPatchProxyList[Node->PatchNum].GetMinZ();
  1083. maxz = m_pTerrainPatchProxyList[Node->PatchNum].GetMaxZ();
  1084. }
  1085.  
  1086. for (long y = Node->y0; y <= Node->y1; y++)
  1087. {
  1088. for (long x = Node->x0; x <= Node->x1; x++)
  1089. {
  1090. long patch = y * m_wPatchCount + x;
  1091.  
  1092. if (!m_pTerrainPatchProxyList[patch].isUsed())
  1093. continue;
  1094.  
  1095. if (m_pTerrainPatchProxyList[patch].GetMinX() < minx)
  1096. minx = m_pTerrainPatchProxyList[patch].GetMinX();
  1097. if (m_pTerrainPatchProxyList[patch].GetMaxX() > maxx)
  1098. maxx = m_pTerrainPatchProxyList[patch].GetMaxX();
  1099.  
  1100. if (m_pTerrainPatchProxyList[patch].GetMinY() < miny)
  1101. miny = m_pTerrainPatchProxyList[patch].GetMinY();
  1102. if (m_pTerrainPatchProxyList[patch].GetMaxY() > maxy)
  1103. maxy = m_pTerrainPatchProxyList[patch].GetMaxY();
  1104.  
  1105. if (m_pTerrainPatchProxyList[patch].GetMinZ() < minz)
  1106. minz = m_pTerrainPatchProxyList[patch].GetMinZ();
  1107. if (m_pTerrainPatchProxyList[patch].GetMaxZ() > maxz)
  1108. maxz = m_pTerrainPatchProxyList[patch].GetMaxZ();
  1109. }
  1110. }
  1111.  
  1112. Node->center.x = (maxx + minx) * 0.5f;
  1113. Node->center.y = (maxy + miny) * 0.5f;
  1114. Node->center.z = (maxz + minz) * 0.5f;
  1115.  
  1116. Node->radius = sqrtf((maxx-minx)*(maxx-minx) +
  1117. (maxy-miny)*(maxy-miny) +
  1118. (maxz-minz)*(maxz-minz)) / 2.0f;
  1119.  
  1120. if (Node->NW_Node != NULL)
  1121. UpdateQuadTreeHeights(Node->NW_Node);
  1122.  
  1123. if (Node->NE_Node != NULL)
  1124. UpdateQuadTreeHeights(Node->NE_Node);
  1125.  
  1126. if (Node->SW_Node != NULL)
  1127. UpdateQuadTreeHeights(Node->SW_Node);
  1128.  
  1129. if (Node->SE_Node != NULL)
  1130. UpdateQuadTreeHeights(Node->SE_Node);
  1131. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement