Physics_AF.h 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #ifndef __PHYSICS_AF_H__
  21. #define __PHYSICS_AF_H__
  22. /*
  23. ===================================================================================
  24. Articulated Figure physics
  25. Employs a constraint force based dynamic simulation using a lagrangian
  26. multiplier method to solve for the constraint forces.
  27. ===================================================================================
  28. */
  29. class idAFConstraint;
  30. class idAFConstraint_Fixed;
  31. class idAFConstraint_BallAndSocketJoint;
  32. class idAFConstraint_BallAndSocketJointFriction;
  33. class idAFConstraint_UniversalJoint;
  34. class idAFConstraint_UniversalJointFriction;
  35. class idAFConstraint_CylindricalJoint;
  36. class idAFConstraint_Hinge;
  37. class idAFConstraint_HingeFriction;
  38. class idAFConstraint_HingeSteering;
  39. class idAFConstraint_Slider;
  40. class idAFConstraint_Line;
  41. class idAFConstraint_Plane;
  42. class idAFConstraint_Spring;
  43. class idAFConstraint_Contact;
  44. class idAFConstraint_ContactFriction;
  45. class idAFConstraint_ConeLimit;
  46. class idAFConstraint_PyramidLimit;
  47. class idAFConstraint_Suspension;
  48. class idAFBody;
  49. class idAFTree;
  50. class idPhysics_AF;
  51. typedef enum {
  52. CONSTRAINT_INVALID,
  53. CONSTRAINT_FIXED,
  54. CONSTRAINT_BALLANDSOCKETJOINT,
  55. CONSTRAINT_UNIVERSALJOINT,
  56. CONSTRAINT_HINGE,
  57. CONSTRAINT_HINGESTEERING,
  58. CONSTRAINT_SLIDER,
  59. CONSTRAINT_CYLINDRICALJOINT,
  60. CONSTRAINT_LINE,
  61. CONSTRAINT_PLANE,
  62. CONSTRAINT_SPRING,
  63. CONSTRAINT_CONTACT,
  64. CONSTRAINT_FRICTION,
  65. CONSTRAINT_CONELIMIT,
  66. CONSTRAINT_PYRAMIDLIMIT,
  67. CONSTRAINT_SUSPENSION
  68. } constraintType_t;
  69. //===============================================================
  70. //
  71. // idAFConstraint
  72. //
  73. //===============================================================
  74. // base class for all constraints
  75. class idAFConstraint {
  76. friend class idPhysics_AF;
  77. friend class idAFTree;
  78. public:
  79. idAFConstraint( void );
  80. virtual ~idAFConstraint( void );
  81. constraintType_t GetType( void ) const { return type; }
  82. const idStr & GetName( void ) const { return name; }
  83. idAFBody * GetBody1( void ) const { return body1; }
  84. idAFBody * GetBody2( void ) const { return body2; }
  85. void SetPhysics( idPhysics_AF *p ) { physics = p; }
  86. const idVecX & GetMultiplier( void );
  87. virtual void SetBody1( idAFBody *body );
  88. virtual void SetBody2( idAFBody *body );
  89. virtual void DebugDraw( void );
  90. virtual void GetForce( idAFBody *body, idVec6 &force );
  91. virtual void Translate( const idVec3 &translation );
  92. virtual void Rotate( const idRotation &rotation );
  93. virtual void GetCenter( idVec3 &center );
  94. virtual void Save( idSaveGame *saveFile ) const;
  95. virtual void Restore( idRestoreGame *saveFile );
  96. protected:
  97. constraintType_t type; // constraint type
  98. idStr name; // name of constraint
  99. idAFBody * body1; // first constrained body
  100. idAFBody * body2; // second constrained body, NULL for world
  101. idPhysics_AF * physics; // for adding additional constraints like limits
  102. // simulation variables set by Evaluate
  103. idMatX J1, J2; // matrix with left hand side of constraint equations
  104. idVecX c1, c2; // right hand side of constraint equations
  105. idVecX lo, hi, e; // low and high bounds and lcp epsilon
  106. idAFConstraint * boxConstraint; // constraint the boxIndex refers to
  107. int boxIndex[6]; // indexes for special box constrained variables
  108. // simulation variables used during calculations
  109. idMatX invI; // transformed inertia
  110. idMatX J; // transformed constraint matrix
  111. idVecX s; // temp solution
  112. idVecX lm; // lagrange multipliers
  113. int firstIndex; // index of the first constraint row in the lcp matrix
  114. struct constraintFlags_s {
  115. bool allowPrimary : 1; // true if the constraint can be used as a primary constraint
  116. bool frameConstraint : 1; // true if this constraint is added to the frame constraints
  117. bool noCollision : 1; // true if body1 and body2 never collide with each other
  118. bool isPrimary : 1; // true if this is a primary constraint
  119. bool isZero : 1; // true if 's' is zero during calculations
  120. } fl;
  121. protected:
  122. virtual void Evaluate( float invTimeStep );
  123. virtual void ApplyFriction( float invTimeStep );
  124. void InitSize( int size );
  125. };
  126. // fixed or rigid joint which allows zero degrees of freedom
  127. // constrains body1 to have a fixed position and orientation relative to body2
  128. class idAFConstraint_Fixed : public idAFConstraint {
  129. public:
  130. idAFConstraint_Fixed( const idStr &name, idAFBody *body1, idAFBody *body2 );
  131. void SetRelativeOrigin( const idVec3 &origin ) { this->offset = origin; }
  132. void SetRelativeAxis( const idMat3 &axis ) { this->relAxis = axis; }
  133. virtual void SetBody1( idAFBody *body );
  134. virtual void SetBody2( idAFBody *body );
  135. virtual void DebugDraw( void );
  136. virtual void Translate( const idVec3 &translation );
  137. virtual void Rotate( const idRotation &rotation );
  138. virtual void GetCenter( idVec3 &center );
  139. virtual void Save( idSaveGame *saveFile ) const;
  140. virtual void Restore( idRestoreGame *saveFile );
  141. protected:
  142. idVec3 offset; // offset of body1 relative to body2 in body2 space
  143. idMat3 relAxis; // rotation of body1 relative to body2
  144. protected:
  145. virtual void Evaluate( float invTimeStep );
  146. virtual void ApplyFriction( float invTimeStep );
  147. void InitOffset( void );
  148. };
  149. // ball and socket or spherical joint which allows 3 degrees of freedom
  150. // constrains body1 relative to body2 with a ball and socket joint
  151. class idAFConstraint_BallAndSocketJoint : public idAFConstraint {
  152. public:
  153. idAFConstraint_BallAndSocketJoint( const idStr &name, idAFBody *body1, idAFBody *body2 );
  154. ~idAFConstraint_BallAndSocketJoint( void );
  155. void SetAnchor( const idVec3 &worldPosition );
  156. idVec3 GetAnchor( void ) const;
  157. void SetNoLimit( void );
  158. void SetConeLimit( const idVec3 &coneAxis, const float coneAngle, const idVec3 &body1Axis );
  159. void SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis,
  160. const float angle1, const float angle2, const idVec3 &body1Axis );
  161. void SetLimitEpsilon( const float e );
  162. void SetFriction( const float f ) { friction = f; }
  163. float GetFriction( void ) const;
  164. virtual void DebugDraw( void );
  165. virtual void GetForce( idAFBody *body, idVec6 &force );
  166. virtual void Translate( const idVec3 &translation );
  167. virtual void Rotate( const idRotation &rotation );
  168. virtual void GetCenter( idVec3 &center );
  169. virtual void Save( idSaveGame *saveFile ) const;
  170. virtual void Restore( idRestoreGame *saveFile );
  171. protected:
  172. idVec3 anchor1; // anchor in body1 space
  173. idVec3 anchor2; // anchor in body2 space
  174. float friction; // joint friction
  175. idAFConstraint_ConeLimit *coneLimit; // cone shaped limit
  176. idAFConstraint_PyramidLimit *pyramidLimit; // pyramid shaped limit
  177. idAFConstraint_BallAndSocketJointFriction *fc; // friction constraint
  178. protected:
  179. virtual void Evaluate( float invTimeStep );
  180. virtual void ApplyFriction( float invTimeStep );
  181. };
  182. // ball and socket joint friction
  183. class idAFConstraint_BallAndSocketJointFriction : public idAFConstraint {
  184. public:
  185. idAFConstraint_BallAndSocketJointFriction( void );
  186. void Setup( idAFConstraint_BallAndSocketJoint *cc );
  187. bool Add( idPhysics_AF *phys, float invTimeStep );
  188. virtual void Translate( const idVec3 &translation );
  189. virtual void Rotate( const idRotation &rotation );
  190. protected:
  191. idAFConstraint_BallAndSocketJoint *joint;
  192. protected:
  193. virtual void Evaluate( float invTimeStep );
  194. virtual void ApplyFriction( float invTimeStep );
  195. };
  196. // universal, Cardan or Hooke joint which allows 2 degrees of freedom
  197. // like a ball and socket joint but also constrains the rotation about the cardan shafts
  198. class idAFConstraint_UniversalJoint : public idAFConstraint {
  199. public:
  200. idAFConstraint_UniversalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 );
  201. ~idAFConstraint_UniversalJoint( void );
  202. void SetAnchor( const idVec3 &worldPosition );
  203. idVec3 GetAnchor( void ) const;
  204. void SetShafts( const idVec3 &cardanShaft1, const idVec3 &cardanShaft2 );
  205. void GetShafts( idVec3 &cardanShaft1, idVec3 &cardanShaft2 ) { cardanShaft1 = shaft1; cardanShaft2 = shaft2; }
  206. void SetNoLimit( void );
  207. void SetConeLimit( const idVec3 &coneAxis, const float coneAngle );
  208. void SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis,
  209. const float angle1, const float angle2 );
  210. void SetLimitEpsilon( const float e );
  211. void SetFriction( const float f ) { friction = f; }
  212. float GetFriction( void ) const;
  213. virtual void DebugDraw( void );
  214. virtual void GetForce( idAFBody *body, idVec6 &force );
  215. virtual void Translate( const idVec3 &translation );
  216. virtual void Rotate( const idRotation &rotation );
  217. virtual void GetCenter( idVec3 &center );
  218. virtual void Save( idSaveGame *saveFile ) const;
  219. virtual void Restore( idRestoreGame *saveFile );
  220. protected:
  221. idVec3 anchor1; // anchor in body1 space
  222. idVec3 anchor2; // anchor in body2 space
  223. idVec3 shaft1; // body1 cardan shaft in body1 space
  224. idVec3 shaft2; // body2 cardan shaft in body2 space
  225. idVec3 axis1; // cardan axis in body1 space
  226. idVec3 axis2; // cardan axis in body2 space
  227. float friction; // joint friction
  228. idAFConstraint_ConeLimit *coneLimit; // cone shaped limit
  229. idAFConstraint_PyramidLimit *pyramidLimit; // pyramid shaped limit
  230. idAFConstraint_UniversalJointFriction *fc; // friction constraint
  231. protected:
  232. virtual void Evaluate( float invTimeStep );
  233. virtual void ApplyFriction( float invTimeStep );
  234. };
  235. // universal joint friction
  236. class idAFConstraint_UniversalJointFriction : public idAFConstraint {
  237. public:
  238. idAFConstraint_UniversalJointFriction( void );
  239. void Setup( idAFConstraint_UniversalJoint *cc );
  240. bool Add( idPhysics_AF *phys, float invTimeStep );
  241. virtual void Translate( const idVec3 &translation );
  242. virtual void Rotate( const idRotation &rotation );
  243. protected:
  244. idAFConstraint_UniversalJoint *joint; // universal joint
  245. protected:
  246. virtual void Evaluate( float invTimeStep );
  247. virtual void ApplyFriction( float invTimeStep );
  248. };
  249. // cylindrical joint which allows 2 degrees of freedom
  250. // constrains body1 to lie on a line relative to body2 and allows only translation along and rotation about the line
  251. class idAFConstraint_CylindricalJoint : public idAFConstraint {
  252. public:
  253. idAFConstraint_CylindricalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 );
  254. virtual void DebugDraw( void );
  255. virtual void Translate( const idVec3 &translation );
  256. virtual void Rotate( const idRotation &rotation );
  257. protected:
  258. protected:
  259. virtual void Evaluate( float invTimeStep );
  260. virtual void ApplyFriction( float invTimeStep );
  261. };
  262. // hinge, revolute or pin joint which allows 1 degree of freedom
  263. // constrains all motion of body1 relative to body2 except the rotation about the hinge axis
  264. class idAFConstraint_Hinge : public idAFConstraint {
  265. public:
  266. idAFConstraint_Hinge( const idStr &name, idAFBody *body1, idAFBody *body2 );
  267. ~idAFConstraint_Hinge( void );
  268. void SetAnchor( const idVec3 &worldPosition );
  269. idVec3 GetAnchor( void ) const;
  270. void SetAxis( const idVec3 &axis );
  271. void GetAxis( idVec3 &a1, idVec3 &a2 ) const { a1 = axis1; a2 = axis2; }
  272. idVec3 GetAxis( void ) const;
  273. void SetNoLimit( void );
  274. void SetLimit( const idVec3 &axis, const float angle, const idVec3 &body1Axis );
  275. void SetLimitEpsilon( const float e );
  276. float GetAngle( void ) const;
  277. void SetSteerAngle( const float degrees );
  278. void SetSteerSpeed( const float speed );
  279. void SetFriction( const float f ) { friction = f; }
  280. float GetFriction( void ) const;
  281. virtual void DebugDraw( void );
  282. virtual void GetForce( idAFBody *body, idVec6 &force );
  283. virtual void Translate( const idVec3 &translation );
  284. virtual void Rotate( const idRotation &rotation );
  285. virtual void GetCenter( idVec3 &center );
  286. virtual void Save( idSaveGame *saveFile ) const;
  287. virtual void Restore( idRestoreGame *saveFile );
  288. protected:
  289. idVec3 anchor1; // anchor in body1 space
  290. idVec3 anchor2; // anchor in body2 space
  291. idVec3 axis1; // axis in body1 space
  292. idVec3 axis2; // axis in body2 space
  293. idMat3 initialAxis; // initial axis of body1 relative to body2
  294. float friction; // hinge friction
  295. idAFConstraint_ConeLimit *coneLimit; // cone limit
  296. idAFConstraint_HingeSteering *steering; // steering
  297. idAFConstraint_HingeFriction *fc; // friction constraint
  298. protected:
  299. virtual void Evaluate( float invTimeStep );
  300. virtual void ApplyFriction( float invTimeStep );
  301. };
  302. // hinge joint friction
  303. class idAFConstraint_HingeFriction : public idAFConstraint {
  304. public:
  305. idAFConstraint_HingeFriction( void );
  306. void Setup( idAFConstraint_Hinge *cc );
  307. bool Add( idPhysics_AF *phys, float invTimeStep );
  308. virtual void Translate( const idVec3 &translation );
  309. virtual void Rotate( const idRotation &rotation );
  310. protected:
  311. idAFConstraint_Hinge * hinge; // hinge
  312. protected:
  313. virtual void Evaluate( float invTimeStep );
  314. virtual void ApplyFriction( float invTimeStep );
  315. };
  316. // constrains two bodies attached to each other with a hinge to get a specified relative orientation
  317. class idAFConstraint_HingeSteering : public idAFConstraint {
  318. public:
  319. idAFConstraint_HingeSteering( void );
  320. void Setup( idAFConstraint_Hinge *cc );
  321. void SetSteerAngle( const float degrees ) { steerAngle = degrees; }
  322. void SetSteerSpeed( const float speed ) { steerSpeed = speed; }
  323. void SetEpsilon( const float e ) { epsilon = e; }
  324. bool Add( idPhysics_AF *phys, float invTimeStep );
  325. virtual void Translate( const idVec3 &translation );
  326. virtual void Rotate( const idRotation &rotation );
  327. virtual void Save( idSaveGame *saveFile ) const;
  328. virtual void Restore( idRestoreGame *saveFile );
  329. protected:
  330. idAFConstraint_Hinge * hinge; // hinge
  331. float steerAngle; // desired steer angle in degrees
  332. float steerSpeed; // steer speed
  333. float epsilon; // lcp epsilon
  334. protected:
  335. virtual void Evaluate( float invTimeStep );
  336. virtual void ApplyFriction( float invTimeStep );
  337. };
  338. // slider, prismatic or translational constraint which allows 1 degree of freedom
  339. // constrains body1 to lie on a line relative to body2, the orientation is also fixed relative to body2
  340. class idAFConstraint_Slider : public idAFConstraint {
  341. public:
  342. idAFConstraint_Slider( const idStr &name, idAFBody *body1, idAFBody *body2 );
  343. void SetAxis( const idVec3 &ax );
  344. virtual void DebugDraw( void );
  345. virtual void Translate( const idVec3 &translation );
  346. virtual void Rotate( const idRotation &rotation );
  347. virtual void GetCenter( idVec3 &center );
  348. virtual void Save( idSaveGame *saveFile ) const;
  349. virtual void Restore( idRestoreGame *saveFile );
  350. protected:
  351. idVec3 axis; // axis along which body1 slides in body2 space
  352. idVec3 offset; // offset of body1 relative to body2
  353. idMat3 relAxis; // rotation of body1 relative to body2
  354. protected:
  355. virtual void Evaluate( float invTimeStep );
  356. virtual void ApplyFriction( float invTimeStep );
  357. };
  358. // line constraint which allows 4 degrees of freedom
  359. // constrains body1 to lie on a line relative to body2, does not constrain the orientation.
  360. class idAFConstraint_Line : public idAFConstraint {
  361. public:
  362. idAFConstraint_Line( const idStr &name, idAFBody *body1, idAFBody *body2 );
  363. virtual void DebugDraw( void );
  364. virtual void Translate( const idVec3 &translation );
  365. virtual void Rotate( const idRotation &rotation );
  366. protected:
  367. protected:
  368. virtual void Evaluate( float invTimeStep );
  369. virtual void ApplyFriction( float invTimeStep );
  370. };
  371. // plane constraint which allows 5 degrees of freedom
  372. // constrains body1 to lie in a plane relative to body2, does not constrain the orientation.
  373. class idAFConstraint_Plane : public idAFConstraint {
  374. public:
  375. idAFConstraint_Plane( const idStr &name, idAFBody *body1, idAFBody *body2 );
  376. void SetPlane( const idVec3 &normal, const idVec3 &anchor );
  377. virtual void DebugDraw( void );
  378. virtual void Translate( const idVec3 &translation );
  379. virtual void Rotate( const idRotation &rotation );
  380. virtual void Save( idSaveGame *saveFile ) const;
  381. virtual void Restore( idRestoreGame *saveFile );
  382. protected:
  383. idVec3 anchor1; // anchor in body1 space
  384. idVec3 anchor2; // anchor in body2 space
  385. idVec3 planeNormal; // plane normal in body2 space
  386. protected:
  387. virtual void Evaluate( float invTimeStep );
  388. virtual void ApplyFriction( float invTimeStep );
  389. };
  390. // spring constraint which allows 6 or 5 degrees of freedom based on the spring limits
  391. // constrains body1 relative to body2 with a spring
  392. class idAFConstraint_Spring : public idAFConstraint {
  393. public:
  394. idAFConstraint_Spring( const idStr &name, idAFBody *body1, idAFBody *body2 );
  395. void SetAnchor( const idVec3 &worldAnchor1, const idVec3 &worldAnchor2 );
  396. void SetSpring( const float stretch, const float compress, const float damping, const float restLength );
  397. void SetLimit( const float minLength, const float maxLength );
  398. virtual void DebugDraw( void );
  399. virtual void Translate( const idVec3 &translation );
  400. virtual void Rotate( const idRotation &rotation );
  401. virtual void GetCenter( idVec3 &center );
  402. virtual void Save( idSaveGame *saveFile ) const;
  403. virtual void Restore( idRestoreGame *saveFile );
  404. protected:
  405. idVec3 anchor1; // anchor in body1 space
  406. idVec3 anchor2; // anchor in body2 space
  407. float kstretch; // spring constant when stretched
  408. float kcompress; // spring constant when compressed
  409. float damping; // spring damping
  410. float restLength; // rest length of spring
  411. float minLength; // minimum spring length
  412. float maxLength; // maximum spring length
  413. protected:
  414. virtual void Evaluate( float invTimeStep );
  415. virtual void ApplyFriction( float invTimeStep );
  416. };
  417. // constrains body1 to either be in contact with or move away from body2
  418. class idAFConstraint_Contact : public idAFConstraint {
  419. public:
  420. idAFConstraint_Contact( void );
  421. ~idAFConstraint_Contact( void );
  422. void Setup( idAFBody *b1, idAFBody *b2, contactInfo_t &c );
  423. const contactInfo_t & GetContact( void ) const { return contact; }
  424. virtual void DebugDraw( void );
  425. virtual void Translate( const idVec3 &translation );
  426. virtual void Rotate( const idRotation &rotation );
  427. virtual void GetCenter( idVec3 &center );
  428. protected:
  429. contactInfo_t contact; // contact information
  430. idAFConstraint_ContactFriction *fc; // contact friction
  431. protected:
  432. virtual void Evaluate( float invTimeStep );
  433. virtual void ApplyFriction( float invTimeStep );
  434. };
  435. // contact friction
  436. class idAFConstraint_ContactFriction : public idAFConstraint {
  437. public:
  438. idAFConstraint_ContactFriction( void );
  439. void Setup( idAFConstraint_Contact *cc );
  440. bool Add( idPhysics_AF *phys, float invTimeStep );
  441. virtual void DebugDraw( void );
  442. virtual void Translate( const idVec3 &translation );
  443. virtual void Rotate( const idRotation &rotation );
  444. protected:
  445. idAFConstraint_Contact *cc; // contact constraint
  446. protected:
  447. virtual void Evaluate( float invTimeStep );
  448. virtual void ApplyFriction( float invTimeStep );
  449. };
  450. // constrains an axis attached to body1 to be inside a cone relative to body2
  451. class idAFConstraint_ConeLimit : public idAFConstraint {
  452. public:
  453. idAFConstraint_ConeLimit( void );
  454. void Setup( idAFBody *b1, idAFBody *b2, const idVec3 &coneAnchor, const idVec3 &coneAxis,
  455. const float coneAngle, const idVec3 &body1Axis );
  456. void SetAnchor( const idVec3 &coneAnchor );
  457. void SetBody1Axis( const idVec3 &body1Axis );
  458. void SetEpsilon( const float e ) { epsilon = e; }
  459. bool Add( idPhysics_AF *phys, float invTimeStep );
  460. virtual void DebugDraw( void );
  461. virtual void Translate( const idVec3 &translation );
  462. virtual void Rotate( const idRotation &rotation );
  463. virtual void Save( idSaveGame *saveFile ) const;
  464. virtual void Restore( idRestoreGame *saveFile );
  465. protected:
  466. idVec3 coneAnchor; // top of the cone in body2 space
  467. idVec3 coneAxis; // cone axis in body2 space
  468. idVec3 body1Axis; // axis in body1 space that should stay within the cone
  469. float cosAngle; // cos( coneAngle / 2 )
  470. float sinHalfAngle; // sin( coneAngle / 4 )
  471. float cosHalfAngle; // cos( coneAngle / 4 )
  472. float epsilon; // lcp epsilon
  473. protected:
  474. virtual void Evaluate( float invTimeStep );
  475. virtual void ApplyFriction( float invTimeStep );
  476. };
  477. // constrains an axis attached to body1 to be inside a pyramid relative to body2
  478. class idAFConstraint_PyramidLimit : public idAFConstraint {
  479. public:
  480. idAFConstraint_PyramidLimit( void );
  481. void Setup( idAFBody *b1, idAFBody *b2, const idVec3 &pyramidAnchor,
  482. const idVec3 &pyramidAxis, const idVec3 &baseAxis,
  483. const float pyramidAngle1, const float pyramidAngle2, const idVec3 &body1Axis );
  484. void SetAnchor( const idVec3 &pyramidAxis );
  485. void SetBody1Axis( const idVec3 &body1Axis );
  486. void SetEpsilon( const float e ) { epsilon = e; }
  487. bool Add( idPhysics_AF *phys, float invTimeStep );
  488. virtual void DebugDraw( void );
  489. virtual void Translate( const idVec3 &translation );
  490. virtual void Rotate( const idRotation &rotation );
  491. virtual void Save( idSaveGame *saveFile ) const;
  492. virtual void Restore( idRestoreGame *saveFile );
  493. protected:
  494. idVec3 pyramidAnchor; // top of the pyramid in body2 space
  495. idMat3 pyramidBasis; // pyramid basis in body2 space with base[2] being the pyramid axis
  496. idVec3 body1Axis; // axis in body1 space that should stay within the cone
  497. float cosAngle[2]; // cos( pyramidAngle / 2 )
  498. float sinHalfAngle[2]; // sin( pyramidAngle / 4 )
  499. float cosHalfAngle[2]; // cos( pyramidAngle / 4 )
  500. float epsilon; // lcp epsilon
  501. protected:
  502. virtual void Evaluate( float invTimeStep );
  503. virtual void ApplyFriction( float invTimeStep );
  504. };
  505. // vehicle suspension
  506. class idAFConstraint_Suspension : public idAFConstraint {
  507. public:
  508. idAFConstraint_Suspension( void );
  509. void Setup( const char *name, idAFBody *body, const idVec3 &origin, const idMat3 &axis, idClipModel *clipModel );
  510. void SetSuspension( const float up, const float down, const float k, const float d, const float f );
  511. void SetSteerAngle( const float degrees ) { steerAngle = degrees; }
  512. void EnableMotor( const bool enable ) { motorEnabled = enable; }
  513. void SetMotorForce( const float force ) { motorForce = force; }
  514. void SetMotorVelocity( const float vel ) { motorVelocity = vel; }
  515. void SetEpsilon( const float e ) { epsilon = e; }
  516. const idVec3 GetWheelOrigin( void ) const;
  517. virtual void DebugDraw( void );
  518. virtual void Translate( const idVec3 &translation );
  519. virtual void Rotate( const idRotation &rotation );
  520. protected:
  521. idVec3 localOrigin; // position of suspension relative to body1
  522. idMat3 localAxis; // orientation of suspension relative to body1
  523. float suspensionUp; // suspension up movement
  524. float suspensionDown; // suspension down movement
  525. float suspensionKCompress; // spring compress constant
  526. float suspensionDamping; // spring damping
  527. float steerAngle; // desired steer angle in degrees
  528. float friction; // friction
  529. bool motorEnabled; // whether the motor is enabled or not
  530. float motorForce; // motor force
  531. float motorVelocity; // desired velocity
  532. idClipModel * wheelModel; // wheel model
  533. idVec3 wheelOffset; // wheel position relative to body1
  534. trace_t trace; // contact point with the ground
  535. float epsilon; // lcp epsilon
  536. protected:
  537. virtual void Evaluate( float invTimeStep );
  538. virtual void ApplyFriction( float invTimeStep );
  539. };
  540. //===============================================================
  541. //
  542. // idAFBody
  543. //
  544. //===============================================================
  545. typedef struct AFBodyPState_s {
  546. idVec3 worldOrigin; // position in world space
  547. idMat3 worldAxis; // axis at worldOrigin
  548. idVec6 spatialVelocity; // linear and rotational velocity of body
  549. idVec6 externalForce; // external force and torque applied to body
  550. } AFBodyPState_t;
  551. class idAFBody {
  552. friend class idPhysics_AF;
  553. friend class idAFTree;
  554. public:
  555. idAFBody( void );
  556. idAFBody( const idStr &name, idClipModel *clipModel, float density );
  557. ~idAFBody( void );
  558. void Init( void );
  559. const idStr & GetName( void ) const { return name; }
  560. const idVec3 & GetWorldOrigin( void ) const { return current->worldOrigin; }
  561. const idMat3 & GetWorldAxis( void ) const { return current->worldAxis; }
  562. const idVec3 & GetLinearVelocity( void ) const { return current->spatialVelocity.SubVec3(0); }
  563. const idVec3 & GetAngularVelocity( void ) const { return current->spatialVelocity.SubVec3(1); }
  564. idVec3 GetPointVelocity( const idVec3 &point ) const;
  565. const idVec3 & GetCenterOfMass( void ) const { return centerOfMass; }
  566. void SetClipModel( idClipModel *clipModel );
  567. idClipModel * GetClipModel( void ) const { return clipModel; }
  568. void SetClipMask( const int mask ) { clipMask = mask; fl.clipMaskSet = true; }
  569. int GetClipMask( void ) const { return clipMask; }
  570. void SetSelfCollision( const bool enable ) { fl.selfCollision = enable; }
  571. void SetWorldOrigin( const idVec3 &origin ) { current->worldOrigin = origin; }
  572. void SetWorldAxis( const idMat3 &axis ) { current->worldAxis = axis; }
  573. void SetLinearVelocity( const idVec3 &linear ) const { current->spatialVelocity.SubVec3(0) = linear; }
  574. void SetAngularVelocity( const idVec3 &angular ) const { current->spatialVelocity.SubVec3(1) = angular; }
  575. void SetFriction( float linear, float angular, float contact );
  576. float GetContactFriction( void ) const { return contactFriction; }
  577. void SetBouncyness( float bounce );
  578. float GetBouncyness( void ) const { return bouncyness; }
  579. void SetDensity( float density, const idMat3 &inertiaScale = mat3_identity );
  580. float GetInverseMass( void ) const { return invMass; }
  581. idMat3 GetInverseWorldInertia( void ) const { return current->worldAxis.Transpose() * inverseInertiaTensor * current->worldAxis; }
  582. void SetFrictionDirection( const idVec3 &dir );
  583. bool GetFrictionDirection( idVec3 &dir ) const;
  584. void SetContactMotorDirection( const idVec3 &dir );
  585. bool GetContactMotorDirection( idVec3 &dir ) const;
  586. void SetContactMotorVelocity( float vel ) { contactMotorVelocity = vel; }
  587. float GetContactMotorVelocity( void ) const { return contactMotorVelocity; }
  588. void SetContactMotorForce( float force ) { contactMotorForce = force; }
  589. float GetContactMotorForce( void ) const { return contactMotorForce; }
  590. void AddForce( const idVec3 &point, const idVec3 &force );
  591. void InverseWorldSpatialInertiaMultiply( idVecX &dst, const float *v ) const;
  592. idVec6 & GetResponseForce( int index ) { return reinterpret_cast<idVec6 &>(response[ index * 8 ]); }
  593. void Save( idSaveGame *saveFile );
  594. void Restore( idRestoreGame *saveFile );
  595. private:
  596. // properties
  597. idStr name; // name of body
  598. idAFBody * parent; // parent of this body
  599. idList<idAFBody *> children; // children of this body
  600. idClipModel * clipModel; // model used for collision detection
  601. idAFConstraint * primaryConstraint; // primary constraint (this->constraint->body1 = this)
  602. idList<idAFConstraint *>constraints; // all constraints attached to this body
  603. idAFTree * tree; // tree structure this body is part of
  604. float linearFriction; // translational friction
  605. float angularFriction; // rotational friction
  606. float contactFriction; // friction with contact surfaces
  607. float bouncyness; // bounce
  608. int clipMask; // contents this body collides with
  609. idVec3 frictionDir; // specifies a single direction of friction in body space
  610. idVec3 contactMotorDir; // contact motor direction
  611. float contactMotorVelocity; // contact motor velocity
  612. float contactMotorForce; // maximum force applied to reach the motor velocity
  613. // derived properties
  614. float mass; // mass of body
  615. float invMass; // inverse mass
  616. idVec3 centerOfMass; // center of mass of body
  617. idMat3 inertiaTensor; // inertia tensor
  618. idMat3 inverseInertiaTensor; // inverse inertia tensor
  619. // physics state
  620. AFBodyPState_t state[2];
  621. AFBodyPState_t * current; // current physics state
  622. AFBodyPState_t * next; // next physics state
  623. AFBodyPState_t saved; // saved physics state
  624. idVec3 atRestOrigin; // origin at rest
  625. idMat3 atRestAxis; // axis at rest
  626. // simulation variables used during calculations
  627. idMatX inverseWorldSpatialInertia; // inverse spatial inertia in world space
  628. idMatX I, invI; // transformed inertia
  629. idMatX J; // transformed constraint matrix
  630. idVecX s; // temp solution
  631. idVecX totalForce; // total force acting on body
  632. idVecX auxForce; // force from auxiliary constraints
  633. idVecX acceleration; // acceleration
  634. float * response; // forces on body in response to auxiliary constraint forces
  635. int * responseIndex; // index to response forces
  636. int numResponses; // number of response forces
  637. int maxAuxiliaryIndex; // largest index of an auxiliary constraint constraining this body
  638. int maxSubTreeAuxiliaryIndex; // largest index of an auxiliary constraint constraining this body or one of it's children
  639. struct bodyFlags_s {
  640. bool clipMaskSet : 1; // true if this body has a clip mask set
  641. bool selfCollision : 1; // true if this body can collide with other bodies of this AF
  642. bool spatialInertiaSparse: 1; // true if the spatial inertia matrix is sparse
  643. bool useFrictionDir : 1; // true if a single friction direction should be used
  644. bool useContactMotorDir : 1; // true if a contact motor should be used
  645. bool isZero : 1; // true if 's' is zero during calculations
  646. } fl;
  647. };
  648. //===============================================================
  649. //
  650. // idAFTree
  651. //
  652. //===============================================================
  653. class idAFTree {
  654. friend class idPhysics_AF;
  655. public:
  656. void Factor( void ) const;
  657. void Solve( int auxiliaryIndex = 0 ) const;
  658. void Response( const idAFConstraint *constraint, int row, int auxiliaryIndex ) const;
  659. void CalculateForces( float timeStep ) const;
  660. void SetMaxSubTreeAuxiliaryIndex( void );
  661. void SortBodies( void );
  662. void SortBodies_r( idList<idAFBody*>&sortedList, idAFBody *body );
  663. void DebugDraw( const idVec4 &color ) const;
  664. private:
  665. idList<idAFBody *> sortedBodies;
  666. };
  667. //===============================================================
  668. //
  669. // idPhysics_AF
  670. //
  671. //===============================================================
  672. typedef struct AFPState_s {
  673. int atRest; // >= 0 if articulated figure is at rest
  674. float noMoveTime; // time the articulated figure is hardly moving
  675. float activateTime; // time since last activation
  676. float lastTimeStep; // last time step
  677. idVec6 pushVelocity; // velocity with which the af is pushed
  678. } AFPState_t;
  679. typedef struct AFCollision_s {
  680. trace_t trace;
  681. idAFBody * body;
  682. } AFCollision_t;
  683. class idPhysics_AF : public idPhysics_Base {
  684. public:
  685. CLASS_PROTOTYPE( idPhysics_AF );
  686. idPhysics_AF( void );
  687. ~idPhysics_AF( void );
  688. void Save( idSaveGame *savefile ) const;
  689. void Restore( idRestoreGame *savefile );
  690. // initialisation
  691. int AddBody( idAFBody *body ); // returns body id
  692. void AddConstraint( idAFConstraint *constraint );
  693. void AddFrameConstraint( idAFConstraint *constraint );
  694. // force a body to have a certain id
  695. void ForceBodyId( idAFBody *body, int newId );
  696. // get body or constraint id
  697. int GetBodyId( idAFBody *body ) const;
  698. int GetBodyId( const char *bodyName ) const;
  699. int GetConstraintId( idAFConstraint *constraint ) const;
  700. int GetConstraintId( const char *constraintName ) const;
  701. // number of bodies and constraints
  702. int GetNumBodies( void ) const;
  703. int GetNumConstraints( void ) const;
  704. // retrieve body or constraint
  705. idAFBody * GetBody( const char *bodyName ) const;
  706. idAFBody * GetBody( const int id ) const;
  707. idAFBody * GetMasterBody( void ) const { return masterBody; }
  708. idAFConstraint * GetConstraint( const char *constraintName ) const;
  709. idAFConstraint * GetConstraint( const int id ) const;
  710. // delete body or constraint
  711. void DeleteBody( const char *bodyName );
  712. void DeleteBody( const int id );
  713. void DeleteConstraint( const char *constraintName );
  714. void DeleteConstraint( const int id );
  715. // get all the contact constraints acting on the body
  716. int GetBodyContactConstraints( const int id, idAFConstraint_Contact *contacts[], int maxContacts ) const;
  717. // set the default friction for bodies
  718. void SetDefaultFriction( float linear, float angular, float contact );
  719. // suspend settings
  720. void SetSuspendSpeed( const idVec2 &velocity, const idVec2 &acceleration );
  721. // set the time and tolerances used to determine if the simulation can be suspended when the figure hardly moves for a while
  722. void SetSuspendTolerance( const float noMoveTime, const float translationTolerance, const float rotationTolerance );
  723. // set minimum and maximum simulation time in seconds
  724. void SetSuspendTime( const float minTime, const float maxTime );
  725. // set the time scale value
  726. void SetTimeScale( const float ts ) { timeScale = ts; }
  727. // set time scale ramp
  728. void SetTimeScaleRamp( const float start, const float end );
  729. // set the joint friction scale
  730. void SetJointFrictionScale( const float scale ) { jointFrictionScale = scale; }
  731. // set joint friction dent
  732. void SetJointFrictionDent( const float dent, const float start, const float end );
  733. // get the current joint friction scale
  734. float GetJointFrictionScale( void ) const;
  735. // set the contact friction scale
  736. void SetContactFrictionScale( const float scale ) { contactFrictionScale = scale; }
  737. // set contact friction dent
  738. void SetContactFrictionDent( const float dent, const float start, const float end );
  739. // get the current contact friction scale
  740. float GetContactFrictionScale( void ) const;
  741. // enable or disable collision detection
  742. void SetCollision( const bool enable ) { enableCollision = enable; }
  743. // enable or disable self collision
  744. void SetSelfCollision( const bool enable ) { selfCollision = enable; }
  745. // enable or disable coming to a dead stop
  746. void SetComeToRest( bool enable ) { comeToRest = enable; }
  747. // call when structure of articulated figure changes
  748. void SetChanged( void ) { changedAF = true; }
  749. // enable/disable activation by impact
  750. void EnableImpact( void );
  751. void DisableImpact( void );
  752. // lock of unlock the world constraints
  753. void LockWorldConstraints( const bool lock ) { worldConstraintsLocked = lock; }
  754. // set force pushable
  755. void SetForcePushable( const bool enable ) { forcePushable = enable; }
  756. // update the clip model positions
  757. void UpdateClipModels( void );
  758. public: // common physics interface
  759. void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true );
  760. idClipModel * GetClipModel( int id = 0 ) const;
  761. int GetNumClipModels( void ) const;
  762. void SetMass( float mass, int id = -1 );
  763. float GetMass( int id = -1 ) const;
  764. void SetContents( int contents, int id = -1 );
  765. int GetContents( int id = -1 ) const;
  766. const idBounds & GetBounds( int id = -1 ) const;
  767. const idBounds & GetAbsBounds( int id = -1 ) const;
  768. bool Evaluate( int timeStepMSec, int endTimeMSec );
  769. void UpdateTime( int endTimeMSec );
  770. int GetTime( void ) const;
  771. void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const;
  772. void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse );
  773. void AddForce( const int id, const idVec3 &point, const idVec3 &force );
  774. bool IsAtRest( void ) const;
  775. int GetRestStartTime( void ) const;
  776. void Activate( void );
  777. void PutToRest( void );
  778. bool IsPushable( void ) const;
  779. void SaveState( void );
  780. void RestoreState( void );
  781. void SetOrigin( const idVec3 &newOrigin, int id = -1 );
  782. void SetAxis( const idMat3 &newAxis, int id = -1 );
  783. void Translate( const idVec3 &translation, int id = -1 );
  784. void Rotate( const idRotation &rotation, int id = -1 );
  785. const idVec3 & GetOrigin( int id = 0 ) const;
  786. const idMat3 & GetAxis( int id = 0 ) const;
  787. void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 );
  788. void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 );
  789. const idVec3 & GetLinearVelocity( int id = 0 ) const;
  790. const idVec3 & GetAngularVelocity( int id = 0 ) const;
  791. void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const;
  792. void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const;
  793. int ClipContents( const idClipModel *model ) const;
  794. void DisableClip( void );
  795. void EnableClip( void );
  796. void UnlinkClip( void );
  797. void LinkClip( void );
  798. bool EvaluateContacts( void );
  799. void SetPushed( int deltaTime );
  800. const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const;
  801. const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const;
  802. void SetMaster( idEntity *master, const bool orientated = true );
  803. void WriteToSnapshot( idBitMsgDelta &msg ) const;
  804. void ReadFromSnapshot( const idBitMsgDelta &msg );
  805. private:
  806. // articulated figure
  807. idList<idAFTree *> trees; // tree structures
  808. idList<idAFBody *> bodies; // all bodies
  809. idList<idAFConstraint *>constraints; // all frame independent constraints
  810. idList<idAFConstraint *>primaryConstraints; // list with primary constraints
  811. idList<idAFConstraint *>auxiliaryConstraints; // list with auxiliary constraints
  812. idList<idAFConstraint *>frameConstraints; // constraints that only live one frame
  813. idList<idAFConstraint_Contact *>contactConstraints; // contact constraints
  814. idList<int> contactBodies; // body id for each contact
  815. idList<AFCollision_t> collisions; // collisions
  816. bool changedAF; // true when the articulated figure just changed
  817. // properties
  818. float linearFriction; // default translational friction
  819. float angularFriction; // default rotational friction
  820. float contactFriction; // default friction with contact surfaces
  821. float bouncyness; // default bouncyness
  822. float totalMass; // total mass of articulated figure
  823. float forceTotalMass; // force this total mass
  824. idVec2 suspendVelocity; // simulation may not be suspended if a body has more velocity
  825. idVec2 suspendAcceleration; // simulation may not be suspended if a body has more acceleration
  826. float noMoveTime; // suspend simulation if hardly any movement for this many seconds
  827. float noMoveTranslation; // maximum translation considered no movement
  828. float noMoveRotation; // maximum rotation considered no movement
  829. float minMoveTime; // if > 0 the simulation is never suspended before running this many seconds
  830. float maxMoveTime; // if > 0 the simulation is always suspeded after running this many seconds
  831. float impulseThreshold; // threshold below which impulses are ignored to avoid continuous activation
  832. float timeScale; // the time is scaled with this value for slow motion effects
  833. float timeScaleRampStart; // start of time scale change
  834. float timeScaleRampEnd; // end of time scale change
  835. float jointFrictionScale; // joint friction scale
  836. float jointFrictionDent; // joint friction dives from 1 to this value and goes up again
  837. float jointFrictionDentStart; // start time of joint friction dent
  838. float jointFrictionDentEnd; // end time of joint friction dent
  839. float jointFrictionDentScale; // dent scale
  840. float contactFrictionScale; // contact friction scale
  841. float contactFrictionDent; // contact friction dives from 1 to this value and goes up again
  842. float contactFrictionDentStart; // start time of contact friction dent
  843. float contactFrictionDentEnd; // end time of contact friction dent
  844. float contactFrictionDentScale; // dent scale
  845. bool enableCollision; // if true collision detection is enabled
  846. bool selfCollision; // if true the self collision is allowed
  847. bool comeToRest; // if true the figure can come to rest
  848. bool linearTime; // if true use the linear time algorithm
  849. bool noImpact; // if true do not activate when another object collides
  850. bool worldConstraintsLocked; // if true world constraints cannot be moved
  851. bool forcePushable; // if true can be pushed even when bound to a master
  852. // physics state
  853. AFPState_t current;
  854. AFPState_t saved;
  855. idAFBody * masterBody; // master body
  856. idLCP * lcp; // linear complementarity problem solver
  857. private:
  858. void BuildTrees( void );
  859. bool IsClosedLoop( const idAFBody *body1, const idAFBody *body2 ) const;
  860. void PrimaryFactor( void );
  861. void EvaluateBodies( float timeStep );
  862. void EvaluateConstraints( float timeStep );
  863. void AddFrameConstraints( void );
  864. void RemoveFrameConstraints( void );
  865. void ApplyFriction( float timeStep, float endTimeMSec );
  866. void PrimaryForces( float timeStep );
  867. void AuxiliaryForces( float timeStep );
  868. void VerifyContactConstraints( void );
  869. void SetupContactConstraints( void );
  870. void ApplyContactForces( void );
  871. void Evolve( float timeStep );
  872. idEntity * SetupCollisionForBody( idAFBody *body ) const;
  873. bool CollisionImpulse( float timeStep, idAFBody *body, trace_t &collision );
  874. bool ApplyCollisions( float timeStep );
  875. void CheckForCollisions( float timeStep );
  876. void ClearExternalForce( void );
  877. void AddGravity( void );
  878. void SwapStates( void );
  879. bool TestIfAtRest( float timeStep );
  880. void Rest( void );
  881. void AddPushVelocity( const idVec6 &pushVelocity );
  882. void DebugDraw( void );
  883. };
  884. #endif /* !__PHYSICS_AF_H__ */