You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
11 KiB
288 lines
11 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#ifndef PHYSICS_OBJECT_H |
|
#define PHYSICS_OBJECT_H |
|
|
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include "vphysics_interface.h" |
|
|
|
class IVP_Real_Object; |
|
class IVP_Environment; |
|
class IVP_U_Float_Point; |
|
class IVP_SurfaceManager; |
|
class IVP_Controller; |
|
class CPhysicsEnvironment; |
|
struct vphysics_save_cphysicsobject_t |
|
{ |
|
const CPhysCollide *pCollide; |
|
const char *pName; |
|
float sphereRadius; |
|
|
|
bool isStatic; |
|
bool collisionEnabled; |
|
bool gravityEnabled; |
|
bool dragEnabled; |
|
bool motionEnabled; |
|
bool isAsleep; |
|
bool isTrigger; |
|
bool asleepSinceCreation; // has this been asleep since creation? |
|
bool hasTouchedDynamic; |
|
bool hasShadowController; |
|
short collideType; |
|
unsigned short gameIndex; |
|
int hingeAxis; |
|
int materialIndex; |
|
float mass; |
|
Vector rotInertia; |
|
float speedDamping; |
|
float rotSpeedDamping; |
|
Vector massCenterOverride; |
|
|
|
unsigned int callbacks; |
|
unsigned int gameFlags; |
|
|
|
unsigned int contentsMask; |
|
|
|
float volume; |
|
float dragCoefficient; |
|
float angDragCoefficient; |
|
IPhysicsShadowController *pShadow; |
|
//bool m_shadowTempGravityDisable; |
|
|
|
Vector origin; |
|
QAngle angles; |
|
Vector velocity; |
|
AngularImpulse angVelocity; |
|
|
|
DECLARE_SIMPLE_DATADESC(); |
|
}; |
|
|
|
enum |
|
{ |
|
OBJ_AWAKE = 0, // awake, simulating |
|
OBJ_STARTSLEEP = 1, // going to sleep, but not queried yet |
|
OBJ_SLEEP = 2, // sleeping, no state changes since last query |
|
}; |
|
|
|
|
|
class CPhysicsObject : public IPhysicsObject |
|
{ |
|
public: |
|
CPhysicsObject( void ); |
|
virtual ~CPhysicsObject( void ); |
|
|
|
void Init( const CPhysCollide *pCollisionModel, IVP_Real_Object *pObject, int materialIndex, float volume, float drag, float angDrag ); |
|
|
|
// IPhysicsObject functions |
|
bool IsStatic() const; |
|
bool IsAsleep() const; |
|
bool IsTrigger() const; |
|
bool IsFluid() const; |
|
bool IsHinged() const { return (m_hingedAxis != 0) ? true : false; } |
|
bool IsCollisionEnabled() const; |
|
bool IsGravityEnabled() const; |
|
bool IsDragEnabled() const; |
|
bool IsMotionEnabled() const; |
|
bool IsMoveable() const; |
|
bool IsAttachedToConstraint( bool bExternalOnly ) const; |
|
|
|
|
|
void EnableCollisions( bool enable ); |
|
// Enable / disable gravity for this object |
|
void EnableGravity( bool enable ); |
|
// Enable / disable air friction / drag for this object |
|
void EnableDrag( bool enable ); |
|
void EnableMotion( bool enable ); |
|
|
|
void SetGameData( void *pAppData ); |
|
void *GetGameData( void ) const; |
|
void SetCallbackFlags( unsigned short callbackflags ); |
|
unsigned short GetCallbackFlags( void ) const; |
|
void SetGameFlags( unsigned short userFlags ); |
|
unsigned short GetGameFlags( void ) const; |
|
void SetGameIndex( unsigned short gameIndex ); |
|
unsigned short GetGameIndex( void ) const; |
|
|
|
void Wake(); |
|
void WakeNow(); |
|
void Sleep(); |
|
void RecheckCollisionFilter(); |
|
void RecheckContactPoints(); |
|
|
|
void SetMass( float mass ); |
|
float GetMass( void ) const; |
|
float GetInvMass( void ) const; |
|
void SetInertia( const Vector &inertia ); |
|
Vector GetInertia( void ) const; |
|
Vector GetInvInertia( void ) const; |
|
|
|
void GetDamping( float *speed, float *rot ) const; |
|
void SetDamping( const float *speed, const float *rot ); |
|
void SetDragCoefficient( float *pDrag, float *pAngularDrag ); |
|
void SetBuoyancyRatio( float ratio ); |
|
int GetMaterialIndex() const { return GetMaterialIndexInternal(); } |
|
void SetMaterialIndex( int materialIndex ); |
|
inline int GetMaterialIndexInternal( void ) const { return m_materialIndex; } |
|
|
|
unsigned int GetContents() const { return m_contentsMask; } |
|
void SetContents( unsigned int contents ); |
|
|
|
float GetSphereRadius() const; |
|
Vector GetMassCenterLocalSpace() const; |
|
float GetEnergy() const; |
|
|
|
void SetPosition( const Vector &worldPosition, const QAngle &angles, bool isTeleport = false ); |
|
void SetPositionMatrix( const matrix3x4_t& matrix, bool isTeleport = false ); |
|
void GetPosition( Vector *worldPosition, QAngle *angles ) const; |
|
void GetPositionMatrix( matrix3x4_t *positionMatrix ) const; |
|
|
|
void SetVelocity( const Vector *velocity, const AngularImpulse *angularVelocity ); |
|
void SetVelocityInstantaneous( const Vector *velocity, const AngularImpulse *angularVelocity ); |
|
void AddVelocity( const Vector *velocity, const AngularImpulse *angularVelocity ); |
|
void GetVelocity( Vector *velocity, AngularImpulse *angularVelocity ) const; |
|
void GetImplicitVelocity( Vector *velocity, AngularImpulse *angularVelocity ) const; |
|
void GetVelocityAtPoint( const Vector &worldPosition, Vector *pVelocity ) const; |
|
|
|
void LocalToWorld( Vector *worldPosition, const Vector &localPosition ) const; |
|
void WorldToLocal( Vector *localPosition, const Vector &worldPosition ) const; |
|
void LocalToWorldVector( Vector *worldVector, const Vector &localVector ) const; |
|
void WorldToLocalVector( Vector *localVector, const Vector &worldVector ) const; |
|
|
|
void ApplyForceCenter( const Vector &forceVector ); |
|
void ApplyForceOffset( const Vector &forceVector, const Vector &worldPosition ); |
|
void ApplyTorqueCenter( const AngularImpulse & ); |
|
void CalculateForceOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerForce, AngularImpulse *centerTorque ) const; |
|
void CalculateVelocityOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerVelocity, AngularImpulse *centerAngularVelocity ) const; |
|
float CalculateLinearDrag( const Vector &unitDirection ) const; |
|
float CalculateAngularDrag( const Vector &objectSpaceRotationAxis ) const; |
|
|
|
bool GetContactPoint( Vector *contactPoint, IPhysicsObject **contactObject ) const; |
|
void SetShadow( float maxSpeed, float maxAngularSpeed, bool allowPhysicsMovement, bool allowPhysicsRotation ); |
|
void UpdateShadow( const Vector &targetPosition, const QAngle &targetAngles, bool tempDisableGravity, float timeOffset ); |
|
void RemoveShadowController(); |
|
int GetShadowPosition( Vector *position, QAngle *angles ) const; |
|
IPhysicsShadowController *GetShadowController( void ) const; |
|
float ComputeShadowControl( const hlshadowcontrol_params_t ¶ms, float secondsToArrival, float dt ); |
|
|
|
const CPhysCollide *GetCollide( void ) const; |
|
char const *GetName() const; |
|
|
|
float GetDragInDirection( const IVP_U_Float_Point &dir ) const; |
|
float GetAngularDragInDirection( const IVP_U_Float_Point &angVelocity ) const; |
|
void BecomeTrigger(); |
|
void RemoveTrigger(); |
|
void BecomeHinged( int localAxis ); |
|
void RemoveHinged(); |
|
|
|
IPhysicsFrictionSnapshot *CreateFrictionSnapshot(); |
|
void DestroyFrictionSnapshot( IPhysicsFrictionSnapshot *pSnapshot ); |
|
|
|
void OutputDebugInfo() const; |
|
|
|
// local functions |
|
inline IVP_Real_Object *GetObject( void ) const { return m_pObject; } |
|
inline int CallbackFlags( void ) const { return m_callbacks; } |
|
inline void AddCallbackFlags( unsigned short flags ) { m_callbacks |= flags; } |
|
inline void RemoveCallbackFlags( unsigned short flags ) { m_callbacks &= ~flags; } |
|
inline bool HasTouchedDynamic(); |
|
inline void SetTouchedDynamic(); |
|
void NotifySleep( void ); |
|
void NotifyWake( void ); |
|
int GetSleepState( void ) const { return m_sleepState; } |
|
inline void ForceSilentDelete() { m_forceSilentDelete = true; } |
|
|
|
inline int GetActiveIndex( void ) const { return m_activeIndex; } |
|
inline void SetActiveIndex( int index ) { m_activeIndex = index; } |
|
inline float GetBuoyancyRatio( void ) const { return m_buoyancyRatio; } |
|
// returns true if the mass center is set to the default for the collision model |
|
bool IsMassCenterAtDefault() const; |
|
|
|
// is this object simulated, or controlled by game logic? |
|
bool IsControlledByGame() const; |
|
|
|
IVP_SurfaceManager *GetSurfaceManager( void ) const; |
|
|
|
void WriteToTemplate( vphysics_save_cphysicsobject_t &objectTemplate ); |
|
void InitFromTemplate( CPhysicsEnvironment *pEnvironment, void *pGameData, const vphysics_save_cphysicsobject_t &objectTemplate ); |
|
|
|
CPhysicsEnvironment *GetVPhysicsEnvironment(); |
|
const CPhysicsEnvironment *GetVPhysicsEnvironment() const; |
|
|
|
private: |
|
// NOTE: Local to vphysics, used to save/restore shadow controller |
|
void RestoreShadowController( IPhysicsShadowController *pShadowController ); |
|
friend bool RestorePhysicsObject( const physrestoreparams_t ¶ms, CPhysicsObject **ppObject ); |
|
|
|
bool IsControlling( const IVP_Controller *pController ) const; |
|
float GetVolume() const; |
|
void SetVolume( float volume ); |
|
|
|
// the mass has changed, recompute the drag information |
|
void RecomputeDragBases(); |
|
|
|
void ClampVelocity(); |
|
|
|
// NOTE: If m_pGameData is not the first member, the constructor debug code must be modified |
|
void *m_pGameData; |
|
IVP_Real_Object *m_pObject; |
|
const CPhysCollide *m_pCollide; |
|
IPhysicsShadowController *m_pShadow; |
|
|
|
Vector m_dragBasis; |
|
Vector m_angDragBasis; |
|
|
|
// these 5 should pack into a short |
|
// pack new bools here |
|
bool m_shadowTempGravityDisable : 5; |
|
bool m_hasTouchedDynamic : 1; |
|
bool m_asleepSinceCreation : 1; |
|
bool m_forceSilentDelete : 1; |
|
unsigned char m_sleepState : 2; |
|
unsigned char m_hingedAxis : 3; |
|
unsigned char m_collideType : 3; |
|
unsigned short m_gameIndex; |
|
|
|
private: |
|
unsigned short m_materialIndex; |
|
unsigned short m_activeIndex; |
|
|
|
unsigned short m_callbacks; |
|
unsigned short m_gameFlags; |
|
unsigned int m_contentsMask; |
|
|
|
float m_volume; |
|
float m_buoyancyRatio; |
|
float m_dragCoefficient; |
|
float m_angDragCoefficient; |
|
|
|
friend CPhysicsObject *CreatePhysicsObject( CPhysicsEnvironment *pEnvironment, const CPhysCollide *pCollisionModel, int materialIndex, const Vector &position, const QAngle& angles, objectparams_t *pParams, bool isStatic ); |
|
friend bool CPhysicsEnvironment::TransferObject( IPhysicsObject *pObject, IPhysicsEnvironment *pDestinationEnvironment ); //need direct access to m_pShadow for Portal mod's physics object transfer system |
|
}; |
|
|
|
// If you haven't ever touched a dynamic object, there's no need to search for contacting objects to |
|
// wakeup when you are deleted. So cache a bit here when contacts are generated |
|
inline bool CPhysicsObject::HasTouchedDynamic() |
|
{ |
|
return m_hasTouchedDynamic; |
|
} |
|
|
|
inline void CPhysicsObject::SetTouchedDynamic() |
|
{ |
|
m_hasTouchedDynamic = true; |
|
} |
|
|
|
extern CPhysicsObject *CreatePhysicsObject( CPhysicsEnvironment *pEnvironment, const CPhysCollide *pCollisionModel, int materialIndex, const Vector &position, const QAngle &angles, objectparams_t *pParams, bool isStatic ); |
|
extern CPhysicsObject *CreatePhysicsSphere( CPhysicsEnvironment *pEnvironment, float radius, int materialIndex, const Vector &position, const QAngle &angles, objectparams_t *pParams, bool isStatic ); |
|
extern void PostRestorePhysicsObject(); |
|
extern IPhysicsObject *CreateObjectFromBuffer( CPhysicsEnvironment *pEnvironment, void *pGameData, unsigned char *pBuffer, unsigned int bufferSize, bool enableCollisions ); |
|
extern IPhysicsObject *CreateObjectFromBuffer_UseExistingMemory( CPhysicsEnvironment *pEnvironment, void *pGameData, unsigned char *pBuffer, unsigned int bufferSize, CPhysicsObject *pExistingMemory ); |
|
|
|
#endif // PHYSICS_OBJECT_H
|
|
|