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.

408 lines
13 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //=============================================================================//
  9. #ifndef DISPINFO_H
  10. #define DISPINFO_H
  11. #ifdef _WIN32
  12. #pragma once
  13. #endif
  14. //=============================================================================
  15. #include <assert.h>
  16. #include "idispinfo.h"
  17. #include "bspfile.h"
  18. #include "mathlib/vmatrix.h"
  19. #include "dispnode.h"
  20. #include "builddisp.h"
  21. #include "utlvector.h"
  22. #include "disp_helpers.h"
  23. #include "tier0/fasttimer.h"
  24. #include "dlight.h"
  25. #include "utllinkedlist.h"
  26. #include "zone.h"
  27. struct model_t;
  28. class IMesh;
  29. class CMeshBuilder;
  30. struct ShadowInfo_t;
  31. class CDecalNodeSetupCache;
  32. class CDispInfo : public IDispInfo, public CDispUtilsHelper
  33. {
  34. // IDispInfo overrides.
  35. public:
  36. virtual ~CDispInfo();
  37. virtual void GetIntersectingSurfaces( GetIntersectingSurfaces_Struct *pStruct );
  38. virtual void RenderWireframeInLightmapPage( int pageId );
  39. virtual void GetBoundingBox( Vector& bbMin, Vector& bbMax );
  40. virtual void SetParent( SurfaceHandle_t surfID );
  41. virtual SurfaceHandle_t GetParent(); // returns surfID
  42. // add the dlights on this surface to the lightmap buffer for updload
  43. virtual void AddDynamicLights( dlight_t *pLights, unsigned int lightMask );
  44. // compute which dlights affect this surface
  45. virtual unsigned int ComputeDynamicLightMask( dlight_t *pLights );
  46. virtual DispDecalHandle_t NotifyAddDecal( decal_t *pDecal, float flSize );
  47. virtual void NotifyRemoveDecal( DispDecalHandle_t h );
  48. virtual DispShadowHandle_t AddShadowDecal( ShadowHandle_t shadowHandle );
  49. virtual void RemoveShadowDecal( DispShadowHandle_t handle );
  50. // Compute shadow fragments for a particular shadow
  51. virtual bool ComputeShadowFragments( DispShadowHandle_t h, int& vertexCount, int& indexCount );
  52. virtual bool GetTag();
  53. virtual void SetTag();
  54. public:
  55. //=========================================================================
  56. //
  57. // Construction/Decontruction
  58. //
  59. CDispInfo();
  60. // Used for indexing displacements.
  61. CDispInfo* GetDispByIndex( int index ) { return index == 0xFFFF ? 0 : &m_pDispArray->m_pDispInfos[index]; }
  62. // Get this displacement's index into the main array.
  63. int GetDispIndex() { return this - m_pDispArray->m_pDispInfos; }
  64. //=========================================================================
  65. //
  66. // Flags
  67. //
  68. void SetTouched( bool bTouched );
  69. bool IsTouched( void );
  70. // Rendering.
  71. void ClearLOD();
  72. void DrawDispAxes();
  73. bool Render( CGroupMesh *pGroup, bool bAllowDebugModes );
  74. // Add in the contribution of a dynamic light.
  75. void AddSingleDynamicLight( dlight_t& dl );
  76. void AddSingleDynamicLightBumped( dlight_t& dl );
  77. // Add in the contribution of a dynamic alpha light.
  78. void AddSingleDynamicAlphaLight( dlight_t& dl );
  79. // Cast a ray against this surface
  80. bool TestRay( Ray_t const& ray, float start, float end, float& dist,
  81. Vector2D* lightmapUV, Vector2D* texureUV );
  82. // CDispUtilsHelper implementation.
  83. public:
  84. virtual const CPowerInfo* GetPowerInfo() const;
  85. virtual CDispNeighbor* GetEdgeNeighbor( int index );
  86. virtual CDispCornerNeighbors* GetCornerNeighbors( int index );
  87. virtual CDispUtilsHelper* GetDispUtilsByIndex( int index );
  88. // Initialization functions.
  89. public:
  90. // These are used to mess with indices.
  91. int VertIndex( int x, int y ) const;
  92. int VertIndex( CVertIndex const &vert ) const;
  93. CVertIndex IndexToVert( int index ) const;
  94. // Helpers to test decal intersection bit on decals.
  95. void SetNodeIntersectsDecal( CDispDecal *pDispDecal, CVertIndex const &nodeIndex );
  96. int GetNodeIntersectsDecal( CDispDecal *pDispDecal, CVertIndex const &nodeIndex );
  97. public:
  98. // Copy data from a ddispinfo_t.
  99. void CopyMapDispData( const ddispinfo_t *pBuildDisp );
  100. // This is called from CreateStaticBuffers_All after the CCoreDispInfo is fully
  101. // initialized. It just copies the data that it needs.
  102. bool CopyCoreDispData(
  103. model_t *pWorld,
  104. const MaterialSystem_SortInfo_t *pSortInfos,
  105. const CCoreDispInfo *pInfo,
  106. bool bRestoring );
  107. // called by CopyCoreDispData, just copies the vert data
  108. void CopyCoreDispVertData( const CCoreDispInfo *pInfo, float bumpSTexCoordOffset );
  109. // Checks the SURFDRAW_BUMPLIGHT flag and returns NUM_BUMP_VECTS+1 if it's set
  110. // and 1 if not.
  111. int NumLightMaps();
  112. // This calculates the vertex's position on the base surface.
  113. // (Same result as CCoreDisp::GetFlatVert).
  114. Vector GetFlatVert( int iVertex );
  115. // Rendering functions.
  116. public:
  117. // Set m_BBoxMin and m_BBoxMax. Uses g_TempDispVerts and assumes m_LODs have been validated.
  118. void UpdateBoundingBox();
  119. // Number of verts per side.
  120. int GetSideLength() const;
  121. // Return the total number of vertices.
  122. int NumVerts() const;
  123. // Figure out the vector's projection in the decal's space.
  124. void DecalProjectVert( Vector const &vPos, CDispDecalBase *pDispDecal, ShadowInfo_t const* pInfo, Vector &out );
  125. void CullDecals(
  126. int iNodeBit,
  127. CDispDecal **decals,
  128. int nDecals,
  129. CDispDecal **childDecals,
  130. int &nChildDecals );
  131. void TesselateDisplacement();
  132. // Pass all the mesh data in to the material system.
  133. void SpecifyDynamicMesh();
  134. void SpecifyWalkableDynamicMesh( void );
  135. void SpecifyBuildableDynamicMesh( void );
  136. // Clear all active verts except the corner verts.
  137. void InitializeActiveVerts();
  138. // Returns a particular vertex
  139. CDispRenderVert* GetVertex( int i );
  140. // Methods to compute lightmap coordinates, texture coordinates,
  141. // and lightmap color based on displacement u,v
  142. void ComputeLightmapAndTextureCoordinate( RayDispOutput_t const& output,
  143. Vector2D* luv, Vector2D* tuv );
  144. // This little beastie generate decal fragments
  145. void GenerateDecalFragments( CVertIndex const &nodeIndex,
  146. int iNodeBitIndex, unsigned short decalHandle, CDispDecalBase *pDispDecal );
  147. private:
  148. // Initializes node AABB tree
  149. void UpdateNodeBoundingBoxes();
  150. void UpdateNodeBoundingBoxes_R( CVertIndex const &nodeIndex, int iNodeBitIndex, int iLevel );
  151. // Two functions for adding decals
  152. void TestAddDecalTri( int iIndexStart, unsigned short decalHandle, CDispDecal *pDispDecal );
  153. void TestAddDecalTri( int iIndexStart, unsigned short decalHandle, CDispShadowDecal *pDispDecal );
  154. // Allocates fragments...
  155. CDispDecalFragment* AllocateDispDecalFragment( DispDecalHandle_t h, int nVerts = 6);
  156. // Clears decal fragment lists
  157. void ClearDecalFragments( DispDecalHandle_t h );
  158. void ClearAllDecalFragments();
  159. // Allocates fragments...
  160. CDispShadowFragment* AllocateShadowDecalFragment( DispShadowHandle_t h, int nCount );
  161. // Clears shadow decal fragment lists
  162. void ClearShadowDecalFragments( DispShadowHandle_t h );
  163. void ClearAllShadowDecalFragments();
  164. // Used by GenerateDecalFragments
  165. void GenerateDecalFragments_R( CVertIndex const &nodeIndex,
  166. int iNodeBitIndex, unsigned short decalHandle, CDispDecalBase *pDispDecal, int iLevel );
  167. // Used to create a bitfield to help cull decal tests
  168. void SetupDecalNodeIntersect( CVertIndex const &nodeIndex, int iNodeBitIndex,
  169. CDispDecalBase *pDispDecal, ShadowInfo_t const* pInfo );
  170. // Used by SetupDecalNodeIntersect
  171. bool SetupDecalNodeIntersect_R( CVertIndex const &nodeIndex, int iNodeBitIndex,
  172. CDispDecalBase *pDispDecal, ShadowInfo_t const* pInfo, int iLevel, CDecalNodeSetupCache* pCache );
  173. // Used for hierarchical culling of nodes against shadow frustum
  174. void FindNodesInShadowFrustum( const Frustum_t& frustum, unsigned short* pNodeArray, int* pNumNodes, int iNodeBit, int iLevel );
  175. // Used for clipping and adding all tris in a number of nodes to a shadow decal
  176. void AddNodeTrisToDecal( CDispShadowDecal *pDispDecal, unsigned short decalHandle, unsigned short* pNodeIndices, int nNumIndices );
  177. // Vertex/index data access.
  178. public:
  179. // bounding box
  180. Vector m_BBoxMin;
  181. Vector m_BBoxMax;
  182. int m_nIndices; // The actual # of indices being used (it can be less than m_Indices.Count() if
  183. // our LOD is reducing the triangle count).
  184. int m_iIndexOffset;
  185. // Used to get material..
  186. CGroupMesh *m_pMesh;
  187. int m_iVertOffset;
  188. float m_BumpSTexCoordOffset;
  189. // This can be used to access the vertex data in a platform-independent way.
  190. // XBOX will get them directly out of the static vertex buffer.
  191. // PC gets them out of CDispRenderVerts.
  192. CMeshReader m_MeshReader;
  193. // List of all indices in the displacement in the current tesselation.
  194. // These indices are straight into the static buffer (ie: they're not relative
  195. // to m_iVertOffset).
  196. CUtlVector<unsigned short> m_Indices;
  197. CUtlVector<CDispRenderVert, CHunkMemory<CDispRenderVert> > m_Verts; // vectors that define the surface (size is NumVerts()).
  198. public:
  199. // These bits tell which vertices and nodes are currently active.
  200. // These start out the same as m_ErrorVerts but have verts added if
  201. // a neighbor needs to activate some verts.
  202. CBitVec<CCoreDispInfo::MAX_VERT_COUNT> m_ActiveVerts;
  203. // These are set to 1 if the vert is allowed to become active.
  204. // This is what takes care of different-sized neighbors.
  205. CBitVec<CCoreDispInfo::MAX_VERT_COUNT> m_AllowedVerts;
  206. int m_idLMPage; // lightmap page id
  207. SurfaceHandle_t m_ParentSurfID; // parent surfaceID
  208. int m_iPointStart; // starting point (orientation) on base face
  209. int m_iLightmapAlphaStart;
  210. int m_Contents; // surface contents
  211. public:
  212. bool m_bTouched; // touched flag
  213. int m_fSurfProp; // surface properties flag - bump-mapping, etc.
  214. int m_Power; // surface size (sides are 2^n+1).
  215. unsigned short *m_pTags; // property tags
  216. // Position and texcoordinates at the four corner points
  217. Vector m_BaseSurfacePositions[4];
  218. Vector2D m_BaseSurfaceTexCoords[4];
  219. // Precalculated data for displacements of this size.
  220. const CPowerInfo *m_pPowerInfo;
  221. // Neighbor info for each side, indexed by NEIGHBOREDGE_ enums.
  222. // First 4 are edge neighbors, the rest are corners.
  223. CDispNeighbor m_EdgeNeighbors[4];
  224. CDispCornerNeighbors m_CornerNeighbors[4];
  225. // Copied from the ddispinfo. Speciifes where in g_DispLightmapSamplePositions the (compressed)
  226. // lightmap sample positions start.
  227. int m_iLightmapSamplePositionStart;
  228. // The current triangulation for visualizing tag data.
  229. int m_nWalkIndexCount;
  230. unsigned short *m_pWalkIndices;
  231. int m_nBuildIndexCount;
  232. unsigned short *m_pBuildIndices;
  233. // This here's a bunch of per-node information
  234. DispNodeInfo_t *m_pNodeInfo;
  235. // Where the viewer was when we last tesselated.
  236. // When the viewer moves out of the sphere, UpdateLOD is called.
  237. Vector m_ViewerSphereCenter;
  238. // Used to make sure it doesn't activate verts in the wrong dispinfos.
  239. bool m_bInUse;
  240. // Decals + Shadow decals
  241. DispDecalHandle_t m_FirstDecal;
  242. DispShadowHandle_t m_FirstShadowDecal;
  243. unsigned short m_Index; // helps in debugging
  244. // Current tag value.
  245. unsigned short m_Tag;
  246. CDispArray *m_pDispArray;
  247. };
  248. extern int g_nDispTris;
  249. extern CCycleCount g_DispRenderTime;
  250. extern bool DispInfoRenderDebugModes();
  251. // --------------------------------------------------------------------------------- //
  252. // CDispInfo functions.
  253. // --------------------------------------------------------------------------------- //
  254. inline int CDispInfo::GetSideLength() const
  255. {
  256. return m_pPowerInfo->m_SideLength;
  257. }
  258. inline int CDispInfo::NumVerts() const
  259. {
  260. Assert( m_Verts.Count() == m_pPowerInfo->m_MaxVerts );
  261. return m_pPowerInfo->m_MaxVerts;
  262. }
  263. //-----------------------------------------------------------------------------
  264. // Returns a particular vertex
  265. //-----------------------------------------------------------------------------
  266. inline CDispRenderVert* CDispInfo::GetVertex( int i )
  267. {
  268. Assert( i < NumVerts() );
  269. return &m_Verts[i];
  270. }
  271. //-----------------------------------------------------------------------------
  272. //-----------------------------------------------------------------------------
  273. inline void CDispInfo::SetTouched( bool bTouched )
  274. {
  275. m_bTouched = bTouched;
  276. }
  277. //-----------------------------------------------------------------------------
  278. //-----------------------------------------------------------------------------
  279. inline bool CDispInfo::IsTouched( void )
  280. {
  281. return m_bTouched;
  282. }
  283. inline int CDispInfo::VertIndex( int x, int y ) const
  284. {
  285. Assert( x >= 0 && x < GetSideLength() && y >= 0 && y < GetSideLength() );
  286. return y * GetSideLength() + x;
  287. }
  288. inline int CDispInfo::VertIndex( CVertIndex const &vert ) const
  289. {
  290. Assert( vert.x >= 0 && vert.x < GetSideLength() && vert.y >= 0 && vert.y < GetSideLength() );
  291. return vert.y * GetSideLength() + vert.x;
  292. }
  293. void DispInfo_BatchDecals( CDispInfo **pVisibleDisps, int nVisibleDisps );
  294. void DispInfo_DrawDecals( class IMatRenderContext *pRenderContex, CDispInfo **pVisibleDisps, int nVisibleDisps );
  295. #endif // DISPINFO_H