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.
nekohook/modules/source2013/sdk/public/vphysics_interfaceV30.h
2020-08-04 13:13:01 -04:00

1223 lines
51 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Public interfaces to vphysics DLL
//
// $NoKeywords: $
//=============================================================================
#ifndef VPHYSICS_INTERFACE_V30_H
#define VPHYSICS_INTERFACE_V30_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
#include "mathlib/vector.h"
#include "mathlib/vector4d.h"
#include "vcollide.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class IPhysicsObjectPairHash;
class IPhysicsConstraint;
class IPhysicsConstraintGroup;
class IPhysicsFluidController;
class IPhysicsSpring;
class IPhysicsVehicleController;
class IPhysicsCollisionSet;
class IPhysicsPlayerController;
class IPhysicsFrictionSnapshot;
struct Ray_t;
struct constraint_ragdollparams_t;
struct constraint_hingeparams_t;
struct constraint_fixedparams_t;
struct constraint_ballsocketparams_t;
struct constraint_slidingparams_t;
struct constraint_pulleyparams_t;
struct constraint_lengthparams_t;
struct constraint_groupparams_t;
struct vehicleparams_t;
struct matrix3x4_t;
struct fluidparams_t;
struct springparams_t;
struct objectparams_t;
struct debugcollide_t;
class CGameTrace;
typedef CGameTrace trace_t;
struct physics_stats_t;
struct physics_performanceparams_t;
struct physsaveparams_t;
struct physrestoreparams_t;
struct physprerestoreparams_t;
namespace VPhysicsInterfaceV30 {
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class IPhysicsObject;
class IPhysicsEnvironment;
class IPhysicsSurfaceProps;
class IConvexInfo;
enum PhysInterfaceId_t {
PIID_UNKNOWN,
PIID_IPHYSICSOBJECT,
PIID_IPHYSICSFLUIDCONTROLLER,
PIID_IPHYSICSSPRING,
PIID_IPHYSICSCONSTRAINTGROUP,
PIID_IPHYSICSCONSTRAINT,
PIID_IPHYSICSSHADOWCONTROLLER,
PIID_IPHYSICSPLAYERCONTROLLER,
PIID_IPHYSICSMOTIONCONTROLLER,
PIID_IPHYSICSVEHICLECONTROLLER,
PIID_IPHYSICSGAMETRACE,
PIID_NUM_TYPES
};
class ISave;
class IRestore;
#define VPHYSICS_DEBUG_OVERLAY_INTERFACE_VERSION_1 "VPhysicsDebugOverlay001"
abstract_class IVPhysicsDebugOverlay {
public:
virtual void AddEntityTextOverlay(
int ent_index, int line_offset, float duration, int r, int g, int b,
int a, PRINTF_FORMAT_STRING const char *format, ...) = 0;
virtual void AddBoxOverlay(const Vector &origin, const Vector &mins,
const Vector &max, QAngle const &orientation,
int r, int g, int b, int a, float duration) = 0;
virtual void AddTriangleOverlay(
const Vector &p1, const Vector &p2, const Vector &p3, int r, int g,
int b, int a, bool noDepthTest, float duration) = 0;
virtual void AddLineOverlay(const Vector &origin, const Vector &dest, int r,
int g, int b, bool noDepthTest,
float duration) = 0;
virtual void AddTextOverlay(const Vector &origin, float duration,
PRINTF_FORMAT_STRING const char *format,
...) = 0;
virtual void AddTextOverlay(
const Vector &origin, int line_offset, float duration,
PRINTF_FORMAT_STRING const char *format, ...) = 0;
virtual void AddScreenTextOverlay(float flXPos, float flYPos,
float flDuration, int r, int g, int b,
int a, const char *text) = 0;
virtual void AddSweptBoxOverlay(const Vector &start, const Vector &end,
const Vector &mins, const Vector &max,
const QAngle &angles, int r, int g, int b,
int a, float flDuration) = 0;
virtual void AddTextOverlayRGB(
const Vector &origin, int line_offset, float duration, float r, float g,
float b, float alpha, PRINTF_FORMAT_STRING const char *format, ...) = 0;
};
#define VPHYSICS_INTERFACE_VERSION_30 "VPhysics030"
abstract_class IPhysics {
public:
virtual IPhysicsEnvironment *CreateEnvironment(void) = 0;
virtual void DestroyEnvironment(IPhysicsEnvironment *) = 0;
virtual IPhysicsEnvironment *GetActiveEnvironmentByIndex(int index) = 0;
// Creates a fast hash of pairs of objects
// Useful for maintaining a table of object relationships like pairs that do
// not collide.
virtual IPhysicsObjectPairHash *CreateObjectPairHash() = 0;
virtual void DestroyObjectPairHash(IPhysicsObjectPairHash * pHash) = 0;
// holds a cache of these by id. So you can get by id to search for the
// previously created set UNDONE: Sets are currently limited to 32 elements.
// More elements will return NULL in create. NOTE: id is not allowed to be
// zero.
virtual IPhysicsCollisionSet *FindOrCreateCollisionSet(
unsigned int id, int maxElementCount) = 0;
virtual IPhysicsCollisionSet *FindCollisionSet(unsigned int id) = 0;
virtual void DestroyAllCollisionSets() = 0;
};
// CPhysConvex is a single convex solid
class CPhysConvex;
// CPhysPolysoup is an abstract triangle soup mesh
class CPhysPolysoup;
class ICollisionQuery;
class IVPhysicsKeyParser;
struct convertconvexparams_t;
// UNDONE: Find a better place for this? Should be in collisionutils, but it's
// needs VPHYSICS' solver.
struct truncatedcone_t {
Vector origin;
Vector normal;
float h; // height of the cone (hl units)
float theta; // cone angle (degrees)
};
#define VPHYSICS_COLLISION_INTERFACE_VERSION_7 "VPhysicsCollision007"
abstract_class IPhysicsCollision {
public:
virtual ~IPhysicsCollision(void) {}
// produce a convex element from verts (convex hull around verts)
virtual CPhysConvex *ConvexFromVerts(Vector * *pVerts, int vertCount) = 0;
// produce a convex element from planes (csg of planes)
virtual CPhysConvex *ConvexFromPlanes(float *pPlanes, int planeCount,
float mergeDistance) = 0;
// calculate volume of a convex element
virtual float ConvexVolume(CPhysConvex * pConvex) = 0;
// Convert an array of convex elements to a compiled collision model (this
// deletes the convex elements)
virtual CPhysCollide *ConvertConvexToCollide(CPhysConvex * *pConvex,
int convexCount) = 0;
virtual float ConvexSurfaceArea(CPhysConvex * pConvex) = 0;
// store game-specific data in a convex solid
virtual void SetConvexGameData(CPhysConvex * pConvex,
unsigned int gameData) = 0;
// If not converted, free the convex elements with this call
virtual void ConvexFree(CPhysConvex * pConvex) = 0;
// concave objects
// create a triangle soup
virtual CPhysPolysoup *PolysoupCreate(void) = 0;
// destroy the container and memory
virtual void PolysoupDestroy(CPhysPolysoup * pSoup) = 0;
// add a triangle to the soup
virtual void PolysoupAddTriangle(CPhysPolysoup * pSoup, const Vector &a,
const Vector &b, const Vector &c,
int materialIndex7bits) = 0;
// convert the convex into a compiled collision model
virtual CPhysCollide *ConvertPolysoupToCollide(CPhysPolysoup * pSoup,
bool useMOPP) = 0;
// Get the memory size in bytes of the collision model for serialization
virtual int CollideSize(CPhysCollide * pCollide) = 0;
// serialize the collide to a block of memory
virtual int CollideWrite(char *pDest, CPhysCollide *pCollide) = 0;
// Free a collide that was created with ConvertConvexToCollide()
// UNDONE: Move this up near the other Collide routines when the version is
// changed
virtual void DestroyCollide(CPhysCollide * pCollide) = 0;
// compute the volume of a collide
virtual float CollideVolume(CPhysCollide * pCollide) = 0;
// compute surface area for tools
virtual float CollideSurfaceArea(CPhysCollide * pCollide) = 0;
// Get the support map for a collide in the given direction
virtual Vector CollideGetExtent(
const CPhysCollide *pCollide, const Vector &collideOrigin,
const QAngle &collideAngles, const Vector &direction) = 0;
// Get an AABB for an oriented collision model
virtual void CollideGetAABB(
Vector & mins, Vector & maxs, const CPhysCollide *pCollide,
const Vector &collideOrigin, const QAngle &collideAngles) = 0;
// Convert a bbox to a collide
virtual CPhysCollide *BBoxToCollide(const Vector &mins,
const Vector &maxs) = 0;
// Trace an AABB against a collide
virtual void TraceBox(const Vector &start, const Vector &end,
const Vector &mins, const Vector &maxs,
const CPhysCollide *pCollide,
const Vector &collideOrigin,
const QAngle &collideAngles, trace_t *ptr) = 0;
virtual void TraceBox(const Ray_t &ray, const CPhysCollide *pCollide,
const Vector &collideOrigin,
const QAngle &collideAngles, trace_t *ptr) = 0;
// Trace one collide against another
virtual void TraceCollide(
const Vector &start, const Vector &end,
const CPhysCollide *pSweepCollide, const QAngle &sweepAngles,
const CPhysCollide *pCollide, const Vector &collideOrigin,
const QAngle &collideAngles, trace_t *ptr) = 0;
// loads a set of solids into a vcollide_t
virtual void VCollideLoad(vcollide_t * pOutput, int solidCount,
const char *pBuffer, int size) = 0;
// destroyts the set of solids created by VCollideLoad
virtual void VCollideUnload(vcollide_t * pVCollide) = 0;
// begins parsing a vcollide. NOTE: This keeps pointers to the text
// If you free the text and call members of IVPhysicsKeyParser, it will
// crash
virtual IVPhysicsKeyParser *VPhysicsKeyParserCreate(
const char *pKeyData) = 0;
// Free the parser created by VPhysicsKeyParserCreate
virtual void VPhysicsKeyParserDestroy(IVPhysicsKeyParser * pParser) = 0;
// creates a list of verts from a collision mesh
virtual int CreateDebugMesh(CPhysCollide const *pCollisionModel,
Vector **outVerts) = 0;
// destroy the list of verts created by CreateDebugMesh
virtual void DestroyDebugMesh(int vertCount, Vector *outVerts) = 0;
// create a queryable version of the collision model
virtual ICollisionQuery *CreateQueryModel(CPhysCollide * pCollide) = 0;
// destroy the queryable version
virtual void DestroyQueryModel(ICollisionQuery * pQuery) = 0;
virtual IPhysicsCollision *ThreadContextCreate(void) = 0;
virtual void ThreadContextDestroy(IPhysicsCollision * pThreadContex) = 0;
virtual unsigned int ReadStat(int statID) = 0;
// UNDONE: Move this up when changing the interface version
virtual void TraceBox(
const Ray_t &ray, unsigned int contentsMask, IConvexInfo *pConvexInfo,
const CPhysCollide *pCollide, const Vector &collideOrigin,
const QAngle &collideAngles, trace_t *ptr) = 0;
virtual void CollideGetMassCenter(CPhysCollide * pCollide,
Vector * pOutMassCenter) = 0;
virtual void CollideSetMassCenter(CPhysCollide * pCollide,
const Vector &massCenter) = 0;
// query the collide index in the physics model for the instance
virtual int CollideIndex(const CPhysCollide *pCollide) = 0;
virtual CPhysCollide *ConvertConvexToCollideParams(
CPhysConvex * *pConvex, int convexCount,
const convertconvexparams_t &convertParams) = 0;
virtual CPhysConvex *BBoxToConvex(const Vector &mins,
const Vector &maxs) = 0;
// get the approximate cross-sectional area projected orthographically on
// the bbox of the collide NOTE: These are fractional areas - unitless.
// Basically this is the fraction of the OBB on each axis that would be
// visible if the object were rendered orthographically. NOTE: This has been
// precomputed when the collide was built or this function will return 1,1,1
virtual Vector CollideGetOrthographicAreas(
const CPhysCollide *pCollide) = 0;
// dumps info about the collide to Msg()
virtual void OutputDebugInfo(const CPhysCollide *pCollide) = 0;
// relatively slow test for box vs. truncated cone
virtual bool IsBoxIntersectingCone(const Vector &boxAbsMins,
const Vector &boxAbsMaxs,
const truncatedcone_t &cone) = 0;
};
// this can be used to post-process a collision model
abstract_class ICollisionQuery {
public:
virtual ~ICollisionQuery() {}
// number of convex pieces in the whole solid
virtual int ConvexCount(void) = 0;
// triangle count for this convex piece
virtual int TriangleCount(int convexIndex) = 0;
// get the stored game data
virtual unsigned int GetGameData(int convexIndex) = 0;
// Gets the triangle's verts to an array
virtual void GetTriangleVerts(int convexIndex, int triangleIndex,
Vector *verts) = 0;
// UNDONE: This doesn't work!!!
virtual void SetTriangleVerts(int convexIndex, int triangleIndex,
const Vector *verts) = 0;
// returns the 7-bit material index
virtual int GetTriangleMaterialIndex(int convexIndex,
int triangleIndex) = 0;
// sets a 7-bit material index for this triangle
virtual void SetTriangleMaterialIndex(int convexIndex, int triangleIndex,
int index7bits) = 0;
};
//-----------------------------------------------------------------------------
// Purpose: Ray traces from game engine.
//-----------------------------------------------------------------------------
abstract_class IPhysicsGameTrace {
public:
virtual void VehicleTraceRay(const Ray_t &ray, void *pVehicle,
trace_t *pTrace) = 0;
virtual void VehicleTraceRayWithWater(const Ray_t &ray, void *pVehicle,
trace_t *pTrace) = 0;
virtual bool VehiclePointInWater(const Vector &vecPoint) = 0;
};
// The caller should implement this to return contents masks per convex on a
// collide
abstract_class IConvexInfo {
public:
virtual unsigned int GetContents(int convexGameData) = 0;
};
class CPhysicsEventHandler;
abstract_class IPhysicsCollisionData {
public:
virtual void GetSurfaceNormal(
Vector &
out) = 0; // normal points toward second object (object index 1)
virtual void GetContactPoint(
Vector & out) = 0; // contact point of collision (in world space)
virtual void GetContactSpeed(
Vector &
out) = 0; // speed of surface 1 relative to surface 0 (in world space)
};
struct vcollisionevent_t {
IPhysicsObject *pObjects[2];
int surfaceProps[2];
bool isCollision;
bool isShadowCollision;
float deltaCollisionTime;
float collisionSpeed; // only valid at postCollision
IPhysicsCollisionData *pInternalData; // may change pre/post collision
};
abstract_class IPhysicsCollisionEvent {
public:
// returns the two objects that collided, time between last collision of
// these objects and an opaque data block of collision information NOTE:
// PreCollision/PostCollision ALWAYS come in matched pairs!!!
virtual void PreCollision(vcollisionevent_t * pEvent) = 0;
virtual void PostCollision(vcollisionevent_t * pEvent) = 0;
// This is a scrape event. The object has scraped across another object
// consuming the indicated energy
virtual void Friction(IPhysicsObject * pObject, float energy,
int surfaceProps, int surfacePropsHit,
IPhysicsCollisionData *pData) = 0;
virtual void StartTouch(IPhysicsObject * pObject1,
IPhysicsObject * pObject2,
IPhysicsCollisionData * pTouchData) = 0;
virtual void EndTouch(IPhysicsObject * pObject1, IPhysicsObject * pObject2,
IPhysicsCollisionData * pTouchData) = 0;
virtual void FluidStartTouch(IPhysicsObject * pObject,
IPhysicsFluidController * pFluid) = 0;
virtual void FluidEndTouch(IPhysicsObject * pObject,
IPhysicsFluidController * pFluid) = 0;
virtual void PostSimulationFrame() = 0;
virtual void ObjectEnterTrigger(IPhysicsObject * pTrigger,
IPhysicsObject * pObject) {}
virtual void ObjectLeaveTrigger(IPhysicsObject * pTrigger,
IPhysicsObject * pObject) {}
};
abstract_class IPhysicsObjectEvent {
public:
// these can be used to optimize out queries on sleeping objects
// Called when an object is woken after sleeping
virtual void ObjectWake(IPhysicsObject * pObject) = 0;
// called when an object goes to sleep (no longer simulating)
virtual void ObjectSleep(IPhysicsObject * pObject) = 0;
};
class IPhysicsConstraintEvent {
public:
// the constraint is now inactive, the game code is required to delete it or
// re-activate it.
virtual void ConstraintBroken(IPhysicsConstraint *) = 0;
};
struct hlshadowcontrol_params_t {
Vector targetPosition;
QAngle targetRotation;
float maxAngular;
float maxDampAngular;
float maxSpeed;
float maxDampSpeed;
float dampFactor;
float teleportDistance;
};
// UNDONE: At some point allow this to be parameterized using
// hlshadowcontrol_params_t. All of the infrastructure is in place to do that.
abstract_class IPhysicsShadowController {
public:
virtual ~IPhysicsShadowController(void) {}
virtual void Update(const Vector &position, const QAngle &angles,
float timeOffset) = 0;
virtual void MaxSpeed(float maxSpeed, float maxAngularSpeed) = 0;
virtual void StepUp(float height) = 0;
// If the teleport distance is non-zero, the object will be teleported to
// the target location when the error exceeds this quantity.
virtual void SetTeleportDistance(float teleportDistance) = 0;
virtual bool AllowsTranslation() = 0;
virtual bool AllowsRotation() = 0;
// There are two classes of shadow objects:
// 1) Game physics controlled, shadow follows game physics (this is the
// default) 2) Physically controlled - shadow position is a target, but the
// game hasn't guaranteed that the space can be occupied by this object
virtual void SetPhysicallyControlled(bool isPhysicallyControlled) = 0;
virtual bool IsPhysicallyControlled() = 0;
virtual void GetLastImpulse(Vector * pOut) = 0;
virtual void UseShadowMaterial(bool bUseShadowMaterial) = 0;
virtual void ObjectMaterialChanged(int materialIndex) = 0;
};
class CPhysicsSimObject;
class IPhysicsMotionController;
// Callback for simulation
class IMotionEvent {
public:
// These constants instruct the simulator as to how to apply the values
// copied to linear & angular GLOBAL/LOCAL refer to the coordinate system of
// the values, whereas acceleration/force determine whether or not mass is
// divided out (forces must be divided by mass to compute acceleration)
enum simresult_e {
SIM_NOTHING = 0,
SIM_LOCAL_ACCELERATION,
SIM_LOCAL_FORCE,
SIM_GLOBAL_ACCELERATION,
SIM_GLOBAL_FORCE
};
virtual simresult_e Simulate(IPhysicsMotionController *pController,
IPhysicsObject *pObject, float deltaTime,
Vector &linear, AngularImpulse &angular) = 0;
};
abstract_class IPhysicsMotionController {
public:
virtual ~IPhysicsMotionController(void) {}
virtual void SetEventHandler(IMotionEvent * handler) = 0;
virtual void AttachObject(IPhysicsObject * pObject,
bool checkIfAlreadyAttached) = 0;
virtual void DetachObject(IPhysicsObject * pObject) = 0;
// returns the number of objects currently attached to the controller
virtual int CountObjects(void) = 0;
// NOTE: pObjectList is an array with at least CountObjects() allocated
virtual void GetObjects(IPhysicsObject * *pObjectList) = 0;
// detaches all attached objects
virtual void ClearObjects(void) = 0;
// wakes up all attached objects
virtual void WakeObjects(void) = 0;
enum priority_t {
LOW_PRIORITY = 0,
MEDIUM_PRIORITY = 1,
HIGH_PRIORITY = 2,
};
virtual void SetPriority(priority_t priority) = 0;
};
// -------------------
// Collision filter function. Return 0 if objects should not be tested for
// collisions, nonzero otherwise Install with
// IPhysicsEnvironment::SetCollisionFilter()
// -------------------
abstract_class IPhysicsCollisionSolver {
public:
virtual int ShouldCollide(IPhysicsObject * pObj0, IPhysicsObject * pObj1,
void *pGameData0, void *pGameData1) = 0;
virtual int ShouldSolvePenetration(IPhysicsObject * pObj0,
IPhysicsObject * pObj1, void *pGameData0,
void *pGameData1, float dt) = 0;
// pObject has already done the max number of collisions this tick, should
// we freeze it to save CPU?
virtual bool ShouldFreezeObject(IPhysicsObject * pObject) = 0;
// The system has already done too many collision checks, performance will
// suffer. How many more should it do?
virtual int AdditionalCollisionChecksThisTick(int currentChecksDone) = 0;
};
enum PhysicsTraceType_t {
VPHYSICS_TRACE_EVERYTHING = 0,
VPHYSICS_TRACE_STATIC_ONLY,
VPHYSICS_TRACE_MOVING_ONLY,
VPHYSICS_TRACE_TRIGGERS_ONLY,
VPHYSICS_TRACE_STATIC_AND_MOVING,
};
abstract_class IPhysicsTraceFilter {
public:
virtual bool ShouldHitObject(IPhysicsObject * pObject,
int contentsMask) = 0;
virtual PhysicsTraceType_t GetTraceType() const = 0;
};
abstract_class IPhysicsEnvironment {
public:
virtual ~IPhysicsEnvironment(void) {}
virtual void SetDebugOverlay(CreateInterfaceFn debugOverlayFactory) = 0;
virtual IVPhysicsDebugOverlay *GetDebugOverlay(void) = 0;
// gravity is a 3-vector in in/s^2
virtual void SetGravity(const Vector &gravityVector) = 0;
virtual void GetGravity(Vector & gravityVector) = 0;
// air density is in kg / m^3 (water is 1000)
// This controls drag, air that is more dense has more drag.
virtual void SetAirDensity(float density) = 0;
virtual float GetAirDensity(void) = 0;
// object creation
// create a polygonal object. pCollisionModel was created by the physics
// builder DLL in a pre-process.
virtual IPhysicsObject *CreatePolyObject(
const CPhysCollide *pCollisionModel, int materialIndex,
const Vector &position, const QAngle &angles,
objectparams_t *pParams) = 0;
// same as above, but this one cannot move or rotate (infinite mass/inertia)
virtual IPhysicsObject *CreatePolyObjectStatic(
const CPhysCollide *pCollisionModel, int materialIndex,
const Vector &position, const QAngle &angles,
objectparams_t *pParams) = 0;
// Create a perfectly spherical object
virtual IPhysicsObject *CreateSphereObject(
float radius, int materialIndex, const Vector &position,
const QAngle &angles, objectparams_t *pParams, bool isStatic) = 0;
// Create a polygonal fluid body out of the specified collision model
// This object will affect any other objects that collide with the collision
// model
virtual IPhysicsFluidController *CreateFluidController(
IPhysicsObject * pFluidObject, fluidparams_t * pParams) = 0;
// Create a simulated spring that connects 2 objects
virtual IPhysicsSpring *CreateSpring(IPhysicsObject * pObjectStart,
IPhysicsObject * pObjectEnd,
springparams_t * pParams) = 0;
// Create a constraint in the space of pReferenceObject which is attached by
// the constraint to pAttachedObject
virtual IPhysicsConstraint *CreateRagdollConstraint(
IPhysicsObject * pReferenceObject, IPhysicsObject * pAttachedObject,
IPhysicsConstraintGroup * pGroup,
const constraint_ragdollparams_t &ragdoll) = 0;
virtual IPhysicsConstraint *CreateHingeConstraint(
IPhysicsObject * pReferenceObject, IPhysicsObject * pAttachedObject,
IPhysicsConstraintGroup * pGroup,
const constraint_hingeparams_t &hinge) = 0;
virtual IPhysicsConstraint *CreateFixedConstraint(
IPhysicsObject * pReferenceObject, IPhysicsObject * pAttachedObject,
IPhysicsConstraintGroup * pGroup,
const constraint_fixedparams_t &fixed) = 0;
virtual IPhysicsConstraint *CreateSlidingConstraint(
IPhysicsObject * pReferenceObject, IPhysicsObject * pAttachedObject,
IPhysicsConstraintGroup * pGroup,
const constraint_slidingparams_t &sliding) = 0;
virtual IPhysicsConstraint *CreateBallsocketConstraint(
IPhysicsObject * pReferenceObject, IPhysicsObject * pAttachedObject,
IPhysicsConstraintGroup * pGroup,
const constraint_ballsocketparams_t &ballsocket) = 0;
virtual IPhysicsConstraint *CreatePulleyConstraint(
IPhysicsObject * pReferenceObject, IPhysicsObject * pAttachedObject,
IPhysicsConstraintGroup * pGroup,
const constraint_pulleyparams_t &pulley) = 0;
virtual IPhysicsConstraint *CreateLengthConstraint(
IPhysicsObject * pReferenceObject, IPhysicsObject * pAttachedObject,
IPhysicsConstraintGroup * pGroup,
const constraint_lengthparams_t &length) = 0;
virtual IPhysicsConstraintGroup *CreateConstraintGroup(
const constraint_groupparams_t &groupParams) = 0;
// destroy an object created with CreatePolyObject() or
// CreatePolyObjectStatic()
virtual void DestroyObject(IPhysicsObject *) = 0;
virtual void DestroySpring(IPhysicsSpring *) = 0;
// Destroy an object created with CreateFluidController()
virtual void DestroyFluidController(IPhysicsFluidController *) = 0;
virtual void DestroyConstraint(IPhysicsConstraint *) = 0;
virtual void DestroyConstraintGroup(IPhysicsConstraintGroup * pGroup) = 0;
// install a function to filter collisions/penentration
virtual void SetCollisionSolver(IPhysicsCollisionSolver * pSolver) = 0;
// run the simulator for deltaTime seconds
virtual void Simulate(float deltaTime) = 0;
// true if currently running the simulator (i.e. in a callback during
// physenv->Simulate())
virtual bool IsInSimulation(void) const = 0;
// Manage the timestep (period) of the simulator. The main functions are
// all integrated with this period as dt.
virtual float GetSimulationTimestep(void) = 0;
virtual void SetSimulationTimestep(float timestep) = 0;
// returns the current simulation clock's value. This is an absolute time.
virtual float GetSimulationTime(void) = 0;
virtual void ResetSimulationClock(void) = 0;
// Collision callbacks (game code collision response)
virtual void SetCollisionEventHandler(IPhysicsCollisionEvent *
pCollisionEvents) = 0;
virtual void SetObjectEventHandler(IPhysicsObjectEvent * pObjectEvents) = 0;
virtual void SetConstraintEventHandler(IPhysicsConstraintEvent *
pConstraintEvents) = 0;
virtual IPhysicsShadowController *CreateShadowController(
IPhysicsObject * pObject, bool allowTranslation,
bool allowRotation) = 0;
virtual void DestroyShadowController(IPhysicsShadowController *) = 0;
virtual IPhysicsPlayerController *CreatePlayerController(IPhysicsObject *
pObject) = 0;
virtual void DestroyPlayerController(IPhysicsPlayerController *) = 0;
virtual IPhysicsMotionController *CreateMotionController(IMotionEvent *
pHandler) = 0;
virtual void DestroyMotionController(IPhysicsMotionController *
pController) = 0;
virtual IPhysicsVehicleController *CreateVehicleController(
IPhysicsObject * pVehicleBodyObject, const vehicleparams_t &params,
unsigned int nVehicleType, IPhysicsGameTrace *pGameTrace) = 0;
virtual void DestroyVehicleController(IPhysicsVehicleController *) = 0;
virtual void SetQuickDelete(bool bQuick) = 0;
virtual int GetActiveObjectCount(void) = 0;
virtual void GetActiveObjects(IPhysicsObject * *pOutputObjectList) = 0;
virtual void CleanupDeleteList(void) = 0;
virtual void EnableDeleteQueue(bool enable) = 0;
// Save/Restore methods
virtual bool Save(const physsaveparams_t &params) = 0;
virtual void PreRestore(const physprerestoreparams_t &params) = 0;
virtual bool Restore(const physrestoreparams_t &params) = 0;
virtual void PostRestore() = 0;
// Debugging:
virtual bool IsCollisionModelUsed(CPhysCollide * pCollide) = 0;
// Physics world version of the enginetrace API:
virtual void TraceRay(const Ray_t &ray, unsigned int fMask,
IPhysicsTraceFilter *pTraceFilter,
trace_t *pTrace) = 0;
virtual void SweepCollideable(
const CPhysCollide *pCollide, const Vector &vecAbsStart,
const Vector &vecAbsEnd, const QAngle &vecAngles, unsigned int fMask,
IPhysicsTraceFilter *pTraceFilter, trace_t *pTrace) = 0;
// performance tuning
virtual void GetPerformanceSettings(physics_performanceparams_t *
pOutput) = 0;
virtual void SetPerformanceSettings(
const physics_performanceparams_t *pSettings) = 0;
// perf/cost statistics
virtual void ReadStats(physics_stats_t * pOutput) = 0;
virtual void ClearStats() = 0;
};
enum callbackflags {
CALLBACK_GLOBAL_COLLISION = 0x0001,
CALLBACK_GLOBAL_FRICTION = 0x0002,
CALLBACK_GLOBAL_TOUCH = 0x0004,
CALLBACK_GLOBAL_TOUCH_STATIC = 0x0008,
CALLBACK_SHADOW_COLLISION = 0x0010,
CALLBACK_GLOBAL_COLLIDE_STATIC = 0x0020,
CALLBACK_IS_VEHICLE_WHEEL = 0x0040,
CALLBACK_FLUID_TOUCH = 0x0100,
CALLBACK_NEVER_DELETED = 0x0200, // HACKHACK: This means this object will
// never be deleted (set on the world)
CALLBACK_MARKED_FOR_DELETE =
0x0400, // This allows vphysics to skip some work for this object since
// it will be deleted later this frame. (Set automatically by
// destroy calls)
CALLBACK_ENABLING_COLLISION =
0x0800, // This is active during the time an object is enabling
// collisions allows us to skip collisions between "new"
// objects and objects marked for delete
CALLBACK_DO_FLUID_SIMULATION =
0x1000, // remove this to opt out of fluid simulations
CALLBACK_IS_PLAYER_CONTROLLER =
0x2000, // HACKHACK: Set this on players until player cotrollers are
// unified with shadow controllers
CALLBACK_CHECK_COLLISION_DISABLE = 0x4000,
CALLBACK_MARKED_FOR_TEST =
0x8000, // debug -- marked object is being debugged
};
abstract_class IPhysicsObject {
public:
virtual ~IPhysicsObject(void) {}
// returns true if this object is static/unmoveable
// NOTE: returns false for objects that are not created static, but set
// EnableMotion(false); Call IsMoveable() to find if the object is static OR
// has motion disabled
virtual bool IsStatic(void) = 0;
// "wakes up" an object
// NOTE: ALL OBJECTS ARE "Asleep" WHEN CREATED
virtual void Wake(void) = 0;
virtual void Sleep(void) = 0;
virtual bool IsAsleep(void) = 0;
// Game can store data in each object (link back to game object)
virtual void SetGameData(void *pGameData) = 0;
virtual void *GetGameData(void) const = 0;
// This flags word can be defined by the game as well
virtual void SetGameFlags(unsigned short userFlags) = 0;
virtual unsigned short GetGameFlags(void) const = 0;
virtual void SetGameIndex(unsigned short gameIndex) = 0;
virtual unsigned short GetGameIndex(void) const = 0;
// setup various callbacks for this object
virtual void SetCallbackFlags(unsigned short callbackflags) = 0;
// get the current callback state for this object
virtual unsigned short GetCallbackFlags(void) = 0;
// mass accessors
virtual void SetMass(float mass) = 0;
virtual float GetMass(void) const = 0;
// get 1/mass (it's cached)
virtual float GetInvMass(void) const = 0;
virtual Vector GetInertia(void) const = 0;
virtual Vector GetInvInertia(void) const = 0;
virtual void SetInertia(const Vector &inertia) = 0;
virtual void SetDamping(const float *speed, const float *rot) = 0;
virtual void GetDamping(float *speed, float *rot) = 0;
// material index
virtual int GetMaterialIndex() const = 0;
virtual void SetMaterialIndex(int materialIndex) = 0;
// Enable / disable collisions for this object
virtual void EnableCollisions(bool enable) = 0;
// Enable / disable gravity for this object
virtual void EnableGravity(bool enable) = 0;
// Enable / disable air friction / drag for this object
virtual void EnableDrag(bool enable) = 0;
// Enable / disable motion (pin / unpin the object)
virtual void EnableMotion(bool enable) = 0;
// call this when the collision filter conditions change due to this
// object's state (e.g. changing solid type or collision group)
virtual void RecheckCollisionFilter() = 0;
// NOTE: These are here for convenience, but you can do them yourself by
// using the matrix
// returned from GetPositionMatrix()
// convenient coordinate system transformations (params - dest, src)
virtual void LocalToWorld(Vector * worldPosition,
const Vector &localPosition) = 0;
virtual void WorldToLocal(Vector * localPosition,
const Vector &worldPosition) = 0;
// transforms a vector (no translation) from object-local to world space
virtual void LocalToWorldVector(Vector * worldVector,
const Vector &localVector) = 0;
// transforms a vector (no translation) from world to object-local space
virtual void WorldToLocalVector(Vector * localVector,
const Vector &worldVector) = 0;
// push on an object
// force vector is direction & magnitude of impulse kg in / s
virtual void ApplyForceCenter(const Vector &forceVector) = 0;
virtual void ApplyForceOffset(const Vector &forceVector,
const Vector &worldPosition) = 0;
// Calculates the force/torque on the center of mass for an offset force
// impulse (pass output to ApplyForceCenter / ApplyTorqueCenter)
virtual void CalculateForceOffset(
const Vector &forceVector, const Vector &worldPosition,
Vector *centerForce, AngularImpulse *centerTorque) = 0;
// Calculates the linear/angular velocities on the center of mass for an
// offset force impulse (pass output to AddVelocity)
virtual void CalculateVelocityOffset(
const Vector &forceVector, const Vector &worldPosition,
Vector *centerVelocity, AngularImpulse *centerAngularVelocity) = 0;
// apply torque impulse. This will change the angular velocity on the
// object. HL Axes, kg degrees / s
virtual void ApplyTorqueCenter(const AngularImpulse &torque) = 0;
// NOTE: This will teleport the object
virtual void SetPosition(const Vector &worldPosition, const QAngle &angles,
bool isTeleport) = 0;
virtual void SetPositionMatrix(const matrix3x4_t &matrix,
bool isTeleport) = 0;
virtual void GetPosition(Vector * worldPosition, QAngle * angles) = 0;
virtual void GetPositionMatrix(matrix3x4_t * positionMatrix) = 0;
// force the velocity to a new value
// NOTE: velocity is in worldspace, angularVelocity is relative to the
// object's local axes (just like pev->velocity, pev->avelocity)
virtual void SetVelocity(const Vector *velocity,
const AngularImpulse *angularVelocity) = 0;
// like the above, but force the change into the simulator immediately
virtual void SetVelocityInstantaneous(
const Vector *velocity, const AngularImpulse *angularVelocity) = 0;
// NOTE: velocity is in worldspace, angularVelocity is relative to the
// object's local axes (just like pev->velocity, pev->avelocity)
virtual void GetVelocity(Vector * velocity,
AngularImpulse * angularVelocity) = 0;
// NOTE: These are velocities, not forces. i.e. They will have the same
// effect regardless of the object's mass or inertia
virtual void AddVelocity(const Vector *velocity,
const AngularImpulse *angularVelocity) = 0;
virtual void GetVelocityAtPoint(const Vector &worldPosition,
Vector &velocity) = 0;
virtual float GetEnergy() = 0;
// returns true if the object is in contact with another object
// if true, puts a point on the contact surface in contactPoint, and
// a pointer to the object in contactObject
// NOTE: You can pass NULL for either to avoid computations
// JAY: This is still an experiment
virtual bool GetContactPoint(Vector * contactPoint,
IPhysicsObject * *contactObject) = 0;
// refactor this a bit - move some of this to IPhysicsShadowController
virtual void SetShadow(float maxSpeed, float maxAngularSpeed,
bool allowPhysicsMovement,
bool allowPhysicsRotation) = 0;
virtual void UpdateShadow(const Vector &targetPosition,
const QAngle &targetAngles,
bool tempDisableGravity, float timeOffset) = 0;
// returns number of ticks since last Update() call
virtual int GetShadowPosition(Vector * position, QAngle * angles) = 0;
virtual IPhysicsShadowController *GetShadowController(void) const = 0;
virtual const CPhysCollide *GetCollide(void) const = 0;
virtual const char *GetName() = 0;
virtual void RemoveShadowController() = 0;
virtual bool IsMoveable() = 0;
// applies the math of the shadow controller to this object.
// for use in your own controllers
// returns the new value of secondsToArrival with dt time elapsed
virtual float ComputeShadowControl(const hlshadowcontrol_params_t &params,
float secondsToArrival, float dt) = 0;
// coefficients are optional, pass either
virtual void SetDragCoefficient(float *pDrag, float *pAngularDrag) = 0;
// Get the radius if this is a sphere object (zero if this is a polygonal
// mesh)
virtual float GetSphereRadius() = 0;
virtual float CalculateLinearDrag(const Vector &unitDirection) const = 0;
virtual float CalculateAngularDrag(const Vector &objectSpaceRotationAxis)
const = 0;
virtual void SetBuoyancyRatio(float ratio) = 0; // Override bouyancy
virtual void BecomeTrigger() = 0;
virtual void RemoveTrigger() = 0;
virtual bool IsTrigger() = 0;
virtual bool
IsFluid() = 0; // fluids are special triggers with fluid controllers
// attached, they return true to IsTrigger() as well!
// sets the object to be hinged. Fixed it place, but able to rotate around
// one axis.
virtual void BecomeHinged(int localAxis) = 0;
// resets the object to original state
virtual void RemoveHinged() = 0;
virtual bool IsHinged() = 0;
virtual unsigned int GetContents() = 0;
virtual void SetContents(unsigned int contents) = 0;
virtual Vector GetMassCenterLocalSpace() = 0;
// used to iterate the contact points of an object
virtual IPhysicsFrictionSnapshot *CreateFrictionSnapshot() = 0;
virtual void DestroyFrictionSnapshot(IPhysicsFrictionSnapshot *
pSnapshot) = 0;
// dumps info about the object to Msg()
virtual void OutputDebugInfo() = 0;
virtual void GetImplicitVelocity(Vector * velocity,
AngularImpulse * angularVelocity) = 0;
// this is a hack to recheck current contacts
// some of them may not be valid if the object's collision rules have
// recently changed UNDONE: Force this in RecheckCollisionFilter() ?
virtual void RecheckContactPoints() = 0;
};
abstract_class IPhysicsSpring {
public:
virtual ~IPhysicsSpring(void) {}
virtual void GetEndpoints(Vector * worldPositionStart,
Vector * worldPositionEnd) = 0;
virtual void SetSpringConstant(float flSpringContant) = 0;
virtual void SetSpringDamping(float flSpringDamping) = 0;
virtual void SetSpringLength(float flSpringLenght) = 0;
// Get the starting object
virtual IPhysicsObject *GetStartObject(void) = 0;
// Get the end object
virtual IPhysicsObject *GetEndObject(void) = 0;
};
//-----------------------------------------------------------------------------
// Purpose: These properties are defined per-material. This is accessible at
// each triangle in a collision mesh
//-----------------------------------------------------------------------------
struct surfacephysicsparams_t {
// vphysics physical properties
float friction;
float elasticity; // collision elasticity - used to compute coefficient of
// restitution
float density; // physical density (in kg / m^3)
float thickness; // material thickness if not solid (sheet materials) in
// inches
float dampening;
};
struct surfaceaudioparams_t {
// sounds / audio data
float reflectivity; // like elasticity, but how much sound should be
// reflected by this surface
float hardnessFactor; // like elasticity, but only affects impact sound
// choices
float roughnessFactor; // like friction, but only affects scrape sound
// choices
// audio thresholds
float roughThreshold; // surface roughness > this causes "rough" scrapes, <
// this causes "smooth" scrapes
float hardThreshold; // surface hardness > this causes "hard" impacts, <
// this causes "soft" impacts
float hardVelocityThreshold; // collision velocity > this causes "hard"
// impacts, < this causes "soft" impacts NOTE:
// Hard impacts must meet both hardnessFactor
// AND velocity thresholds
};
struct surfacesoundnames_t {
unsigned short stepleft;
unsigned short stepright;
unsigned short impactSoft;
unsigned short impactHard;
unsigned short scrapeSmooth;
unsigned short scrapeRough;
unsigned short bulletImpact;
unsigned short rolling;
unsigned short breakSound;
unsigned short strainSound;
};
struct surfacegameprops_t {
// game movement data
float maxSpeedFactor; // Modulates player max speed when walking on this
// surface
float jumpFactor; // Indicates how much higher the player should jump when
// on the surface
// Game-specific data
unsigned short material;
// Indicates whether or not the player is on a ladder.
unsigned char climbable;
unsigned char pad;
};
//-----------------------------------------------------------------------------
// Purpose: Each different material has an entry like this
//-----------------------------------------------------------------------------
struct surfacedata_t {
surfacephysicsparams_t physics; // physics parameters
surfaceaudioparams_t audio; // audio parameters
surfacesoundnames_t sounds; // names of linked sounds
surfacegameprops_t game; // Game data / properties
};
#define VPHYSICS_SURFACEPROPS_INTERFACE_VERSION_1 "VPhysicsSurfaceProps001"
abstract_class IPhysicsSurfaceProps {
public:
virtual ~IPhysicsSurfaceProps(void) {}
// parses a text file containing surface prop keys
virtual int ParseSurfaceData(const char *pFilename,
const char *pTextfile) = 0;
// current number of entries in the database
virtual int SurfacePropCount(void) = 0;
virtual int GetSurfaceIndex(const char *pSurfacePropName) = 0;
virtual void GetPhysicsProperties(int surfaceDataIndex, float *density,
float *thickness, float *friction,
float *elasticity) = 0;
virtual surfacedata_t *GetSurfaceData(int surfaceDataIndex) = 0;
virtual const char *GetString(unsigned short stringTableIndex) = 0;
virtual const char *GetPropName(int surfaceDataIndex) = 0;
// sets the global index table for world materials
virtual void SetWorldMaterialIndexTable(int *pMapArray, int mapSize) = 0;
// NOTE: Same as GetPhysicsProperties, but maybe more convenient
virtual void GetPhysicsParameters(int surfaceDataIndex,
surfacephysicsparams_t *pParamsOut) = 0;
};
abstract_class IPhysicsFluidController {
public:
virtual ~IPhysicsFluidController(void) {}
virtual void SetGameData(void *pGameData) = 0;
virtual void *GetGameData(void) const = 0;
virtual void GetSurfacePlane(Vector * pNormal, float *pDist) = 0;
virtual float GetDensity() = 0;
virtual void WakeAllSleepingObjects() = 0;
virtual int GetContents() const = 0;
};
//-----------------------------------------------------------------------------
// Purpose: parameter block for creating fluid dynamic motion
// UNDONE: Expose additional fluid model paramters?
//-----------------------------------------------------------------------------
struct fluidparams_t {
Vector4D surfacePlane; // x,y,z normal, dist (plane constant) fluid surface
Vector currentVelocity; // velocity of the current in inches/second
float damping; // damping factor for buoyancy (tweak)
float torqueFactor;
float viscosityFactor;
void *pGameData;
bool useAerodynamics; // true if this controller should calculate surface
// pressure
int contents;
fluidparams_t() {}
fluidparams_t(fluidparams_t const &src) {
Vector4DCopy(src.surfacePlane, surfacePlane);
VectorCopy(src.currentVelocity, currentVelocity);
damping = src.damping;
torqueFactor = src.torqueFactor;
viscosityFactor = src.viscosityFactor;
contents = src.contents;
}
};
//-----------------------------------------------------------------------------
// Purpose: parameter block for creating linear springs
// UNDONE: Expose additional spring model paramters?
//-----------------------------------------------------------------------------
struct springparams_t {
springparams_t() { memset(this, 0, sizeof(*this)); }
float constant; // spring constant
float naturalLength; // relaxed length
float damping; // damping factor
float relativeDamping; // relative damping (damping proportional to the
// change in the relative position of the objects)
Vector startPosition;
Vector endPosition;
bool useLocalPositions; // start & end Position are in local space to start
// and end objects if this is true
bool onlyStretch; // only apply forces when the length is greater than the
// natural length
};
//-----------------------------------------------------------------------------
// Purpose: parameter block for creating polygonal objects
//-----------------------------------------------------------------------------
struct objectparams_t {
Vector *massCenterOverride;
float mass;
float inertia;
float damping;
float rotdamping;
float rotInertiaLimit;
const char *pName; // used only for debugging
void *pGameData;
float volume;
float dragCoefficient;
bool enableCollisions;
};
struct convertconvexparams_t {
bool buildOuterConvexHull;
bool buildDragAxisAreas;
bool buildOptimizedTraceTables;
float dragAreaEpsilon;
CPhysConvex *pForcedOuterHull;
void Defaults() {
dragAreaEpsilon = 0.25f; // 0.5in x 0.5in square
buildOuterConvexHull = false;
buildDragAxisAreas = false;
buildOptimizedTraceTables = false;
pForcedOuterHull = NULL;
}
};
//-----------------------------------------------------------------------------
// Physics interface IDs
//
// Note that right now the order of the enum also defines the order of save/load
//-----------------------------------------------------------------------------
// Purpose: parameter blocks for save and load operations
//-----------------------------------------------------------------------------
struct physsaveparams_t {
ISave *pSave;
void *pObject;
PhysInterfaceId_t type;
};
struct physrestoreparams_t {
IRestore *pRestore;
void **ppObject;
PhysInterfaceId_t type;
void *pGameData;
const char *pName; // used only for debugging
const CPhysCollide *pCollisionModel;
IPhysicsEnvironment *pEnvironment;
IPhysicsGameTrace *pGameTrace;
};
struct physrecreateparams_t {
void *pOldObject;
void *pNewObject;
};
struct physprerestoreparams_t {
int recreatedObjectCount;
physrecreateparams_t recreatedObjectList[1];
};
//-------------------------------------
#define DEFINE_PIID(type, enumval) \
template <> \
inline PhysInterfaceId_t GetPhysIID<type>(type **) { \
return enumval; \
}
template <class PHYSPTR>
inline PhysInterfaceId_t GetPhysIID(
PHYSPTR **); // will get link error if no match
DEFINE_PIID(IPhysicsObject, PIID_IPHYSICSOBJECT);
DEFINE_PIID(IPhysicsFluidController, PIID_IPHYSICSFLUIDCONTROLLER);
DEFINE_PIID(IPhysicsSpring, PIID_IPHYSICSSPRING);
DEFINE_PIID(IPhysicsConstraintGroup, PIID_IPHYSICSCONSTRAINTGROUP);
DEFINE_PIID(IPhysicsConstraint, PIID_IPHYSICSCONSTRAINT);
DEFINE_PIID(IPhysicsShadowController, PIID_IPHYSICSSHADOWCONTROLLER);
DEFINE_PIID(IPhysicsPlayerController, PIID_IPHYSICSPLAYERCONTROLLER);
DEFINE_PIID(IPhysicsMotionController, PIID_IPHYSICSMOTIONCONTROLLER);
DEFINE_PIID(IPhysicsVehicleController, PIID_IPHYSICSVEHICLECONTROLLER);
DEFINE_PIID(IPhysicsGameTrace, PIID_IPHYSICSGAMETRACE);
//-----------------------------------------------------------------------------
} // end namespace VPhysicsInterfaceV30
#endif // VPHYSICS_INTERFACE_V30_H