#pragma once class CTraceListData; class CPhysCollide; class Vector4D; class ITraceListData; struct virtualmeshlist_t; struct BrushSideInfo_t; enum TraceType_t { TRACE_EVERYTHING = 0, TRACE_WORLD_ONLY, TRACE_ENTITIES_ONLY, TRACE_EVERYTHING_FILTER_PROPS, }; enum DebugTraceCounterBehavior_t { kTRACE_COUNTER_SET = 0, kTRACE_COUNTER_INC, }; struct cplane_t { Vector normal; float dist; unsigned char type; unsigned char signbits; unsigned char pad[2]; }; struct csurface_t { const char* name; short surfaceProps; unsigned short flags; }; struct trace_t { Vector startpos; Vector endpos; cplane_t plane; float fraction; int contents; unsigned int dispFlags; bool allsolid; bool startsolid; float fractionleftsolid; csurface_t surface; HitGroups hitgroup; short physicsbone; unsigned short worldSurfaceIndex; C_BaseEntity* m_pEntityHit; int hitbox; }; struct Ray_t { VectorAligned m_Start; VectorAligned m_Delta; VectorAligned m_StartOffset; VectorAligned m_Extents; const matrix3x4_t* m_pWorldAxisTransform; bool m_IsRay; bool m_IsSwept; Ray_t() : m_pWorldAxisTransform(NULL) {} void Init(Vector vecStart, Vector vecEnd) { m_Delta = vecEnd - vecStart; m_IsSwept = (m_Delta.LengthSqr() != 0); m_Extents.x = m_Extents.y = m_Extents.z = 0.0f; m_pWorldAxisTransform = NULL; m_IsRay = true; m_StartOffset.x = m_StartOffset.y = m_StartOffset.z = 0.0f; m_Start = vecStart; } void Init(Vector const& start, Vector const& end, Vector const& mins, Vector const& maxs) { m_Delta = end - start; m_pWorldAxisTransform = NULL; m_IsSwept = (m_Delta.LengthSqr() != 0); m_Extents = maxs - mins; m_Extents *= 0.5f; m_IsRay = (m_Extents.LengthSqr() < 1e-6); // Offset m_Start to be in the center of the box... m_StartOffset = maxs + mins; m_StartOffset *= 0.5f; m_Start = start + m_StartOffset; m_StartOffset *= -1.0f; } }; class ITraceFilter { public: virtual bool ShouldHitEntity(C_BaseEntity* pEntity, int contentsMask) = 0; virtual TraceType_t GetTraceType() const = 0; }; class CTraceFilter : public ITraceFilter { public: bool ShouldHitEntity(C_BaseEntity* pEntityHandle, int contentsMask) { return !(pEntityHandle == pSkip); } virtual TraceType_t GetTraceType() const { return TRACE_EVERYTHING; } void* pSkip; }; class IEntityEnumerator { public: // This gets called with each handle virtual bool EnumEntity(IHandleEntity* pHandleEntity) = 0; }; class CTraceFilterWorldOnly : public ITraceFilter { public: bool ShouldHitEntity(C_BaseEntity* pEntityHandle, int contentsMask) { return false; } TraceType_t GetTraceType() const { return TRACE_WORLD_ONLY; } }; class CTraceFilterEntitiesOnly : public ITraceFilter { public: bool ShouldHitEntity(C_BaseEntity* pEntityHandle, int contentsMask) { return !(pEntityHandle == pSkip); } virtual TraceType_t GetTraceType() const { return TRACE_ENTITIES_ONLY; } void* pSkip; }; class IEngineTrace { public: // Returns the contents mask + entity at a particular world-space position 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. // // If the entity isn't a static prop or a brush model, it returns // CONTENTS_EMPTY and sets bFailed to true if bFailed is non-null. virtual int GetPointContents_Collideable(ICollideable* pCollide, const Vector& vecAbsPosition) = 0; // Traces a ray against a particular entity virtual void ClipRayToEntity(const Ray_t& ray, unsigned int fMask, IHandleEntity* pEnt, trace_t* pTrace) = 0; // Traces a ray against a particular entity virtual void ClipRayToCollideable(const Ray_t& ray, unsigned int fMask, ICollideable* pCollide, trace_t* pTrace) = 0; // A version that simply accepts a ray (can work as a traceline or // tracehull) 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, 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 vecAngles represents the collision angles of the // collideable during the sweep virtual void SweepCollideable(ICollideable* pCollide, const Vector& vecAbsStart, const Vector& vecAbsEnd, const QAngle& vecAngles, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace) = 0; // Enumerates over all entities along a ray // If triggers == true, it enumerates all triggers along a ray virtual void EnumerateEntities(const Ray_t& ray, bool triggers, IEntityEnumerator* pEnumerator) = 0; // Same thing, but enumerate entitys within a box virtual void EnumerateEntities(const Vector& vecAbsMins, const Vector& vecAbsMaxs, IEntityEnumerator* pEnumerator) = 0; // Convert a handle entity to a collideable. Useful inside enumer virtual ICollideable* GetCollideable(IHandleEntity* pEntity) = 0; // HACKHACK: Temp for performance measurments virtual int GetStatByIndex(int index, bool bClear) = 0; // 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; // 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; // 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 true if data is being // returned in the output pointers, false if the brush doesn't exist virtual bool GetBrushInfo(int iBrush, CUtlVector* pBrushSideInfoOut, int* pContentsOut) = 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; };