wheel.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program 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. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWPhys *
  23. * *
  24. * $Archive:: /Commando/Code/wwphys/wheel.h $*
  25. * *
  26. * Original Author:: Greg Hjelstrom *
  27. * *
  28. * $Author:: Greg_h $*
  29. * *
  30. * $Modtime:: 11/19/01 3:47p $*
  31. * *
  32. * $Revision:: 13 $*
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  37. #ifndef WHEEL_H
  38. #define WHEEL_H
  39. #include "vector3.h"
  40. #include "matrix3d.h"
  41. class VehiclePhysClass;
  42. class RenderObjClass;
  43. /*
  44. ** Some default suspension constants
  45. */
  46. const float DEFAULT_SPRING_CONSTANT = 3.0f;
  47. const float DEFAULT_DAMPING_COEFFICIENT = 0.75f;
  48. const float DEFAULT_SPRING_LENGTH = 1.0f;
  49. /**
  50. ** Wheels. An instance of a wheel object will contain information on each
  51. ** wheel detected in the vehicle model. Wheels use a pair of named bones.
  52. ** The "position" bone is used to move the wheel up and down according to
  53. ** the suspension system and to rotate if this is a "steering" wheel. The
  54. ** "rotation" bone is used to roll the wheel on the terrain.
  55. **
  56. ** More Info on the "Position" and "Center" bones:
  57. ** - The "center" bone is only used in computing the radius of the wheel and
  58. ** it is rotated about its z-axis to make the wheel appear to roll
  59. ** - The "position" bone is used in conjunction with the length parameter
  60. ** to define the suspension springs.
  61. **
  62. ** Defining the "spring-segment" using the position bone:
  63. ** - The default location of the position bone is considered the point of maximum-
  64. ** compression. (this point should be *inside* the collision box for the model!)
  65. ** - The spring will extend down the -z axis in the position bone's coordinate system
  66. **
  67. ** Graphical constraints for the wheel
  68. ** - One of three methods can be used to graphically constrain the wheel with the
  69. ** ground: Translation along the z-axis of the position bone, or rotation of
  70. ** a rotation constraint bone.
  71. ** - Normal case: There are two bones for the wheel: position and center. The position
  72. ** bone is moved along its Z-axis to the point of collision with the ground
  73. ** - Translation: There is an additional translation bone (WheelTxx) which defines
  74. ** the axis that the wheel is to be translated along.
  75. ** - Fork/Rotation: a "fork" bone (WheelFxx) is rotated such that the Z-coordinate (in
  76. ** the fork's coordinate system) meets the ground.
  77. **
  78. ** Wheel Flags:
  79. ** - 'E' Engine. this wheel is connected to the engine and should exert its force
  80. ** - 'S' Steering: The position bone for this wheel rotates about its Z-axis for steering
  81. ** - 's' Inverse Steering: The position bone for this wheel rotates the opposite way
  82. ** - 'L' Left Track: this wheel is part of the left track of a tracked vehicle
  83. ** - 'R' Right Track: this wheel is part of the right track of a tracked vehicle
  84. ** - 'F' Fake: just move, don't compute any forces
  85. */
  86. /**
  87. ** SuspensionElementClass
  88. ** This class only has the functionality of a support strut with a contact point. Derived
  89. ** wheel classes add in the forces exerted at the contact patch.
  90. */
  91. class SuspensionElementClass
  92. {
  93. public:
  94. enum FlagsType
  95. {
  96. FAKE = 0x0001, // this wheel is for looks only (e.g. some of the tank wheels)
  97. STEERING = 0x0002, // this wheel turns with the steering input
  98. INV_STEERING = 0x0004, // this wheel turns opposite of the steering input
  99. TILT_STEERING = 0x0008, // this wheel turns with tilt abount the X axis of the vehicle (bikes).
  100. ENGINE = 0x0010, // this wheel exerts the engine force
  101. LEFT_TRACK = 0x0020, // this wheel is part of the left track of a tank
  102. RIGHT_TRACK = 0x0040, // this wheel is part of the right track of a tank
  103. DISABLED = 0x0100, // this wheel is disabled
  104. INCONTACT = 0x0200, // this wheel is in contact with the ground
  105. BRAKING = 0x0400, // this wheel is undergoing braking
  106. DEFAULT_FLAGS = 0
  107. };
  108. SuspensionElementClass(void);
  109. virtual ~SuspensionElementClass(void);
  110. virtual void Init(VehiclePhysClass * obj,int pbone,int rbone,int forkbone,int axisbone);
  111. /*
  112. ** Accessors to properties
  113. */
  114. bool Get_Flag(FlagsType flag) { return ((Flags & flag) == flag); }
  115. void Set_Flag(FlagsType flag,bool onoff) { (onoff ? Flags |= flag : Flags &= ~flag); }
  116. float Get_Spring_Constant(void) { return SpringConstant; }
  117. void Set_Spring_Constant(float k) { SpringConstant = k; }
  118. float Get_Damping_Coefficient(void) { return DampingCoefficient; }
  119. void Set_Damping_Coefficient(float k) { DampingCoefficient = k; }
  120. float Get_Spring_Length(void) { return SpringLength; }
  121. void Set_Spring_Length(float len) { SpringLength = len; }
  122. /*
  123. ** Inputs from the parent object
  124. */
  125. float Get_Steering_Angle(void) { return SteeringAngle; }
  126. void Set_Steering_Angle(float angle) { SteeringAngle = angle; }
  127. /*
  128. ** Accessors to state variables
  129. */
  130. void Get_Wheel_Position(Vector3 * set_pos) { WheelTM.Get_Translation(set_pos); }
  131. int Get_Contact_Surface(void) const { return ContactSurface; }
  132. const Vector3 &Get_Contact_Point(void) const { return Contact; }
  133. const Vector3 &Get_Contact_Normal(void) const { return Normal; }
  134. const Matrix3D&Get_Wheel_Transform(void) const { return WheelTM; }
  135. virtual float Get_Slip_Factor(void) const { return 1.0f; }
  136. virtual float Get_Rotation_Delta(void) const { return 0.0f; }
  137. /*
  138. ** Physics processing
  139. */
  140. virtual void Compute_Force_And_Torque(Vector3 * force,Vector3 * torque) = 0;
  141. virtual void Update_Model(void);
  142. virtual void Non_Physical_Update(float suspension_fraction,float rotation);
  143. protected:
  144. /*
  145. ** Internal functions
  146. */
  147. void Intersect_Spring(void);
  148. void Non_Physical_Intersect_Spring(float suspension_fraction);
  149. void Translate_Wheel(RenderObjClass * model);
  150. void Translate_Wheel_On_Axis(RenderObjClass * model);
  151. void Rotate_Fork(RenderObjClass * model);
  152. /*
  153. ** Properties
  154. */
  155. VehiclePhysClass * Parent; // Vehicle I am attached to.
  156. int Flags; // bit-field of flags used by this and derived classes
  157. int PositionBone; // Bone index of the position bone (wheel coordinate system)
  158. int ForkBone; // Bone index for the "fork" constraint (if not -1, we use fork constraints)
  159. int AxisBone; // Bone index for the translation axis bone (if not -1, we translate on its z-axis instead)
  160. Matrix3D ObjWheelTM; // Wheel coordinate system in object-space
  161. float SpringConstant; // spring
  162. float DampingCoefficient; // shock absorber
  163. float SpringLength; // unstretched/compressed length
  164. /*
  165. ** Inputs
  166. */
  167. float SteeringAngle; // current steering angle
  168. /*
  169. ** State
  170. */
  171. Vector3 SuspensionForce; // current suspension force
  172. Matrix3D WheelTM; // current wheel coordinate system (positioned at contact point)
  173. Vector3 WheelP0; // current position of the top of the spring
  174. Vector3 Contact; // current contact point (only valid if INCONTACT is true)
  175. Vector3 Normal; // current contact normal (only valid if INCONTACT is true)
  176. int ContactSurface; // current contact surface (only valid if INCONTACT is true)
  177. /*
  178. ** Visual State
  179. */
  180. Vector3 LastPoint; // last position of the wheel (for rolling)
  181. /*
  182. ** Constraint variables
  183. */
  184. float TranslationScale;
  185. Vector3 ObjAxis; // axis used for wheels with an overridden translation axis
  186. Matrix3D ObjForkTM; // these are constants used for "fork" constrained wheels
  187. float ForkLength; // I'm calling the back wheel of a motorcycle a "fork" this
  188. float ForkZ; // is not the best name... Its more like an "arm"
  189. float ForkSin0; // These constants are all used in the equation to determine
  190. float ForkCos0; // how far to rotate the "arm" or "fork" in order for the
  191. float ForkA; // wheel to touch the ground.
  192. float ForkB;
  193. /*
  194. ** The latest known location of the spring end points - this is used to determine if the spring has moved
  195. */
  196. Vector3 SpringEndP1;
  197. Vector3 SpringEndP0;
  198. private:
  199. // not implemented
  200. SuspensionElementClass(const SuspensionElementClass & that);
  201. SuspensionElementClass & operator = (const SuspensionElementClass & that);
  202. };
  203. /**
  204. ** WheelClass
  205. ** This class adds code which is common to all rolling wheels. It adds a wheel radius
  206. ** and wheel rotation variables.
  207. */
  208. class WheelClass : public SuspensionElementClass
  209. {
  210. public:
  211. WheelClass(void);
  212. virtual ~WheelClass(void);
  213. virtual void Init(VehiclePhysClass * obj,int postion_bone,int rotation_bone=-1,int fork_bone=-1,int axis_bone=-1);
  214. virtual void Compute_Force_And_Torque(Vector3 * force,Vector3 * torque);
  215. /*
  216. ** Accessors
  217. */
  218. bool Is_Drive_Wheel(void) { return (Get_Flag(ENGINE)||Get_Flag(LEFT_TRACK)||Get_Flag(RIGHT_TRACK)); }
  219. float Get_Slip_Factor(void) const { return SlipFactor; }
  220. float Get_Rotation_Delta(void) const { return RotationDelta; }
  221. float Get_Ideal_Drive_Wheel_Angular_Velocity(float max_avel);
  222. float Get_Radius(void) const { return Radius; }
  223. /*
  224. ** Inputs
  225. */
  226. float Get_Axle_Torque(void) { return AxleTorque; }
  227. void Set_Axle_Torque(float torque) { AxleTorque = torque; }
  228. protected:
  229. /*
  230. ** Component functions for Compute_Force_And_Torque
  231. */
  232. void Compute_Suspension_Force(const Vector3 & pdot,const Vector3 & local_pdot,Vector3 * suspension_force);
  233. void Apply_Forces(Vector3 * force,Vector3 * torque);
  234. /*
  235. ** Derived wheel classes implement this to compute the traction forces
  236. */
  237. virtual void Compute_Traction_Forces(const Vector3 & local_pdot,float normal_force,float * set_lateral_force,float * set_tractive_force) = 0;
  238. /*
  239. ** Properties
  240. */
  241. float Radius; // radius of the wheel (for rolling)
  242. int RotationBone; // bone index of the rotation bone
  243. float Rotation; // amount the wheel has rolled.
  244. float RotationDelta; // so we can keep the wheel rolling in the air
  245. /*
  246. ** Inputs
  247. */
  248. float AxleTorque; // engine torque applied to the axle
  249. /*
  250. ** State
  251. */
  252. Vector3 TractiveFrictionForce; // current tractive friction force
  253. Vector3 LateralFrictionForce; // current lateral friction force
  254. float SlipFactor; // fraction of force "clipped" off to traction circle
  255. float IdealAngularVelocity; // non-slipping angular velocity (IF IN CONTACT)
  256. private:
  257. //not implemented
  258. WheelClass(const WheelClass & that);
  259. const WheelClass & operator = (const WheelClass & that);
  260. };
  261. /**
  262. ** WVWheelClass (Wheeled-Vehicle-Wheel)
  263. ** This wheel class is used by things like Humvees and Buggys.
  264. */
  265. class WVWheelClass : public WheelClass
  266. {
  267. public:
  268. WVWheelClass(void) { }
  269. virtual ~WVWheelClass(void) { }
  270. virtual void Update_Model(void);
  271. virtual void Non_Physical_Update(float suspension_fraction,float rotation);
  272. protected:
  273. virtual void Compute_Traction_Forces(const Vector3 & local_pdot,float normal_force,float * set_lateral_force,float * set_tractive_force);
  274. void Roll_Wheel(void);
  275. };
  276. /**
  277. ** TrackWheelClass
  278. ** This wheel type is used by TrackedVehicleClass. The differences between
  279. ** it and the WVWheelClass are minor, mainly in the logic for how the wheels
  280. ** roll and possibly the lack of a traction circle.
  281. */
  282. class TrackWheelClass : public WheelClass
  283. {
  284. public:
  285. TrackWheelClass(void) { }
  286. virtual ~TrackWheelClass(void) { }
  287. virtual void Update_Model(void);
  288. virtual void Non_Physical_Update(float suspension_fraction,float rotation);
  289. protected:
  290. virtual void Compute_Traction_Forces(const Vector3 & local_pdot,float normal_force,float * set_lateral_force,float * set_tractive_force);
  291. void Roll_Wheel(void);
  292. };
  293. /**
  294. ** VTOLWheelClass
  295. ** This wheel type is used by the VTOL vehicles. It simply resists movement in
  296. ** all directions and rolls depending on its motion (if it has a WheelC bone...)
  297. */
  298. class VTOLWheelClass : public WheelClass
  299. {
  300. public:
  301. VTOLWheelClass(void) { }
  302. virtual ~VTOLWheelClass(void) { }
  303. virtual void Update_Model(void);
  304. virtual void Non_Physical_Update(float suspension_fraction,float rotation);
  305. protected:
  306. virtual void Compute_Traction_Forces(const Vector3 & local_pdot,float normal_force,float * set_lateral_force,float * set_tractive_force);
  307. void Roll_Wheel(void);
  308. };
  309. #endif //WHEEL_H