Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1234 lines
45 KiB

  1. //========= Copyright � 1996-2004, Valve LLC, All rights reserved. ============
  2. //
  3. //
  4. //=============================================================================
  5. #include <stdafx.h>
  6. #include "FaceEditSheet.h"
  7. #include "MainFrm.h"
  8. #include "GlobalFunctions.h"
  9. #include "MapDisp.h"
  10. #include "DispShore.h"
  11. #include "UtlVector.h"
  12. #include "mapdoc.h"
  13. #include "mapworld.h"
  14. #include "mapsolid.h"
  15. #include "materialsystem/IMesh.h"
  16. #include "Material.h"
  17. #include "collisionutils.h"
  18. #include "TextureSystem.h"
  19. #include "mapoverlay.h"
  20. // memdbgon must be the last include file in a .cpp file!!!
  21. #include <tier0/memdbgon.h>
  22. IMPLEMENT_MAPCLASS( CMapOverlayTransition )
  23. #define DISPSHORE_WIDTH_WORLD 25.0f
  24. #define DISPSHORE_WIDTH_WATER 25.0f
  25. #define DISPSHORE_VECTOR_EPS 0.1f
  26. #define DISPSHORE_SURF_LENGTH 120.0f
  27. //-----------------------------------------------------------------------------
  28. // Purpose:
  29. //-----------------------------------------------------------------------------
  30. Shoreline_t::Shoreline_t()
  31. {
  32. m_nShorelineId = -1;
  33. m_aSegments.Purge();
  34. m_aOverlays.Purge();
  35. m_flLength = 0.0f;
  36. }
  37. //-----------------------------------------------------------------------------
  38. // Purpose:
  39. //-----------------------------------------------------------------------------
  40. Shoreline_t::~Shoreline_t()
  41. {
  42. m_aSegments.Purge();
  43. m_aOverlays.Purge();
  44. }
  45. //-----------------------------------------------------------------------------
  46. // Purpose:
  47. //-----------------------------------------------------------------------------
  48. void Shoreline_t::AddSegment( Vector &vecPoint0, Vector &vecPoint1,
  49. Vector &vecNormal, float flWaterZ,
  50. CMapFace *pWaterFace, EditDispHandle_t hDisp )
  51. {
  52. // Check for duplicates!
  53. int nSegmentCount = m_aSegments.Count();
  54. int iSegment;
  55. for ( iSegment = 0; iSegment < nSegmentCount; ++iSegment )
  56. {
  57. if ( VectorsAreEqual( m_aSegments[iSegment].m_vecPoints[0], vecPoint0, DISPSHORE_VECTOR_EPS ) )
  58. {
  59. if ( VectorsAreEqual( m_aSegments[iSegment].m_vecPoints[1], vecPoint1, DISPSHORE_VECTOR_EPS ) )
  60. return;
  61. }
  62. if ( VectorsAreEqual( m_aSegments[iSegment].m_vecPoints[1], vecPoint0, DISPSHORE_VECTOR_EPS ) )
  63. {
  64. if ( VectorsAreEqual( m_aSegments[iSegment].m_vecPoints[0], vecPoint1, DISPSHORE_VECTOR_EPS ) )
  65. return;
  66. }
  67. }
  68. iSegment = m_aSegments.AddToTail();
  69. Vector vecEdge, vecCross;
  70. VectorSubtract( vecPoint1, vecPoint0, vecEdge );
  71. CrossProduct( vecNormal, vecEdge, vecCross );
  72. if ( vecCross.z >= 0.0f )
  73. {
  74. VectorCopy( vecPoint1, m_aSegments[iSegment].m_vecPoints[0] );
  75. VectorCopy( vecPoint0, m_aSegments[iSegment].m_vecPoints[1] );
  76. }
  77. else
  78. {
  79. VectorCopy( vecPoint0, m_aSegments[iSegment].m_vecPoints[0] );
  80. VectorCopy( vecPoint1, m_aSegments[iSegment].m_vecPoints[1] );
  81. }
  82. VectorCopy( vecNormal, m_aSegments[iSegment].m_vecNormals[0] );
  83. VectorCopy( vecNormal, m_aSegments[iSegment].m_vecNormals[1] );
  84. m_aSegments[iSegment].m_hDisp = hDisp;
  85. m_aSegments[iSegment].m_flWaterZ = flWaterZ;
  86. m_aSegments[iSegment].m_iStartPoint = 0;
  87. m_aSegments[iSegment].m_bTouch = false;
  88. m_aSegments[iSegment].m_bCreated = false;
  89. m_aSegments[iSegment].m_vecCenter.Init();
  90. m_aSegments[iSegment].m_WorldFace.m_bAdjWinding = false;
  91. m_aSegments[iSegment].m_WaterFace.m_bAdjWinding = false;
  92. for ( int i = 0; i < 4; ++i )
  93. {
  94. m_aSegments[iSegment].m_WorldFace.m_vecPoints[i].Init();
  95. m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[i].Init();
  96. m_aSegments[iSegment].m_WorldFace.m_pFaces[i] = NULL;
  97. m_aSegments[iSegment].m_WaterFace.m_vecPoints[i].Init();
  98. m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[i].Init();
  99. m_aSegments[iSegment].m_WaterFace.m_pFaces[i] = NULL;
  100. }
  101. }
  102. //=============================================================================
  103. //
  104. // CDispShoreManager
  105. //
  106. class CDispShoreManager : public IDispShoreManager
  107. {
  108. public:
  109. CDispShoreManager();
  110. ~CDispShoreManager();
  111. // Interface.
  112. bool Init( void );
  113. void Shutdown( void );
  114. int GetShorelineCount( void );
  115. Shoreline_t *GetShoreline( int nShorelineId );
  116. void AddShoreline( int nShorelineId );
  117. void RemoveShoreline( int nShorelineId );
  118. void BuildShoreline( int nShorelineId, CUtlVector<CMapFace*> &aFaces, CUtlVector<CMapFace*> &aWaterFaces );
  119. void Draw( CRender3D *pRender );
  120. void DebugDraw( CRender3D *pRender );
  121. private:
  122. void BuildShorelineSegments( Shoreline_t *pShoreline, CUtlVector<CMapFace*> &aFaces, CUtlVector<CMapFace*> &aWaterFaces );
  123. void AverageShorelineNormals( Shoreline_t *pShoreline );
  124. void BuildShorelineOverlayPoints( Shoreline_t *pShoreline, CUtlVector<CMapFace*> &aWaterFaces );
  125. void BuildShorelineOverlayPoint( Shoreline_t *pShoreline, int iSegment, CUtlVector<CMapFace*> &aWaterFaces );
  126. bool TexcoordShoreline( Shoreline_t *pShoreline );
  127. void ShorelineLength( Shoreline_t *pShoreline );
  128. void GenerateTexCoord( Shoreline_t *pShoreline, int iSegment, float flLengthToSegment, bool bEnd );
  129. void BuildShorelineOverlays( Shoreline_t *pShoreline );
  130. void CreateOverlays( Shoreline_t *pShoreline, int iSegment );
  131. void DrawShorelines( int iShoreline );
  132. void DrawShorelineNormals( int iShoreline );
  133. void DrawShorelineOverlayPoints( CRender3D *pRender, int iShoreline );
  134. bool ConnectShorelineSegments( Shoreline_t *pShoreline );
  135. int FindShorelineStart( Shoreline_t *pShoreline );
  136. bool IsTouched( Shoreline_t *pShoreline, int iSegment ) { return pShoreline->m_aSegments[iSegment].m_bTouch; }
  137. private:
  138. CUtlVector<Shoreline_t> m_aShorelines;
  139. // Displacement face and water face cache - for building.
  140. CUtlVector<CMapDisp*> m_aDispCache;
  141. };
  142. //-----------------------------------------------------------------------------
  143. // Purpose:
  144. //-----------------------------------------------------------------------------
  145. static CDispShoreManager s_DispShoreManager;
  146. IDispShoreManager *GetShoreManager( void )
  147. {
  148. return &s_DispShoreManager;
  149. }
  150. //-----------------------------------------------------------------------------
  151. // Purpose:
  152. //-----------------------------------------------------------------------------
  153. CDispShoreManager::CDispShoreManager()
  154. {
  155. m_aDispCache.Purge();
  156. m_aShorelines.Purge();
  157. }
  158. //-----------------------------------------------------------------------------
  159. // Purpose:
  160. //-----------------------------------------------------------------------------
  161. CDispShoreManager::~CDispShoreManager()
  162. {
  163. m_aDispCache.Purge();
  164. m_aShorelines.Purge();
  165. }
  166. //-----------------------------------------------------------------------------
  167. // Purpose:
  168. //-----------------------------------------------------------------------------
  169. bool CDispShoreManager::Init( void )
  170. {
  171. return true;
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Purpose:
  175. //-----------------------------------------------------------------------------
  176. void CDispShoreManager::Shutdown( void )
  177. {
  178. }
  179. //-----------------------------------------------------------------------------
  180. // Purpose:
  181. //-----------------------------------------------------------------------------
  182. int CDispShoreManager::GetShorelineCount( void )
  183. {
  184. return m_aShorelines.Count();
  185. }
  186. //-----------------------------------------------------------------------------
  187. // Purpose:
  188. //-----------------------------------------------------------------------------
  189. Shoreline_t *CDispShoreManager::GetShoreline( int nShorelineId )
  190. {
  191. int nShorelineCount = m_aShorelines.Count();
  192. for ( int iShoreline = 0; iShoreline < nShorelineCount; ++iShoreline )
  193. {
  194. if ( m_aShorelines[iShoreline].m_nShorelineId == nShorelineId )
  195. return &m_aShorelines[iShoreline];
  196. }
  197. return NULL;
  198. }
  199. //-----------------------------------------------------------------------------
  200. // Purpose:
  201. //-----------------------------------------------------------------------------
  202. void CDispShoreManager::AddShoreline( int nShorelineId )
  203. {
  204. // Check to see if the id is already taken, if so remove it and re-add it.
  205. RemoveShoreline( nShorelineId );
  206. int iShoreline = m_aShorelines.AddToTail();
  207. m_aShorelines[iShoreline].m_nShorelineId = nShorelineId;
  208. }
  209. //-----------------------------------------------------------------------------
  210. // Purpose:
  211. //-----------------------------------------------------------------------------
  212. void CDispShoreManager::RemoveShoreline( int nShorelineId )
  213. {
  214. int nShorelineCount = m_aShorelines.Count();
  215. for ( int iShoreline = ( nShorelineCount - 1 ); iShoreline >= 0; --iShoreline )
  216. {
  217. if ( m_aShorelines[iShoreline].m_nShorelineId == nShorelineId )
  218. {
  219. m_aShorelines.Remove( iShoreline );
  220. }
  221. }
  222. }
  223. //-----------------------------------------------------------------------------
  224. // Purpose:
  225. //-----------------------------------------------------------------------------
  226. void CDispShoreManager::BuildShoreline( int nShorelineId, CUtlVector<CMapFace*> &aFaces, CUtlVector<CMapFace*> &aWaterFaces )
  227. {
  228. // Verify faces to build a shoreline.
  229. if ( ( aFaces.Count() == 0 ) ||( aWaterFaces.Count() == 0 ) )
  230. return;
  231. Shoreline_t *pShoreline = GetShoreline( nShorelineId );
  232. if ( pShoreline )
  233. {
  234. BuildShorelineSegments( pShoreline, aFaces, aWaterFaces );
  235. AverageShorelineNormals( pShoreline );
  236. BuildShorelineOverlayPoints( pShoreline, aWaterFaces );
  237. TexcoordShoreline( pShoreline );
  238. BuildShorelineOverlays( pShoreline );
  239. }
  240. }
  241. //-----------------------------------------------------------------------------
  242. // Purpose:
  243. //-----------------------------------------------------------------------------
  244. void CDispShoreManager::BuildShorelineSegments( Shoreline_t *pShoreline, CUtlVector<CMapFace*> &aFaces, CUtlVector<CMapFace*> &aWaterFaces )
  245. {
  246. int nWaterFaceCount = aWaterFaces.Count();
  247. for ( int iWaterFace = 0; iWaterFace < nWaterFaceCount; ++iWaterFace )
  248. {
  249. int nFaceCount = aFaces.Count();
  250. for ( int iFace = 0; iFace < nFaceCount; ++iFace )
  251. {
  252. CMapFace *pFace = aFaces.Element( iFace );
  253. if ( pFace )
  254. {
  255. if ( !pFace->HasDisp() )
  256. {
  257. // Ignore for now!
  258. }
  259. else
  260. {
  261. // Displacement.
  262. CMapDisp *pDisp = EditDispMgr()->GetDisp( pFace->GetDisp() );
  263. if ( pDisp )
  264. {
  265. pDisp->CreateShoreOverlays( aWaterFaces[iWaterFace], pShoreline );
  266. }
  267. }
  268. }
  269. }
  270. }
  271. }
  272. //-----------------------------------------------------------------------------
  273. // Purpose:
  274. //-----------------------------------------------------------------------------
  275. void CDispShoreManager::AverageShorelineNormals( Shoreline_t *pShoreline )
  276. {
  277. int nSegmentCount = pShoreline->m_aSegments.Count();
  278. if ( nSegmentCount == 0 )
  279. return;
  280. for ( int iSegment1 = 0; iSegment1 < nSegmentCount; ++iSegment1 )
  281. {
  282. for ( int iSegment2 = iSegment1 + 1; iSegment2 < nSegmentCount; ++iSegment2 )
  283. {
  284. int iPoint1 = -1;
  285. int iPoint2 = -1;
  286. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment1].m_vecPoints[0],
  287. pShoreline->m_aSegments[iSegment2].m_vecPoints[0], DISPSHORE_VECTOR_EPS ) )
  288. {
  289. iPoint1 = 0;
  290. iPoint2 = 0;
  291. }
  292. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment1].m_vecPoints[0],
  293. pShoreline->m_aSegments[iSegment2].m_vecPoints[1], DISPSHORE_VECTOR_EPS ) )
  294. {
  295. iPoint1 = 0;
  296. iPoint2 = 1;
  297. }
  298. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment1].m_vecPoints[1],
  299. pShoreline->m_aSegments[iSegment2].m_vecPoints[0], DISPSHORE_VECTOR_EPS ) )
  300. {
  301. iPoint1 = 1;
  302. iPoint2 = 0;
  303. }
  304. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment1].m_vecPoints[1],
  305. pShoreline->m_aSegments[iSegment2].m_vecPoints[1], DISPSHORE_VECTOR_EPS ) )
  306. {
  307. iPoint1 = 1;
  308. iPoint2 = 1;
  309. }
  310. if ( ( iPoint1 != -1 ) && ( iPoint2 != -1 ) )
  311. {
  312. pShoreline->m_aSegments[iSegment2].m_vecPoints[iPoint2] = pShoreline->m_aSegments[iSegment1].m_vecPoints[iPoint1];
  313. Vector vecNormal = pShoreline->m_aSegments[iSegment1].m_vecNormals[iPoint1] + pShoreline->m_aSegments[iSegment2].m_vecNormals[iPoint2];
  314. VectorNormalize( vecNormal );
  315. pShoreline->m_aSegments[iSegment1].m_vecNormals[iPoint1] = vecNormal;
  316. pShoreline->m_aSegments[iSegment2].m_vecNormals[iPoint2] = vecNormal;
  317. }
  318. }
  319. }
  320. }
  321. //-----------------------------------------------------------------------------
  322. // Purpose:
  323. //-----------------------------------------------------------------------------
  324. void CDispShoreManager::BuildShorelineOverlayPoints( Shoreline_t *pShoreline, CUtlVector<CMapFace*> &aWaterFaces )
  325. {
  326. int nSegmentCount = pShoreline->m_aSegments.Count();
  327. if ( nSegmentCount == 0 )
  328. return;
  329. for ( int iSegment = 0; iSegment < nSegmentCount; ++iSegment )
  330. {
  331. BuildShorelineOverlayPoint( pShoreline, iSegment, aWaterFaces );
  332. }
  333. }
  334. //-----------------------------------------------------------------------------
  335. // Purpose:
  336. //-----------------------------------------------------------------------------
  337. void CDispShoreManager::BuildShorelineOverlayPoint( Shoreline_t *pShoreline, int iSegment, CUtlVector<CMapFace*> &aWaterFaces )
  338. {
  339. // Get the displacement manager and segment displacement.
  340. CMapDisp *pDisp = EditDispMgr()->GetDisp( pShoreline->m_aSegments[iSegment].m_hDisp );
  341. if ( !pDisp )
  342. return;
  343. IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
  344. if( !pDispMgr )
  345. return;
  346. // Build a bounding box from the world points.
  347. Vector vecPoints[4];
  348. vecPoints[0] = pShoreline->m_aSegments[iSegment].m_vecPoints[0];
  349. vecPoints[3] = pShoreline->m_aSegments[iSegment].m_vecPoints[1];
  350. vecPoints[1] = vecPoints[0] + ( pShoreline->m_aSegments[iSegment].m_vecNormals[0] * pShoreline->m_ShoreData.m_flWidths[0] );
  351. vecPoints[2] = vecPoints[3] + ( pShoreline->m_aSegments[iSegment].m_vecNormals[1] * pShoreline->m_ShoreData.m_flWidths[0] );
  352. Vector vecWorldMin = vecPoints[0];
  353. Vector vecWorldMax = vecPoints[0];
  354. for ( int iPoint = 1; iPoint < 4; ++iPoint )
  355. {
  356. for ( int iAxis = 0; iAxis < 3; ++iAxis )
  357. {
  358. if ( vecPoints[iPoint][iAxis] < vecWorldMin[iAxis] )
  359. {
  360. vecWorldMin[iAxis] = vecPoints[iPoint][iAxis];
  361. }
  362. if ( vecPoints[iPoint][iAxis] > vecWorldMax[iAxis] )
  363. {
  364. vecWorldMax[iAxis] = vecPoints[iPoint][iAxis];
  365. }
  366. }
  367. }
  368. for ( int iAxis = 0; iAxis < 2; ++iAxis )
  369. {
  370. vecWorldMin[iAxis] -= 1.0f;
  371. vecWorldMax[iAxis] += 1.0f;
  372. }
  373. vecWorldMin.z -= 150.0f;
  374. vecWorldMax.z += 150.0f;
  375. // Build a list of displacements that intersect the bounding box.
  376. CUtlVector<CMapDisp*> m_aDispList;
  377. m_aDispList.Purge();
  378. Vector vecDispMin, vecDispMax;
  379. int nDispCount = pDispMgr->WorldCount();
  380. for ( int iDisp = 0; iDisp < nDispCount; ++iDisp )
  381. {
  382. CMapDisp *pCurDisp = pDispMgr->GetFromWorld( iDisp );
  383. if ( !pCurDisp )
  384. continue;
  385. if ( pCurDisp == pDisp )
  386. continue;
  387. // Check for intersections.
  388. pCurDisp->GetBoundingBox( vecDispMin, vecDispMax );
  389. if ( IsBoxIntersectingBox( vecWorldMin, vecWorldMax, vecDispMin, vecDispMax ) )
  390. {
  391. m_aDispList.AddToTail( pCurDisp );
  392. }
  393. }
  394. // World points.
  395. CMapFace *pFace = static_cast<CMapFace*>( pDisp->GetParent() );
  396. for ( int iFace = 0; iFace < 4; ++iFace )
  397. {
  398. pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[iFace] = pFace;
  399. }
  400. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[0] = pShoreline->m_aSegments[iSegment].m_vecPoints[0];
  401. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[3] = pShoreline->m_aSegments[iSegment].m_vecPoints[1];
  402. Vector vecPoint = pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[0] + ( pShoreline->m_aSegments[iSegment].m_vecNormals[0] * pShoreline->m_ShoreData.m_flWidths[0] );
  403. Vector vecStart( vecPoint.x, vecPoint.y, vecPoint.z + 150.0f );
  404. Vector vecEnd( vecPoint.x, vecPoint.y, vecPoint.z - 150.0f );
  405. Vector vecHit, vecHitNormal;
  406. CMapFace *pHitFace = pFace;
  407. if ( !pDisp->TraceLine( vecHit, vecHitNormal, vecStart, vecEnd ) )
  408. {
  409. nDispCount = m_aDispList.Count();
  410. int iDisp;
  411. for ( iDisp = 0; iDisp < nDispCount; ++iDisp )
  412. {
  413. if ( m_aDispList[iDisp]->TraceLine( vecHit, vecHitNormal, vecStart, vecEnd ) )
  414. {
  415. pHitFace = ( CMapFace* )m_aDispList[iDisp]->GetParent();
  416. break;
  417. }
  418. }
  419. if ( iDisp == nDispCount )
  420. {
  421. pDisp->TraceLineSnapTo( vecHit, vecHitNormal, vecStart, vecEnd );
  422. }
  423. }
  424. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[1] = vecHit;
  425. pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[1] = pHitFace;
  426. vecPoint = pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[3] + ( pShoreline->m_aSegments[iSegment].m_vecNormals[1] * pShoreline->m_ShoreData.m_flWidths[0] );
  427. vecStart.Init( vecPoint.x, vecPoint.y, vecPoint.z + 150.0f );
  428. vecEnd.Init( vecPoint.x, vecPoint.y, vecPoint.z - 150.0f );
  429. pHitFace = pFace;
  430. if ( !pDisp->TraceLine( vecHit, vecHitNormal, vecStart, vecEnd ) )
  431. {
  432. nDispCount = m_aDispList.Count();
  433. int iDisp;
  434. for ( iDisp = 0; iDisp < nDispCount; ++iDisp )
  435. {
  436. if ( m_aDispList[iDisp]->TraceLine( vecHit, vecHitNormal, vecStart, vecEnd ) )
  437. {
  438. pHitFace = ( CMapFace* )m_aDispList[iDisp]->GetParent();
  439. break;
  440. }
  441. }
  442. if ( iDisp == nDispCount )
  443. {
  444. pDisp->TraceLineSnapTo( vecHit, vecHitNormal, vecStart, vecEnd );
  445. }
  446. }
  447. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[2] = vecHit;
  448. pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[2] = pHitFace;
  449. // Water points.
  450. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[0] = pShoreline->m_aSegments[iSegment].m_vecPoints[0] + ( pShoreline->m_aSegments[iSegment].m_vecNormals[0] * -pShoreline->m_ShoreData.m_flWidths[1] );
  451. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[1] = pShoreline->m_aSegments[iSegment].m_vecPoints[0];
  452. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[2] = pShoreline->m_aSegments[iSegment].m_vecPoints[1];
  453. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[3] = pShoreline->m_aSegments[iSegment].m_vecPoints[1] + ( pShoreline->m_aSegments[iSegment].m_vecNormals[1] * -pShoreline->m_ShoreData.m_flWidths[1] );
  454. int nWaterFaceCount = aWaterFaces.Count();
  455. for ( int iWaterFace = 0; iWaterFace < nWaterFaceCount; ++iWaterFace )
  456. {
  457. CMapFace *pWaterFace = aWaterFaces.Element( iWaterFace );
  458. if ( pWaterFace )
  459. {
  460. for ( int iWaterPoint = 0; iWaterPoint < 4; ++iWaterPoint )
  461. {
  462. vecPoint = pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[iWaterPoint];
  463. vecStart.Init( vecPoint.x, vecPoint.y, vecPoint.z + 150.0f );
  464. vecEnd.Init( vecPoint.x, vecPoint.y, vecPoint.z - 150.0f );
  465. if ( pWaterFace->TraceLineInside( vecHit, vecHitNormal, vecStart, vecEnd ) )
  466. {
  467. pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[iWaterPoint] = pWaterFace;
  468. }
  469. }
  470. }
  471. }
  472. // Water face clean up!
  473. int nNoFaceCount = false;
  474. for ( int iWaterPoint = 0; iWaterPoint < 4; ++iWaterPoint )
  475. {
  476. if ( !pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[iWaterPoint] )
  477. {
  478. ++nNoFaceCount;
  479. }
  480. }
  481. if ( ( nNoFaceCount > 0 ) && ( nNoFaceCount < 4 ) )
  482. {
  483. // Find a valid face.
  484. CMapFace *pWaterFace = NULL;
  485. for ( int iWaterPoint = 0; iWaterPoint < 4; ++iWaterPoint )
  486. {
  487. if ( pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[iWaterPoint] )
  488. {
  489. pWaterFace = pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[iWaterPoint];
  490. break;
  491. }
  492. }
  493. for ( int iWaterPoint = 0; iWaterPoint < 4; ++iWaterPoint )
  494. {
  495. if ( !pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[iWaterPoint] )
  496. {
  497. pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[iWaterPoint] = pWaterFace;
  498. }
  499. }
  500. }
  501. // Center.
  502. pShoreline->m_aSegments[iSegment].m_vecCenter = ( pShoreline->m_aSegments[iSegment].m_vecPoints[0] + pShoreline->m_aSegments[iSegment].m_vecPoints[1] ) * 0.5f;
  503. // Check winding.
  504. Vector vecEdge0, vecEdge1, vecCross;
  505. pShoreline->m_aSegments[iSegment].m_WorldFace.m_bAdjWinding = false;
  506. VectorSubtract( pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[1], pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[0], vecEdge0 );
  507. VectorSubtract( pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[2], pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[0], vecEdge1 );
  508. VectorNormalize( vecEdge0 );
  509. VectorNormalize( vecEdge1 );
  510. CrossProduct( vecEdge1, vecEdge0, vecCross );
  511. if ( vecCross.z < 0.0f )
  512. {
  513. // Adjust winding.
  514. Vector vecTmp = pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[1];
  515. CMapFace *pTmpFace = pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[1];
  516. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[1] = pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[3];
  517. pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[1] = pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[3];
  518. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[3] = vecTmp;
  519. pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[3] = pTmpFace;
  520. pShoreline->m_aSegments[iSegment].m_WorldFace.m_bAdjWinding = true;
  521. }
  522. pShoreline->m_aSegments[iSegment].m_WaterFace.m_bAdjWinding = false;
  523. VectorSubtract( pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[1], pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[0], vecEdge0 );
  524. VectorSubtract( pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[2], pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[0], vecEdge1 );
  525. VectorNormalize( vecEdge0 );
  526. VectorNormalize( vecEdge1 );
  527. CrossProduct( vecEdge1, vecEdge0, vecCross );
  528. if ( vecCross.z < 0.0f )
  529. {
  530. // Adjust winding.
  531. Vector vecTmp = pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[1];
  532. CMapFace *pTmpFace = pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[1];
  533. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[1] = pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[3];
  534. pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[1] = pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[3];
  535. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[3] = vecTmp;
  536. pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[3] = pTmpFace;
  537. pShoreline->m_aSegments[iSegment].m_WaterFace.m_bAdjWinding = true;
  538. }
  539. }
  540. //-----------------------------------------------------------------------------
  541. // Purpose:
  542. //-----------------------------------------------------------------------------
  543. bool CDispShoreManager::TexcoordShoreline( Shoreline_t *pShoreline )
  544. {
  545. int nSegmentCount = pShoreline->m_aSegments.Count();
  546. if ( nSegmentCount == 0 )
  547. return false;
  548. // Conncect the shoreline segments to produce a continuous shoreline.
  549. if ( !ConnectShorelineSegments( pShoreline ) )
  550. return false;
  551. ShorelineLength( pShoreline );
  552. float flLengthToSegment = 0.0f;
  553. int nSortedSegmentCount = pShoreline->m_aSortedSegments.Count();
  554. for ( int iSegment = 0; iSegment < nSortedSegmentCount; ++iSegment )
  555. {
  556. int iSortSegment = pShoreline->m_aSortedSegments[iSegment];
  557. GenerateTexCoord( pShoreline, iSortSegment, flLengthToSegment, false );
  558. Vector vecEdge;
  559. VectorSubtract( pShoreline->m_aSegments[iSortSegment].m_vecPoints[1], pShoreline->m_aSegments[iSortSegment].m_vecPoints[0], vecEdge );
  560. flLengthToSegment += vecEdge.Length();
  561. GenerateTexCoord( pShoreline, iSortSegment, flLengthToSegment, true );
  562. }
  563. return true;
  564. }
  565. //-----------------------------------------------------------------------------
  566. // Purpose:
  567. //-----------------------------------------------------------------------------
  568. bool CDispShoreManager::ConnectShorelineSegments( Shoreline_t *pShoreline )
  569. {
  570. // Reset/recreate the shoreline sorted segment list.
  571. pShoreline->m_aSortedSegments.Purge();
  572. int iSegment = FindShorelineStart( pShoreline );
  573. if ( iSegment == -1 )
  574. {
  575. iSegment = 0;
  576. }
  577. int nSegmentCount = pShoreline->m_aSegments.Count();
  578. while ( iSegment != -1 )
  579. {
  580. int iSegment2;
  581. for ( iSegment2 = 0; iSegment2 < nSegmentCount; ++iSegment2 )
  582. {
  583. if ( iSegment2 == iSegment )
  584. continue;
  585. bool bIsTouching0 = false;
  586. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment].m_vecPoints[0], pShoreline->m_aSegments[iSegment2].m_vecPoints[0], DISPSHORE_VECTOR_EPS ) ) { bIsTouching0 = true; }
  587. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment].m_vecPoints[1], pShoreline->m_aSegments[iSegment2].m_vecPoints[0], DISPSHORE_VECTOR_EPS ) ) { bIsTouching0 = true; }
  588. bool bIsTouching1 = false;
  589. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment].m_vecPoints[0], pShoreline->m_aSegments[iSegment2].m_vecPoints[1], DISPSHORE_VECTOR_EPS ) ) { bIsTouching1 = true; }
  590. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment].m_vecPoints[1], pShoreline->m_aSegments[iSegment2].m_vecPoints[1], DISPSHORE_VECTOR_EPS ) ) { bIsTouching1 = true; }
  591. if ( ( bIsTouching0 || bIsTouching1 ) && !IsTouched( pShoreline, iSegment2 ) )
  592. {
  593. pShoreline->m_aSegments[iSegment2].m_iStartPoint = 0;
  594. if ( bIsTouching1 )
  595. {
  596. pShoreline->m_aSegments[iSegment2].m_iStartPoint = 1;
  597. }
  598. pShoreline->m_aSortedSegments.AddToTail( iSegment2 );
  599. pShoreline->m_aSegments[iSegment2].m_bTouch = true;
  600. break;
  601. }
  602. }
  603. if ( iSegment2 != nSegmentCount )
  604. {
  605. iSegment = iSegment2;
  606. }
  607. else
  608. {
  609. iSegment = -1;
  610. }
  611. }
  612. return true;
  613. }
  614. //-----------------------------------------------------------------------------
  615. // Purpose:
  616. //-----------------------------------------------------------------------------
  617. int CDispShoreManager::FindShorelineStart( Shoreline_t *pShoreline )
  618. {
  619. // Find a segment that doesn't have any (fewest) matching point data.
  620. int nSegmentCount = pShoreline->m_aSegments.Count();
  621. for ( int iSegment = 0; iSegment < nSegmentCount; ++iSegment )
  622. {
  623. int nTouchCount = 0;
  624. int iStartPoint = -1;
  625. for ( int iSegment2 = 0; iSegment2 < nSegmentCount; ++iSegment2 )
  626. {
  627. if ( iSegment == iSegment2 )
  628. continue;
  629. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment].m_vecPoints[0], pShoreline->m_aSegments[iSegment2].m_vecPoints[0], DISPSHORE_VECTOR_EPS ) )
  630. {
  631. ++nTouchCount;
  632. iStartPoint = 1;
  633. }
  634. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment].m_vecPoints[0], pShoreline->m_aSegments[iSegment2].m_vecPoints[1], DISPSHORE_VECTOR_EPS ) )
  635. {
  636. ++nTouchCount;
  637. iStartPoint = 1;
  638. }
  639. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment].m_vecPoints[1], pShoreline->m_aSegments[iSegment2].m_vecPoints[0], DISPSHORE_VECTOR_EPS ) )
  640. {
  641. ++nTouchCount;
  642. iStartPoint = 0;
  643. }
  644. if ( VectorsAreEqual( pShoreline->m_aSegments[iSegment].m_vecPoints[1], pShoreline->m_aSegments[iSegment2].m_vecPoints[1], DISPSHORE_VECTOR_EPS ) )
  645. {
  646. ++nTouchCount;
  647. iStartPoint = 0;
  648. }
  649. }
  650. if ( nTouchCount == 1 )
  651. {
  652. pShoreline->m_aSegments[iSegment].m_iStartPoint = iStartPoint;
  653. pShoreline->m_aSortedSegments.AddToTail( iSegment );
  654. pShoreline->m_aSegments[iSegment].m_bTouch = true;
  655. return iSegment;
  656. }
  657. }
  658. return -1;
  659. }
  660. //-----------------------------------------------------------------------------
  661. // Purpose:
  662. //-----------------------------------------------------------------------------
  663. void CDispShoreManager::ShorelineLength( Shoreline_t *pShoreline )
  664. {
  665. float flLength = 0.0f;
  666. int nSegmentCount = pShoreline->m_aSegments.Count();
  667. for ( int iSegment = 0; iSegment < nSegmentCount; ++iSegment )
  668. {
  669. Vector vecEdge;
  670. VectorSubtract( pShoreline->m_aSegments[iSegment].m_vecPoints[1], pShoreline->m_aSegments[iSegment].m_vecPoints[0], vecEdge );
  671. flLength += vecEdge.Length();
  672. }
  673. pShoreline->m_flLength = flLength;
  674. }
  675. //-----------------------------------------------------------------------------
  676. // Purpose:
  677. //-----------------------------------------------------------------------------
  678. void CDispShoreManager::GenerateTexCoord( Shoreline_t *pShoreline, int iSegment, float flLengthToSegment, bool bEnd )
  679. {
  680. float flValue = pShoreline->m_ShoreData.m_vecLengthTexcoord[1] - pShoreline->m_ShoreData.m_vecLengthTexcoord[0];
  681. if ( pShoreline->m_aSegments[iSegment].m_iStartPoint == 0 )
  682. {
  683. if ( !bEnd )
  684. {
  685. float flRatio = flLengthToSegment / pShoreline->m_flLength;
  686. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[0].x = flValue * flRatio;
  687. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[0].x = flValue * flRatio;
  688. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[0].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  689. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[0].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[0];
  690. if ( pShoreline->m_aSegments[iSegment].m_WorldFace.m_bAdjWinding )
  691. {
  692. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[3].x = flValue * flRatio;
  693. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[3].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1];
  694. }
  695. else
  696. {
  697. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[1].x = flValue * flRatio;
  698. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[1].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1];
  699. }
  700. if ( pShoreline->m_aSegments[iSegment].m_WaterFace.m_bAdjWinding )
  701. {
  702. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[3].x = flValue * flRatio;
  703. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[3].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  704. }
  705. else
  706. {
  707. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[1].x = flValue * flRatio;
  708. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[1].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  709. }
  710. }
  711. else
  712. {
  713. float flRatio = flLengthToSegment / pShoreline->m_flLength;
  714. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[2].x = flValue * flRatio;
  715. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[2].x = flValue * flRatio;
  716. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[2].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1];
  717. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[2].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  718. if ( pShoreline->m_aSegments[iSegment].m_WorldFace.m_bAdjWinding )
  719. {
  720. flRatio = flLengthToSegment / pShoreline->m_flLength;
  721. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[1].x = flValue * flRatio;
  722. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[1].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  723. }
  724. else
  725. {
  726. flRatio = flLengthToSegment / pShoreline->m_flLength;
  727. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[3].x = flValue * flRatio;
  728. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[3].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  729. }
  730. if ( pShoreline->m_aSegments[iSegment].m_WaterFace.m_bAdjWinding )
  731. {
  732. flRatio = flLengthToSegment / pShoreline->m_flLength;
  733. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[1].x = flValue * flRatio;
  734. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[1].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[0];
  735. }
  736. else
  737. {
  738. flRatio = flLengthToSegment / pShoreline->m_flLength;
  739. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[3].x = flValue * flRatio;
  740. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[3].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[0];
  741. }
  742. }
  743. }
  744. else
  745. {
  746. if ( !bEnd )
  747. {
  748. float flRatio = flLengthToSegment / pShoreline->m_flLength;
  749. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[2].x = flValue * flRatio;
  750. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[2].x = flValue * flRatio;
  751. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[2].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1];
  752. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[2].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  753. if ( pShoreline->m_aSegments[iSegment].m_WorldFace.m_bAdjWinding )
  754. {
  755. flRatio = flLengthToSegment / pShoreline->m_flLength;
  756. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[1].x = flValue * flRatio;
  757. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[1].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  758. }
  759. else
  760. {
  761. flRatio = flLengthToSegment / pShoreline->m_flLength;
  762. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[3].x = flValue * flRatio;
  763. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[3].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  764. }
  765. if ( pShoreline->m_aSegments[iSegment].m_WaterFace.m_bAdjWinding )
  766. {
  767. flRatio = flLengthToSegment / pShoreline->m_flLength;
  768. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[1].x = flValue * flRatio;
  769. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[1].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[0];
  770. }
  771. else
  772. {
  773. flRatio = flLengthToSegment / pShoreline->m_flLength;
  774. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[3].x = flValue * flRatio;
  775. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[3].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[0];
  776. }
  777. }
  778. else
  779. {
  780. float flRatio = flLengthToSegment / pShoreline->m_flLength;
  781. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[0].x = flValue * flRatio;
  782. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[0].x = flValue * flRatio;
  783. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[0].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  784. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[0].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[0];
  785. if ( pShoreline->m_aSegments[iSegment].m_WorldFace.m_bAdjWinding )
  786. {
  787. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[3].x = flValue * flRatio;
  788. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[3].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1];
  789. }
  790. else
  791. {
  792. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[1].x = flValue * flRatio;
  793. pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords[1].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1];
  794. }
  795. if ( pShoreline->m_aSegments[iSegment].m_WaterFace.m_bAdjWinding )
  796. {
  797. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[3].x = flValue * flRatio;
  798. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[3].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  799. }
  800. else
  801. {
  802. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[1].x = flValue * flRatio;
  803. pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords[1].y = pShoreline->m_ShoreData.m_vecWidthTexcoord[1] * 0.5f;
  804. }
  805. }
  806. }
  807. }
  808. //-----------------------------------------------------------------------------
  809. // Purpose:
  810. //-----------------------------------------------------------------------------
  811. void CDispShoreManager::BuildShorelineOverlays( Shoreline_t *pShoreline )
  812. {
  813. // Reset the list.
  814. if ( pShoreline->m_aOverlays.Count() != 0 )
  815. {
  816. pShoreline->m_aOverlays.Purge();
  817. }
  818. int nSegmentCount = pShoreline->m_aSegments.Count();
  819. if ( nSegmentCount == 0 )
  820. return;
  821. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  822. if ( !pDoc )
  823. return;
  824. for ( int iSegment = 0; iSegment < nSegmentCount; ++iSegment )
  825. {
  826. CMapDisp *pDisp = EditDispMgr()->GetDisp( pShoreline->m_aSegments[iSegment].m_hDisp );
  827. if ( !pDisp )
  828. continue;
  829. CMapFace *pFace = ( CMapFace* )pDisp->GetParent();
  830. if ( !pFace )
  831. continue;
  832. CreateOverlays( pShoreline, iSegment );
  833. }
  834. }
  835. //-----------------------------------------------------------------------------
  836. // Purpose:
  837. //-----------------------------------------------------------------------------
  838. void CDispShoreManager::CreateOverlays( Shoreline_t *pShoreline, int iSegment )
  839. {
  840. // Create the face list than this overlay will act upon.
  841. CUtlVector<CMapFace*> aWorldFaces;
  842. CUtlVector<CMapFace*> aWaterFaces;
  843. for ( int iFace = 0; iFace < 4; ++iFace )
  844. {
  845. if ( !pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[iFace] ||
  846. !pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[iFace] )
  847. return;
  848. // World
  849. if ( aWorldFaces.Find( pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[iFace] ) == -1 )
  850. {
  851. aWorldFaces.AddToTail( pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[iFace] );
  852. }
  853. // Water
  854. if ( aWaterFaces.Find( pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[iFace] ) == -1 )
  855. {
  856. aWaterFaces.AddToTail( pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[iFace] );
  857. }
  858. }
  859. // Create and add data to the world overlay.
  860. int iOverlay = pShoreline->m_aOverlays.AddToTail();
  861. CMapOverlay *pOverlay = &pShoreline->m_aOverlays[iOverlay];
  862. pOverlay->SetOverlayType( OVERLAY_TYPE_SHORE );
  863. pOverlay->Basis_Init( aWorldFaces[0] );
  864. pOverlay->Handles_Init( aWorldFaces[0] );
  865. pOverlay->SideList_Init( aWorldFaces[0] );
  866. int nFaceCount = aWorldFaces.Count();
  867. for ( int iFace = 1; iFace < nFaceCount; ++iFace )
  868. {
  869. pOverlay->SideList_AddFace( aWorldFaces[iFace] );
  870. }
  871. pOverlay->SetLoaded( true );
  872. pOverlay->HandleMoveTo( 0, pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[0], pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[0] );
  873. pOverlay->HandleMoveTo( 1, pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[1], pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[1] );
  874. pOverlay->HandleMoveTo( 2, pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[2], pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[2] );
  875. pOverlay->HandleMoveTo( 3, pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[3], pShoreline->m_aSegments[iSegment].m_WorldFace.m_pFaces[3] );
  876. if ( !pShoreline->m_ShoreData.m_pTexture )
  877. {
  878. pOverlay->SetMaterial( "decals/decal_signroute004b" );
  879. }
  880. else
  881. {
  882. pOverlay->SetMaterial( pShoreline->m_ShoreData.m_pTexture );
  883. }
  884. pOverlay->SetTexCoords( pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecTexCoords );
  885. pOverlay->CalcBounds( true );
  886. pOverlay->DoClip();
  887. pOverlay->PostUpdate( Notify_Changed );
  888. // Create and add data to the water overlay.
  889. iOverlay = pShoreline->m_aOverlays.AddToTail();
  890. pOverlay = &pShoreline->m_aOverlays[iOverlay];
  891. pOverlay->SetOverlayType( OVERLAY_TYPE_SHORE );
  892. pOverlay->Basis_Init( aWaterFaces[0] );
  893. pOverlay->Handles_Init( aWaterFaces[0] );
  894. pOverlay->SideList_Init( aWaterFaces[0] );
  895. nFaceCount = aWaterFaces.Count();
  896. for ( int iFace = 1; iFace < nFaceCount; ++iFace )
  897. {
  898. pOverlay->SideList_AddFace( aWaterFaces[iFace] );
  899. }
  900. pOverlay->SetLoaded( true );
  901. pOverlay->HandleMoveTo( 0, pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[0], pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[0] );
  902. pOverlay->HandleMoveTo( 1, pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[1], pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[1] );
  903. pOverlay->HandleMoveTo( 2, pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[2], pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[2] );
  904. pOverlay->HandleMoveTo( 3, pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[3], pShoreline->m_aSegments[iSegment].m_WaterFace.m_pFaces[3] );
  905. if ( !pShoreline->m_ShoreData.m_pTexture )
  906. {
  907. pOverlay->SetMaterial( "decals/decal_signroute004b" );
  908. }
  909. else
  910. {
  911. pOverlay->SetMaterial( pShoreline->m_ShoreData.m_pTexture );
  912. }
  913. pOverlay->SetTexCoords( pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecTexCoords );
  914. pOverlay->SetOverlayType( OVERLAY_TYPE_SHORE );
  915. pOverlay->CalcBounds( true );
  916. pOverlay->DoClip();
  917. pOverlay->PostUpdate( Notify_Changed );
  918. }
  919. //-----------------------------------------------------------------------------
  920. // Purpose:
  921. //-----------------------------------------------------------------------------
  922. void CDispShoreManager::Draw( CRender3D *pRender )
  923. {
  924. int nShoreCount = m_aShorelines.Count();
  925. for ( int iShore = 0; iShore < nShoreCount; ++iShore )
  926. {
  927. Shoreline_t *pShoreline = &m_aShorelines[iShore];
  928. if ( pShoreline )
  929. {
  930. int nOverlayCount = pShoreline->m_aOverlays.Count();
  931. for ( int iOverlay = 0; iOverlay < nOverlayCount; ++iOverlay )
  932. {
  933. CMapOverlay *pOverlay = &pShoreline->m_aOverlays[iOverlay];
  934. if ( pOverlay )
  935. {
  936. pOverlay->Render3D( pRender );
  937. }
  938. }
  939. }
  940. }
  941. }
  942. //-----------------------------------------------------------------------------
  943. // Purpose:
  944. //-----------------------------------------------------------------------------
  945. void CDispShoreManager::DebugDraw( CRender3D *pRender )
  946. {
  947. pRender->SetRenderMode( RENDER_MODE_WIREFRAME );
  948. int nShorelineCount = GetShorelineCount();
  949. for ( int iShoreline = 0; iShoreline < nShorelineCount; ++iShoreline )
  950. {
  951. DrawShorelines( iShoreline );
  952. DrawShorelineNormals( iShoreline );
  953. DrawShorelineOverlayPoints( pRender, iShoreline );
  954. }
  955. }
  956. //-----------------------------------------------------------------------------
  957. // Purpose:
  958. //-----------------------------------------------------------------------------
  959. void CDispShoreManager::DrawShorelines( int iShoreline )
  960. {
  961. Shoreline_t *pShoreline = &m_aShorelines[iShoreline];
  962. if ( pShoreline )
  963. {
  964. int nSegmentCount = pShoreline->m_aSegments.Count();
  965. if ( nSegmentCount == 0 )
  966. return;
  967. CMeshBuilder meshBuilder;
  968. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  969. IMesh* pMesh = pRenderContext->GetDynamicMesh();
  970. meshBuilder.Begin( pMesh, MATERIAL_LINES, ( nSegmentCount * 2 ) );
  971. for ( int iSegment = 0; iSegment < nSegmentCount; ++iSegment )
  972. {
  973. meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
  974. meshBuilder.Position3f( pShoreline->m_aSegments[iSegment].m_vecPoints[0].x,
  975. pShoreline->m_aSegments[iSegment].m_vecPoints[0].y,
  976. pShoreline->m_aSegments[iSegment].m_vecPoints[0].z + 50.0f );
  977. meshBuilder.AdvanceVertex();
  978. meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
  979. meshBuilder.Position3f( pShoreline->m_aSegments[iSegment].m_vecPoints[1].x,
  980. pShoreline->m_aSegments[iSegment].m_vecPoints[1].y,
  981. pShoreline->m_aSegments[iSegment].m_vecPoints[1].z + 50.0f );
  982. meshBuilder.AdvanceVertex();
  983. }
  984. meshBuilder.End();
  985. pMesh->Draw();
  986. }
  987. }
  988. //-----------------------------------------------------------------------------
  989. // Purpose:
  990. //-----------------------------------------------------------------------------
  991. void CDispShoreManager::DrawShorelineNormals( int iShoreline )
  992. {
  993. #define DISPSHORE_NORMAL_SCALE 25.0f
  994. Shoreline_t *pShoreline = &m_aShorelines[iShoreline];
  995. if ( pShoreline )
  996. {
  997. int nSegmentCount = pShoreline->m_aSegments.Count();
  998. if ( nSegmentCount == 0 )
  999. return;
  1000. CMeshBuilder meshBuilder;
  1001. CMatRenderContextPtr pRenderContext( materials );
  1002. IMesh* pMesh = pRenderContext->GetDynamicMesh();
  1003. meshBuilder.Begin( pMesh, MATERIAL_LINES, ( nSegmentCount * 4 ) );
  1004. for ( int iSegment = 0; iSegment < nSegmentCount; ++iSegment )
  1005. {
  1006. // Normal for vertex 0.
  1007. meshBuilder.Color3f( 1.0f, 1.0f, 0.0f );
  1008. meshBuilder.Position3f( pShoreline->m_aSegments[iSegment].m_vecPoints[0].x,
  1009. pShoreline->m_aSegments[iSegment].m_vecPoints[0].y,
  1010. pShoreline->m_aSegments[iSegment].m_vecPoints[0].z + 50.0f );
  1011. meshBuilder.AdvanceVertex();
  1012. meshBuilder.Color3f( 1.0f, 1.0f, 0.0f );
  1013. meshBuilder.Position3f( pShoreline->m_aSegments[iSegment].m_vecPoints[0].x + ( pShoreline->m_aSegments[iSegment].m_vecNormals[0].x * DISPSHORE_NORMAL_SCALE ),
  1014. pShoreline->m_aSegments[iSegment].m_vecPoints[0].y + ( pShoreline->m_aSegments[iSegment].m_vecNormals[0].y * DISPSHORE_NORMAL_SCALE ),
  1015. pShoreline->m_aSegments[iSegment].m_vecPoints[0].z + 50.0f + ( pShoreline->m_aSegments[iSegment].m_vecNormals[0].z * DISPSHORE_NORMAL_SCALE ) );
  1016. meshBuilder.AdvanceVertex();
  1017. // Normal for vertex 1.
  1018. meshBuilder.Color3f( 1.0f, 1.0f, 0.0f );
  1019. meshBuilder.Position3f( pShoreline->m_aSegments[iSegment].m_vecPoints[1].x,
  1020. pShoreline->m_aSegments[iSegment].m_vecPoints[1].y,
  1021. pShoreline->m_aSegments[iSegment].m_vecPoints[1].z + 50.0f );
  1022. meshBuilder.AdvanceVertex();
  1023. meshBuilder.Color3f( 1.0f, 1.0f, 0.0f );
  1024. meshBuilder.Position3f( pShoreline->m_aSegments[iSegment].m_vecPoints[1].x + ( pShoreline->m_aSegments[iSegment].m_vecNormals[1].x * DISPSHORE_NORMAL_SCALE ),
  1025. pShoreline->m_aSegments[iSegment].m_vecPoints[1].y + ( pShoreline->m_aSegments[iSegment].m_vecNormals[1].y * DISPSHORE_NORMAL_SCALE ),
  1026. pShoreline->m_aSegments[iSegment].m_vecPoints[1].z + 50.0f + ( pShoreline->m_aSegments[iSegment].m_vecNormals[1].z * DISPSHORE_NORMAL_SCALE ) );
  1027. meshBuilder.AdvanceVertex();
  1028. }
  1029. meshBuilder.End();
  1030. pMesh->Draw();
  1031. }
  1032. #undef DISPSHORE_NORMAL_SCALE
  1033. }
  1034. //-----------------------------------------------------------------------------
  1035. // Purpose:
  1036. //-----------------------------------------------------------------------------
  1037. void CDispShoreManager::DrawShorelineOverlayPoints( CRender3D *pRender, int iShoreline )
  1038. {
  1039. #define DISPSHORE_BOX_SIZE 5.0f
  1040. Shoreline_t *pShoreline = &m_aShorelines[iShoreline];
  1041. if ( pShoreline )
  1042. {
  1043. int nSegmentCount = pShoreline->m_aSegments.Count();
  1044. if ( nSegmentCount == 0 )
  1045. return;
  1046. Vector vecWorldMin, vecWorldMax;
  1047. for ( int iSegment = 0; iSegment < nSegmentCount; ++iSegment )
  1048. {
  1049. for ( int iWorldPoint = 0; iWorldPoint < 4; ++iWorldPoint )
  1050. {
  1051. vecWorldMin = pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[iWorldPoint];
  1052. vecWorldMax = pShoreline->m_aSegments[iSegment].m_WorldFace.m_vecPoints[iWorldPoint];
  1053. for ( int iAxis = 0; iAxis < 3; ++iAxis )
  1054. {
  1055. vecWorldMin[iAxis] -= DISPSHORE_BOX_SIZE;
  1056. vecWorldMax[iAxis] += DISPSHORE_BOX_SIZE;
  1057. }
  1058. pRender->RenderBox( vecWorldMin, vecWorldMax, 255, 0, 0, SELECT_NONE );
  1059. }
  1060. for ( int iWorldPoint = 0; iWorldPoint < 4; ++iWorldPoint )
  1061. {
  1062. vecWorldMin = pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[iWorldPoint];
  1063. vecWorldMax = pShoreline->m_aSegments[iSegment].m_WaterFace.m_vecPoints[iWorldPoint];
  1064. for ( int iAxis = 0; iAxis < 3; ++iAxis )
  1065. {
  1066. vecWorldMin[iAxis] -= DISPSHORE_BOX_SIZE;
  1067. vecWorldMax[iAxis] += DISPSHORE_BOX_SIZE;
  1068. }
  1069. pRender->RenderBox( vecWorldMin, vecWorldMax, 0, 0, 255, SELECT_NONE );
  1070. }
  1071. }
  1072. }
  1073. #undef DISPSHORE_BOX_SIZE
  1074. }