You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1148 lines
50 KiB
1148 lines
50 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Public interfaces to vphysics DLL |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#ifndef VPHYSICS_INTERFACE_H |
|
#define VPHYSICS_INTERFACE_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
|
|
#include "tier1/interface.h" |
|
#include "appframework/IAppSystem.h" |
|
#include "mathlib/vector.h" |
|
#include "mathlib/vector4d.h" |
|
#include "vcollide.h" |
|
|
|
|
|
// ------------------------------------------------------------------------------------ |
|
// UNITS: |
|
// ------------------------------------------------------------------------------------ |
|
// NOTE: Coordinates are in HL units. 1 unit == 1 inch. X is east (forward), Y is north (left), Z is up (up) |
|
// QAngle are pitch (around y), Yaw (around Z), Roll (around X) |
|
// AngularImpulse are exponetial maps (an axis in HL units scaled by a "twist" angle in degrees) |
|
// They can be transformed like normals/covectors and added linearly |
|
// mass is kg, volume is in^3, acceleration is in/s^2, velocity is in/s |
|
|
|
// density is kg/m^3 (water ~= 998 at room temperature) |
|
// preferably, these would be in kg/in^3, but the range of those numbers makes them not very human readable |
|
// having water be about 1000 is really convenient for data entry. |
|
// Since volume is in in^3 and density is in kg/m^3: |
|
// density = (mass / volume) * CUBIC_METERS_PER_CUBIC_INCH |
|
// Force is applied using impulses (kg*in/s) |
|
// Torque is applied using impulses (kg*degrees/s) |
|
// ------------------------------------------------------------------------------------ |
|
|
|
#define METERS_PER_INCH (0.0254f) |
|
#define CUBIC_METERS_PER_CUBIC_INCH (METERS_PER_INCH*METERS_PER_INCH*METERS_PER_INCH) |
|
// 2.2 lbs / kg |
|
#define POUNDS_PER_KG (2.2f) |
|
#define KG_PER_POUND (1.0f/POUNDS_PER_KG) |
|
|
|
// convert from pounds to kg |
|
#define lbs2kg(x) ((x)*KG_PER_POUND) |
|
#define kg2lbs(x) ((x)*POUNDS_PER_KG) |
|
|
|
const float VPHYSICS_MIN_MASS = 0.1f; |
|
const float VPHYSICS_MAX_MASS = 5e4f; |
|
|
|
class IPhysicsObject; |
|
class IPhysicsEnvironment; |
|
class IPhysicsSurfaceProps; |
|
class IPhysicsConstraint; |
|
class IPhysicsConstraintGroup; |
|
class IPhysicsFluidController; |
|
class IPhysicsSpring; |
|
class IPhysicsVehicleController; |
|
class IConvexInfo; |
|
class IPhysicsObjectPairHash; |
|
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 virtualmeshparams_t; |
|
|
|
//enum PhysInterfaceId_t; |
|
struct physsaveparams_t; |
|
struct physrestoreparams_t; |
|
struct physprerestoreparams_t; |
|
|
|
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 "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 "VPhysics031" |
|
|
|
abstract_class IPhysics : public IAppSystem |
|
{ |
|
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; |
|
class CPackedPhysicsDescription; |
|
|
|
class CPolyhedron; |
|
|
|
// 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 "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; |
|
|
|
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; |
|
virtual CPhysConvex *BBoxToConvex( const Vector &mins, const Vector &maxs ) = 0; |
|
// produce a convex element from a convex polyhedron |
|
virtual CPhysConvex *ConvexFromConvexPolyhedron( const CPolyhedron &ConvexPolyhedron ) = 0; |
|
// produce a set of convex triangles from a convex polygon, normal is assumed to be on the side with forward point ordering, which should be clockwise, output will need to be able to hold exactly (iPointCount-2) convexes |
|
virtual void ConvexesFromConvexPolygon( const Vector &vPolyNormal, const Vector *pPoints, int iPointCount, CPhysConvex **pOutput ) = 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; |
|
|
|
// 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 CPhysCollide *ConvertConvexToCollideParams( CPhysConvex **pConvex, int convexCount, const convertconvexparams_t &convertParams ) = 0; |
|
// Free a collide that was created with ConvertConvexToCollide() |
|
virtual void DestroyCollide( CPhysCollide *pCollide ) = 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, bool bSwap = false ) = 0; |
|
// unserialize the collide from a block of memory |
|
virtual CPhysCollide *UnserializeCollide( char *pBuffer, int size, int index ) = 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 *pMins, Vector *pMaxs, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles ) = 0; |
|
|
|
virtual void CollideGetMassCenter( CPhysCollide *pCollide, Vector *pOutMassCenter ) = 0; |
|
virtual void CollideSetMassCenter( CPhysCollide *pCollide, const Vector &massCenter ) = 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; |
|
virtual void CollideSetOrthographicAreas( CPhysCollide *pCollide, const Vector &areas ) = 0; |
|
|
|
// query the vcollide index in the physics model for the instance |
|
virtual int CollideIndex( const CPhysCollide *pCollide ) = 0; |
|
|
|
// Convert a bbox to a collide |
|
virtual CPhysCollide *BBoxToCollide( const Vector &mins, const Vector &maxs ) = 0; |
|
virtual int GetConvexesUsedInCollideable( const CPhysCollide *pCollideable, CPhysConvex **pOutputArray, int iOutputArrayLimit ) = 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; |
|
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; |
|
|
|
// 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; |
|
|
|
// relatively slow test for box vs. truncated cone |
|
virtual bool IsBoxIntersectingCone( const Vector &boxAbsMins, const Vector &boxAbsMaxs, const truncatedcone_t &cone ) = 0; |
|
|
|
// loads a set of solids into a vcollide_t |
|
virtual void VCollideLoad( vcollide_t *pOutput, int solidCount, const char *pBuffer, int size, bool swap = false ) = 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 CPhysCollide *CreateVirtualMesh( const virtualmeshparams_t ¶ms ) = 0; |
|
virtual bool SupportsVirtualMesh() = 0; |
|
|
|
|
|
virtual bool GetBBoxCacheSize( int *pCachedSize, int *pCachedCount ) = 0; |
|
|
|
|
|
// extracts a polyhedron that defines a CPhysConvex's shape |
|
virtual CPolyhedron *PolyhedronFromConvex( CPhysConvex * const pConvex, bool bUseTempPolyhedron ) = 0; |
|
|
|
// dumps info about the collide to Msg() |
|
virtual void OutputDebugInfo( const CPhysCollide *pCollide ) = 0; |
|
virtual unsigned int ReadStat( int statID ) = 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; |
|
}; |
|
|
|
abstract_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; |
|
|
|
|
|
//Basically get the last inputs to IPhysicsShadowController::Update(), returns last input to timeOffset in Update() |
|
virtual float GetTargetPosition( Vector *pPositionOut, QAngle *pAnglesOut ) = 0; |
|
|
|
virtual float GetTeleportDistance( void ) = 0; |
|
virtual void GetMaxSpeed( float *pMaxSpeedOut, float *pMaxAngularSpeedOut ) = 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; |
|
|
|
// This list of objects is in a connected contact graph that is too large to solve quickly |
|
// return true to freeze the system, false to solve it |
|
virtual bool ShouldFreezeContacts( IPhysicsObject **pObjectList, int objectCount ) = 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 *pGravityVector ) const = 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 ) const = 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; |
|
// destroy an object created with CreatePolyObject() or CreatePolyObjectStatic() |
|
virtual void DestroyObject( IPhysicsObject * ) = 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; |
|
// Destroy an object created with CreateFluidController() |
|
virtual void DestroyFluidController( IPhysicsFluidController * ) = 0; |
|
|
|
// Create a simulated spring that connects 2 objects |
|
virtual IPhysicsSpring *CreateSpring( IPhysicsObject *pObjectStart, IPhysicsObject *pObjectEnd, springparams_t *pParams ) = 0; |
|
virtual void DestroySpring( IPhysicsSpring * ) = 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 void DestroyConstraint( IPhysicsConstraint * ) = 0; |
|
|
|
virtual IPhysicsConstraintGroup *CreateConstraintGroup( const constraint_groupparams_t &groupParams ) = 0; |
|
virtual void DestroyConstraintGroup( IPhysicsConstraintGroup *pGroup ) = 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; |
|
|
|
// 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() const = 0; |
|
|
|
// Manage the timestep (period) of the simulator. The main functions are all integrated with |
|
// this period as dt. |
|
virtual float GetSimulationTimestep() const = 0; |
|
virtual void SetSimulationTimestep( float timestep ) = 0; |
|
|
|
// returns the current simulation clock's value. This is an absolute time. |
|
virtual float GetSimulationTime() const = 0; |
|
virtual void ResetSimulationClock() = 0; |
|
// returns the current simulation clock's value at the next frame. This is an absolute time. |
|
virtual float GetNextFrameTime( void ) const = 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 void SetQuickDelete( bool bQuick ) = 0; |
|
|
|
virtual int GetActiveObjectCount() const = 0; |
|
virtual void GetActiveObjects( IPhysicsObject **pOutputObjectList ) const = 0; |
|
virtual const IPhysicsObject **GetObjectList( int *pOutputObjectCount ) const = 0; |
|
virtual bool TransferObject( IPhysicsObject *pObject, IPhysicsEnvironment *pDestinationEnvironment ) = 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 ) const = 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 ) const = 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; |
|
|
|
virtual unsigned int GetObjectSerializeSize( IPhysicsObject *pObject ) const = 0; |
|
virtual void SerializeObjectToBuffer( IPhysicsObject *pObject, unsigned char *pBuffer, unsigned int bufferSize ) = 0; |
|
virtual IPhysicsObject *UnserializeObjectFromBuffer( void *pGameData, unsigned char *pBuffer, unsigned int bufferSize, bool enableCollisions ) = 0; |
|
|
|
|
|
virtual void EnableConstraintNotify( bool bEnable ) = 0; |
|
virtual void DebugCheckContacts(void) = 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() const = 0; |
|
virtual bool IsAsleep() const = 0; |
|
virtual bool IsTrigger() const = 0; |
|
virtual bool IsFluid() const = 0; // fluids are special triggers with fluid controllers attached, they return true to IsTrigger() as well! |
|
virtual bool IsHinged() const = 0; |
|
virtual bool IsCollisionEnabled() const = 0; |
|
virtual bool IsGravityEnabled() const = 0; |
|
virtual bool IsDragEnabled() const = 0; |
|
virtual bool IsMotionEnabled() const = 0; |
|
virtual bool IsMoveable() const = 0; // legacy: IsMotionEnabled() && !IsStatic() |
|
virtual bool IsAttachedToConstraint(bool bExternalOnly) const = 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; |
|
|
|
// 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 ) const = 0; |
|
|
|
// "wakes up" an object |
|
// NOTE: ALL OBJECTS ARE "Asleep" WHEN CREATED |
|
virtual void Wake( void ) = 0; |
|
virtual void Sleep( void ) = 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: Contact points aren't updated when collision rules change, call this to force an update |
|
// UNDONE: Force this in RecheckCollisionFilter() ? |
|
virtual void RecheckContactPoints() = 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 ) const = 0; |
|
|
|
// coefficients are optional, pass either |
|
virtual void SetDragCoefficient( float *pDrag, float *pAngularDrag ) = 0; |
|
virtual void SetBuoyancyRatio( float ratio ) = 0; // Override bouyancy |
|
|
|
// material index |
|
virtual int GetMaterialIndex() const = 0; |
|
virtual void SetMaterialIndex( int materialIndex ) = 0; |
|
|
|
// contents bits |
|
virtual unsigned int GetContents() const = 0; |
|
virtual void SetContents( unsigned int contents ) = 0; |
|
|
|
// Get the radius if this is a sphere object (zero if this is a polygonal mesh) |
|
virtual float GetSphereRadius() const = 0; |
|
virtual float GetEnergy() const = 0; |
|
virtual Vector GetMassCenterLocalSpace() const = 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 ) const = 0; |
|
virtual void GetPositionMatrix( matrix3x4_t *positionMatrix ) const = 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 ) const = 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; |
|
// gets a velocity in the object's local frame of reference at a specific point |
|
virtual void GetVelocityAtPoint( const Vector &worldPosition, Vector *pVelocity ) const = 0; |
|
// gets the velocity actually moved by the object in the last simulation update |
|
virtual void GetImplicitVelocity( Vector *velocity, AngularImpulse *angularVelocity ) const = 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 ) const = 0; |
|
virtual void WorldToLocal( Vector *localPosition, const Vector &worldPosition ) const = 0; |
|
|
|
// transforms a vector (no translation) from object-local to world space |
|
virtual void LocalToWorldVector( Vector *worldVector, const Vector &localVector ) const = 0; |
|
// transforms a vector (no translation) from world to object-local space |
|
virtual void WorldToLocalVector( Vector *localVector, const Vector &worldVector ) const = 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; |
|
// apply torque impulse. This will change the angular velocity on the object. |
|
// HL Axes, kg degrees / s |
|
virtual void ApplyTorqueCenter( const AngularImpulse &torque ) = 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 ) const = 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 ) const = 0; |
|
// calculate drag scale |
|
virtual float CalculateLinearDrag( const Vector &unitDirection ) const = 0; |
|
virtual float CalculateAngularDrag( const Vector &objectSpaceRotationAxis ) const = 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 |
|
// BUGBUG: Use CreateFrictionSnapshot instead of this - this is a simple hack |
|
virtual bool GetContactPoint( Vector *contactPoint, IPhysicsObject **contactObject ) const = 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 ) const = 0; |
|
virtual IPhysicsShadowController *GetShadowController( void ) const = 0; |
|
virtual void RemoveShadowController() = 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; |
|
|
|
|
|
virtual const CPhysCollide *GetCollide( void ) const = 0; |
|
virtual const char *GetName() const = 0; |
|
|
|
virtual void BecomeTrigger() = 0; |
|
virtual void RemoveTrigger() = 0; |
|
|
|
// 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; |
|
|
|
// 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() const = 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 surfacesoundhandles_t |
|
{ |
|
short stepleft; |
|
short stepright; |
|
|
|
short impactSoft; |
|
short impactHard; |
|
|
|
short scrapeSmooth; |
|
short scrapeRough; |
|
|
|
short bulletImpact; |
|
short rolling; |
|
|
|
short breakSound; |
|
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 |
|
|
|
surfacesoundhandles_t soundhandles; |
|
}; |
|
|
|
#define VPHYSICS_SURFACEPROPS_INTERFACE_VERSION "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 ) const = 0; |
|
|
|
virtual int GetSurfaceIndex( const char *pSurfacePropName ) const = 0; |
|
virtual void GetPhysicsProperties( int surfaceDataIndex, float *density, float *thickness, float *friction, float *elasticity ) const = 0; |
|
|
|
virtual surfacedata_t *GetSurfaceData( int surfaceDataIndex ) = 0; |
|
virtual const char *GetString( unsigned short stringTableIndex ) const = 0; |
|
|
|
|
|
virtual const char *GetPropName( int surfaceDataIndex ) const = 0; |
|
|
|
// sets the global index table for world materials |
|
// UNDONE: Make this per-CPhysCollide |
|
virtual void SetWorldMaterialIndexTable( int *pMapArray, int mapSize ) = 0; |
|
|
|
// NOTE: Same as GetPhysicsProperties, but maybe more convenient |
|
virtual void GetPhysicsParameters( int surfaceDataIndex, surfacephysicsparams_t *pParamsOut ) const = 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 ) const = 0; |
|
virtual float GetDensity() const = 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() = default; |
|
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 |
|
{ |
|
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 ); |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
#endif // VPHYSICS_INTERFACE_H
|
|
|