mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-17 14:07:48 +00:00
1
This commit is contained in:
@@ -0,0 +1,345 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CONSTRAINTS_H
|
||||
#define CONSTRAINTS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "vphysics_interface.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
// constraint groups
|
||||
struct constraint_groupparams_t
|
||||
{
|
||||
int additionalIterations; // additional solver iterations make the constraint system more stable
|
||||
int minErrorTicks; // minimum number of ticks with an error before it's reported
|
||||
float errorTolerance; // error tolerance in HL units
|
||||
|
||||
inline void Defaults()
|
||||
{
|
||||
additionalIterations = 0;
|
||||
minErrorTicks = 15;
|
||||
errorTolerance = 3.0f;
|
||||
}
|
||||
};
|
||||
|
||||
// Breakable constraints;
|
||||
//
|
||||
// forceLimit - kg * in / s limit (N * conversion(in/m))
|
||||
// torqueLimit - kg * in^2 / s (Nm * conversion(in^2/m^2))
|
||||
|
||||
//
|
||||
// strength 0 - 1
|
||||
struct constraint_breakableparams_t
|
||||
{
|
||||
float strength; // strength of the constraint 0.0 - 1.0
|
||||
float forceLimit; // constraint force limit to break (0 means never break)
|
||||
float torqueLimit; // constraint torque limit to break (0 means never break)
|
||||
float bodyMassScale[2]; // scale applied to mass of reference/attached object before solving constriant
|
||||
bool isActive;
|
||||
|
||||
inline void Defaults()
|
||||
{
|
||||
forceLimit = 0.0f;
|
||||
torqueLimit = 0.0f;
|
||||
strength = 1.0f;
|
||||
bodyMassScale[0] = 1.0f;
|
||||
bodyMassScale[1] = 1.0f;
|
||||
isActive = true;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: constraint limit on a single rotation axis
|
||||
//-----------------------------------------------------------------------------
|
||||
struct constraint_axislimit_t
|
||||
{
|
||||
float minRotation;
|
||||
float maxRotation;
|
||||
float angularVelocity; // desired angular velocity around hinge
|
||||
float torque; // torque to achieve angular velocity (use 0, torque for "friction")
|
||||
|
||||
inline void SetAxisFriction( float rmin, float rmax, float friction )
|
||||
{
|
||||
minRotation = rmin;
|
||||
maxRotation = rmax;
|
||||
angularVelocity = 0;
|
||||
torque = friction;
|
||||
}
|
||||
inline void Defaults()
|
||||
{
|
||||
SetAxisFriction(0,0,0);
|
||||
}
|
||||
};
|
||||
|
||||
// Builds a transform which maps points in the input object's local space
|
||||
// to the output object's local space
|
||||
inline void BuildObjectRelativeXform( IPhysicsObject *pOutputSpace, IPhysicsObject *pInputSpace, matrix3x4_t &xformInToOut )
|
||||
{
|
||||
matrix3x4_t outInv, tmp, input;
|
||||
pOutputSpace->GetPositionMatrix( &tmp );
|
||||
MatrixInvert( tmp, outInv );
|
||||
pInputSpace->GetPositionMatrix( &input );
|
||||
ConcatTransforms( outInv, input, xformInToOut );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: special limited ballsocket constraint for ragdolls.
|
||||
// Has axis limits for all 3 axes.
|
||||
//-----------------------------------------------------------------------------
|
||||
struct constraint_ragdollparams_t
|
||||
{
|
||||
constraint_breakableparams_t constraint;
|
||||
matrix3x4_t constraintToReference;// xform constraint space to refobject space
|
||||
matrix3x4_t constraintToAttached; // xform constraint space to attached object space
|
||||
int parentIndex; // NOTE: only used for parsing. NEED NOT BE SET for create
|
||||
int childIndex; // NOTE: only used for parsing. NEED NOT BE SET for create
|
||||
|
||||
constraint_axislimit_t axes[3];
|
||||
bool onlyAngularLimits; // only angular limits (not translation as well?)
|
||||
bool isActive;
|
||||
bool useClockwiseRotations; // HACKHACK: Did this wrong in version one. Fix in the future.
|
||||
|
||||
inline void Defaults()
|
||||
{
|
||||
constraint.Defaults();
|
||||
isActive = true;
|
||||
SetIdentityMatrix( constraintToReference );
|
||||
SetIdentityMatrix( constraintToAttached );
|
||||
parentIndex = -1;
|
||||
childIndex = -1;
|
||||
axes[0].Defaults();
|
||||
axes[1].Defaults();
|
||||
axes[2].Defaults();
|
||||
onlyAngularLimits = false;
|
||||
useClockwiseRotations = false;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Used to init a hinge restricting the relative position and orientation
|
||||
// of two objects to rotation around a single axis
|
||||
//-----------------------------------------------------------------------------
|
||||
struct constraint_hingeparams_t
|
||||
{
|
||||
Vector worldPosition; // position in world space on the hinge axis
|
||||
Vector worldAxisDirection; // unit direction vector of the hinge axis in world space
|
||||
constraint_axislimit_t hingeAxis;
|
||||
constraint_breakableparams_t constraint;
|
||||
|
||||
inline void Defaults()
|
||||
{
|
||||
worldPosition.Init();
|
||||
worldAxisDirection.Init();
|
||||
hingeAxis.Defaults();
|
||||
constraint.Defaults();
|
||||
}
|
||||
};
|
||||
|
||||
struct constraint_limitedhingeparams_t : public constraint_hingeparams_t
|
||||
{
|
||||
Vector referencePerpAxisDirection; // unit direction vector vector perpendicular to the hinge axis in world space
|
||||
Vector attachedPerpAxisDirection; // unit direction vector vector perpendicular to the hinge axis in world space
|
||||
|
||||
constraint_limitedhingeparams_t() {}
|
||||
constraint_limitedhingeparams_t( const constraint_hingeparams_t &hinge )
|
||||
{
|
||||
static_cast<constraint_hingeparams_t &>(*this) = hinge;
|
||||
referencePerpAxisDirection.Init();
|
||||
attachedPerpAxisDirection.Init();
|
||||
}
|
||||
|
||||
inline void Defaults()
|
||||
{
|
||||
this->constraint_hingeparams_t::Defaults();
|
||||
referencePerpAxisDirection.Init();
|
||||
attachedPerpAxisDirection.Init();
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Used to init a constraint that fixes the position and orientation
|
||||
// of two objects relative to each other (like glue)
|
||||
//-----------------------------------------------------------------------------
|
||||
struct constraint_fixedparams_t
|
||||
{
|
||||
matrix3x4_t attachedRefXform; // xform attached object space to ref object space
|
||||
constraint_breakableparams_t constraint;
|
||||
|
||||
inline void InitWithCurrentObjectState( IPhysicsObject *pRef, IPhysicsObject *pAttached )
|
||||
{
|
||||
BuildObjectRelativeXform( pRef, pAttached, attachedRefXform );
|
||||
}
|
||||
|
||||
inline void Defaults()
|
||||
{
|
||||
SetIdentityMatrix( attachedRefXform );
|
||||
constraint.Defaults();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Same parameters as fixed constraint, but torqueLimit has no effect
|
||||
//-----------------------------------------------------------------------------
|
||||
struct constraint_ballsocketparams_t
|
||||
{
|
||||
Vector constraintPosition[2]; // position of the constraint in each object's space
|
||||
constraint_breakableparams_t constraint;
|
||||
inline void Defaults()
|
||||
{
|
||||
constraint.Defaults();
|
||||
constraintPosition[0].Init();
|
||||
constraintPosition[1].Init();
|
||||
}
|
||||
|
||||
void InitWithCurrentObjectState( IPhysicsObject *pRef, IPhysicsObject *pAttached, const Vector &ballsocketOrigin )
|
||||
{
|
||||
pRef->WorldToLocal( &constraintPosition[0], ballsocketOrigin );
|
||||
pAttached->WorldToLocal( &constraintPosition[1], ballsocketOrigin );
|
||||
}
|
||||
};
|
||||
|
||||
struct constraint_slidingparams_t
|
||||
{
|
||||
matrix3x4_t attachedRefXform; // xform attached object space to ref object space
|
||||
Vector slideAxisRef; // unit direction vector of the slide axis in ref object space
|
||||
constraint_breakableparams_t constraint;
|
||||
// NOTE: if limitMin == limitMax there is NO limit set!
|
||||
float limitMin; // minimum limit coordinate refAxisDirection space
|
||||
float limitMax; // maximum limit coordinate refAxisDirection space
|
||||
float friction; // friction on sliding
|
||||
float velocity; // desired velocity
|
||||
|
||||
inline void Defaults()
|
||||
{
|
||||
SetIdentityMatrix( attachedRefXform );
|
||||
slideAxisRef.Init();
|
||||
limitMin = limitMax = 0;
|
||||
friction = 0;
|
||||
velocity = 0;
|
||||
constraint.Defaults();
|
||||
}
|
||||
|
||||
inline void SetFriction( float inputFriction )
|
||||
{
|
||||
friction = inputFriction;
|
||||
velocity = 0;
|
||||
}
|
||||
|
||||
inline void SetLinearMotor( float inputVelocity, float maxForce )
|
||||
{
|
||||
friction = maxForce;
|
||||
velocity = inputVelocity;
|
||||
}
|
||||
|
||||
inline void InitWithCurrentObjectState( IPhysicsObject *pRef, IPhysicsObject *pAttached, const Vector &slideDirWorldspace )
|
||||
{
|
||||
BuildObjectRelativeXform( pRef, pAttached, attachedRefXform );
|
||||
matrix3x4_t tmp;
|
||||
pRef->GetPositionMatrix( &tmp );
|
||||
VectorIRotate( slideDirWorldspace, tmp, slideAxisRef );
|
||||
}
|
||||
};
|
||||
|
||||
struct constraint_pulleyparams_t
|
||||
{
|
||||
constraint_breakableparams_t constraint;
|
||||
Vector pulleyPosition[2]; // These are the pulley positions for the reference and attached objects in world space
|
||||
Vector objectPosition[2]; // local positions of attachments to the ref,att objects
|
||||
float totalLength; // total rope length (include gearing!)
|
||||
float gearRatio; // gearing affects attached object ALWAYS
|
||||
bool isRigid;
|
||||
|
||||
inline void Defaults()
|
||||
{
|
||||
constraint.Defaults();
|
||||
totalLength = 1.0;
|
||||
gearRatio = 1.0;
|
||||
pulleyPosition[0].Init();
|
||||
pulleyPosition[1].Init();
|
||||
objectPosition[0].Init();
|
||||
objectPosition[1].Init();
|
||||
isRigid = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct constraint_lengthparams_t
|
||||
{
|
||||
constraint_breakableparams_t constraint;
|
||||
Vector objectPosition[2]; // These are the positions for the reference and attached objects in local space
|
||||
float totalLength; // Length of rope/spring/constraint. Distance to maintain
|
||||
float minLength; // if rigid, objects are not allowed to move closer than totalLength either
|
||||
|
||||
void InitWorldspace( IPhysicsObject *pRef, IPhysicsObject *pAttached, const Vector &refPosition, const Vector &attachedPosition, bool rigid = false )
|
||||
{
|
||||
pRef->WorldToLocal( &objectPosition[0], refPosition );
|
||||
pAttached->WorldToLocal( &objectPosition[1], attachedPosition );
|
||||
totalLength = (refPosition - attachedPosition).Length();
|
||||
minLength = rigid ? totalLength : 0;
|
||||
}
|
||||
|
||||
inline void Defaults()
|
||||
{
|
||||
constraint.Defaults();
|
||||
objectPosition[0].Init();
|
||||
objectPosition[1].Init();
|
||||
totalLength = 1;
|
||||
minLength = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class IPhysicsConstraint
|
||||
{
|
||||
public:
|
||||
virtual ~IPhysicsConstraint( void ) {}
|
||||
|
||||
// NOTE: Constraints are active when created. You can temporarily enable/disable them with these functions
|
||||
virtual void Activate( void ) = 0;
|
||||
virtual void Deactivate( void ) = 0;
|
||||
|
||||
// set a pointer to the game object
|
||||
virtual void SetGameData( void *gameData ) = 0;
|
||||
|
||||
// get a pointer to the game object
|
||||
virtual void *GetGameData( void ) const = 0;
|
||||
|
||||
// Get the parent/referenced object
|
||||
virtual IPhysicsObject *GetReferenceObject( void ) const = 0;
|
||||
|
||||
// Get the attached object
|
||||
virtual IPhysicsObject *GetAttachedObject( void ) const = 0;
|
||||
|
||||
virtual void SetLinearMotor( float speed, float maxLinearImpulse ) = 0;
|
||||
virtual void SetAngularMotor( float rotSpeed, float maxAngularImpulse ) = 0;
|
||||
|
||||
virtual void UpdateRagdollTransforms( const matrix3x4_t &constraintToReference, const matrix3x4_t &constraintToAttached ) = 0;
|
||||
virtual bool GetConstraintTransform( matrix3x4_t *pConstraintToReference, matrix3x4_t *pConstraintToAttached ) const = 0;
|
||||
virtual bool GetConstraintParams( constraint_breakableparams_t *pParams ) const = 0;
|
||||
|
||||
virtual void OutputDebugInfo() = 0;
|
||||
};
|
||||
|
||||
|
||||
class IPhysicsConstraintGroup
|
||||
{
|
||||
public:
|
||||
virtual ~IPhysicsConstraintGroup( void ) {}
|
||||
virtual void Activate() = 0;
|
||||
virtual bool IsInErrorState() = 0;
|
||||
virtual void ClearErrorState() = 0;
|
||||
virtual void GetErrorParams( constraint_groupparams_t *pParams ) = 0;
|
||||
virtual void SetErrorParams( const constraint_groupparams_t ¶ms ) = 0;
|
||||
virtual void SolvePenetration( IPhysicsObject *pObj0, IPhysicsObject *pObj1 ) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // CONSTRAINTS_H
|
||||
Reference in New Issue
Block a user