1223 lines
51 KiB
C++
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 ¶ms,
|
|
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 ¶ms) = 0;
|
|
virtual void PreRestore(const physprerestoreparams_t ¶ms) = 0;
|
|
virtual bool Restore(const physrestoreparams_t ¶ms) = 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 ¶ms,
|
|
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
|