//========= 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 = 5e4 f ;
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 & params ) = 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 & params , 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 & params ) = 0 ;
virtual void PreRestore ( const physprerestoreparams_t & params ) = 0 ;
virtual bool Restore ( const physrestoreparams_t & params ) = 0 ;
virtual void PostRestore ( ) = 0 ;
// Debugging:
virtual bool IsCollisionModelUsed ( CPhysCollide * pCollide ) 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 & params , 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