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.

246 lines
10 KiB

  1. //========= Copyright � 1996-2009, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: this is the only public access point to the Fog of War routines
  4. //
  5. // $NoKeywords: $
  6. //=====================================================================================//
  7. #ifndef FOW_H
  8. #define FOW_H
  9. #if defined( COMPILER_MSVC )
  10. #pragma once
  11. #endif
  12. #include "utlvector.h"
  13. #include "utlmap.h"
  14. #include "utlspheretree.h"
  15. class CFoW_RadiusOccluder;
  16. class CFoW_Viewer;
  17. class CFoW_TriSoupCollection;
  18. class CFoW_LineOccluder;
  19. class CFoW_HorizontalSlice;
  20. class IFileSystem;
  21. class CPhysCollide;
  22. class IPhysicsCollision;
  23. // maximum number of unique visible sides / teams
  24. #define MAX_FOW_TEAMS 2
  25. // fow does maximum amount of safety checks for data coming into it
  26. #define FOW_SAFETY_DANCE 1
  27. // bit pattern for Visibility Grid
  28. #define FOW_VG_MAX_HEIGHT_GROUP 0x07 // only support height groups from 0 to 7
  29. #define FOW_VG_UNUSED 0x08 // unused
  30. #define FOW_VG_DEFAULT_VISIBLE 0x10 // future optimization to mark default viewing radius
  31. #define FOW_VG_IS_VISIBLE 0x20 // cell is currently visible
  32. #define FOW_VG_WAS_VISIBLE 0x40 // cell has been visible at one point in the past
  33. #define FOW_VG_INVALID 0x80 // invalid cell location
  34. // debug flags
  35. #define FOW_DEBUG_SHOW_VIEWERS_TEAM_0 0x00000001
  36. #define FOW_DEBUG_SHOW_OCCLUDERS 0x00000002
  37. #define FOW_DEBUG_SHOW_GRID 0x00000004
  38. #define FOW_DEBUG_SHOW_VIEWERS_TEAM_1 0x00000008
  39. #define FOW_DEBUG_VIEW_TIME ( 1.0f / 15.0f )
  40. //#define FOW_DEBUG_VIEW_TIME ( 0 )
  41. // fow limits
  42. #define FOW_MAX_VIEWERS_TO_CHECK 100
  43. #define FOW_MAX_RADIUS_OCCLUDERS_TO_CHECK 400
  44. #define FOW_MAX_LINE_OCCLUDERS_TO_CHECK 400
  45. #define FOW_OVER_VISIBILITY 1.5f // keeps around a fully visibile area a bit longer
  46. #define FOW_FADE_DELAY 0.25f; // helps control flickering on edge cases when viewers are moving
  47. class CFoW
  48. {
  49. public:
  50. CFoW( );
  51. ~CFoW( );
  52. // setup
  53. // Frees all memory
  54. void ClearState( );
  55. // Sets the number of viewer teams
  56. void SetNumberOfTeams( int nCount );
  57. // Sets the world mins/maxs and how big the grid sizes should be
  58. void SetSize( Vector &vWorldMins, Vector &vWorldMaxs, int nHorizontalGridSize, int nVerticalGridSize = -1 );
  59. //
  60. void SetCustomVerticalLevels( float *pflHeightLevels, int nCount );
  61. // Sets the visibility degree fade rate ( in seconds )
  62. void SetDegreeFadeRate( float flDegreeFadeRate ) { m_flDegreeFadeRate = flDegreeFadeRate; }
  63. // fow system info
  64. // are we initialized?
  65. bool IsInitialized( ) { return m_bInitialized; }
  66. // get the world size of the FoW
  67. void GetSize( Vector &vWorldMins, Vector &vWorldMaxs );
  68. // get the horizontal grid size
  69. inline int GetHorizontalGridSize( ) { return m_nHorizontalGridSize; }
  70. //
  71. int GetXGridUnits( ) { return m_nGridXUnits; }
  72. //
  73. int GetYGridUnits( ) { return m_nGridYUnits; }
  74. // get the lower vertical coord, the grid size, and grid units
  75. void GetVerticalGridInfo( int &nBottomZ, int &nGridSize, int &nGridUnits, float **pVerticalLevels );
  76. // snap the x/y coordinates to the grid
  77. void SnapCoordsToGrid( Vector &vIn, Vector &vOut, bool bGoLower );
  78. // return how visible a cell is ( 0.0 = not currently visible, 1.0 = fully visible )
  79. float LookupVisibilityDegree( int nXLoc, int nYLoc, int nTeam );
  80. // creates or returns a grid to radius table
  81. int *FindRadiusTable( float flRadius );
  82. //
  83. void CenterCoordToGrid( Vector &vCoords );
  84. // debug info
  85. //
  86. void SetDebugVisibility( bool bVisible );
  87. //
  88. void EnableDebugFlags( unsigned nFlags );
  89. //
  90. void DisableDebugFlags( unsigned nFlags );
  91. //
  92. void DrawDebugInfo( Vector &vLocation, float flViewRadius );
  93. //
  94. void PrintStats( );
  95. // viewers
  96. // adds a new viewer to the system
  97. int AddViewer( unsigned nViewerTeam );
  98. // removes a viewer from the system
  99. void RemoveViewer( int nID );
  100. // updates the viewer's location
  101. void UpdateViewerLocation( int nID, const Vector &vLocation );
  102. // updates the viewer's seeing radius
  103. void UpdateViewerSize( int nID, float flRadius );
  104. // updates the viewer's seeing radius
  105. void UpdateViewerHeightGroup( int nID, uint8 nHeightGroup );
  106. // radius occluders
  107. // adds a new radius occluder to the system
  108. int AddOccluder( bool nPermanent );
  109. // removes an occluder from the system
  110. void RemoveOccluder( int nID );
  111. void EnableOccluder( int nID, bool bEnable );
  112. // returns the total number of radius occluders
  113. inline int GetNumOccluders() { return m_Occluders.Count(); }
  114. // get access to the radius occluder object
  115. inline CFoW_RadiusOccluder *GetOccluder( int nIndex ) { return m_Occluders[ nIndex ]; }
  116. // update an occluder's location
  117. void UpdateOccluderLocation( int nID, Vector &vLocation );
  118. // update an occluder's size
  119. void UpdateOccluderSize( int nID, float flRadius );
  120. // updates the occluder's height group
  121. void UpdateOccluderHeightGroup( int nID, uint8 nHeightGroup );
  122. // internal function called by viewers to radius occlude nearby objects
  123. void ObstructOccludersNearViewer( int nViewerID );
  124. // world occlusion
  125. void SetWorldCollision( CPhysCollide *pCollideable, IPhysicsCollision *pPhysCollision );
  126. // tri soup ( line ) occluders
  127. // adds a tri soup collection to the system
  128. int AddTriSoup( );
  129. // removes a tri soup collection from the system
  130. void RemoveTriSoup( int nID );
  131. // clears all entries from the collection ( useful for hammer editing only )
  132. void ClearTriSoup( int nID );
  133. // adds a tri to the collection. this is immediately split up into the horizontal slices. very slow!
  134. void AddTri( int nID, Vector &vPointA, Vector &vPointB, Vector &vPointC );
  135. //
  136. int GetNumTriSoups( ) { return m_TriSoupCollection.Count(); }
  137. // get access to a tri soup collection object
  138. CFoW_TriSoupCollection *GetTriSoup( int nID );
  139. // add a line occulder from a horizontal slice
  140. void AddTriSoupOccluder( CFoW_LineOccluder *pOccluder, int nSliceNum );
  141. // horizontal slices ( from tri soups )
  142. // get the slice index given the vertical position
  143. int GetHorizontalSlice( float flZPos );
  144. //
  145. float GetSliceZPosition( int nIndex ) { return m_pVerticalLevels[ nIndex ]; }
  146. // get access to the slice object
  147. inline CFoW_HorizontalSlice *GetSlice( int nIndex ) { return m_pHorizontalSlices[ nIndex ]; }
  148. // visibility
  149. // solve the visibility for all teams and all viewers - slow!
  150. void SolveVisibility( float flFrameTime );
  151. // Purpose: returns the visibility info of a location to a team
  152. uint8 GetLocationInfo( unsigned nViewerTeam, const Vector &vLocation );
  153. // Purpose: returns the visibility degree of a location to a team
  154. float GetLocationVisibilityDegree( unsigned nViewerTeam, const Vector &vLocation, float flRadius = 0.0f );
  155. // given the coords and an offset to move BACK, finds the grid location
  156. void GetGridUnits( const Vector &vCoords, float flXOffset, float flYOffset, bool bGoLower, int &nGridX, int &nGridY );
  157. // debug
  158. // Generates a vmf file based upon the current viewers and occluders
  159. void GenerateVMF( IFileSystem *pFileSystem, const char *pszFileName );
  160. private:
  161. // adds an occluder to the sphere tree
  162. void InsertViewerIntoTree( int nIndex );
  163. // removes an occluder from the sphere tree
  164. void RemoveViewerFromTree( int nIndex, Vector *pvOldLocation = NULL );
  165. //
  166. void DirtyViewers( Vector &vLocation, float flRadius );
  167. // adds all occluders back into the visibility tree
  168. void RepopulateOccluders( );
  169. // adds an occluder to the sphere tree
  170. void InsertOccluderIntoTree( int nIndex );
  171. // removes an occluder from the sphere tree
  172. void RemoveOccluderFromTree( int nIndex );
  173. // defaults the viewing grids
  174. void PrepVisibility( );
  175. // updates the viewer grids
  176. void UpdateVisibleAmounts( float flFrameTime );
  177. // given the coords and an offset to move BACK, finds the grid index
  178. int GetGridIndex( const Vector &vCoords, float flXOffset, float flYOffset, bool bGoLower );
  179. // merge a local viewer's visibility to the global grid
  180. void MergeViewerVisibility( int nID );
  181. private:
  182. bool m_bInitialized; // fow system is ready
  183. int m_nNumberOfTeams; // number of teams
  184. Vector m_vWorldMins; // world mins
  185. Vector m_vWorldMaxs; // world maxs
  186. float m_flDegreeFadeRate; // fade in rate for visibility degree
  187. int m_nHorizontalGridSize; // the horizontal ( x y ) grid size
  188. int m_nVerticalGridSize; // the vertical ( z ) grid size
  189. int m_nGridXUnits; // number of X grid pieces ( world X size / horizontal grid size ) rounded up
  190. int m_nGridYUnits; // number of Y grid pieces ( world Y size / horizontal grid size ) rounded up
  191. int m_nTotalHorizontalUnits; // X * Y grid pieces
  192. int m_nGridZUnits; // number of Z grid pieces ( world Z size / vertical grid size ) rounded up
  193. float32 *m_pVisibilityGridDegree[ MAX_FOW_TEAMS ]; // the degree of visibility ( 0.0 = not visible, 1.0 = visible )
  194. float32 *m_pVisibilityFadeTimer[ MAX_FOW_TEAMS ]; // the delay before visibility starts to fade
  195. uint8 *m_pVisibilityGridFlags[ MAX_FOW_TEAMS ]; // flags to indicate visibility status
  196. CFoW_HorizontalSlice **m_pHorizontalSlices; // horizontal line occluder slices from tri soups
  197. float32 *m_pVerticalLevels;
  198. CUtlVector< CFoW_Viewer * > m_Viewers; // the list of all viewers
  199. CUtlVector< CFoW_RadiusOccluder * > m_Occluders; // the list of all radius occluders
  200. CUtlSphereTree m_ViewerTree; // sphere tree for quick finding of nearby viewers
  201. CUtlSphereTree m_OccluderTree; // sphere tree for quick finding of nearby radius occluders
  202. CUtlVector< CFoW_TriSoupCollection * > m_TriSoupCollection; // the list of all tri soups
  203. CUtlMap< float, int * > m_RadiusTables; // the cached visibility tables to go from grid to radius
  204. // debug info
  205. bool m_bDebugVisible;
  206. unsigned m_nDebugFlags;
  207. size_t m_nHorizontalGridAllocationSize;
  208. size_t m_nVerticalGridAllocationSize;
  209. size_t m_nRadiusTableSize;
  210. friend void PrepVisibilityThreaded( CFoW *pFoW );
  211. };
  212. #endif // FOW_H