source-engine/game/shared/physics_shared.h

176 lines
7.4 KiB
C
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef PHYSICS_SHARED_H
#define PHYSICS_SHARED_H
#ifdef _WIN32
#pragma once
#endif
class IPhysics;
class IPhysicsEnvironment;
class IPhysicsSurfaceProps;
class IPhysicsCollision;
class IPhysicsObject;
class IPhysicsObjectPairHash;
class CSoundPatch;
extern IPhysicsObject *g_PhysWorldObject;
extern IPhysics *physics;
extern IPhysicsCollision *physcollision;
extern IPhysicsEnvironment *physenv;
#ifdef PORTAL
extern IPhysicsEnvironment *physenv_main;
#endif
extern IPhysicsSurfaceProps *physprops;
extern IPhysicsObjectPairHash *g_EntityCollisionHash;
extern const objectparams_t g_PhysDefaultObjectParams;
// Compute enough energy of a reference mass travelling at speed
// makes numbers more intuitive
#define MASS_SPEED2ENERGY(mass, speed) ((speed)*(speed)*(mass))
// energy of a 10kg mass moving at speed
#define MASS10_SPEED2ENERGY(speed) MASS_SPEED2ENERGY(10,speed)
#define MASS_ENERGY2SPEED(mass,energy) (FastSqrt((energy)/mass))
#define ENERGY_VOLUME_SCALE (1.0f / 15500.0f)
#define FLUID_TIME_MAX 2.0f // keep track of last time hitting fluid for up to 2 seconds
// VPHYSICS object game-specific flags
#define FVPHYSICS_DMG_SLICE 0x0001 // does slice damage, not just blunt damage
#define FVPHYSICS_CONSTRAINT_STATIC 0x0002 // object is constrained to the world, so it should behave like a static
#define FVPHYSICS_PLAYER_HELD 0x0004 // object is held by the player, so have a very inelastic collision response
#define FVPHYSICS_PART_OF_RAGDOLL 0x0008 // object is part of a client or server ragdoll
#define FVPHYSICS_MULTIOBJECT_ENTITY 0x0010 // object is part of a multi-object entity
#define FVPHYSICS_HEAVY_OBJECT 0x0020 // HULK SMASH! (Do large damage even if the mass is small)
#define FVPHYSICS_PENETRATING 0x0040 // This object is currently stuck inside another object
#define FVPHYSICS_NO_PLAYER_PICKUP 0x0080 // Player can't pick this up for some game rule reason
#define FVPHYSICS_WAS_THROWN 0x0100 // Player threw this object
#define FVPHYSICS_DMG_DISSOLVE 0x0200 // does dissolve damage, not just blunt damage
#define FVPHYSICS_NO_IMPACT_DMG 0x0400 // don't do impact damage to anything
#define FVPHYSICS_NO_NPC_IMPACT_DMG 0x0800 // Don't do impact damage to NPC's. This is temporary for NPC's shooting combine balls (sjb)
#define FVPHYSICS_NO_SELF_COLLISIONS 0x8000 // don't collide with other objects that are part of the same entity
//-----------------------------------------------------------------------------
// Purpose: A little cache of current objects making noises
//-----------------------------------------------------------------------------
struct friction_t
{
CSoundPatch *patch;
CBaseEntity *pObject;
float flLastUpdateTime;
float flLastEffectTime;
};
enum
{
TOUCH_START=0,
TOUCH_END,
};
struct touchevent_t
{
CBaseEntity *pEntity0;
CBaseEntity *pEntity1;
int touchType;
Vector endPoint; //sv
Vector normal; //sv
};
struct fluidevent_t
{
EHANDLE hEntity;
float impactTime;
};
void PhysFrictionSound( CBaseEntity *pEntity, IPhysicsObject *pObject, float energy, int surfaceProps, int surfacePropsHit );
void PhysFrictionSound( CBaseEntity *pEntity, IPhysicsObject *pObject, const char *pSoundName, HSOUNDSCRIPTHANDLE& handle, float flVolume );
void PhysCleanupFrictionSounds( CBaseEntity *pEntity );
void PhysFrictionEffect( Vector &vecPos, Vector vecVel, float energy, int surfaceProps, int surfacePropsHit );
// Convenience routine
// ORs gameFlags with the physics object's current game flags
inline unsigned short PhysSetGameFlags( IPhysicsObject *pPhys, unsigned short gameFlags )
{
unsigned short flags = pPhys->GetGameFlags();
flags |= gameFlags;
pPhys->SetGameFlags( flags );
return flags;
}
// mask off gameFlags
inline unsigned short PhysClearGameFlags( IPhysicsObject *pPhys, unsigned short gameFlags )
{
unsigned short flags = pPhys->GetGameFlags();
flags &= ~gameFlags;
pPhys->SetGameFlags( flags );
return flags;
}
// Create a vphysics object based on a model
IPhysicsObject *PhysModelCreate( CBaseEntity *pEntity, int modelIndex, const Vector &origin, const QAngle &angles, solid_t *pSolid = NULL );
IPhysicsObject *PhysModelCreateBox( CBaseEntity *pEntity, const Vector &mins, const Vector &maxs, const Vector &origin, bool isStatic );
IPhysicsObject *PhysModelCreateOBB( CBaseEntity *pEntity, const Vector &mins, const Vector &maxs, const Vector &origin, const QAngle &angle, bool isStatic );
// Create a vphysics object based on a BSP model (unmoveable)
IPhysicsObject *PhysModelCreateUnmoveable( CBaseEntity *pEntity, int modelIndex, const Vector &origin, const QAngle &angles );
// Create a vphysics object based on an existing collision model
IPhysicsObject *PhysModelCreateCustom( CBaseEntity *pEntity, const CPhysCollide *pModel, const Vector &origin, const QAngle &angles, const char *pName, bool isStatic, solid_t *pSolid = NULL );
// Create a bbox collision model (these may be shared among entities, they are auto-deleted at end of level. do not manage)
CPhysCollide *PhysCreateBbox( const Vector &mins, const Vector &maxs );
// Create a vphysics sphere object
IPhysicsObject *PhysSphereCreate( CBaseEntity *pEntity, float radius, const Vector &origin, solid_t &solid );
// Destroy a physics object created using PhysModelCreate...()
void PhysDestroyObject( IPhysicsObject *pObject, CBaseEntity *pEntity = NULL );
void PhysDisableObjectCollisions( IPhysicsObject *pObject0, IPhysicsObject *pObject1 );
void PhysDisableEntityCollisions( IPhysicsObject *pObject0, IPhysicsObject *pObject1 );
void PhysDisableEntityCollisions( CBaseEntity *pEntity0, CBaseEntity *pEntity1 );
void PhysEnableObjectCollisions( IPhysicsObject *pObject0, IPhysicsObject *pObject1 );
void PhysEnableEntityCollisions( IPhysicsObject *pObject0, IPhysicsObject *pObject1 );
void PhysEnableEntityCollisions( CBaseEntity *pEntity0, CBaseEntity *pEntity1 );
bool PhysEntityCollisionsAreDisabled( CBaseEntity *pEntity0, CBaseEntity *pEntity1 );
// create the world physics objects
IPhysicsObject *PhysCreateWorld_Shared( CBaseEntity *pWorld, vcollide_t *pWorldCollide, const objectparams_t &defaultParams );
// parse the parameters for a single solid from the model's collision data
bool PhysModelParseSolid( solid_t &solid, CBaseEntity *pEntity, int modelIndex );
// parse the parameters for a solid matching a particular index
bool PhysModelParseSolidByIndex( solid_t &solid, CBaseEntity *pEntity, int modelIndex, int solidIndex );
void PhysParseSurfaceData( class IPhysicsSurfaceProps *pProps, class IFileSystem *pFileSystem );
// fill out this solid_t with the AABB defaults (high inertia/no rotation)
void PhysGetDefaultAABBSolid( solid_t &solid );
// Compute an output velocity based on sliding along the current contact points
// in the closest direction toward inputVelocity.
void PhysComputeSlideDirection( IPhysicsObject *pPhysics, const Vector &inputVelocity, const AngularImpulse &inputAngularVelocity,
Vector *pOutputVelocity, Vector *pOutputAngularVelocity, float minMass );
void PhysForceClearVelocity( IPhysicsObject *pPhys );
bool PhysHasContactWithOtherInDirection( IPhysicsObject *pPhysics, const Vector &dir );
//-----------------------------------------------------------------------------
// Singleton access
//-----------------------------------------------------------------------------
IGameSystem* PhysicsGameSystem();
#endif // PHYSICS_SHARED_H