290 lines
11 KiB
C++
290 lines
11 KiB
C++
//=================================================================================================
|
|
//
|
|
// A physics object
|
|
//
|
|
//=================================================================================================
|
|
|
|
#pragma once
|
|
|
|
class IPredictedPhysicsObject;
|
|
|
|
class IJoltObjectDestroyedListener;
|
|
class JoltPhysicsShadowController;
|
|
class JoltPhysicsFluidController;
|
|
class JoltPhysicsEnvironment;
|
|
class JoltPhysicsObject;
|
|
|
|
#if defined( GAME_CSGO_OR_NEWER )
|
|
using IPhysicsObjectInterface = IPredictedPhysicsObject;
|
|
#else
|
|
using IPhysicsObjectInterface = IPhysicsObject;
|
|
#endif
|
|
|
|
class JoltPhysicsObject final : public IPhysicsObjectInterface
|
|
{
|
|
public:
|
|
JoltPhysicsObject( JPH::Body *pBody, JoltPhysicsEnvironment *pEnvironment, bool bStatic, int nMaterialIndex, const objectparams_t *pParams );
|
|
JoltPhysicsObject( JPH::Body *pBody, JoltPhysicsEnvironment *pEnvironment, void *pGameData, JPH::StateRecorder &recorder );
|
|
~JoltPhysicsObject() override;
|
|
|
|
bool IsStatic() const override;
|
|
bool IsAsleep() const override;
|
|
bool IsTrigger() const override;
|
|
bool IsFluid() const override;
|
|
bool IsHinged() const override;
|
|
bool IsCollisionEnabled() const override;
|
|
bool IsGravityEnabled() const override;
|
|
bool IsDragEnabled() const override;
|
|
bool IsMotionEnabled() const override;
|
|
bool IsMoveable() const override; // legacy: IsMotionEnabled() && !IsStatic()
|
|
bool IsAttachedToConstraint( bool bExternalOnly ) const override;
|
|
|
|
void EnableCollisions( bool enable ) override;
|
|
void EnableGravity( bool enable ) override;
|
|
void EnableDrag( bool enable ) override;
|
|
void EnableMotion( bool enable ) override;
|
|
|
|
void SetGameData( void *pGameData ) override;
|
|
void * GetGameData() const override;
|
|
void SetGameFlags( unsigned short userFlags ) override;
|
|
unsigned short GetGameFlags() const override;
|
|
void SetGameIndex( unsigned short gameIndex ) override;
|
|
unsigned short GetGameIndex() const override;
|
|
|
|
void SetCallbackFlags( unsigned short callbackflags ) override;
|
|
unsigned short GetCallbackFlags() const override;
|
|
|
|
void Wake() override;
|
|
void Sleep() override;
|
|
void RecheckCollisionFilter() override;
|
|
void RecheckContactPoints( bool bSearchForNewContacts ) override_portal2;
|
|
void RecheckContactPoints() override_not_portal2 { RecheckContactPoints( false ); }
|
|
|
|
void SetMass( float mass ) override;
|
|
float GetMass() const override;
|
|
float GetInvMass() const override;
|
|
Vector GetInertia() const override;
|
|
Vector GetInvInertia() const override;
|
|
void SetInertia( const Vector &inertia ) override;
|
|
|
|
void SetDamping( const float *speed, const float *rot ) override;
|
|
void GetDamping( float *speed, float *rot ) const override;
|
|
|
|
void SetDragCoefficient( float *pDrag, float *pAngularDrag ) override;
|
|
void SetBuoyancyRatio( float ratio ) override;
|
|
|
|
int GetMaterialIndex() const override;
|
|
void SetMaterialIndex( int materialIndex ) override;
|
|
|
|
unsigned int GetContents() const override;
|
|
void SetContents( unsigned int contents ) override;
|
|
|
|
float GetSphereRadius() const override;
|
|
void SetSphereRadius( float radius ) override_asw;
|
|
float GetEnergy() const override;
|
|
Vector GetMassCenterLocalSpace() const override;
|
|
|
|
void SetPosition( const Vector &worldPosition, const QAngle &angles, bool isTeleport ) override;
|
|
void SetPositionMatrix( const matrix3x4_t &matrix, bool isTeleport ) override;
|
|
|
|
void GetPosition( Vector *worldPosition, QAngle *angles ) const override;
|
|
void GetPositionMatrix( matrix3x4_t *positionMatrix ) const override;
|
|
void SetVelocity( const Vector *velocity, const AngularImpulse *angularVelocity ) override;
|
|
|
|
void SetVelocityInstantaneous( const Vector *velocity, const AngularImpulse *angularVelocity ) override;
|
|
|
|
void GetVelocity( Vector *velocity, AngularImpulse *angularVelocity ) const override;
|
|
|
|
void AddVelocity( const Vector *velocity, const AngularImpulse *angularVelocity ) override;
|
|
void GetVelocityAtPoint( const Vector &worldPosition, Vector *pVelocity ) const override;
|
|
void GetImplicitVelocity( Vector *velocity, AngularImpulse *angularVelocity ) const override;
|
|
void LocalToWorld( Vector *worldPosition, const Vector &localPosition ) const override;
|
|
void WorldToLocal( Vector *localPosition, const Vector &worldPosition ) const override;
|
|
|
|
void LocalToWorldVector( Vector *worldVector, const Vector &localVector ) const override;
|
|
void WorldToLocalVector( Vector *localVector, const Vector &worldVector ) const override;
|
|
|
|
void ApplyForceCenter( const Vector &forceVector ) override;
|
|
void ApplyForceOffset( const Vector &forceVector, const Vector &worldPosition ) override;
|
|
void ApplyTorqueCenter( const AngularImpulse &torque ) override;
|
|
|
|
void CalculateForceOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerForce, AngularImpulse *centerTorque ) const override;
|
|
void CalculateVelocityOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerVelocity, AngularImpulse *centerAngularVelocity ) const override;
|
|
float CalculateLinearDrag( const Vector &unitDirection ) const override;
|
|
float CalculateAngularDrag( const Vector &objectSpaceRotationAxis ) const override;
|
|
|
|
bool GetContactPoint( Vector *contactPoint, IPhysicsObject **contactObject ) const override;
|
|
|
|
void SetShadow( float maxSpeed, float maxAngularSpeed, bool allowPhysicsMovement, bool allowPhysicsRotation ) override;
|
|
void UpdateShadow( const Vector &targetPosition, const QAngle &targetAngles, bool tempDisableGravity, float timeOffset ) override;
|
|
|
|
int GetShadowPosition( Vector *position, QAngle *angles ) const override;
|
|
IPhysicsShadowController * GetShadowController() const override;
|
|
void RemoveShadowController() override;
|
|
float ComputeShadowControl( const hlshadowcontrol_params_t ¶ms, float secondsToArrival, float dt ) override;
|
|
|
|
|
|
const CPhysCollide * GetCollide() const override;
|
|
const char * GetName() const override;
|
|
|
|
void BecomeTrigger() override;
|
|
void RemoveTrigger() override;
|
|
|
|
void BecomeHinged( int localAxis ) override;
|
|
void RemoveHinged() override;
|
|
|
|
IPhysicsFrictionSnapshot *CreateFrictionSnapshot() override;
|
|
void DestroyFrictionSnapshot( IPhysicsFrictionSnapshot *pSnapshot ) override;
|
|
|
|
void OutputDebugInfo() const override;
|
|
|
|
#if OBJECT_WELDING
|
|
void WeldToObject( IPhysicsObject *pParent ) override;
|
|
void RemoveWeld( IPhysicsObject *pOther ) override;
|
|
void RemoveAllWelds() override;
|
|
#endif
|
|
|
|
void SetUseAlternateGravity( bool bSet ) override_asw;
|
|
void SetCollisionHints( uint32 collisionHints ) override_asw;
|
|
uint32 GetCollisionHints() const override_asw;
|
|
|
|
IPredictedPhysicsObject * GetPredictedInterface() const override_csgo;
|
|
void SyncWith( IPhysicsObject *pOther ) override_csgo;
|
|
|
|
void SetErrorDelta_Position( const Vector& vPosition ) override_csgo {}
|
|
void SetErrorDelta_Velocity( const Vector& vVelocity ) override_csgo {}
|
|
|
|
public:
|
|
JoltPhysicsEnvironment *GetEnvironment() { return m_pEnvironment; }
|
|
|
|
JPH::BodyID GetBodyID() { return m_pBody->GetID(); }
|
|
JPH::Body *GetBody() { return m_pBody; }
|
|
|
|
void UpdateEnvironment( JoltPhysicsEnvironment *pEnvironment );
|
|
|
|
void AddDestroyedListener( IJoltObjectDestroyedListener *pListener );
|
|
void RemoveDestroyedListener( IJoltObjectDestroyedListener *pListener );
|
|
|
|
// Grabs the position, adds addPos and teleports the object
|
|
void AddToPosition( JPH::Vec3Arg addPos );
|
|
|
|
// Only sets the position, and nothing else.
|
|
void SetPosition( const Vector &worldPosition );
|
|
|
|
// Adds to the velocity (Source space)
|
|
void AddVelocity( const Vector &worldPosition );
|
|
|
|
Vector GetVelocity();
|
|
|
|
void CalculateBuoyancy();
|
|
|
|
float GetMaterialDensity() const;
|
|
float GetBuoyancyRatio() const;
|
|
float GetVolume() const { return m_flVolume; }
|
|
|
|
bool IsControlledByGame() const;
|
|
|
|
void AddCallbackFlags( uint16 flags ) { m_callbackFlags |= flags; }
|
|
void RemoveCallbackFlags( uint16 flags ) { m_callbackFlags &= ~flags; }
|
|
|
|
void SaveObjectState( JPH::StateRecorder &recorder );
|
|
void RestoreObjectState( JPH::StateRecorder &recorder );
|
|
|
|
unsigned short GetGameMaterial() const
|
|
{
|
|
return m_GameMaterial;
|
|
}
|
|
|
|
bool GetGameMaterialAllowsSounds() const
|
|
{
|
|
return m_GameMaterial != 'X';
|
|
}
|
|
|
|
JoltPhysicsFluidController *GetFluidController()
|
|
{
|
|
return m_pFluidController;
|
|
}
|
|
|
|
void SetFluidController( JoltPhysicsFluidController *pFluidController )
|
|
{
|
|
m_pFluidController = pFluidController;
|
|
}
|
|
|
|
// Fakes a linear velocity so we can have correct before/after velocity
|
|
// when going between PreCollision and PostCollision callbacks.
|
|
JPH::Vec3 FakeJoltLinearVelocity( JPH::Vec3Arg fakeVelocity )
|
|
{
|
|
if ( m_pBody->IsStatic() )
|
|
return JPH::Vec3::sZero();
|
|
|
|
JPH::Vec3 oldVel = m_pBody->GetLinearVelocity();
|
|
m_pBody->SetLinearVelocity( fakeVelocity );
|
|
return oldVel;
|
|
}
|
|
|
|
void RestoreJoltLinearVelocity( JPH::Vec3Arg realVelocity )
|
|
{
|
|
if ( m_pBody->IsStatic() )
|
|
return;
|
|
|
|
m_pBody->SetLinearVelocity( realVelocity );
|
|
}
|
|
|
|
private:
|
|
void UpdateMaterialProperties();
|
|
void UpdateLayer();
|
|
|
|
// Josh:
|
|
// Always put m_pGameData first. Some games that will
|
|
// remain un-named offset by the vtable to get to this
|
|
// instead of calling GetGameData().
|
|
void *m_pGameData = nullptr;
|
|
|
|
uint16 m_gameFlags = 0;
|
|
uint16 m_gameIndex = 0;
|
|
uint16 m_callbackFlags = CALLBACK_GLOBAL_COLLISION|CALLBACK_GLOBAL_FRICTION|CALLBACK_FLUID_TOUCH|CALLBACK_GLOBAL_TOUCH|CALLBACK_GLOBAL_COLLIDE_STATIC|CALLBACK_DO_FLUID_SIMULATION;
|
|
uint32 m_collisionHints = 0;
|
|
|
|
bool m_bStatic = false;
|
|
bool m_bPinned = false;
|
|
|
|
int m_materialIndex = 0;
|
|
uint m_contents = CONTENTS_SOLID;
|
|
|
|
// Need this as Jolt gets very unhappy about reading motion
|
|
// properties of static objects.
|
|
float m_flCachedMass = 0.0f;
|
|
float m_flCachedInvMass = 0.0f;
|
|
bool m_bCachedCollisionEnabled = true;
|
|
|
|
float m_flMaterialDensity = 1.0f; // Material density in Jolt space.
|
|
float m_flBuoyancyRatio = 0.0f;
|
|
float m_flVolume = 0.0f;
|
|
|
|
unsigned short m_GameMaterial = 0;
|
|
|
|
|
|
CUtlVector< IJoltObjectDestroyedListener * > m_destroyedListeners;
|
|
|
|
// Shadow variables
|
|
JoltPhysicsShadowController *m_pShadowController = nullptr;
|
|
JoltPhysicsFluidController *m_pFluidController = nullptr;
|
|
bool m_bShadowTemporarilyDisableGravity = false;
|
|
|
|
JPH::Body *m_pBody = nullptr; // Underlying Jolt body
|
|
JoltPhysicsEnvironment *m_pEnvironment = nullptr; // Physics environment this body belongs to
|
|
JPH::PhysicsSystem *m_pPhysicsSystem = nullptr; // Physics system this body belongs to
|
|
};
|
|
|
|
// Josh: This doesn't handle mass change and is kind of a hack and sliightly wrong.
|
|
// Would be nice to just specify spring constant directly in Jolt.
|
|
inline float GetInvEffectiveMass( JoltPhysicsObject *pObject0, JoltPhysicsObject *pObject1 )
|
|
{
|
|
return ( pObject0->IsStatic() ? 0.0f : pObject0->GetInvMass() ) + ( pObject1->IsStatic() ? 0.0f : pObject1->GetInvMass() );
|
|
}
|
|
|
|
inline float GetSpringFrequency( float flConstant, JoltPhysicsObject *pObject0, JoltPhysicsObject *pObject1 )
|
|
{
|
|
return sqrt( flConstant * GetInvEffectiveMass( pObject0, pObject1 ) ) / ( 2.0f * M_PI_F );
|
|
}
|