Team Fortress 2 Source Code as on 22/4/2020
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.

389 lines
12 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. //
  4. //=============================================================================
  5. #include <stdafx.h>
  6. #include "MapEntity.h"
  7. #include "MapOverlayTrans.h"
  8. #include "DispShore.h"
  9. #include "TextureSystem.h"
  10. #include "ChunkFile.h"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include <tier0/memdbgon.h>
  13. //-----------------------------------------------------------------------------
  14. // Purpose:
  15. //-----------------------------------------------------------------------------
  16. CMapOverlayTransition::CMapOverlayTransition()
  17. {
  18. m_ShoreData.m_pTexture = NULL;
  19. m_ShoreData.m_vecLengthTexcoord.Init();
  20. m_ShoreData.m_vecWidthTexcoord.Init();
  21. m_ShoreData.m_flWidths[0] = 0.0f;
  22. m_ShoreData.m_flWidths[1] = 0.0f;
  23. m_bIsWater = true;
  24. m_aFaceCache1.Purge();
  25. m_aFaceCache2.Purge();
  26. m_bDebugDraw = false;
  27. }
  28. //-----------------------------------------------------------------------------
  29. // Purpose:
  30. //-----------------------------------------------------------------------------
  31. CMapOverlayTransition::~CMapOverlayTransition()
  32. {
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Purpose:
  36. // NOTE: static
  37. //-----------------------------------------------------------------------------
  38. CMapClass *CMapOverlayTransition::Create( CHelperInfo *pInfo, CMapEntity *pParent )
  39. {
  40. CMapOverlayTransition *pOverlayTrans = new CMapOverlayTransition;
  41. return pOverlayTrans;
  42. }
  43. //-----------------------------------------------------------------------------
  44. // Purpose: Called after the entire map has been loaded. This allows the object
  45. // to perform any linking with other map objects or to do other operations
  46. // that require all world objects to be present.
  47. // Input : pWorld - The world that we are in.
  48. //-----------------------------------------------------------------------------
  49. void CMapOverlayTransition::PostloadWorld( CMapWorld *pWorld )
  50. {
  51. OnApply();
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Purpose:
  55. //-----------------------------------------------------------------------------
  56. void CMapOverlayTransition::CalcBounds( BOOL bFullUpdate )
  57. {
  58. CMapClass::CalcBounds( bFullUpdate );
  59. Shoreline_t *pShoreline = GetShoreManager()->GetShoreline( ( int )GetParent() );
  60. if ( pShoreline )
  61. {
  62. Vector vecMins( 99999.0f, 99999.0f, 99999.0f );
  63. Vector vecMaxs( -99999.0f, -99999.0f, -99999.0f );
  64. m_Render2DBox.ResetBounds();
  65. m_CullBox.ResetBounds();
  66. int nSegmentCount = pShoreline->m_aSegments.Count();
  67. for ( int iSegment = 0; iSegment < nSegmentCount; ++iSegment )
  68. {
  69. for ( int iAxis = 0; iAxis < 3; ++iAxis )
  70. {
  71. if ( pShoreline->m_aSegments[iSegment].m_vecPoints[0][iAxis] < vecMins[iAxis] )
  72. {
  73. vecMins[iAxis] = pShoreline->m_aSegments[iSegment].m_vecPoints[0][iAxis];
  74. }
  75. if ( pShoreline->m_aSegments[iSegment].m_vecPoints[1][iAxis] < vecMins[iAxis] )
  76. {
  77. vecMins[iAxis] = pShoreline->m_aSegments[iSegment].m_vecPoints[1][iAxis];
  78. }
  79. if ( pShoreline->m_aSegments[iSegment].m_vecPoints[0][iAxis] > vecMaxs[iAxis] )
  80. {
  81. vecMaxs[iAxis] = pShoreline->m_aSegments[iSegment].m_vecPoints[0][iAxis];
  82. }
  83. if ( pShoreline->m_aSegments[iSegment].m_vecPoints[1][iAxis] > vecMaxs[iAxis] )
  84. {
  85. vecMaxs[iAxis] = pShoreline->m_aSegments[iSegment].m_vecPoints[1][iAxis];
  86. }
  87. }
  88. }
  89. m_Render2DBox.UpdateBounds( vecMins, vecMaxs );
  90. m_CullBox = m_Render2DBox;
  91. m_BoundingBox = m_CullBox;
  92. }
  93. }
  94. //-----------------------------------------------------------------------------
  95. // Purpose:
  96. //-----------------------------------------------------------------------------
  97. CMapClass *CMapOverlayTransition::Copy( bool bUpdateDependencies )
  98. {
  99. CMapOverlayTransition *pCopy = new CMapOverlayTransition;
  100. if ( pCopy )
  101. {
  102. pCopy->CopyFrom( this, bUpdateDependencies );
  103. }
  104. return pCopy;
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose:
  108. //-----------------------------------------------------------------------------
  109. CMapClass *CMapOverlayTransition::CopyFrom( CMapClass *pObject, bool bUpdateDependencies )
  110. {
  111. // Verify the object is of the correct type and cast.
  112. Assert( pObject->IsMapClass( MAPCLASS_TYPE( CMapOverlayTransition ) ) );
  113. CMapOverlayTransition *pFrom = ( CMapOverlayTransition* )pObject;
  114. if ( pFrom )
  115. {
  116. m_ShoreData.m_pTexture = pFrom->m_ShoreData.m_pTexture;
  117. m_ShoreData.m_vecLengthTexcoord = pFrom->m_ShoreData.m_vecLengthTexcoord;
  118. m_ShoreData.m_vecWidthTexcoord = pFrom->m_ShoreData.m_vecWidthTexcoord;
  119. m_ShoreData.m_flWidths[0] = pFrom->m_ShoreData.m_flWidths[0];
  120. m_ShoreData.m_flWidths[1] = pFrom->m_ShoreData.m_flWidths[1];
  121. }
  122. return this;
  123. }
  124. //-----------------------------------------------------------------------------
  125. // Purpose:
  126. //-----------------------------------------------------------------------------
  127. void CMapOverlayTransition::OnParentKeyChanged( const char* szKey, const char* szValue )
  128. {
  129. // Material data.
  130. if ( !stricmp( szKey, "material" ) )
  131. {
  132. IEditorTexture *pTex = g_Textures.FindActiveTexture( szValue );
  133. if ( pTex )
  134. {
  135. m_ShoreData.m_pTexture = pTex;
  136. }
  137. }
  138. // Texture data.
  139. if ( !stricmp( szKey, "LengthTexcoordStart" ) )
  140. {
  141. m_ShoreData.m_vecLengthTexcoord[0] = atof( szValue );
  142. }
  143. if ( !stricmp( szKey, "LengthTexcoordEnd" ) )
  144. {
  145. m_ShoreData.m_vecLengthTexcoord[1] = atof( szValue );
  146. }
  147. if ( !stricmp( szKey, "WidthTexcoordStart" ) )
  148. {
  149. m_ShoreData.m_vecWidthTexcoord[0] = atof( szValue );
  150. }
  151. if ( !stricmp( szKey, "WidthTexcoordEnd" ) )
  152. {
  153. m_ShoreData.m_vecWidthTexcoord[1] = atof( szValue );
  154. }
  155. // Width data.
  156. if ( !stricmp( szKey, "Width1" ) )
  157. {
  158. m_ShoreData.m_flWidths[0] = atof( szValue );
  159. }
  160. if ( !stricmp( szKey, "Width2" ) )
  161. {
  162. m_ShoreData.m_flWidths[1] = atof( szValue );
  163. }
  164. // Debug data.
  165. if ( !stricmp( szKey, "DebugDraw" ) )
  166. {
  167. m_bDebugDraw = true;
  168. if ( atoi( szValue ) == 0 )
  169. {
  170. m_bDebugDraw = false;
  171. }
  172. }
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Purpose:
  176. //-----------------------------------------------------------------------------
  177. void CMapOverlayTransition::OnNotifyDependent( CMapClass *pObject, Notify_Dependent_t eNotifyType )
  178. {
  179. }
  180. //-----------------------------------------------------------------------------
  181. // Purpose:
  182. //-----------------------------------------------------------------------------
  183. void CMapOverlayTransition::OnAddToWorld( CMapWorld *pWorld )
  184. {
  185. OnApply();
  186. }
  187. //-----------------------------------------------------------------------------
  188. // Purpose:
  189. //-----------------------------------------------------------------------------
  190. void CMapOverlayTransition::OnRemoveFromWorld( CMapWorld *pWorld, bool bNotifyChildren )
  191. {
  192. GetShoreManager()->RemoveShoreline( ( int )GetParent() );
  193. }
  194. //-----------------------------------------------------------------------------
  195. // Purpose:
  196. //-----------------------------------------------------------------------------
  197. void CMapOverlayTransition::OnUndoRedo( void )
  198. {
  199. }
  200. //-----------------------------------------------------------------------------
  201. // Purpose:
  202. //-----------------------------------------------------------------------------
  203. void CMapOverlayTransition::DoTransform( const VMatrix& matrix )
  204. {
  205. return;
  206. }
  207. //-----------------------------------------------------------------------------
  208. // Purpose:
  209. //-----------------------------------------------------------------------------
  210. void CMapOverlayTransition::OnPaste( CMapClass *pCopy, CMapWorld *pSourceWorld, CMapWorld *pDestWorld, const CMapObjectList &OriginalList, CMapObjectList &NewList)
  211. {
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Purpose:
  215. //-----------------------------------------------------------------------------
  216. void CMapOverlayTransition::OnClone( CMapClass *pClone, CMapWorld *pWorld, const CMapObjectList &OriginalList, CMapObjectList &NewList )
  217. {
  218. }
  219. //-----------------------------------------------------------------------------
  220. // Purpose:
  221. //-----------------------------------------------------------------------------
  222. void CMapOverlayTransition::Render3D( CRender3D *pRender )
  223. {
  224. GetShoreManager()->Draw( pRender );
  225. if ( m_bDebugDraw )
  226. {
  227. GetShoreManager()->DebugDraw( pRender );
  228. }
  229. }
  230. //-----------------------------------------------------------------------------
  231. // Purpose: Generate a face list from the parent entities' side list child.
  232. //-----------------------------------------------------------------------------
  233. bool CMapOverlayTransition::BuildFaceCaches( void )
  234. {
  235. CMapEntity *pEntity = dynamic_cast<CMapEntity*>( GetParent() );
  236. if ( pEntity )
  237. {
  238. const CMapObjectList *pChildren = pEntity->GetChildren();
  239. FOR_EACH_OBJ( *pChildren, pos )
  240. {
  241. CMapSideList *pSideList = dynamic_cast<CMapSideList*>( pChildren->Element(pos) );
  242. if ( pSideList )
  243. {
  244. // Check name.
  245. if ( !stricmp( "sides" ,pSideList->GetKeyName() ) )
  246. {
  247. int nFaceCount = pSideList->GetFaceCount();
  248. for ( int iFace = 0; iFace < nFaceCount; ++iFace )
  249. {
  250. m_aFaceCache1.AddToTail( pSideList->GetFace( iFace ) );
  251. }
  252. }
  253. else if ( !stricmp( "sides2", pSideList->GetKeyName() ) )
  254. {
  255. int nFaceCount = pSideList->GetFaceCount();
  256. for ( int iFace = 0; iFace < nFaceCount; ++iFace )
  257. {
  258. if ( m_bIsWater )
  259. {
  260. // Verify that the face is a water face.
  261. if ( pSideList->GetFace( iFace )->GetTexture()->IsWater() )
  262. {
  263. m_aFaceCache2.AddToTail( pSideList->GetFace( iFace ) );
  264. }
  265. }
  266. else
  267. {
  268. m_aFaceCache2.AddToTail( pSideList->GetFace( iFace ) );
  269. }
  270. }
  271. }
  272. }
  273. }
  274. }
  275. return ( ( m_aFaceCache1.Count() > 0 ) && ( m_aFaceCache2.Count() > 0 ) );
  276. }
  277. //-----------------------------------------------------------------------------
  278. // Purpose: Create the transition overlays.
  279. //-----------------------------------------------------------------------------
  280. bool CMapOverlayTransition::OnApply( void )
  281. {
  282. if ( m_bIsWater )
  283. {
  284. // Create the shoreline.
  285. if ( GetShoreManager()->Init() )
  286. {
  287. if ( BuildFaceCaches() )
  288. {
  289. m_nShorelineId = ( int )GetParent();
  290. GetShoreManager()->AddShoreline( m_nShorelineId );
  291. Shoreline_t *pShoreline = GetShoreManager()->GetShoreline( m_nShorelineId );
  292. pShoreline->m_ShoreData = m_ShoreData;
  293. GetShoreManager()->BuildShoreline( m_nShorelineId, m_aFaceCache1, m_aFaceCache2 );
  294. // Clean up the face list.
  295. m_aFaceCache1.Purge();
  296. m_aFaceCache2.Purge();
  297. }
  298. GetShoreManager()->Shutdown();
  299. }
  300. // Post updated.
  301. PostUpdate( Notify_Changed );
  302. return true;
  303. }
  304. else
  305. {
  306. // This part is not implemented yet!
  307. return true;
  308. }
  309. }
  310. //-----------------------------------------------------------------------------
  311. // Purpose:
  312. //-----------------------------------------------------------------------------
  313. ChunkFileResult_t CMapOverlayTransition::LoadVMF( CChunkFile *pFile )
  314. {
  315. // This doesn't need to be implemented until we can "edit" the overlay data. For
  316. // now just regenerate the data.
  317. return ChunkFile_Ok;
  318. }
  319. //-----------------------------------------------------------------------------
  320. // Purpose:
  321. //-----------------------------------------------------------------------------
  322. ChunkFileResult_t CMapOverlayTransition::SaveVMF( CChunkFile *pFile, CSaveInfo *pSaveInfo )
  323. {
  324. ChunkFileResult_t eResult = pFile->BeginChunk("overlaytransition");
  325. m_nShorelineId = ( int )GetParent();
  326. Shoreline_t *pShoreline = GetShoreManager()->GetShoreline( m_nShorelineId );
  327. if ( pShoreline )
  328. {
  329. int nOverlayCount = pShoreline->m_aOverlays.Count();
  330. for ( int iOverlay = 0; iOverlay < nOverlayCount; ++iOverlay )
  331. {
  332. CMapOverlay *pOverlay = &pShoreline->m_aOverlays[iOverlay];
  333. if ( pOverlay )
  334. {
  335. pOverlay->SaveDataToVMF( pFile, pSaveInfo );
  336. }
  337. }
  338. }
  339. if ( eResult == ChunkFile_Ok )
  340. {
  341. eResult = pFile->EndChunk();
  342. }
  343. return eResult;
  344. }