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.

367 lines
10 KiB

  1. #include "fow_viewer.h"
  2. #include "fow_radiusoccluder.h"
  3. #include "fow_lineoccluder.h"
  4. #include "fow_horizontalslice.h"
  5. #include "fow.h"
  6. #include "engine/IVDebugOverlay.h"
  7. // memdbgon must be the last include file in a .cpp file!!!
  8. #include <tier0/memdbgon.h>
  9. extern IVDebugOverlay *debugoverlay;
  10. //-----------------------------------------------------------------------------
  11. // Purpose: constructor to init this viewer with the id and temp
  12. // Input : nID - the id of this viewer
  13. // nViewerTeam - the team this viewer is on
  14. //-----------------------------------------------------------------------------
  15. CFoW_Viewer::CFoW_Viewer( int nID, unsigned nViewerTeam )
  16. {
  17. m_nID = nID;
  18. m_nViewerTeam = nViewerTeam;
  19. m_vLocation.Init();
  20. m_flRadius = 0.0f;
  21. m_pVisibility = NULL;
  22. m_pVisibilityRadius = NULL;
  23. m_nRadiusUnits = 0;
  24. m_nHeightGroup = 0;
  25. m_nAllocatedMemory = 0;
  26. m_bDirty = true;
  27. }
  28. //-----------------------------------------------------------------------------
  29. // Purpose: destructor to free up the local vis grids
  30. //-----------------------------------------------------------------------------
  31. CFoW_Viewer::~CFoW_Viewer( void )
  32. {
  33. if ( m_pVisibility )
  34. {
  35. free( m_pVisibility );
  36. m_pVisibility = NULL;
  37. }
  38. if ( m_pVisibilityRadius )
  39. {
  40. free( m_pVisibilityRadius );
  41. m_pVisibilityRadius = NULL;
  42. }
  43. }
  44. //-----------------------------------------------------------------------------
  45. // Purpose: update the radius of the viewer. this will realloc the local vis grids
  46. // Input : pFoW - the main FoW object
  47. // flRadius - the new radius
  48. //-----------------------------------------------------------------------------
  49. void CFoW_Viewer::UpdateSize( CFoW *pFoW, float flRadius )
  50. {
  51. m_flRadius = flRadius;
  52. if ( m_pVisibility )
  53. {
  54. free( m_pVisibility );
  55. }
  56. if ( m_pVisibilityRadius )
  57. {
  58. free( m_pVisibilityRadius );
  59. }
  60. m_nAllocatedMemory = 0;
  61. int nGridSize = pFoW->GetHorizontalGridSize();
  62. m_nGridUnits = ( ( m_flRadius * 2 ) + nGridSize - 1 ) / nGridSize;
  63. m_nGridUnits |= 1; // always make it odd, so that we have a true center
  64. m_pVisibility = ( byte * )malloc( sizeof( m_pVisibility[ 0 ] ) * m_nGridUnits * m_nGridUnits );
  65. m_nAllocatedMemory += sizeof( m_pVisibility[ 0 ] ) * m_nGridUnits * m_nGridUnits;
  66. m_nRadiusUnits = ( ( 2 * M_PI * m_flRadius ) + nGridSize - 1 ) / nGridSize;
  67. // m_nRadiusUnits = 360;
  68. m_pVisibilityRadius = ( int * )malloc( sizeof( m_pVisibilityRadius[ 0 ] ) * m_nRadiusUnits );
  69. m_nAllocatedMemory += sizeof( m_pVisibilityRadius[ 0 ] ) * m_nRadiusUnits;
  70. m_pVisibilityTable = pFoW->FindRadiusTable( flRadius );
  71. m_bDirty = true;
  72. }
  73. //-----------------------------------------------------------------------------
  74. // Purpose: update the location of the viewer
  75. // Input : vLocation - the new location
  76. //-----------------------------------------------------------------------------
  77. bool CFoW_Viewer::UpdateLocation( CFoW *pFoW, const Vector &vLocation, Vector *pvOldLocation )
  78. {
  79. Vector vNewLocation = vLocation;
  80. m_vRealLocation = vLocation;
  81. pFoW->CenterCoordToGrid( vNewLocation );
  82. if ( vNewLocation.x != m_vLocation.x || vNewLocation.y != m_vLocation.y )
  83. { // we've moved to a new grid center
  84. m_bDirty = true;
  85. if ( pvOldLocation != NULL )
  86. {
  87. *pvOldLocation = m_vLocation;
  88. }
  89. m_vLocation = vNewLocation;
  90. return true;
  91. }
  92. return false;
  93. }
  94. //-----------------------------------------------------------------------------
  95. // Purpose: update the height group of this viewer
  96. // Input : nHeightGroup - the new height group
  97. //-----------------------------------------------------------------------------
  98. void CFoW_Viewer::UpdateHeightGroup( uint8 nHeightGroup )
  99. {
  100. if ( m_nHeightGroup != nHeightGroup )
  101. {
  102. m_bDirty = true;
  103. }
  104. m_nHeightGroup = nHeightGroup;
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose: get the upper left coords of this viewer
  108. // Output : vResults - the upper left location of this viewer
  109. //-----------------------------------------------------------------------------
  110. void CFoW_Viewer::GetStartPosition( Vector2D &vResults )
  111. {
  112. vResults.x = m_vLocation.x - m_flRadius;
  113. vResults.y = m_vLocation.y - m_flRadius;
  114. }
  115. //-----------------------------------------------------------------------------
  116. // Purpose: get the lower right coords of this viewer
  117. // Output : vResults - the lower right of this viewer
  118. //-----------------------------------------------------------------------------
  119. void CFoW_Viewer::GetEndPosition( Vector2D &vResults )
  120. {
  121. vResults.x = m_vLocation.x + m_flRadius;
  122. vResults.y = m_vLocation.y + m_flRadius;
  123. }
  124. //-----------------------------------------------------------------------------
  125. // Purpose: calculate the localized visibility against all occluders.
  126. // Input : pFoW - the main FoW object
  127. //-----------------------------------------------------------------------------
  128. void CFoW_Viewer::CalcLocalizedVisibility( CFoW *pFoW )
  129. {
  130. if ( m_bDirty == false )
  131. {
  132. return;
  133. }
  134. // DefaultViewingArea( pFoW );
  135. DefaultViewingRadius( pFoW );
  136. pFoW->ObstructOccludersNearViewer( m_nID );
  137. #if 0
  138. int NumOccluders = FoW->GetNumOccluders();
  139. for ( int i = 0; i < NumOccluders; i++ )
  140. {
  141. CFoW_RadiusOccluder *Occluder = FoW->GetOccluder( i );
  142. if ( !Occluder )
  143. {
  144. continue;
  145. }
  146. if ( !Occluder->IsInRange( this ) )
  147. {
  148. continue;
  149. }
  150. Occluder->ObstructViewer( FoW, this );
  151. }
  152. #endif
  153. int nSliceIndex = pFoW->GetHorizontalSlice( m_vLocation.z );
  154. if ( nSliceIndex != -1 )
  155. {
  156. pFoW->GetSlice( nSliceIndex )->ObstructViewer( pFoW, this );
  157. }
  158. ResolveRadius( pFoW );
  159. m_bDirty = false;
  160. }
  161. //-----------------------------------------------------------------------------
  162. // Purpose: clear the localized visibility grid to just the raw radius
  163. // Input : pFoW - the main FoW object
  164. //-----------------------------------------------------------------------------
  165. // use this FOW_VG_DEFAULT_VISIBLE
  166. void CFoW_Viewer::DefaultViewingArea( CFoW *pFoW )
  167. {
  168. memset( m_pVisibility, 0, sizeof( m_pVisibility[ 0 ] ) * m_nGridUnits * m_nGridUnits );
  169. int nGridSize = pFoW->GetHorizontalGridSize();
  170. int nOffset = ( m_nGridUnits / 2 ) * nGridSize;
  171. byte *pVisibility = m_pVisibility;
  172. int nRadius2 = m_flRadius * m_flRadius;
  173. for ( int x = 0, xPos = -nOffset; x < m_nGridUnits; x++, xPos += nGridSize )
  174. {
  175. for ( int y = 0, yPos = -nOffset; y < m_nGridUnits; y++, yPos += nGridSize, pVisibility++ )
  176. {
  177. if ( ( ( xPos * xPos ) + ( yPos * yPos ) ) <= nRadius2 )
  178. {
  179. *pVisibility = FOW_VG_IS_VISIBLE | FOW_VG_DEFAULT_VISIBLE;
  180. }
  181. else
  182. {
  183. *pVisibility = 0;
  184. }
  185. }
  186. }
  187. }
  188. //-----------------------------------------------------------------------------
  189. // Purpose: clear the localized radius grid to the maximum distance
  190. // Input : pFoW - the main FoW object
  191. //-----------------------------------------------------------------------------
  192. void CFoW_Viewer::DefaultViewingRadius( CFoW *pFoW )
  193. {
  194. int nRadius2 = m_flRadius * m_flRadius;
  195. for ( int i = 0; i < m_nRadiusUnits; i++ )
  196. {
  197. m_pVisibilityRadius[ i ] = nRadius2;
  198. }
  199. }
  200. //-----------------------------------------------------------------------------
  201. // Purpose:
  202. // Input :
  203. //-----------------------------------------------------------------------------
  204. void CFoW_Viewer::DrawDebugInfo( Vector &vLocation, float flViewRadius, unsigned nFlags )
  205. {
  206. if ( ( nFlags & ( FOW_DEBUG_SHOW_VIEWERS_TEAM_0 | FOW_DEBUG_SHOW_VIEWERS_TEAM_1 ) ) == 0 )
  207. {
  208. return;
  209. }
  210. Vector vDiff = vLocation - m_vLocation;
  211. if ( vDiff.Length2D() > flViewRadius + m_flRadius )
  212. {
  213. return;
  214. }
  215. if ( ( nFlags & FOW_DEBUG_SHOW_VIEWERS_TEAM_0 ) != 0 )
  216. {
  217. debugoverlay->AddSphereOverlay( m_vLocation, m_flRadius, 10, 10, 0, 255, 0, 127, FOW_DEBUG_VIEW_TIME );
  218. debugoverlay->AddBoxOverlay( m_vLocation, Vector( -16.0f, -16.0f, -16.0f ), Vector( 16.0f, 16.0f, 16.0f ), QAngle( 0, 0, 0 ), 0, 255, 0, 127, FOW_DEBUG_VIEW_TIME );
  219. }
  220. if ( ( nFlags & FOW_DEBUG_SHOW_VIEWERS_TEAM_1 ) != 0 )
  221. {
  222. debugoverlay->AddSphereOverlay( m_vLocation, m_flRadius, 10, 10, 0, 0, 255, 127, FOW_DEBUG_VIEW_TIME );
  223. debugoverlay->AddBoxOverlay( m_vLocation, Vector( -16.0f, -16.0f, -16.0f ), Vector( 16.0f, 16.0f, 16.0f ), QAngle( 0, 0, 0 ), 0, 0, 255, 127, FOW_DEBUG_VIEW_TIME );
  224. }
  225. }
  226. //-----------------------------------------------------------------------------
  227. // Purpose: turn the radius grid into the localized visibility grid
  228. // Input : pFoW - the main FoW object
  229. //-----------------------------------------------------------------------------
  230. void CFoW_Viewer::ResolveRadius( CFoW *pFoW )
  231. {
  232. #if 0
  233. int nGridSize = pFoW->GetHorizontalGridSize();
  234. int nHalfGridSize = nGridSize / 2;
  235. byte *pVisibility = m_pVisibility;
  236. // int Radius2 = m_flRadius * m_flRadius;
  237. for ( int x = 0, xPos = -m_flRadius + nHalfGridSize; x < m_nGridUnits; x++, xPos += nGridSize )
  238. {
  239. for ( int y = 0, yPos = -m_flRadius + nHalfGridSize; y < m_nGridUnits; y++, yPos += nGridSize, pVisibility++ )
  240. {
  241. float flDist = sqrt( ( float )( ( xPos * xPos ) + ( yPos * yPos ) ) );
  242. if ( flDist > m_flRadius )
  243. {
  244. *pVisibility = 0;
  245. continue;
  246. }
  247. float nx = xPos / flDist;
  248. float ny = yPos / flDist;
  249. float flAngle = ( 0 * nx ) + ( 1 * ny );
  250. float flRealAngle = RAD2DEG( acos( flAngle ) );
  251. flAngle = -flAngle + 1;
  252. if ( nx < 0.0f )
  253. {
  254. flAngle = 4 - flAngle;
  255. flRealAngle = 360 - flRealAngle;
  256. }
  257. flAngle /= 4.0f;
  258. flAngle *= m_nRadiusUnits;
  259. flRealAngle = ( flRealAngle / 360.0f ) * m_nRadiusUnits;
  260. if ( flDist <= m_pVisibilityRadius[ ( int )flRealAngle ] )
  261. {
  262. *pVisibility = FOW_VG_IS_VISIBLE;
  263. }
  264. else
  265. {
  266. *pVisibility = 0;
  267. }
  268. }
  269. }
  270. #else
  271. int nGridSize = pFoW->GetHorizontalGridSize();
  272. int nOffset = ( m_nGridUnits / 2 ) * nGridSize;
  273. byte *pVisibility = m_pVisibility;
  274. int *pVisibilityTable = m_pVisibilityTable;
  275. for ( int x = 0, xPos = -nOffset; x < m_nGridUnits; x++, xPos += nGridSize )
  276. {
  277. for ( int y = 0, yPos = -nOffset; y < m_nGridUnits; y++, yPos += nGridSize, pVisibility++, pVisibilityTable++ )
  278. {
  279. if ( ( *pVisibilityTable ) == -1 )
  280. {
  281. *pVisibility = 0;
  282. continue;
  283. }
  284. float flDist = ( ( xPos * xPos ) + ( yPos * yPos ) );
  285. if ( flDist <= m_pVisibilityRadius[ *pVisibilityTable ] )
  286. {
  287. *pVisibility = FOW_VG_IS_VISIBLE;
  288. }
  289. else
  290. {
  291. *pVisibility = 0;
  292. }
  293. }
  294. }
  295. #endif
  296. }
  297. #include <tier0/memdbgoff.h>