From 99f0813ba8fb6dcbb92a37f32c8a0b91acced289 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Tue, 22 Dec 2015 09:48:05 -0500 Subject: [PATCH] Update IEngineTrace. --- public/engine/IEngineTrace.h | 115 +++++++++++++++++++++++++++++++---- 1 file changed, 104 insertions(+), 11 deletions(-) diff --git a/public/engine/IEngineTrace.h b/public/engine/IEngineTrace.h index 0a28fa37..9f0cb3f9 100644 --- a/public/engine/IEngineTrace.h +++ b/public/engine/IEngineTrace.h @@ -15,6 +15,7 @@ #include "basehandle.h" #include "utlvector.h" //need CUtlVector for IEngineTrace::GetBrushesIn*() #include "mathlib/vector4d.h" +#include "bspflags.h" class Vector; class IHandleEntity; @@ -23,9 +24,10 @@ class CGameTrace; typedef CGameTrace trace_t; class ICollideable; class QAngle; -class CTraceListData; +class ITraceListData; class CPhysCollide; struct cplane_t; +struct virtualmeshlist_t; //----------------------------------------------------------------------------- // The standard trace filter... NOTE: Most normal traces inherit from CTraceFilter!!! @@ -109,6 +111,12 @@ public: }; +enum DebugTraceCounterBehavior_t +{ + kTRACE_COUNTER_SET = 0, + kTRACE_COUNTER_INC, +}; + //----------------------------------------------------------------------------- // Enumeration interface for EnumerateLinkEntities //----------------------------------------------------------------------------- @@ -120,17 +128,73 @@ public: }; +struct BrushSideInfo_t +{ + cplane_t plane; // The plane of the brush side + unsigned short bevel; // Bevel plane? + unsigned short thin; // Thin? +}; + +//something we can easily create on the stack while easily maintaining our data release contract with IEngineTrace +class CBrushQuery +{ +public: + CBrushQuery( void ) + { + m_iCount = 0; + m_pBrushes = NULL; + m_iMaxBrushSides = 0; + m_pReleaseFunc = NULL; + m_pData = NULL; + } + ~CBrushQuery( void ) + { + ReleasePrivateData(); + } + void ReleasePrivateData( void ) + { + if( m_pReleaseFunc ) + { + m_pReleaseFunc( this ); + } + + m_iCount = 0; + m_pBrushes = NULL; + m_iMaxBrushSides = 0; + m_pReleaseFunc = NULL; + m_pData = NULL; + } + + inline int Count( void ) const { return m_iCount; } + inline uint32 *Base( void ) { return m_pBrushes; } + inline uint32 operator[]( int iIndex ) const { return m_pBrushes[iIndex]; } + inline uint32 GetBrushNumber( int iIndex ) const { return m_pBrushes[iIndex]; } + + //maximum number of sides of any 1 brush in the query results + inline int MaxBrushSides( void ) const { return m_iMaxBrushSides; } + +protected: + int m_iCount; + uint32 *m_pBrushes; + int m_iMaxBrushSides; + void (*m_pReleaseFunc)(CBrushQuery *); //release function is almost always in a different dll than calling code + void *m_pData; +}; + //----------------------------------------------------------------------------- // Interface the engine exposes to the game DLL //----------------------------------------------------------------------------- -#define INTERFACEVERSION_ENGINETRACE_SERVER "EngineTraceServer003" -#define INTERFACEVERSION_ENGINETRACE_CLIENT "EngineTraceClient003" +#define INTERFACEVERSION_ENGINETRACE_SERVER "EngineTraceServer004" +#define INTERFACEVERSION_ENGINETRACE_CLIENT "EngineTraceClient004" abstract_class IEngineTrace { public: // Returns the contents mask + entity at a particular world-space position - virtual int GetPointContents( const Vector &vecAbsPosition, IHandleEntity** ppEntity = NULL ) = 0; + virtual int GetPointContents( const Vector &vecAbsPosition, int contentsMask = MASK_ALL, IHandleEntity** ppEntity = NULL ) = 0; + // Returns the contents mask of the world only @ the world-space position (static props are ignored) + virtual int GetPointContents_WorldOnly( const Vector &vecAbsPosition, int contentsMask = MASK_ALL ) = 0; + // Get the point contents, but only test the specific entity. This works // on static props and brush models. // @@ -148,9 +212,9 @@ public: virtual void TraceRay( const Ray_t &ray, unsigned int fMask, ITraceFilter *pTraceFilter, trace_t *pTrace ) = 0; // A version that sets up the leaf and entity lists and allows you to pass those in for collision. - virtual void SetupLeafAndEntityListRay( const Ray_t &ray, CTraceListData &traceData ) = 0; - virtual void SetupLeafAndEntityListBox( const Vector &vecBoxMin, const Vector &vecBoxMax, CTraceListData &traceData ) = 0; - virtual void TraceRayAgainstLeafAndEntityList( const Ray_t &ray, CTraceListData &traceData, unsigned int fMask, ITraceFilter *pTraceFilter, trace_t *pTrace ) = 0; + virtual void SetupLeafAndEntityListRay( const Ray_t &ray, ITraceListData *pTraceData ) = 0; + virtual void SetupLeafAndEntityListBox( const Vector &vecBoxMin, const Vector &vecBoxMax, ITraceListData *pTraceData ) = 0; + virtual void TraceRayAgainstLeafAndEntityList( const Ray_t &ray, ITraceListData *pTraceData, unsigned int fMask, ITraceFilter *pTraceFilter, trace_t *pTrace ) = 0; // A version that sweeps a collideable through the world // abs start + abs end represents the collision origins you want to sweep the collideable through @@ -173,20 +237,49 @@ public: //finds brushes in an AABB, prone to some false positives - virtual void GetBrushesInAABB( const Vector &vMins, const Vector &vMaxs, CUtlVector *pOutput, int iContentsMask = 0xFFFFFFFF ) = 0; + virtual void GetBrushesInAABB( const Vector &vMins, const Vector &vMaxs, CBrushQuery &BrushQuery, int iContentsMask = 0xFFFFFFFF, int cmodelIndex = 0 ) = 0; //Creates a CPhysCollide out of all displacements wholly or partially contained in the specified AABB virtual CPhysCollide* GetCollidableFromDisplacementsInAABB( const Vector& vMins, const Vector& vMaxs ) = 0; - //retrieve brush planes and contents, returns true if data is being returned in the output pointers, false if the brush doesn't exist - virtual bool GetBrushInfo( int iBrush, CUtlVector *pPlanesOut, int *pContentsOut ) = 0; + // gets the number of displacements in the world + virtual int GetNumDisplacements( ) = 0; + + // gets a specific diplacement mesh + virtual void GetDisplacementMesh( int nIndex, virtualmeshlist_t *pMeshTriList ) = 0; + + //retrieve brush planes and contents, returns zero if the brush doesn't exist, + //returns positive number of sides filled out if the array can hold them all, negative number of slots needed to hold info if the array is too small + virtual int GetBrushInfo( int iBrush, int &ContentsOut, BrushSideInfo_t *pBrushSideInfoOut, int iBrushSideInfoArraySize ) = 0; virtual bool PointOutsideWorld( const Vector &ptTest ) = 0; //Tests a point to see if it's outside any playable area // Walks bsp to find the leaf containing the specified point virtual int GetLeafContainingPoint( const Vector &ptTest ) = 0; + + virtual ITraceListData *AllocTraceListData() = 0; + virtual void FreeTraceListData(ITraceListData *) = 0; + + /// Used only in debugging: get/set/clear/increment the trace debug counter. See comment below for details. + virtual int GetSetDebugTraceCounter( int value, DebugTraceCounterBehavior_t behavior ) = 0; + + //Similar to GetCollidableFromDisplacementsInAABB(). But returns the intermediate mesh data instead of a collideable + virtual int GetMeshesFromDisplacementsInAABB( const Vector& vMins, const Vector& vMaxs, virtualmeshlist_t *pOutputMeshes, int iMaxOutputMeshes ) = 0; + + virtual void GetBrushesInCollideable( ICollideable *pCollideable, CBrushQuery &BrushQuery ) = 0; }; - +/// IEngineTrace::GetSetDebugTraceCounter +/// SET to a negative number to disable. SET to a positive number to reset the counter; it'll tick down by +/// one for each trace, and break into the debugger on hitting zero. INC lets you add or subtract from the +/// counter. In each case it will return the value of the counter BEFORE you set or incremented it. INC 0 +/// to query. This end-around approach is necessary for security: because only the engine knows when we +/// are in a trace, and only the server knows when we are in a think, data must somehow be shared between +/// them. Simply returning a pointer to an address inside the engine in a retail build is unacceptable, +/// and in the PC there is no way to distinguish between retail and non-retail builds at compile time +/// (there is no #define for it). +/// This may seem redundant with the VPROF_INCREMENT_COUNTER( "TraceRay" ), but it's not, because while +/// that's readable across DLLs, there's no way to trap on its exceeding a certain value, nor can we reset +/// it for each think. #endif // ENGINE_IENGINETRACE_H