aboutsummaryrefslogtreecommitdiff
path: root/mp/src/public/vphysics_interface.h
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /mp/src/public/vphysics_interface.h
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/public/vphysics_interface.h')
-rw-r--r--mp/src/public/vphysics_interface.h1152
1 files changed, 1152 insertions, 0 deletions
diff --git a/mp/src/public/vphysics_interface.h b/mp/src/public/vphysics_interface.h
new file mode 100644
index 00000000..bed104ce
--- /dev/null
+++ b/mp/src/public/vphysics_interface.h
@@ -0,0 +1,1152 @@
+//========= 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 &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() {}
+ fluidparams_t( fluidparams_t const& src )
+ {
+ Vector4DCopy( src.surfacePlane, surfacePlane );
+ VectorCopy( src.currentVelocity, currentVelocity );
+ damping = src.damping;
+ torqueFactor = src.torqueFactor;
+ viscosityFactor = src.viscosityFactor;
+ contents = src.contents;
+ }
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: parameter block for creating linear springs
+// UNDONE: Expose additional spring model paramters?
+//-----------------------------------------------------------------------------
+struct springparams_t
+{
+ springparams_t()
+ {
+ memset( this, 0, sizeof(*this) );
+ }
+ float constant; // spring constant
+ float naturalLength;// relaxed length
+ float damping; // damping factor
+ float relativeDamping; // relative damping (damping proportional to the change in the relative position of the objects)
+ Vector startPosition;
+ Vector endPosition;
+ bool useLocalPositions; // start & end Position are in local space to start and end objects if this is true
+ bool onlyStretch; // only apply forces when the length is greater than the natural length
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: parameter block for creating polygonal objects
+//-----------------------------------------------------------------------------
+struct objectparams_t
+{
+ Vector *massCenterOverride;
+ float mass;
+ float inertia;
+ float damping;
+ float rotdamping;
+ float rotInertiaLimit;
+ const char *pName; // used only for debugging
+ void *pGameData;
+ float volume;
+ float dragCoefficient;
+ bool enableCollisions;
+};
+
+struct convertconvexparams_t
+{
+ bool buildOuterConvexHull;
+ bool buildDragAxisAreas;
+ bool buildOptimizedTraceTables;
+ float dragAreaEpsilon;
+ CPhysConvex *pForcedOuterHull;
+
+ void Defaults()
+ {
+ dragAreaEpsilon = 0.25f; // 0.5in x 0.5in square
+ buildOuterConvexHull = false;
+ buildDragAxisAreas = false;
+ buildOptimizedTraceTables = false;
+ pForcedOuterHull = NULL;
+ }
+};
+
+//-----------------------------------------------------------------------------
+// Physics interface IDs
+//
+// Note that right now the order of the enum also defines the order of save/load
+
+
+//-----------------------------------------------------------------------------
+// Purpose: parameter blocks for save and load operations
+//-----------------------------------------------------------------------------
+struct physsaveparams_t
+{
+ ISave *pSave;
+ void *pObject;
+ PhysInterfaceId_t type;
+};
+
+struct physrestoreparams_t
+{
+ IRestore *pRestore;
+ void **ppObject;
+ PhysInterfaceId_t type;
+ void *pGameData;
+ const char *pName; // used only for debugging
+ const CPhysCollide *pCollisionModel;
+ IPhysicsEnvironment *pEnvironment;
+ IPhysicsGameTrace *pGameTrace;
+};
+
+struct physrecreateparams_t
+{
+ void *pOldObject;
+ void *pNewObject;
+};
+
+struct physprerestoreparams_t
+{
+ int recreatedObjectCount;
+ physrecreateparams_t recreatedObjectList[1];
+};
+
+//-------------------------------------
+
+#define DEFINE_PIID( type, enumval ) \
+ template <> inline PhysInterfaceId_t GetPhysIID<type>( type ** ) { return enumval; }
+
+template <class PHYSPTR> inline PhysInterfaceId_t GetPhysIID(PHYSPTR **); // will get link error if no match
+
+DEFINE_PIID( IPhysicsObject, PIID_IPHYSICSOBJECT );
+DEFINE_PIID( IPhysicsFluidController, PIID_IPHYSICSFLUIDCONTROLLER );
+DEFINE_PIID( IPhysicsSpring, PIID_IPHYSICSSPRING );
+DEFINE_PIID( IPhysicsConstraintGroup, PIID_IPHYSICSCONSTRAINTGROUP );
+DEFINE_PIID( IPhysicsConstraint, PIID_IPHYSICSCONSTRAINT );
+DEFINE_PIID( IPhysicsShadowController, PIID_IPHYSICSSHADOWCONTROLLER );
+DEFINE_PIID( IPhysicsPlayerController, PIID_IPHYSICSPLAYERCONTROLLER );
+DEFINE_PIID( IPhysicsMotionController, PIID_IPHYSICSMOTIONCONTROLLER );
+DEFINE_PIID( IPhysicsVehicleController, PIID_IPHYSICSVEHICLECONTROLLER );
+DEFINE_PIID( IPhysicsGameTrace, PIID_IPHYSICSGAMETRACE );
+
+//-----------------------------------------------------------------------------
+
+#endif // VPHYSICS_INTERFACE_H