mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-19 03:56:10 +08:00
553 lines
18 KiB
C++
553 lines
18 KiB
C++
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================//
|
|
|
|
#ifndef GAMETRACE_H
|
|
#define GAMETRACE_H
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
|
|
#include "cmodel.h"
|
|
#include "Color.h"
|
|
#include "entity2/entityinstance.h"
|
|
#include "mathlib/transform.h"
|
|
#include "tier1/generichash.h"
|
|
#include "tier1/utlvector.h"
|
|
#include "tier1/utlstring.h"
|
|
#include "ispatialpartition.h"
|
|
|
|
class IPhysicsBody;
|
|
class IPhysicsShape;
|
|
|
|
typedef IPhysicsBody* HPhysicsBody;
|
|
typedef IPhysicsShape* HPhysicsShape;
|
|
|
|
enum CollisionFunctionMask_t
|
|
{
|
|
FCOLLISION_FUNC_ENABLE_SOLID_CONTACT = (1<<0),
|
|
FCOLLISION_FUNC_ENABLE_TRACE_QUERY = (1<<1),
|
|
FCOLLISION_FUNC_ENABLE_TOUCH_EVENT = (1<<2),
|
|
FCOLLISION_FUNC_ENABLE_SELF_COLLISIONS = (1<<3),
|
|
FCOLLISION_FUNC_IGNORE_FOR_HITBOX_TEST = (1<<4),
|
|
FCOLLISION_FUNC_ENABLE_TOUCH_PERSISTS = (1<<5),
|
|
};
|
|
|
|
// these are on by default
|
|
#define FCOLLISION_FUNC_DEFAULT (FCOLLISION_FUNC_ENABLE_SOLID_CONTACT | FCOLLISION_FUNC_ENABLE_TRACE_QUERY | FCOLLISION_FUNC_ENABLE_TOUCH_EVENT)
|
|
|
|
enum RnQueryObjectSet
|
|
{
|
|
// AMNOTE:
|
|
// RNQUERY_OBJECTS_STATIC (0x1) is used in
|
|
// CLightQueryGameSystem::OnPostSimulate
|
|
// ray test by loading rays.bin
|
|
// CBaePlayerPawn::IsPlayerAimingAtTarget
|
|
// CBaseRagdoll related
|
|
// CSoundOpvarSetAutoRoomEntity::Spawn
|
|
// CNavSpaceBuildTreeJob
|
|
|
|
// RNQUERY_OBJECTS_STATIC | RNQUERY_OBJECTS_KEYFRAMED (0x3) is used in
|
|
// when decoy hit entity isn't player pawn
|
|
|
|
// RNQUERY_OBJECTS_KEYFRAMED | RNQUERY_OBJECTS_DYNAMIC (0x6) is used in
|
|
// checking if a grenade projectile has hit any player
|
|
// filtering bullet trace result
|
|
// checking if hit entity is a *_door_rotating
|
|
// checking if player is aiming at a CPointCommentaryNode
|
|
|
|
// RNQUERY_OBJECTS_LOCATABLE (0x8) is used in
|
|
// checking if a CSmokeGrenadeProjectile is exploded from inferno
|
|
// CGamePhysicsQueryInterface::EntitiesAlong* to add g_LocatableEntities to results
|
|
|
|
// RNQUERY_OBJECTS_KEYFRAMED | RNQUERY_OBJECTS_DYNAMIC | RNQUERY_OBJECTS_LOCATABLE (0xE) is used in
|
|
// CBotBreakableEnumerator
|
|
// CInferno::Think damage
|
|
// CBombTarget
|
|
// UTIL_EntitiesAlongRay
|
|
// CEnvShake::ApplyShake with type rumble
|
|
// CBaseFilter Think
|
|
|
|
// RNQUERY_OBJECTS_STATIC | RNQUERY_OBJECTS_KEYFRAMED | RNQUERY_OBJECTS_DYNAMIC | RNQUERY_OBJECTS_LOCATABLE (0xF) is used in pretty much every trace filter
|
|
|
|
RNQUERY_OBJECTS_STATIC = (1 << 0), // static body
|
|
RNQUERY_OBJECTS_KEYFRAMED = (1 << 1), // keyframed body
|
|
RNQUERY_OBJECTS_DYNAMIC = (1 << 2), // dynamic body
|
|
RNQUERY_OBJECTS_LOCATABLE = (1 << 3),
|
|
|
|
|
|
RNQUERY_OBJECTS_ALL_GAME_ENTITIES = RNQUERY_OBJECTS_KEYFRAMED | RNQUERY_OBJECTS_DYNAMIC | RNQUERY_OBJECTS_LOCATABLE,
|
|
RNQUERY_OBJECTS_ALL = RNQUERY_OBJECTS_STATIC | RNQUERY_OBJECTS_ALL_GAME_ENTITIES,
|
|
};
|
|
|
|
enum HitGroup_t
|
|
{
|
|
HITGROUP_INVALID = -1,
|
|
HITGROUP_GENERIC = 0,
|
|
HITGROUP_HEAD,
|
|
HITGROUP_CHEST,
|
|
HITGROUP_STOMACH,
|
|
HITGROUP_LEFTARM,
|
|
HITGROUP_RIGHTARM,
|
|
HITGROUP_LEFTLEG,
|
|
HITGROUP_RIGHTLEG,
|
|
HITGROUP_NECK,
|
|
HITGROUP_UNUSED,
|
|
HITGROUP_GEAR,
|
|
HITGROUP_SPECIAL,
|
|
HITGROUP_COUNT,
|
|
};
|
|
|
|
enum HitboxShapeType_t
|
|
{
|
|
HITBOX_SHAPE_HULL = 0,
|
|
HITBOX_SHAPE_SPHERE,
|
|
HITBOX_SHAPE_CAPSULE,
|
|
};
|
|
|
|
class CPhysSurfacePropertiesPhysics
|
|
{
|
|
public:
|
|
CPhysSurfacePropertiesPhysics()
|
|
{
|
|
m_friction = 0.0f;
|
|
m_elasticity = 0.0f;
|
|
m_density = 0.0f;
|
|
m_thickness = 0.1f;
|
|
m_softContactFrequency = 0.0f;
|
|
m_softContactDampingRatio = 0.0f;
|
|
}
|
|
|
|
public:
|
|
float m_friction;
|
|
float m_elasticity;
|
|
float m_density;
|
|
float m_thickness;
|
|
float m_softContactFrequency;
|
|
float m_softContactDampingRatio;
|
|
};
|
|
|
|
class CPhysSurfacePropertiesVehicle
|
|
{
|
|
public:
|
|
CPhysSurfacePropertiesVehicle()
|
|
{
|
|
m_wheelDrag = 0.0f;
|
|
m_wheelFrictionScale = 0.0f;
|
|
}
|
|
|
|
public:
|
|
float m_wheelDrag;
|
|
float m_wheelFrictionScale;
|
|
};
|
|
|
|
class CPhysSurfacePropertiesSoundNames
|
|
{
|
|
public:
|
|
CPhysSurfacePropertiesSoundNames()
|
|
{
|
|
m_meleeImpact = "";
|
|
m_pushOff = "";
|
|
m_skidStop = "";
|
|
}
|
|
|
|
public:
|
|
CUtlString m_impactSoft;
|
|
CUtlString m_impactHard;
|
|
CUtlString m_scrapeSmooth;
|
|
CUtlString m_scrapeRough;
|
|
CUtlString m_bulletImpact;
|
|
CUtlString m_rolling;
|
|
CUtlString m_break;
|
|
CUtlString m_strain;
|
|
CUtlString m_meleeImpact;
|
|
CUtlString m_pushOff;
|
|
CUtlString m_skidStop;
|
|
CUtlString m_resonant;
|
|
};
|
|
|
|
class CPhysSurfacePropertiesAudio
|
|
{
|
|
public:
|
|
CPhysSurfacePropertiesAudio()
|
|
{
|
|
m_reflectivity = 0.0f;
|
|
m_hardnessFactor = 0.0f;
|
|
m_roughnessFactor = 0.0f;
|
|
m_roughThreshold = 0.0f;
|
|
m_hardThreshold = 0.0f;
|
|
m_hardVelocityThreshold = 0.0f;
|
|
m_flStaticImpactVolume = 0.0f;
|
|
m_flOcclusionFactor = 0.0f;
|
|
}
|
|
|
|
public:
|
|
float m_reflectivity;
|
|
float m_hardnessFactor;
|
|
float m_roughnessFactor;
|
|
float m_roughThreshold;
|
|
float m_hardThreshold;
|
|
float m_hardVelocityThreshold;
|
|
float m_flStaticImpactVolume;
|
|
float m_flOcclusionFactor;
|
|
};
|
|
|
|
class CPhysSurfaceProperties
|
|
{
|
|
public:
|
|
CPhysSurfaceProperties()
|
|
{
|
|
m_bHidden = false;
|
|
}
|
|
|
|
public:
|
|
CUtlString m_name;
|
|
uint32 m_nameHash;
|
|
uint32 m_baseNameHash;
|
|
int32 m_nListIndex;
|
|
int32 m_nBaseListIndex;
|
|
bool m_bHidden;
|
|
CUtlString m_description;
|
|
CPhysSurfacePropertiesPhysics m_physics;
|
|
CPhysSurfacePropertiesVehicle m_vehicleParams;
|
|
CPhysSurfacePropertiesSoundNames m_audioSounds;
|
|
CPhysSurfacePropertiesAudio m_audioParams;
|
|
};
|
|
|
|
class CHitBox
|
|
{
|
|
public:
|
|
CHitBox()
|
|
{
|
|
m_vMinBounds.Init();
|
|
m_vMaxBounds.Init();
|
|
m_nGroupId = HITGROUP_GENERIC;
|
|
m_nShapeType = HITBOX_SHAPE_HULL;
|
|
m_bTranslationOnly = false;
|
|
m_CRC = 0;
|
|
m_cRenderColor.SetColor( 255, 255, 255, 255 );
|
|
m_nHitBoxIndex = 0;
|
|
m_bForcedTransform = false;
|
|
m_forcedTransform.SetToIdentity();
|
|
}
|
|
|
|
public:
|
|
CUtlString m_name;
|
|
CUtlString m_sSurfaceProperty;
|
|
CUtlString m_sBoneName;
|
|
Vector m_vMinBounds;
|
|
Vector m_vMaxBounds;
|
|
float m_flShapeRadius;
|
|
CUtlStringToken m_nBoneNameHash;
|
|
int32 m_nGroupId;
|
|
uint8 m_nShapeType;
|
|
bool m_bTranslationOnly;
|
|
uint32 m_CRC;
|
|
Color m_cRenderColor;
|
|
uint16 m_nHitBoxIndex;
|
|
bool m_bForcedTransform;
|
|
CTransform m_forcedTransform;
|
|
};
|
|
|
|
class CDefaultHitbox : public CHitBox
|
|
{
|
|
public:
|
|
CDefaultHitbox()
|
|
{
|
|
V_strncpy( m_tempName, "invalid_hitbox", sizeof( m_tempName ) );
|
|
V_strncpy( m_tempBoneName, "invalid_bone", sizeof( m_tempBoneName ) );
|
|
V_strncpy( m_tempSurfaceProp, "default", sizeof( m_tempSurfaceProp ) );
|
|
|
|
m_name = m_tempName;
|
|
m_sSurfaceProperty = m_tempSurfaceProp;
|
|
|
|
m_sBoneName = m_tempBoneName;
|
|
m_nBoneNameHash = MakeStringToken( m_tempBoneName );
|
|
|
|
m_cRenderColor.SetColor( 0, 0, 0, 0 );
|
|
}
|
|
|
|
public:
|
|
char m_tempName[16];
|
|
char m_tempBoneName[16];
|
|
char m_tempSurfaceProp[16];
|
|
};
|
|
|
|
struct RnQueryShapeAttr_t
|
|
{
|
|
public:
|
|
RnQueryShapeAttr_t()
|
|
{
|
|
m_nInteractsWith = 0;
|
|
m_nInteractsExclude = 0;
|
|
m_nInteractsAs = 0;
|
|
|
|
m_nEntityIdsToIgnore[0] = -1;
|
|
m_nEntityIdsToIgnore[1] = -1;
|
|
|
|
m_nOwnerIdsToIgnore[0] = -1;
|
|
m_nOwnerIdsToIgnore[1] = -1;
|
|
|
|
m_nHierarchyIds[0] = 0;
|
|
m_nHierarchyIds[1] = 0;
|
|
|
|
m_nObjectSetMask = RNQUERY_OBJECTS_ALL;
|
|
m_nCollisionGroup = COLLISION_GROUP_ALWAYS;
|
|
|
|
m_bHitSolid = true;
|
|
m_bHitSolidRequiresGenerateContacts = false;
|
|
m_bHitTrigger = false;
|
|
m_bShouldIgnoreDisabledPairs = true;
|
|
m_bIgnoreIfBothInteractWithHitboxes = false;
|
|
m_bForceHitEverything = false;
|
|
m_bUnknown = true;
|
|
}
|
|
|
|
bool HasInteractsAsLayer( int nLayerIndex ) const { return ( m_nInteractsAs & ( 1ull << nLayerIndex ) ) != 0; }
|
|
bool HasInteractsWithLayer( int nLayerIndex ) const { return ( m_nInteractsWith & ( 1ull << nLayerIndex ) ) != 0; }
|
|
bool HasInteractsExcludeLayer( int nLayerIndex ) const { return ( m_nInteractsExclude & ( 1ull << nLayerIndex ) ) != 0; }
|
|
void EnableInteractsAsLayer( int nLayer ) { m_nInteractsAs |= ( 1ull << nLayer ); }
|
|
void EnableInteractsWithLayer( int nLayer ) { m_nInteractsWith |= ( 1ull << nLayer ); }
|
|
void EnableInteractsExcludeLayer( int nLayer ) { m_nInteractsExclude |= ( 1ull << nLayer ); }
|
|
void DisableInteractsAsLayer( int nLayer ) { m_nInteractsAs &= ~( 1ull << nLayer ); }
|
|
void DisableInteractsWithLayer( int nLayer ) { m_nInteractsWith &= ~( 1ull << nLayer ); }
|
|
void DisableInteractsExcludeLayer( int nLayer ) { m_nInteractsExclude &= ~( 1ull << nLayer ); }
|
|
|
|
public:
|
|
// Which interaction layers do I interact or collide with? (e.g. I collide with LAYER_INDEX_CONTENTS_PASS_BULLETS because I am not a bullet)
|
|
// NOTE: This is analogous to the "solid mask" or "trace mask" in source 1 (bit mask of CONTENTS_* or 1<<LAYER_INDEX_*)
|
|
uint64 m_nInteractsWith;
|
|
|
|
// Which interaction layers do I _not_ interact or collide with? If my exclusion layers match m_nInteractsAs on the other object then no interaction happens.
|
|
uint64 m_nInteractsExclude;
|
|
|
|
// Which interaction layers do I represent? (e.g. I am a LAYER_INDEX_CONTENTS_PLAYER_CLIP volume)
|
|
// NOTE: This is analogous to "contents" in source 1 (bit mask of CONTENTS_* or 1<<LAYER_INDEX_*)
|
|
uint64 m_nInteractsAs;
|
|
|
|
uint32 m_nEntityIdsToIgnore[2]; // this is the ID of the game entity which should be ignored
|
|
uint32 m_nOwnerIdsToIgnore[2]; // this is the ID of the owner of the game entity which should be ignored
|
|
uint16 m_nHierarchyIds[2]; // this is an ID for the hierarchy of game entities (used to disable collision among objects in a hierarchy)
|
|
uint8 m_nObjectSetMask; // set of RnQueryObjectSet bits
|
|
uint8 m_nCollisionGroup; // one of the registered collision groups
|
|
|
|
bool m_bHitSolid : 1; // if true, then query will hit solid
|
|
bool m_bHitSolidRequiresGenerateContacts : 1; // if true, the FCOLLISION_FUNC_ENABLE_SOLID_CONTACT flag will be checked to hit solid
|
|
bool m_bHitTrigger : 1; // if true, then query will hit tirgger
|
|
bool m_bShouldIgnoreDisabledPairs : 1; // if true, then ignores if the query and shape entity IDs are in collision pairs
|
|
bool m_bIgnoreIfBothInteractWithHitboxes : 1; // if true, then ignores if both query and shape interact with LAYER_INDEX_CONTENTS_HITBOX
|
|
bool m_bForceHitEverything : 1; // if true, will hit any objects without any conditions
|
|
bool m_bUnknown : 1; // haven't found where this is used yet
|
|
};
|
|
|
|
struct RnQueryAttr_t : public RnQueryShapeAttr_t
|
|
{
|
|
};
|
|
|
|
class CTraceFilter : public RnQueryAttr_t
|
|
{
|
|
public:
|
|
CTraceFilter( uint64 nInteractsWith = 0, int nCollisionGroup = COLLISION_GROUP_DEFAULT, bool bIterateEntities = true )
|
|
{
|
|
m_nInteractsWith = nInteractsWith;
|
|
m_nCollisionGroup = nCollisionGroup;
|
|
m_bIterateEntities = bIterateEntities;
|
|
}
|
|
|
|
CTraceFilter( CEntityInstance* pPassEntity,
|
|
CEntityInstance* pPassEntityOwner,
|
|
uint16 nHierarchyId,
|
|
uint64 nInteractsWith = 0,
|
|
int nCollisionGroup = COLLISION_GROUP_DEFAULT,
|
|
bool bIterateEntities = true )
|
|
{
|
|
SetPassEntity1( pPassEntity );
|
|
|
|
SetPassEntityOwner1( pPassEntityOwner );
|
|
|
|
m_nHierarchyIds[0] = nHierarchyId;
|
|
|
|
m_nInteractsWith = nInteractsWith;
|
|
m_nCollisionGroup = nCollisionGroup;
|
|
m_bIterateEntities = bIterateEntities;
|
|
}
|
|
|
|
CTraceFilter( CEntityInstance* pPassEntity1,
|
|
CEntityInstance* pPassEntity2,
|
|
CEntityInstance* pPassEntityOwner1,
|
|
CEntityInstance* pPassEntityOwner2,
|
|
uint16 nHierarchyId1,
|
|
uint16 nHierarchyId2,
|
|
uint64 nInteractsWith = 0,
|
|
int nCollisionGroup = COLLISION_GROUP_DEFAULT,
|
|
bool bIterateEntities = true )
|
|
{
|
|
SetPassEntity1( pPassEntity1 );
|
|
SetPassEntity2( pPassEntity2 );
|
|
|
|
SetPassEntityOwner1( pPassEntityOwner1 );
|
|
SetPassEntityOwner2( pPassEntityOwner2 );
|
|
|
|
m_nHierarchyIds[0] = nHierarchyId1;
|
|
m_nHierarchyIds[1] = nHierarchyId2;
|
|
|
|
m_nInteractsWith = nInteractsWith;
|
|
m_nCollisionGroup = nCollisionGroup;
|
|
m_bIterateEntities = bIterateEntities;
|
|
}
|
|
|
|
void SetPassEntity1( CEntityInstance* pEntity ) { m_nEntityIdsToIgnore[0] = pEntity ? pEntity->GetRefEHandle().ToInt() : -1; }
|
|
void SetPassEntity2( CEntityInstance* pEntity ) { m_nEntityIdsToIgnore[1] = pEntity ? pEntity->GetRefEHandle().ToInt() : -1; }
|
|
|
|
void SetPassEntityOwner1( CEntityInstance* pOwner ) { m_nOwnerIdsToIgnore[0] = pOwner ? pOwner->GetRefEHandle().ToInt() : -1; }
|
|
void SetPassEntityOwner2( CEntityInstance* pOwner ) { m_nOwnerIdsToIgnore[1] = pOwner ? pOwner->GetRefEHandle().ToInt() : -1; }
|
|
|
|
virtual ~CTraceFilter() {}
|
|
virtual bool ShouldHitEntity( CEntityInstance* pEntity ) { return true; }
|
|
|
|
public:
|
|
bool m_bIterateEntities; // if true then calls ShouldHitEntity for each hit entity
|
|
};
|
|
|
|
struct RnCollisionAttr_t
|
|
{
|
|
public:
|
|
RnCollisionAttr_t()
|
|
{
|
|
m_nInteractsAs = 0;
|
|
m_nInteractsWith = 0;
|
|
m_nInteractsExclude = 0;
|
|
m_nEntityId = 0;
|
|
m_nOwnerId = -1;
|
|
m_nHierarchyId = 0;
|
|
m_nCollisionGroup = COLLISION_GROUP_ALWAYS;
|
|
m_nCollisionFunctionMask = FCOLLISION_FUNC_DEFAULT;
|
|
}
|
|
|
|
bool IsSolidContactEnabled() const { return ( m_nCollisionFunctionMask & FCOLLISION_FUNC_ENABLE_SOLID_CONTACT ) != 0; }
|
|
bool IsTraceAndQueryEnabled() const { return ( m_nCollisionFunctionMask & FCOLLISION_FUNC_ENABLE_TRACE_QUERY ) != 0; }
|
|
bool IsTouchEventEnabled() const { return ( m_nCollisionFunctionMask & FCOLLISION_FUNC_ENABLE_TOUCH_EVENT ) != 0; }
|
|
bool IsSelfCollisionsEnabled() const { return ( m_nCollisionFunctionMask & FCOLLISION_FUNC_ENABLE_SELF_COLLISIONS ) != 0; }
|
|
bool ShouldIgnoreForHitboxTest() const { return ( m_nCollisionFunctionMask & FCOLLISION_FUNC_IGNORE_FOR_HITBOX_TEST ) != 0; }
|
|
bool IsTouchPersistsEnabled() const { return ( m_nCollisionFunctionMask & FCOLLISION_FUNC_ENABLE_TOUCH_PERSISTS ) != 0; }
|
|
|
|
bool HasInteractsAsLayer( int nLayerIndex ) const { return ( m_nInteractsAs & ( 1ull << nLayerIndex ) ) != 0; }
|
|
bool HasInteractsWithLayer( int nLayerIndex ) const { return ( m_nInteractsWith & ( 1ull << nLayerIndex ) ) != 0; }
|
|
bool HasInteractsExcludeLayer( int nLayerIndex ) const { return ( m_nInteractsExclude & ( 1ull << nLayerIndex ) ) != 0; }
|
|
void EnableInteractsAsLayer( int nLayer ) { m_nInteractsAs |= ( 1ull << nLayer ); }
|
|
void EnableInteractsWithLayer( int nLayer ) { m_nInteractsWith |= ( 1ull << nLayer ); }
|
|
void EnableInteractsExcludeLayer( int nLayer ) { m_nInteractsExclude |= ( 1ull << nLayer ); }
|
|
void DisableInteractsAsLayer( int nLayer ) { m_nInteractsAs &= ~( 1ull << nLayer ); }
|
|
void DisableInteractsWithLayer( int nLayer ) { m_nInteractsWith &= ~( 1ull << nLayer ); }
|
|
void DisableInteractsExcludeLayer( int nLayer ) { m_nInteractsExclude &= ~( 1ull << nLayer ); }
|
|
|
|
public:
|
|
// Which interaction layers do I represent? (e.g. I am a LAYER_INDEX_CONTENTS_PLAYER_CLIP volume)
|
|
// NOTE: This is analogous to "contents" in source 1 (bit mask of CONTENTS_* or 1<<LAYER_INDEX_*)
|
|
uint64 m_nInteractsAs;
|
|
|
|
// Which interaction layers do I interact or collide with? (e.g. I collide with LAYER_INDEX_CONTENTS_PASS_BULLETS because I am not a bullet)
|
|
// NOTE: This is analogous to the "solid mask" or "trace mask" in source 1 (bit mask of CONTENTS_* or 1<<LAYER_INDEX_*)
|
|
uint64 m_nInteractsWith;
|
|
|
|
// Which interaction layers do I _not_ interact or collide with? If my exclusion layers match m_nInteractsAs on the other object then no interaction happens.
|
|
uint64 m_nInteractsExclude;
|
|
|
|
uint32 m_nEntityId; // this is the ID of the game entity
|
|
uint32 m_nOwnerId; // this is the ID of the owner of the game entity
|
|
uint16 m_nHierarchyId; // this is an ID for the hierarchy of game entities (used to disable collision among objects in a hierarchy)
|
|
uint8 m_nCollisionGroup; // one of the registered collision groups
|
|
uint8 m_nCollisionFunctionMask; // set of CollisionFunctionMask_t bits
|
|
};
|
|
|
|
class CGameTrace
|
|
{
|
|
public:
|
|
CGameTrace()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
void Init()
|
|
{
|
|
m_pSurfaceProperties = NULL;
|
|
m_pEnt = NULL;
|
|
m_pHitbox = NULL;
|
|
m_hBody = NULL;
|
|
m_hShape = NULL;
|
|
m_nContents = 0;
|
|
m_BodyTransform.SetToIdentity();
|
|
m_vHitNormal.Init();
|
|
m_vHitPoint.Init();
|
|
m_flHitOffset = 0.0f;
|
|
m_flFraction = 1.0f;
|
|
m_nTriangle = -1;
|
|
m_nHitboxBoneIndex = -1;
|
|
m_eRayType = RAY_TYPE_LINE;
|
|
m_bStartInSolid = false;
|
|
m_bExactHitPoint = false;
|
|
}
|
|
|
|
// Returns true if there was any kind of impact at all
|
|
bool DidHit() const
|
|
{
|
|
return m_flFraction < 1 || m_bStartInSolid;
|
|
}
|
|
|
|
public:
|
|
const CPhysSurfaceProperties *m_pSurfaceProperties;
|
|
CEntityInstance *m_pEnt;
|
|
const CHitBox *m_pHitbox;
|
|
|
|
HPhysicsBody m_hBody;
|
|
HPhysicsShape m_hShape;
|
|
|
|
uint64 m_nContents; // contents on other side of surface hit
|
|
|
|
CTransform m_BodyTransform;
|
|
RnCollisionAttr_t m_ShapeAttributes;
|
|
|
|
Vector m_vStartPos; // start position
|
|
Vector m_vEndPos; // final position
|
|
Vector m_vHitNormal; // surface normal at impact
|
|
Vector m_vHitPoint; // exact hit point if m_bExactHitPoint is true, otherwise equal to m_vEndPos
|
|
|
|
float m_flHitOffset; // surface normal hit offset
|
|
float m_flFraction; // time completed, 1.0 = didn't hit anything
|
|
|
|
int32 m_nTriangle; // the index of the triangle that was hit
|
|
int16 m_nHitboxBoneIndex; // the index of the hitbox bone that was hit
|
|
|
|
RayType_t m_eRayType;
|
|
|
|
bool m_bStartInSolid; // if true, the initial point was in a solid area
|
|
bool m_bExactHitPoint; // if true, then m_vHitPoint is the exact hit point of the query and the shape
|
|
|
|
private:
|
|
// No copy constructors allowed
|
|
CGameTrace(const CGameTrace& vOther);
|
|
};
|
|
|
|
|
|
typedef CGameTrace trace_t;
|
|
|
|
//=============================================================================
|
|
|
|
class ITraceListData
|
|
{
|
|
public:
|
|
virtual ~ITraceListData() {}
|
|
|
|
virtual void Reset() = 0;
|
|
virtual bool IsEmpty() = 0;
|
|
// CanTraceRay will return true if the current volume encloses the ray
|
|
// NOTE: The leaflist trace will NOT check this. Traces are intersected
|
|
// against the culled volume exclusively.
|
|
virtual bool CanTraceRay( const Ray_t &ray ) = 0;
|
|
};
|
|
#endif // GAMETRACE_H
|
|
|