This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

203 lines
7.1 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: This is the abstraction layer for the physics simulation system
// Any calls to the external physics library (ipion) should be made through this
// layer. Eventually, the physics system will probably become a DLL and made
// accessible to the client & server side code.
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#ifndef PHYSICS_H
#define PHYSICS_H
#ifdef _WIN32
#pragma once
#endif
#include "physics_shared.h"
class CBaseEntity;
class IPhysicsMaterial;
class IPhysicsConstraint;
class IPhysicsSpring;
class IPhysicsSurfaceProps;
class CTakeDamageInfo;
class ConVar;
extern IPhysicsMaterial *g_Material;
extern ConVar phys_pushscale;
extern ConVar phys_timescale;
struct objectparams_t;
extern IPhysicsGameTrace *physgametrace;
class IPhysicsCollisionSolver;
class IPhysicsCollisionEvent;
class IPhysicsObjectEvent;
extern IPhysicsCollisionSolver *const g_pCollisionSolver;
extern IPhysicsCollisionEvent *const g_pCollisionEventHandler;
extern IPhysicsObjectEvent *const g_pObjectEventHandler;
// HACKHACK: We treat anything >= 500kg as a special "large mass" that does more
// impact damage and has special recovery on crushing/killing other objects also
// causes screen shakes on impact with static/world objects
const float VPHYSICS_LARGE_OBJECT_MASS = 500.0f;
struct gamevcollisionevent_t : public vcollisionevent_t {
Vector preVelocity[2];
Vector postVelocity[2];
AngularImpulse preAngularVelocity[2];
CBaseEntity *pEntities[2];
void Init(vcollisionevent_t *pEvent) {
*((vcollisionevent_t *)this) = *pEvent;
pEntities[0] = NULL;
pEntities[1] = NULL;
}
};
struct triggerevent_t {
CBaseEntity *pTriggerEntity;
IPhysicsObject *pTriggerPhysics;
CBaseEntity *pEntity;
IPhysicsObject *pObject;
bool bStart;
inline void Init(CBaseEntity *triggerEntity, IPhysicsObject *triggerPhysics,
CBaseEntity *entity, IPhysicsObject *object,
bool startTouch) {
pTriggerEntity = triggerEntity;
pTriggerPhysics = triggerPhysics;
pEntity = entity;
pObject = object;
bStart = startTouch;
}
inline void Clear() { memset(this, 0, sizeof(*this)); }
};
// parse solid parameter overrides out of a string
void PhysSolidOverride(solid_t &solid, string_t overrideScript);
extern CEntityList *g_pShadowEntities;
#ifdef PORTAL
extern CEntityList *g_pShadowEntities_Main;
#endif
void PhysAddShadow(CBaseEntity *pEntity);
void PhysRemoveShadow(CBaseEntity *pEntity);
bool PhysHasShadow(CBaseEntity *pEntity);
void PhysEnableFloating(IPhysicsObject *pObject, bool bEnable);
void PhysCollisionSound(CBaseEntity *pEntity, IPhysicsObject *pPhysObject,
int channel, int surfaceProps, int surfacePropsHit,
float deltaTime, float speed);
void PhysCollisionScreenShake(gamevcollisionevent_t *pEvent, int index);
void PhysCollisionDust(gamevcollisionevent_t *pEvent, surfacedata_t *phit);
#if HL2_EPISODIC
void PhysCollisionWarpEffect(gamevcollisionevent_t *pEvent,
surfacedata_t *phit);
#endif
void PhysBreakSound(CBaseEntity *pEntity, IPhysicsObject *pPhysObject,
Vector vecOrigin);
// plays the impact sound for a particular material
void PhysicsImpactSound(CBaseEntity *pEntity, IPhysicsObject *pPhysObject,
int channel, int surfaceProps, int surfacePropsHit,
float volume, float impactSpeed);
void PhysCallbackDamage(CBaseEntity *pEntity, const CTakeDamageInfo &info);
void PhysCallbackDamage(CBaseEntity *pEntity, const CTakeDamageInfo &info,
gamevcollisionevent_t &event, int hurtIndex);
// Applies force impulses at a later time
void PhysCallbackImpulse(IPhysicsObject *pPhysicsObject,
const Vector &vecCenterForce,
const AngularImpulse &vecCenterTorque);
// Sets the velocity at a later time
void PhysCallbackSetVelocity(IPhysicsObject *pPhysicsObject,
const Vector &vecVelocity);
// queue up a delete on this object
void PhysCallbackRemove(IServerNetworkable *pRemove);
bool PhysGetDamageInflictorVelocityStartOfFrame(IPhysicsObject *pInflictor,
Vector &velocity,
AngularImpulse &angVelocity);
// force a physics entity to sleep immediately
void PhysForceEntityToSleep(CBaseEntity *pEntity, IPhysicsObject *pObject);
// teleport an entity to it's position relative to an object it's constrained to
void PhysTeleportConstrainedEntity(CBaseEntity *pTeleportSource,
IPhysicsObject *pObject0,
IPhysicsObject *pObject1,
const Vector &prevPosition,
const QAngle &prevAngles,
bool physicsRotate);
void PhysGetListOfPenetratingEntities(CBaseEntity *pSearch,
CUtlVector<CBaseEntity *> &list);
bool PhysShouldCollide(IPhysicsObject *pObj0, IPhysicsObject *pObj1);
// returns true when processing a callback - so we can defer things that can't
// be done inside a callback
bool PhysIsInCallback();
bool PhysIsFinalTick();
bool PhysGetTriggerEvent(triggerevent_t *pEvent, CBaseEntity *pTrigger);
// note: pErrorEntity is used to report errors (object not found, more than one
// found). It can be NULL
IPhysicsObject *FindPhysicsObjectByName(const char *pName,
CBaseEntity *pErrorEntity);
bool PhysFindOrAddVehicleScript(const char *pScriptName,
struct vehicleparams_t *pParams,
struct vehiclesounds_t *pSounds);
void PhysFlushVehicleScripts();
// this is called to flush all queues when the delete list is cleared
void PhysOnCleanupDeleteList();
struct masscenteroverride_t {
enum align_type {
ALIGN_POINT = 0,
ALIGN_AXIS = 1,
};
void Defaults() { entityName = NULL_STRING; }
void SnapToPoint(string_t name, const Vector &pointWS) {
entityName = name;
center = pointWS;
axis.Init();
alignType = ALIGN_POINT;
}
void SnapToAxis(string_t name, const Vector &axisStartWS,
const Vector &unitAxisDirWS) {
entityName = name;
center = axisStartWS;
axis = unitAxisDirWS;
alignType = ALIGN_AXIS;
}
Vector center;
Vector axis;
int alignType;
string_t entityName;
};
void PhysSetMassCenterOverride(masscenteroverride_t &override);
// NOTE: this removes the entry from the table as well as retrieving it
void PhysGetMassCenterOverride(CBaseEntity *pEntity, vcollide_t *pCollide,
solid_t &solidOut);
float PhysGetEntityMass(CBaseEntity *pEntity);
void PhysSetEntityGameFlags(CBaseEntity *pEntity, unsigned short flags);
void DebugDrawContactPoints(IPhysicsObject *pPhysics);
#endif // PHYSICS_H