mirror of
https://github.com/celisej567/source-engine.git
synced 2026-09-19 20:09:06 +03:00
1
This commit is contained in:
398
engine/disp.h
Normal file
398
engine/disp.h
Normal file
@@ -0,0 +1,398 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DISPINFO_H
|
||||
#define DISPINFO_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
|
||||
#include <assert.h>
|
||||
#include "idispinfo.h"
|
||||
#include "bspfile.h"
|
||||
#include "mathlib/vmatrix.h"
|
||||
#include "dispnode.h"
|
||||
#include "builddisp.h"
|
||||
#include "utlvector.h"
|
||||
#include "disp_helpers.h"
|
||||
#include "tier0/fasttimer.h"
|
||||
#include "dlight.h"
|
||||
#include "utllinkedlist.h"
|
||||
#include "zone.h"
|
||||
|
||||
struct model_t;
|
||||
class IMesh;
|
||||
class CMeshBuilder;
|
||||
struct ShadowInfo_t;
|
||||
|
||||
class CDecalNodeSetupCache;
|
||||
|
||||
|
||||
|
||||
class CDispInfo : public IDispInfo, public CDispUtilsHelper
|
||||
{
|
||||
// IDispInfo overrides.
|
||||
public:
|
||||
virtual ~CDispInfo();
|
||||
|
||||
virtual void GetIntersectingSurfaces( GetIntersectingSurfaces_Struct *pStruct );
|
||||
virtual void RenderWireframeInLightmapPage( int pageId );
|
||||
|
||||
virtual void GetBoundingBox( Vector& bbMin, Vector& bbMax );
|
||||
|
||||
virtual void SetParent( SurfaceHandle_t surfID );
|
||||
virtual SurfaceHandle_t GetParent(); // returns surfID
|
||||
|
||||
// add the dlights on this surface to the lightmap buffer for updload
|
||||
virtual void AddDynamicLights( dlight_t *pLights, unsigned int lightMask );
|
||||
// compute which dlights affect this surface
|
||||
virtual unsigned int ComputeDynamicLightMask( dlight_t *pLights );
|
||||
|
||||
virtual DispDecalHandle_t NotifyAddDecal( decal_t *pDecal, float flSize );
|
||||
virtual void NotifyRemoveDecal( DispDecalHandle_t h );
|
||||
virtual DispShadowHandle_t AddShadowDecal( ShadowHandle_t shadowHandle );
|
||||
virtual void RemoveShadowDecal( DispShadowHandle_t handle );
|
||||
|
||||
// Compute shadow fragments for a particular shadow
|
||||
virtual bool ComputeShadowFragments( DispShadowHandle_t h, int& vertexCount, int& indexCount );
|
||||
|
||||
virtual bool GetTag();
|
||||
virtual void SetTag();
|
||||
|
||||
public:
|
||||
|
||||
//=========================================================================
|
||||
//
|
||||
// Construction/Decontruction
|
||||
//
|
||||
CDispInfo();
|
||||
|
||||
// Used for indexing displacements.
|
||||
CDispInfo* GetDispByIndex( int index ) { return index == 0xFFFF ? 0 : &m_pDispArray->m_pDispInfos[index]; }
|
||||
|
||||
// Get this displacement's index into the main array.
|
||||
int GetDispIndex() { return this - m_pDispArray->m_pDispInfos; }
|
||||
|
||||
|
||||
//=========================================================================
|
||||
//
|
||||
// Flags
|
||||
//
|
||||
void SetTouched( bool bTouched );
|
||||
bool IsTouched( void );
|
||||
|
||||
// Rendering.
|
||||
void ClearLOD();
|
||||
|
||||
void DrawDispAxes();
|
||||
bool Render( CGroupMesh *pGroup, bool bAllowDebugModes );
|
||||
|
||||
// Add in the contribution of a dynamic light.
|
||||
void AddSingleDynamicLight( dlight_t& dl );
|
||||
void AddSingleDynamicLightBumped( dlight_t& dl );
|
||||
|
||||
// Add in the contribution of a dynamic alpha light.
|
||||
void AddSingleDynamicAlphaLight( dlight_t& dl );
|
||||
|
||||
// Cast a ray against this surface
|
||||
bool TestRay( Ray_t const& ray, float start, float end, float& dist,
|
||||
Vector2D* lightmapUV, Vector2D* texureUV );
|
||||
|
||||
// CDispUtilsHelper implementation.
|
||||
public:
|
||||
|
||||
virtual const CPowerInfo* GetPowerInfo() const;
|
||||
virtual CDispNeighbor* GetEdgeNeighbor( int index );
|
||||
virtual CDispCornerNeighbors* GetCornerNeighbors( int index );
|
||||
virtual CDispUtilsHelper* GetDispUtilsByIndex( int index );
|
||||
|
||||
|
||||
// Initialization functions.
|
||||
public:
|
||||
|
||||
// These are used to mess with indices.
|
||||
int VertIndex( int x, int y ) const;
|
||||
int VertIndex( CVertIndex const &vert ) const;
|
||||
CVertIndex IndexToVert( int index ) const;
|
||||
|
||||
// Helpers to test decal intersection bit on decals.
|
||||
void SetNodeIntersectsDecal( CDispDecal *pDispDecal, CVertIndex const &nodeIndex );
|
||||
int GetNodeIntersectsDecal( CDispDecal *pDispDecal, CVertIndex const &nodeIndex );
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Copy data from a ddispinfo_t.
|
||||
void CopyMapDispData( const ddispinfo_t *pBuildDisp );
|
||||
|
||||
// This is called from CreateStaticBuffers_All after the CCoreDispInfo is fully
|
||||
// initialized. It just copies the data that it needs.
|
||||
bool CopyCoreDispData(
|
||||
model_t *pWorld,
|
||||
const MaterialSystem_SortInfo_t *pSortInfos,
|
||||
const CCoreDispInfo *pInfo,
|
||||
bool bRestoring );
|
||||
|
||||
// called by CopyCoreDispData, just copies the vert data
|
||||
void CopyCoreDispVertData( const CCoreDispInfo *pInfo, float bumpSTexCoordOffset );
|
||||
|
||||
// Checks the SURFDRAW_BUMPLIGHT flag and returns NUM_BUMP_VECTS+1 if it's set
|
||||
// and 1 if not.
|
||||
int NumLightMaps();
|
||||
|
||||
// This calculates the vertex's position on the base surface.
|
||||
// (Same result as CCoreDisp::GetFlatVert).
|
||||
Vector GetFlatVert( int iVertex );
|
||||
|
||||
|
||||
// Rendering functions.
|
||||
public:
|
||||
|
||||
// Set m_BBoxMin and m_BBoxMax. Uses g_TempDispVerts and assumes m_LODs have been validated.
|
||||
void UpdateBoundingBox();
|
||||
|
||||
// Number of verts per side.
|
||||
int GetSideLength() const;
|
||||
|
||||
// Return the total number of vertices.
|
||||
int NumVerts() const;
|
||||
|
||||
// Figure out the vector's projection in the decal's space.
|
||||
void DecalProjectVert( Vector const &vPos, CDispDecalBase *pDispDecal, ShadowInfo_t const* pInfo, Vector &out );
|
||||
|
||||
void CullDecals(
|
||||
int iNodeBit,
|
||||
CDispDecal **decals,
|
||||
int nDecals,
|
||||
CDispDecal **childDecals,
|
||||
int &nChildDecals );
|
||||
|
||||
void TesselateDisplacement();
|
||||
|
||||
// Pass all the mesh data in to the material system.
|
||||
void SpecifyDynamicMesh();
|
||||
void SpecifyWalkableDynamicMesh( void );
|
||||
void SpecifyBuildableDynamicMesh( void );
|
||||
|
||||
// Clear all active verts except the corner verts.
|
||||
void InitializeActiveVerts();
|
||||
|
||||
// Returns a particular vertex
|
||||
CDispRenderVert* GetVertex( int i );
|
||||
|
||||
// Methods to compute lightmap coordinates, texture coordinates,
|
||||
// and lightmap color based on displacement u,v
|
||||
void ComputeLightmapAndTextureCoordinate( RayDispOutput_t const& output,
|
||||
Vector2D* luv, Vector2D* tuv );
|
||||
|
||||
// This little beastie generate decal fragments
|
||||
void GenerateDecalFragments( CVertIndex const &nodeIndex,
|
||||
int iNodeBitIndex, unsigned short decalHandle, CDispDecalBase *pDispDecal );
|
||||
|
||||
private:
|
||||
// Two functions for adding decals
|
||||
void TestAddDecalTri( int iIndexStart, unsigned short decalHandle, CDispDecal *pDispDecal );
|
||||
void TestAddDecalTri( int iIndexStart, unsigned short decalHandle, CDispShadowDecal *pDispDecal );
|
||||
|
||||
// Allocates fragments...
|
||||
CDispDecalFragment* AllocateDispDecalFragment( DispDecalHandle_t h, int nVerts = 6);
|
||||
|
||||
// Clears decal fragment lists
|
||||
void ClearDecalFragments( DispDecalHandle_t h );
|
||||
void ClearAllDecalFragments();
|
||||
|
||||
// Allocates fragments...
|
||||
CDispShadowFragment* AllocateShadowDecalFragment( DispShadowHandle_t h, int nCount );
|
||||
|
||||
// Clears shadow decal fragment lists
|
||||
void ClearShadowDecalFragments( DispShadowHandle_t h );
|
||||
void ClearAllShadowDecalFragments();
|
||||
|
||||
// Used by GenerateDecalFragments
|
||||
void GenerateDecalFragments_R( CVertIndex const &nodeIndex,
|
||||
int iNodeBitIndex, unsigned short decalHandle, CDispDecalBase *pDispDecal, int iLevel );
|
||||
|
||||
// Used to create a bitfield to help cull decal tests
|
||||
void SetupDecalNodeIntersect( CVertIndex const &nodeIndex, int iNodeBitIndex,
|
||||
CDispDecalBase *pDispDecal, ShadowInfo_t const* pInfo );
|
||||
|
||||
// Used by SetupDecalNodeIntersect
|
||||
bool SetupDecalNodeIntersect_R( CVertIndex const &nodeIndex, int iNodeBitIndex,
|
||||
CDispDecalBase *pDispDecal, ShadowInfo_t const* pInfo, int iLevel, CDecalNodeSetupCache* pCache );
|
||||
|
||||
|
||||
// Vertex/index data access.
|
||||
public:
|
||||
|
||||
// bounding box
|
||||
Vector m_BBoxMin;
|
||||
Vector m_BBoxMax;
|
||||
|
||||
int m_nIndices; // The actual # of indices being used (it can be less than m_Indices.Count() if
|
||||
// our LOD is reducing the triangle count).
|
||||
int m_iIndexOffset;
|
||||
// Used to get material..
|
||||
CGroupMesh *m_pMesh;
|
||||
int m_iVertOffset;
|
||||
float m_BumpSTexCoordOffset;
|
||||
|
||||
// This can be used to access the vertex data in a platform-independent way.
|
||||
// XBOX will get them directly out of the static vertex buffer.
|
||||
// PC gets them out of CDispRenderVerts.
|
||||
CMeshReader m_MeshReader;
|
||||
|
||||
// List of all indices in the displacement in the current tesselation.
|
||||
// These indices are straight into the static buffer (ie: they're not relative
|
||||
// to m_iVertOffset).
|
||||
CUtlVector<unsigned short> m_Indices;
|
||||
|
||||
CUtlVector<CDispRenderVert, CHunkMemory<CDispRenderVert> > m_Verts; // vectors that define the surface (size is NumVerts()).
|
||||
|
||||
public:
|
||||
|
||||
// These bits tell which vertices and nodes are currently active.
|
||||
// These start out the same as m_ErrorVerts but have verts added if
|
||||
// a neighbor needs to activate some verts.
|
||||
CBitVec<CCoreDispInfo::MAX_VERT_COUNT> m_ActiveVerts;
|
||||
|
||||
// These are set to 1 if the vert is allowed to become active.
|
||||
// This is what takes care of different-sized neighbors.
|
||||
CBitVec<CCoreDispInfo::MAX_VERT_COUNT> m_AllowedVerts;
|
||||
|
||||
int m_idLMPage; // lightmap page id
|
||||
|
||||
SurfaceHandle_t m_ParentSurfID; // parent surfaceID
|
||||
int m_iPointStart; // starting point (orientation) on base face
|
||||
|
||||
int m_iLightmapAlphaStart;
|
||||
|
||||
int m_Contents; // surface contents
|
||||
|
||||
public:
|
||||
|
||||
bool m_bTouched; // touched flag
|
||||
|
||||
int m_fSurfProp; // surface properties flag - bump-mapping, etc.
|
||||
|
||||
int m_Power; // surface size (sides are 2^n+1).
|
||||
|
||||
unsigned short *m_pTags; // property tags
|
||||
|
||||
// Position and texcoordinates at the four corner points
|
||||
Vector m_BaseSurfacePositions[4];
|
||||
Vector2D m_BaseSurfaceTexCoords[4];
|
||||
|
||||
// Precalculated data for displacements of this size.
|
||||
const CPowerInfo *m_pPowerInfo;
|
||||
|
||||
// Neighbor info for each side, indexed by NEIGHBOREDGE_ enums.
|
||||
// First 4 are edge neighbors, the rest are corners.
|
||||
CDispNeighbor m_EdgeNeighbors[4];
|
||||
CDispCornerNeighbors m_CornerNeighbors[4];
|
||||
|
||||
// Copied from the ddispinfo. Speciifes where in g_DispLightmapSamplePositions the (compressed)
|
||||
// lightmap sample positions start.
|
||||
int m_iLightmapSamplePositionStart;
|
||||
|
||||
// The current triangulation for visualizing tag data.
|
||||
int m_nWalkIndexCount;
|
||||
unsigned short *m_pWalkIndices;
|
||||
|
||||
int m_nBuildIndexCount;
|
||||
unsigned short *m_pBuildIndices;
|
||||
|
||||
// This here's a bunch of per-node information
|
||||
DispNodeInfo_t *m_pNodeInfo;
|
||||
|
||||
// Where the viewer was when we last tesselated.
|
||||
// When the viewer moves out of the sphere, UpdateLOD is called.
|
||||
Vector m_ViewerSphereCenter;
|
||||
|
||||
// Used to make sure it doesn't activate verts in the wrong dispinfos.
|
||||
bool m_bInUse;
|
||||
|
||||
// Decals + Shadow decals
|
||||
DispDecalHandle_t m_FirstDecal;
|
||||
DispShadowHandle_t m_FirstShadowDecal;
|
||||
|
||||
unsigned short m_Index; // helps in debugging
|
||||
|
||||
// Current tag value.
|
||||
unsigned short m_Tag;
|
||||
CDispArray *m_pDispArray;
|
||||
};
|
||||
|
||||
|
||||
extern int g_nDispTris;
|
||||
extern CCycleCount g_DispRenderTime;
|
||||
extern bool DispInfoRenderDebugModes();
|
||||
|
||||
// --------------------------------------------------------------------------------- //
|
||||
// CDispInfo functions.
|
||||
// --------------------------------------------------------------------------------- //
|
||||
|
||||
inline int CDispInfo::GetSideLength() const
|
||||
{
|
||||
return m_pPowerInfo->m_SideLength;
|
||||
}
|
||||
|
||||
|
||||
inline int CDispInfo::NumVerts() const
|
||||
{
|
||||
Assert( m_Verts.Count() == m_pPowerInfo->m_MaxVerts );
|
||||
return m_pPowerInfo->m_MaxVerts;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns a particular vertex
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline CDispRenderVert* CDispInfo::GetVertex( int i )
|
||||
{
|
||||
Assert( i < NumVerts() );
|
||||
return &m_Verts[i];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void CDispInfo::SetTouched( bool bTouched )
|
||||
{
|
||||
m_bTouched = bTouched;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool CDispInfo::IsTouched( void )
|
||||
{
|
||||
return m_bTouched;
|
||||
}
|
||||
|
||||
|
||||
inline int CDispInfo::VertIndex( int x, int y ) const
|
||||
{
|
||||
Assert( x >= 0 && x < GetSideLength() && y >= 0 && y < GetSideLength() );
|
||||
return y * GetSideLength() + x;
|
||||
}
|
||||
|
||||
|
||||
inline int CDispInfo::VertIndex( CVertIndex const &vert ) const
|
||||
{
|
||||
Assert( vert.x >= 0 && vert.x < GetSideLength() && vert.y >= 0 && vert.y < GetSideLength() );
|
||||
return vert.y * GetSideLength() + vert.x;
|
||||
}
|
||||
|
||||
|
||||
void DispInfo_BatchDecals( CDispInfo **pVisibleDisps, int nVisibleDisps );
|
||||
void DispInfo_DrawDecals( CDispInfo **pVisibleDisps, int nVisibleDisps );
|
||||
|
||||
#endif // DISPINFO_H
|
||||
Reference in New Issue
Block a user