2
0

phys3.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  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/phys3.h $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 10/24/01 11:15a $*
  29. * *
  30. * $Revision:: 46 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if defined(_MSC_VER)
  36. #pragma once
  37. #endif
  38. #ifndef PHYS3_H
  39. #define PHYS3_H
  40. #include "vector3.h"
  41. #include "movephys.h"
  42. #include "ode.h"
  43. class Phys3DefClass;
  44. class Phys3HistoryClass;
  45. /**
  46. ** Phys3Class
  47. ** 3 Degree of Freedom Physics
  48. ** This object can translate in X,Y,and Z. It will be represented
  49. ** in the world by an axis-aligned box.
  50. */
  51. class Phys3Class : public MoveablePhysClass
  52. {
  53. public:
  54. Phys3Class(void);
  55. virtual ~Phys3Class(void);
  56. virtual Phys3Class * As_Phys3Class(void) { return this; }
  57. void Init(const Phys3DefClass & def);
  58. virtual const AABoxClass & Get_Bounding_Box(void) const;
  59. virtual const Matrix3D & Get_Transform(void) const;
  60. virtual void Set_Transform(const Matrix3D & m);
  61. virtual const AABoxClass & Get_Collision_Box(void) const { return CollisionBox; }
  62. virtual bool Cast_Ray(PhysRayCollisionTestClass & raytest);
  63. virtual bool Cast_AABox(PhysAABoxCollisionTestClass & boxtest);
  64. virtual bool Cast_OBBox(PhysOBBoxCollisionTestClass & boxtest);
  65. virtual bool Intersection_Test(PhysAABoxIntersectionTestClass & test);
  66. virtual bool Intersection_Test(PhysOBBoxIntersectionTestClass & test);
  67. virtual bool Intersection_Test(PhysMeshIntersectionTestClass & test);
  68. virtual void Set_Model(RenderObjClass * model);
  69. virtual void Get_Velocity(Vector3 * set_vel) const;
  70. virtual void Set_Velocity(const Vector3 & newvel);
  71. virtual void Apply_Impulse(const Vector3 & imp);
  72. virtual void Apply_Impulse(const Vector3 & imp, const Vector3 & wpos);
  73. virtual void Timestep(float dt);
  74. virtual bool Is_In_Contact(void) const { return OnGround; }
  75. // Set_In_Contact needed for network state updates so we don't have to wait for Check_Ground
  76. virtual void Set_In_Contact( bool onoff ) { OnGround = onoff; }
  77. virtual int Get_Contact_Surface_Type(void) { return GroundSurface; }
  78. virtual void Invalidate_Ground_State(void);
  79. PhysClass * Peek_Ground_Object(void) { return GroundState.GroundObject; }
  80. void Assert_State_Valid(void);
  81. /*
  82. ** Teleport support
  83. */
  84. virtual bool Can_Teleport(const Matrix3D &new_tm,bool check_dyn_only = false,NonRefPhysListClass * result_list = NULL);
  85. virtual bool Can_Teleport_And_Stand(const Matrix3D &new_tm, Matrix3D *out);
  86. virtual bool Find_Teleport_Location(const Vector3 &start, float radius, Vector3 *out);
  87. virtual bool Can_Move_To(const Matrix3D &new_tm);
  88. /*
  89. ** Phys3 movement controls
  90. */
  91. virtual void Set_Position(const Vector3 & position);
  92. virtual const Vector3 & Get_Position(void) const;
  93. virtual void Set_Heading(float heading);
  94. virtual float Get_Heading(void) const;
  95. virtual void Set_Slide_Angle(float angle);
  96. virtual float Get_Slide_Angle(void) const;
  97. virtual void Set_Normalized_Speed(float val) { NormSpeed = val; }
  98. virtual float Get_Normalized_Speed(void) const { return NormSpeed; }
  99. void Add_Animation_Move(const Vector3 & move) { AnimationMove += move; }
  100. void Get_Animation_Move(Vector3 * set_move) { *set_move = AnimationMove; }
  101. void Reset_Animation_Move(void) { AnimationMove.Set(0,0,0); }
  102. /*
  103. ** Shadow support
  104. */
  105. virtual void Get_Shadow_Blob_Box(AABoxClass * set_obj_space_box);
  106. void Get_Collision_Box(AABoxClass * set_box);
  107. /*
  108. ** MoveablePhysClass Push interface. Phys3's try to move when they are pushed.
  109. */
  110. virtual bool Push(const Vector3 & move);
  111. virtual bool Collide(const Vector3 & move);
  112. /*
  113. ** Network state updates
  114. */
  115. void Network_State_Update( const Vector3 & pos,
  116. const Vector3 & vel);
  117. void Network_Latency_State_Update( const Vector3 & pos,
  118. const Vector3 & vel);
  119. static void Set_Correction_Time(float time) { _CorrectionTime = time; }
  120. static void Set_Allowable_Error(float err) { _AllowableError = err; }
  121. static void Set_Pop_Error(float err) { _PopError = err; }
  122. static float Get_Correction_Time(void) { return _CorrectionTime; }
  123. static float Get_Allowable_Error(void) { return _AllowableError; }
  124. static float Get_Pop_Error(void) { return _PopError; }
  125. /*
  126. ** Save-Load system
  127. */
  128. virtual const PersistFactoryClass & Get_Factory (void) const;
  129. virtual bool Save (ChunkSaveClass &csave);
  130. virtual bool Load (ChunkLoadClass &cload);
  131. virtual void On_Post_Load(void);
  132. protected:
  133. /*
  134. ** GroundStateStruct status of the object's contact with the ground
  135. */
  136. struct GroundStateStruct
  137. {
  138. GroundStateStruct(void);
  139. void Reset(void);
  140. void Init_From_Collision_Result(PhysAABoxCollisionTestClass & test,float height);
  141. bool IsDirty; // data contained within is invalid
  142. bool OnGround; // indicates whether the object is "on the ground"
  143. bool OnDynamicObj; // must "dirty" the groundstate at end of frame if we're on a dyn obj
  144. int SurfaceType; // surface type the object is resting on
  145. float Height; // our height above the ground
  146. Vector3 Normal; // normal for the surface
  147. Vector3 Down; // slide direction for the surface
  148. PhysClass * GroundObject; // pointer to the object we are on
  149. RenderObjClass * GroundRenderObject;
  150. };
  151. /*
  152. ** State of a Phys3 object
  153. */
  154. struct StateStruct
  155. {
  156. StateStruct(void);
  157. StateStruct(const StateStruct & that);
  158. StateStruct & operator = (const StateStruct & that);
  159. Vector3 Position;
  160. Vector3 Velocity;
  161. };
  162. /*
  163. ** Phys3 Movement algorithm
  164. */
  165. virtual GroundStateStruct & Get_Ground_State(void);
  166. virtual void Check_Ground(const AABoxClass & box,GroundStateStruct * gs,float check_dist);
  167. virtual bool User_Move(float dt);
  168. virtual bool Ballistic_Move(float dt);
  169. virtual bool Slide_Move(const GroundStateStruct & gs,float dt);
  170. virtual bool Normal_Move(const GroundStateStruct & gs,float dt);
  171. virtual bool Collide_Move(const Vector3 & requested_move,float dt);
  172. bool Apply_Move(const Vector3 & move,float dt,bool allow_sliding = true,bool allow_stepping = false,bool stop_on_walkable = false);
  173. void Snap_To_Ground(const Vector3 & actual_move,bool was_stepping);
  174. void Clip_Move(const Vector3 * contacts,int contact_count,Vector3 * move);
  175. void Attach_To_Ground_Object(void);
  176. /*
  177. ** Internal functions
  178. */
  179. void Update_Cached_Model_Parameters(void);
  180. void Update_Transform(bool position_only = false);
  181. void Compute_WS_Collision_Box(const StateStruct & state,AABoxClass * set_box);
  182. bool Debug_Verify_Position(void);
  183. void Network_Teleport_Correction(void);
  184. enum MoveModeType
  185. {
  186. USER_OVERRIDE = 0,
  187. BALLISTIC_MOVE,
  188. SLIDE_MOVE,
  189. NORMAL_MOVE,
  190. COLLIDE_MOVE
  191. };
  192. /*
  193. ** Members
  194. */
  195. AABoxClass CollisionBox; // object space collision box
  196. bool OnGround; // flag indicates whether object is resting on something
  197. bool InCollision; // this object is already participating in a collision
  198. bool HeadingChanged; // If the heading changes, transform will be updated on next timestep
  199. int GroundSurface; // surface type id of the ground we're standing on.
  200. StateStruct State; // state vector
  201. float Heading; // heading, a move of 1,0,0 will move in this direction.
  202. float NormSpeed; // speed to move when controller is 1.0
  203. float SlideAngle; // slope angle at which this object slides off
  204. float SlideNormalZ; // cos(SlideAngle)
  205. float SlideAngleTan; // tan(SlideAngle)
  206. float StepHeight; // step side that this object will hop over
  207. MoveModeType MoveMode; // current movement mode
  208. PhysClass * GroundObject; // object that we are standing on
  209. GroundStateStruct GroundState; // info on the surface we're standing on (if any)
  210. Vector3 AnimationMove; // how far this object moved for animation purposes
  211. Phys3HistoryClass * History; // history of our state for smarter network updating
  212. Vector3 LatencyError; // remaining latency error
  213. Vector3 LastKnownPosition;// last position received from server
  214. Vector3 LastKnownVelocity;// last velocity received from server
  215. static float _CorrectionTime; // Network correction handling constants
  216. static float _AllowableError;
  217. static float _PopError;
  218. private:
  219. // not implemented
  220. Phys3Class(const Phys3Class &);
  221. Phys3Class & operator = (const Phys3Class &);
  222. };
  223. inline void Phys3Class::Get_Velocity(Vector3 * set_vel) const
  224. {
  225. *set_vel = State.Velocity;
  226. }
  227. inline void Phys3Class::Set_Velocity(const Vector3 & newvel)
  228. {
  229. State.Velocity = newvel;
  230. }
  231. inline void Phys3Class::Compute_WS_Collision_Box(const StateStruct & state,AABoxClass * set_box)
  232. {
  233. set_box->Center = CollisionBox.Center + state.Position;
  234. set_box->Extent = CollisionBox.Extent;
  235. }
  236. inline Phys3Class::StateStruct::StateStruct(void) :
  237. Position(0,0,0),
  238. Velocity(0,0,0)
  239. {
  240. }
  241. inline Phys3Class::StateStruct::StateStruct(const StateStruct & that)
  242. {
  243. *this = that;
  244. }
  245. inline
  246. Phys3Class::StateStruct &
  247. Phys3Class::StateStruct::operator = (const StateStruct & that)
  248. {
  249. Position = that.Position;
  250. Velocity = that.Velocity;
  251. return *this;
  252. }
  253. /**
  254. ** Phys3DefClass
  255. ** Initialization/Game-Database support for Phys3Class
  256. */
  257. class Phys3DefClass : public MoveablePhysDefClass
  258. {
  259. public:
  260. Phys3DefClass(void);
  261. // From Definition
  262. virtual uint32 Get_Class_ID (void) const;
  263. virtual PersistClass * Create(void) const;
  264. // From PhysDefClass
  265. virtual const char * Get_Type_Name(void) { return "Phys3Def"; }
  266. virtual bool Is_Type(const char *);
  267. // From PersistClass
  268. virtual const PersistFactoryClass & Get_Factory (void) const;
  269. virtual bool Save(ChunkSaveClass &csave);
  270. virtual bool Load(ChunkLoadClass &cload);
  271. // Editable interface requirements
  272. DECLARE_EDITABLE(Phys3DefClass,MoveablePhysDefClass);
  273. protected:
  274. float NormSpeed; // speed to move when controller is 1.0
  275. float SlideAngle; // slope angle at which this object slides off
  276. float StepHeight; // step side that this object will hop over
  277. friend class Phys3Class;
  278. };
  279. #endif