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