Counter Strike : Global Offensive Source Code
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.

353 lines
11 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef CONSTRAINTS_H
  8. #define CONSTRAINTS_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "vphysics_interface.h"
  13. #include "mathlib/mathlib.h"
  14. // constraint groups
  15. struct constraint_groupparams_t
  16. {
  17. int additionalIterations; // additional solver iterations make the constraint system more stable
  18. int minErrorTicks; // minimum number of ticks with an error before it's reported
  19. float errorTolerance; // error tolerance in HL units
  20. inline void Defaults()
  21. {
  22. additionalIterations = 0;
  23. minErrorTicks = 15;
  24. errorTolerance = 3.0f;
  25. }
  26. };
  27. // Breakable constraints;
  28. //
  29. // forceLimit - kg * in / s limit (N * conversion(in/m))
  30. // torqueLimit - kg * in^2 / s (Nm * conversion(in^2/m^2))
  31. //
  32. // strength 0 - 1
  33. struct constraint_breakableparams_t
  34. {
  35. float strength; // strength of the constraint 0.0 - 1.0
  36. float forceLimit; // constraint force limit to break (0 means never break)
  37. float torqueLimit; // constraint torque limit to break (0 means never break)
  38. float bodyMassScale[2]; // scale applied to mass of reference/attached object before solving constriant
  39. bool isActive;
  40. inline void Defaults()
  41. {
  42. forceLimit = 0.0f;
  43. torqueLimit = 0.0f;
  44. strength = 1.0f;
  45. bodyMassScale[0] = 1.0f;
  46. bodyMassScale[1] = 1.0f;
  47. isActive = true;
  48. }
  49. };
  50. //-----------------------------------------------------------------------------
  51. // Purpose: constraint limit on a single rotation axis
  52. //-----------------------------------------------------------------------------
  53. struct constraint_axislimit_t
  54. {
  55. float minRotation;
  56. float maxRotation;
  57. float angularVelocity; // desired angular velocity around hinge
  58. float torque; // torque to achieve angular velocity (use 0, torque for "friction")
  59. inline void SetAxisFriction( float rmin, float rmax, float friction )
  60. {
  61. minRotation = rmin;
  62. maxRotation = rmax;
  63. angularVelocity = 0;
  64. torque = friction;
  65. }
  66. inline void Defaults()
  67. {
  68. SetAxisFriction(0,0,0);
  69. }
  70. };
  71. // Builds a transform which maps points in the input object's local space
  72. // to the output object's local space
  73. inline void BuildObjectRelativeXform( IPhysicsObject *pOutputSpace, IPhysicsObject *pInputSpace, matrix3x4_t &xformInToOut )
  74. {
  75. matrix3x4_t outInv, tmp, input;
  76. pOutputSpace->GetPositionMatrix( &tmp );
  77. MatrixInvert( tmp, outInv );
  78. pInputSpace->GetPositionMatrix( &input );
  79. ConcatTransforms( outInv, input, xformInToOut );
  80. }
  81. //-----------------------------------------------------------------------------
  82. // Purpose: special limited ballsocket constraint for ragdolls.
  83. // Has axis limits for all 3 axes.
  84. //-----------------------------------------------------------------------------
  85. struct constraint_ragdollparams_t
  86. {
  87. constraint_breakableparams_t constraint;
  88. matrix3x4_t constraintToReference;// xform constraint space to refobject space
  89. matrix3x4_t constraintToAttached; // xform constraint space to attached object space
  90. int parentIndex; // NOTE: only used for parsing. NEED NOT BE SET for create
  91. int childIndex; // NOTE: only used for parsing. NEED NOT BE SET for create
  92. constraint_axislimit_t axes[3];
  93. bool onlyAngularLimits; // only angular limits (not translation as well?)
  94. bool isActive;
  95. bool useClockwiseRotations; // HACKHACK: Did this wrong in version one. Fix in the future.
  96. inline void Defaults()
  97. {
  98. constraint.Defaults();
  99. isActive = true;
  100. SetIdentityMatrix( constraintToReference );
  101. SetIdentityMatrix( constraintToAttached );
  102. parentIndex = -1;
  103. childIndex = -1;
  104. axes[0].Defaults();
  105. axes[1].Defaults();
  106. axes[2].Defaults();
  107. onlyAngularLimits = false;
  108. useClockwiseRotations = false;
  109. }
  110. };
  111. //-----------------------------------------------------------------------------
  112. // Purpose: Used to init a hinge restricting the relative position and orientation
  113. // of two objects to rotation around a single axis
  114. //-----------------------------------------------------------------------------
  115. struct constraint_hingeparams_t
  116. {
  117. Vector worldPosition; // position in world space on the hinge axis
  118. Vector worldAxisDirection; // unit direction vector of the hinge axis in world space
  119. constraint_axislimit_t hingeAxis;
  120. constraint_breakableparams_t constraint;
  121. inline void Defaults()
  122. {
  123. worldPosition.Init();
  124. worldAxisDirection.Init();
  125. hingeAxis.Defaults();
  126. constraint.Defaults();
  127. }
  128. };
  129. struct constraint_limitedhingeparams_t : public constraint_hingeparams_t
  130. {
  131. Vector referencePerpAxisDirection; // unit direction vector vector perpendicular to the hinge axis in world space
  132. Vector attachedPerpAxisDirection; // unit direction vector vector perpendicular to the hinge axis in world space
  133. constraint_limitedhingeparams_t() {}
  134. constraint_limitedhingeparams_t( const constraint_hingeparams_t &hinge )
  135. {
  136. static_cast<constraint_hingeparams_t &>(*this) = hinge;
  137. referencePerpAxisDirection.Init();
  138. attachedPerpAxisDirection.Init();
  139. }
  140. inline void Defaults()
  141. {
  142. this->constraint_hingeparams_t::Defaults();
  143. referencePerpAxisDirection.Init();
  144. attachedPerpAxisDirection.Init();
  145. }
  146. };
  147. //-----------------------------------------------------------------------------
  148. // Purpose: Used to init a constraint that fixes the position and orientation
  149. // of two objects relative to each other (like glue)
  150. //-----------------------------------------------------------------------------
  151. struct constraint_fixedparams_t
  152. {
  153. matrix3x4_t attachedRefXform; // xform attached object space to ref object space
  154. constraint_breakableparams_t constraint;
  155. inline void InitWithCurrentObjectState( IPhysicsObject *pRef, IPhysicsObject *pAttached )
  156. {
  157. BuildObjectRelativeXform( pRef, pAttached, attachedRefXform );
  158. }
  159. inline void Defaults()
  160. {
  161. SetIdentityMatrix( attachedRefXform );
  162. constraint.Defaults();
  163. }
  164. };
  165. //-----------------------------------------------------------------------------
  166. // Purpose: Same parameters as fixed constraint, but torqueLimit has no effect
  167. //-----------------------------------------------------------------------------
  168. struct constraint_ballsocketparams_t
  169. {
  170. Vector constraintPosition[2]; // position of the constraint in each object's space
  171. constraint_breakableparams_t constraint;
  172. inline void Defaults()
  173. {
  174. constraint.Defaults();
  175. constraintPosition[0].Init();
  176. constraintPosition[1].Init();
  177. }
  178. void InitWithCurrentObjectState( IPhysicsObject *pRef, IPhysicsObject *pAttached, const Vector &ballsocketOrigin )
  179. {
  180. pRef->WorldToLocal( &constraintPosition[0], ballsocketOrigin );
  181. pAttached->WorldToLocal( &constraintPosition[1], ballsocketOrigin );
  182. }
  183. };
  184. struct constraint_slidingparams_t
  185. {
  186. matrix3x4_t attachedRefXform; // xform attached object space to ref object space
  187. Vector slideAxisRef; // unit direction vector of the slide axis in ref object space
  188. constraint_breakableparams_t constraint;
  189. // NOTE: if limitMin == limitMax there is NO limit set!
  190. float limitMin; // minimum limit coordinate refAxisDirection space
  191. float limitMax; // maximum limit coordinate refAxisDirection space
  192. float friction; // friction on sliding
  193. float velocity; // desired velocity
  194. inline void Defaults()
  195. {
  196. SetIdentityMatrix( attachedRefXform );
  197. slideAxisRef.Init();
  198. limitMin = limitMax = 0;
  199. friction = 0;
  200. velocity = 0;
  201. constraint.Defaults();
  202. }
  203. inline void SetFriction( float inputFriction )
  204. {
  205. friction = inputFriction;
  206. velocity = 0;
  207. }
  208. inline void SetLinearMotor( float inputVelocity, float maxForce )
  209. {
  210. friction = maxForce;
  211. velocity = inputVelocity;
  212. }
  213. inline void InitWithCurrentObjectState( IPhysicsObject *pRef, IPhysicsObject *pAttached, const Vector &slideDirWorldspace )
  214. {
  215. BuildObjectRelativeXform( pRef, pAttached, attachedRefXform );
  216. matrix3x4_t tmp;
  217. pRef->GetPositionMatrix( &tmp );
  218. VectorIRotate( slideDirWorldspace, tmp, slideAxisRef );
  219. }
  220. };
  221. struct constraint_pulleyparams_t
  222. {
  223. constraint_breakableparams_t constraint;
  224. Vector pulleyPosition[2]; // These are the pulley positions for the reference and attached objects in world space
  225. Vector objectPosition[2]; // local positions of attachments to the ref,att objects
  226. float totalLength; // total rope length (include gearing!)
  227. float gearRatio; // gearing affects attached object ALWAYS
  228. bool isRigid;
  229. inline void Defaults()
  230. {
  231. constraint.Defaults();
  232. totalLength = 1.0;
  233. gearRatio = 1.0;
  234. pulleyPosition[0].Init();
  235. pulleyPosition[1].Init();
  236. objectPosition[0].Init();
  237. objectPosition[1].Init();
  238. isRigid = false;
  239. }
  240. };
  241. struct constraint_lengthparams_t
  242. {
  243. constraint_breakableparams_t constraint;
  244. Vector objectPosition[2]; // These are the positions for the reference and attached objects in local space
  245. float totalLength; // Length of rope/spring/constraint. Distance to maintain
  246. float minLength; // if rigid, objects are not allowed to move closer than totalLength either
  247. void InitWorldspace( IPhysicsObject *pRef, IPhysicsObject *pAttached, const Vector &refPosition, const Vector &attachedPosition, bool rigid = false )
  248. {
  249. pRef->WorldToLocal( &objectPosition[0], refPosition );
  250. pAttached->WorldToLocal( &objectPosition[1], attachedPosition );
  251. totalLength = (refPosition - attachedPosition).Length();
  252. minLength = rigid ? totalLength : 0;
  253. }
  254. void Init( IPhysicsObject *pRef, IPhysicsObject *pAttached, float flLength, bool rigid = false )
  255. {
  256. objectPosition[0] = vec3_origin;
  257. objectPosition[1] = vec3_origin;
  258. totalLength = flLength;
  259. minLength = rigid ? totalLength : 0;
  260. }
  261. inline void Defaults()
  262. {
  263. constraint.Defaults();
  264. objectPosition[0].Init();
  265. objectPosition[1].Init();
  266. totalLength = 1;
  267. minLength = 0;
  268. }
  269. };
  270. class IPhysicsConstraint
  271. {
  272. public:
  273. virtual ~IPhysicsConstraint( void ) {}
  274. // NOTE: Constraints are active when created. You can temporarily enable/disable them with these functions
  275. virtual void Activate( void ) = 0;
  276. virtual void Deactivate( void ) = 0;
  277. // set a pointer to the game object
  278. virtual void SetGameData( void *gameData ) = 0;
  279. // get a pointer to the game object
  280. virtual void *GetGameData( void ) const = 0;
  281. // Get the parent/referenced object
  282. virtual IPhysicsObject *GetReferenceObject( void ) const = 0;
  283. // Get the attached object
  284. virtual IPhysicsObject *GetAttachedObject( void ) const = 0;
  285. virtual void SetLinearMotor( float speed, float maxLinearImpulse ) = 0;
  286. virtual void SetAngularMotor( float rotSpeed, float maxAngularImpulse ) = 0;
  287. virtual void UpdateRagdollTransforms( const matrix3x4_t &constraintToReference, const matrix3x4_t &constraintToAttached ) = 0;
  288. virtual bool GetConstraintTransform( matrix3x4_t *pConstraintToReference, matrix3x4_t *pConstraintToAttached ) const = 0;
  289. virtual bool GetConstraintParams( constraint_breakableparams_t *pParams ) const = 0;
  290. virtual void OutputDebugInfo() = 0;
  291. };
  292. class IPhysicsConstraintGroup
  293. {
  294. public:
  295. virtual ~IPhysicsConstraintGroup( void ) {}
  296. virtual void Activate() = 0;
  297. virtual bool IsInErrorState() = 0;
  298. virtual void ClearErrorState() = 0;
  299. virtual void GetErrorParams( constraint_groupparams_t *pParams ) = 0;
  300. virtual void SetErrorParams( const constraint_groupparams_t &params ) = 0;
  301. virtual void SolvePenetration( IPhysicsObject *pObj0, IPhysicsObject *pObj1 ) = 0;
  302. };
  303. #endif // CONSTRAINTS_H