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

//========= Copyright © 1996-2009, Valve Corporation, All rights reserved. ============//
//
// Purpose: this is the only public access point to the Fog of War routines
//
// $NoKeywords: $
//=====================================================================================//
#ifndef FOW_H
#define FOW_H
#if defined( COMPILER_MSVC )
#pragma once
#endif
#include "utlvector.h"
#include "utlmap.h"
#include "utlspheretree.h"
class CFoW_RadiusOccluder;
class CFoW_Viewer;
class CFoW_TriSoupCollection;
class CFoW_LineOccluder;
class CFoW_HorizontalSlice;
class IFileSystem;
class CPhysCollide;
class IPhysicsCollision;
// maximum number of unique visible sides / teams
#define MAX_FOW_TEAMS 2
// fow does maximum amount of safety checks for data coming into it
#define FOW_SAFETY_DANCE 1
// bit pattern for Visibility Grid
#define FOW_VG_MAX_HEIGHT_GROUP 0x07 // only support height groups from 0 to 7
#define FOW_VG_UNUSED 0x08 // unused
#define FOW_VG_DEFAULT_VISIBLE 0x10 // future optimization to mark default viewing radius
#define FOW_VG_IS_VISIBLE 0x20 // cell is currently visible
#define FOW_VG_WAS_VISIBLE 0x40 // cell has been visible at one point in the past
#define FOW_VG_INVALID 0x80 // invalid cell location
// debug flags
#define FOW_DEBUG_SHOW_VIEWERS_TEAM_0 0x00000001
#define FOW_DEBUG_SHOW_OCCLUDERS 0x00000002
#define FOW_DEBUG_SHOW_GRID 0x00000004
#define FOW_DEBUG_SHOW_VIEWERS_TEAM_1 0x00000008
#define FOW_DEBUG_VIEW_TIME ( 1.0f / 15.0f )
//#define FOW_DEBUG_VIEW_TIME ( 0 )
// fow limits
#define FOW_MAX_VIEWERS_TO_CHECK 100
#define FOW_MAX_RADIUS_OCCLUDERS_TO_CHECK 400
#define FOW_MAX_LINE_OCCLUDERS_TO_CHECK 400
#define FOW_OVER_VISIBILITY 1.5f // keeps around a fully visibile area a bit longer
#define FOW_FADE_DELAY 0.25f; // helps control flickering on edge cases when viewers are moving
class CFoW
{
public:
CFoW( );
~CFoW( );
// setup
// Frees all memory
void ClearState( );
// Sets the number of viewer teams
void SetNumberOfTeams( int nCount );
// Sets the world mins/maxs and how big the grid sizes should be
void SetSize( Vector &vWorldMins, Vector &vWorldMaxs, int nHorizontalGridSize, int nVerticalGridSize = -1 );
//
void SetCustomVerticalLevels( float *pflHeightLevels, int nCount );
// Sets the visibility degree fade rate ( in seconds )
void SetDegreeFadeRate( float flDegreeFadeRate ) { m_flDegreeFadeRate = flDegreeFadeRate; }
// fow system info
// are we initialized?
bool IsInitialized( ) { return m_bInitialized; }
// get the world size of the FoW
void GetSize( Vector &vWorldMins, Vector &vWorldMaxs );
// get the horizontal grid size
inline int GetHorizontalGridSize( ) { return m_nHorizontalGridSize; }
//
int GetXGridUnits( ) { return m_nGridXUnits; }
//
int GetYGridUnits( ) { return m_nGridYUnits; }
// get the lower vertical coord, the grid size, and grid units
void GetVerticalGridInfo( int &nBottomZ, int &nGridSize, int &nGridUnits, float **pVerticalLevels );
// snap the x/y coordinates to the grid
void SnapCoordsToGrid( Vector &vIn, Vector &vOut, bool bGoLower );
// return how visible a cell is ( 0.0 = not currently visible, 1.0 = fully visible )
float LookupVisibilityDegree( int nXLoc, int nYLoc, int nTeam );
// creates or returns a grid to radius table
int *FindRadiusTable( float flRadius );
//
void CenterCoordToGrid( Vector &vCoords );
// debug info
//
void SetDebugVisibility( bool bVisible );
//
void EnableDebugFlags( unsigned nFlags );
//
void DisableDebugFlags( unsigned nFlags );
//
void DrawDebugInfo( Vector &vLocation, float flViewRadius );
//
void PrintStats( );
// viewers
// adds a new viewer to the system
int AddViewer( unsigned nViewerTeam );
// removes a viewer from the system
void RemoveViewer( int nID );
// updates the viewer's location
void UpdateViewerLocation( int nID, const Vector &vLocation );
// updates the viewer's seeing radius
void UpdateViewerSize( int nID, float flRadius );
// updates the viewer's seeing radius
void UpdateViewerHeightGroup( int nID, uint8 nHeightGroup );
// radius occluders
// adds a new radius occluder to the system
int AddOccluder( bool nPermanent );
// removes an occluder from the system
void RemoveOccluder( int nID );
void EnableOccluder( int nID, bool bEnable );
// returns the total number of radius occluders
inline int GetNumOccluders() { return m_Occluders.Count(); }
// get access to the radius occluder object
inline CFoW_RadiusOccluder *GetOccluder( int nIndex ) { return m_Occluders[ nIndex ]; }
// update an occluder's location
void UpdateOccluderLocation( int nID, Vector &vLocation );
// update an occluder's size
void UpdateOccluderSize( int nID, float flRadius );
// updates the occluder's height group
void UpdateOccluderHeightGroup( int nID, uint8 nHeightGroup );
// internal function called by viewers to radius occlude nearby objects
void ObstructOccludersNearViewer( int nViewerID );
// world occlusion
void SetWorldCollision( CPhysCollide *pCollideable, IPhysicsCollision *pPhysCollision );
// tri soup ( line ) occluders
// adds a tri soup collection to the system
int AddTriSoup( );
// removes a tri soup collection from the system
void RemoveTriSoup( int nID );
// clears all entries from the collection ( useful for hammer editing only )
void ClearTriSoup( int nID );
// adds a tri to the collection. this is immediately split up into the horizontal slices. very slow!
void AddTri( int nID, Vector &vPointA, Vector &vPointB, Vector &vPointC );
//
int GetNumTriSoups( ) { return m_TriSoupCollection.Count(); }
// get access to a tri soup collection object
CFoW_TriSoupCollection *GetTriSoup( int nID );
// add a line occulder from a horizontal slice
void AddTriSoupOccluder( CFoW_LineOccluder *pOccluder, int nSliceNum );
// horizontal slices ( from tri soups )
// get the slice index given the vertical position
int GetHorizontalSlice( float flZPos );
//
float GetSliceZPosition( int nIndex ) { return m_pVerticalLevels[ nIndex ]; }
// get access to the slice object
inline CFoW_HorizontalSlice *GetSlice( int nIndex ) { return m_pHorizontalSlices[ nIndex ]; }
// visibility
// solve the visibility for all teams and all viewers - slow!
void SolveVisibility( float flFrameTime );
// Purpose: returns the visibility info of a location to a team
uint8 GetLocationInfo( unsigned nViewerTeam, const Vector &vLocation );
// Purpose: returns the visibility degree of a location to a team
float GetLocationVisibilityDegree( unsigned nViewerTeam, const Vector &vLocation, float flRadius = 0.0f );
// given the coords and an offset to move BACK, finds the grid location
void GetGridUnits( const Vector &vCoords, float flXOffset, float flYOffset, bool bGoLower, int &nGridX, int &nGridY );
// debug
// Generates a vmf file based upon the current viewers and occluders
void GenerateVMF( IFileSystem *pFileSystem, const char *pszFileName );
private:
// adds an occluder to the sphere tree
void InsertViewerIntoTree( int nIndex );
// removes an occluder from the sphere tree
void RemoveViewerFromTree( int nIndex, Vector *pvOldLocation = NULL );
//
void DirtyViewers( Vector &vLocation, float flRadius );
// adds all occluders back into the visibility tree
void RepopulateOccluders( );
// adds an occluder to the sphere tree
void InsertOccluderIntoTree( int nIndex );
// removes an occluder from the sphere tree
void RemoveOccluderFromTree( int nIndex );
// defaults the viewing grids
void PrepVisibility( );
// updates the viewer grids
void UpdateVisibleAmounts( float flFrameTime );
// given the coords and an offset to move BACK, finds the grid index
int GetGridIndex( const Vector &vCoords, float flXOffset, float flYOffset, bool bGoLower );
// merge a local viewer's visibility to the global grid
void MergeViewerVisibility( int nID );
private:
bool m_bInitialized; // fow system is ready
int m_nNumberOfTeams; // number of teams
Vector m_vWorldMins; // world mins
Vector m_vWorldMaxs; // world maxs
float m_flDegreeFadeRate; // fade in rate for visibility degree
int m_nHorizontalGridSize; // the horizontal ( x y ) grid size
int m_nVerticalGridSize; // the vertical ( z ) grid size
int m_nGridXUnits; // number of X grid pieces ( world X size / horizontal grid size ) rounded up
int m_nGridYUnits; // number of Y grid pieces ( world Y size / horizontal grid size ) rounded up
int m_nTotalHorizontalUnits; // X * Y grid pieces
int m_nGridZUnits; // number of Z grid pieces ( world Z size / vertical grid size ) rounded up
float32 *m_pVisibilityGridDegree[ MAX_FOW_TEAMS ]; // the degree of visibility ( 0.0 = not visible, 1.0 = visible )
float32 *m_pVisibilityFadeTimer[ MAX_FOW_TEAMS ]; // the delay before visibility starts to fade
uint8 *m_pVisibilityGridFlags[ MAX_FOW_TEAMS ]; // flags to indicate visibility status
CFoW_HorizontalSlice **m_pHorizontalSlices; // horizontal line occluder slices from tri soups
float32 *m_pVerticalLevels;
CUtlVector< CFoW_Viewer * > m_Viewers; // the list of all viewers
CUtlVector< CFoW_RadiusOccluder * > m_Occluders; // the list of all radius occluders
CUtlSphereTree m_ViewerTree; // sphere tree for quick finding of nearby viewers
CUtlSphereTree m_OccluderTree; // sphere tree for quick finding of nearby radius occluders
CUtlVector< CFoW_TriSoupCollection * > m_TriSoupCollection; // the list of all tri soups
CUtlMap< float, int * > m_RadiusTables; // the cached visibility tables to go from grid to radius
// debug info
bool m_bDebugVisible;
unsigned m_nDebugFlags;
size_t m_nHorizontalGridAllocationSize;
size_t m_nVerticalGridAllocationSize;
size_t m_nRadiusTableSize;
friend void PrepVisibilityThreaded( CFoW *pFoW );
};
#endif // FOW_H