phys.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  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/phys.h $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 3/08/02 5:01p $*
  29. * *
  30. * $Revision:: 89 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if defined(_MSC_VER)
  36. #pragma once
  37. #endif
  38. #ifndef PHYS_H
  39. #define PHYS_H
  40. #include "always.h"
  41. #include "refcount.h"
  42. #include "matrix3d.h"
  43. #include "physobserver.h"
  44. #include "cullsys.h"
  45. #include "rendobj.h"
  46. #include "widgetuser.h"
  47. #include "persist.h"
  48. #include "editable.h"
  49. #include "definition.h"
  50. #include "multilist.h"
  51. #include "phystexproject.h"
  52. #include "wwstring.h"
  53. #include "materialeffect.h"
  54. #include "materialeffectlist.h"
  55. #include "wwstring.h"
  56. #include "umbrasupport.h"
  57. class CullSystemClass;
  58. class CullLinkClass;
  59. class MonoClass;
  60. class AABoxClass;
  61. class CameraClass;
  62. class srScene;
  63. class srGERD;
  64. class RenderInfoClass;
  65. class SpecialRenderInfoClass;
  66. class PhysClass;
  67. class PhysRayCollisionTestClass;
  68. class PhysAABoxCollisionTestClass;
  69. class PhysOBBoxCollisionTestClass;
  70. class PhysAABoxIntersectionTestClass;
  71. class PhysOBBoxIntersectionTestClass;
  72. class PhysMeshIntersectionTestClass;
  73. class AABTreeNodeClass;
  74. class CullLinkClass;
  75. class BitStreamClass;
  76. class LightEnvironmentClass;
  77. class DynamicPhysClass;
  78. class MoveablePhysClass;
  79. class Phys3Class;
  80. class HumanPhysClass;
  81. class RigidBodyClass;
  82. class VehiclePhysClass;
  83. class MotorVehicleClass;
  84. class WheeledVehicleClass;
  85. class MotorcycleClass;
  86. class TrackedVehicleClass;
  87. class VTOLVehicleClass;
  88. class StaticPhysClass;
  89. class StaticAnimPhysClass;
  90. class RenderObjPhysClass;
  91. class DecorationPhysClass;
  92. class TimedDecorationPhysClass;
  93. class DynamicAnimPhysClass;
  94. class RenderObjPhysClass;
  95. class ProjectileClass;
  96. class LightPhysClass;
  97. class ElevatorPhysClass;
  98. class DamageableStaticPhysClass;
  99. class DoorPhysClass;
  100. class AccessiblePhysClass;
  101. class PhysDefClass;
  102. #if (UMBRASUPPORT)
  103. namespace Umbra { class Object; }
  104. #endif
  105. /*
  106. ** Macros for rendering debug widgets. In the release build, these will automatically
  107. ** be removed. These macros can be used inside a member function of any physics object
  108. ** or by calling them through a pointer to a physics object e.g. my_phys_obj->DEBUG_RENDER_POINT(...)
  109. */
  110. #ifdef WWDEBUG
  111. #define DEBUG_RENDER_POINT(v,c) Add_Debug_Point(v,c)
  112. #define DEBUG_RENDER_VECTOR(p,v,c) Add_Debug_Vector(p,v,c)
  113. #define DEBUG_RENDER_AABOX(box,c,o) Add_Debug_AABox(box,c,o)
  114. #define DEBUG_RENDER_OBBOX(box,c,o) Add_Debug_OBBox(box,c,o)
  115. #define DEBUG_RENDER_AXES(tm,c) Add_Debug_Axes(tm,c)
  116. #else
  117. #define DEBUG_RENDER_POINT(v,c)
  118. #define DEBUG_RENDER_VECTOR(p,v,c)
  119. #define DEBUG_RENDER_AABOX(box,c,o)
  120. #define DEBUG_RENDER_OBBOX(box,c,o)
  121. #define DEBUG_RENDER_AXES(tm,c)
  122. #endif
  123. /***************************************************************************************
  124. Physics Class Hierarchy (Pre-Apr 98):
  125. ------------------------------------
  126. PhysObjClass
  127. |_______________________________
  128. | |
  129. MoveableObjClass TerrainPhysClass
  130. ____________|_______________________________________
  131. | | |
  132. Phys4Class Phys6Class Phys3Class
  133. | |
  134. CharPhysClass ______________|______________________________________
  135. | | |
  136. WheeledPhysClass TrackedPhysClass HoverPhysClass
  137. Physics Class Hierarchy (Apr 98):
  138. ---------------------------------
  139. MoveableObjClass RefCountClass CollideableObjClass
  140. | | |
  141. |_________________|________________|
  142. |
  143. PhysObjClass
  144. |
  145. __________________|_________________________________________________________________
  146. | | | |
  147. ProjectileClass Phys4Class Phys6Class TerrainPhysClass
  148. | ___|_________________________________
  149. | | | |
  150. CharPhysClass WheeledPhysClass TrackedPhysClass HoverPhysClass
  151. NOTES:
  152. - CollideableClass and MoveableClass are organizational only. I could just
  153. put all of their interfaces directly into PhysObjClass.
  154. - TerrainPhysClass's never move and are complex meshes which do polygon-level
  155. collision detection
  156. - Projectiles can never be collided with, they collide with others, they
  157. - Physics system should store all "Collideable" objects in a list or
  158. actually in a spatial data structure for collision checking.
  159. - Physics system should also store all "Moveable" objects in another list
  160. for updating everything's motions (or should that be up to the game engine?)
  161. - Bullets are Phys3Class's, nothing can collide with them, they will use
  162. ray casting for collision, they do not have "size" or "orientation"
  163. - TerrainPhys is a big object that doesn't move and has complex geometry.
  164. - A lot of things will be Phys4Classes, these are axis-aligned boxes to
  165. the collision system. They can move in x,y, and z and rotate inside their box
  166. Physics Class Hierarchy (Sept 98):
  167. ----------------------------------
  168. PhysClass Hierarchy:
  169. Starting from scratch in some respects. Culling and collision detection is the
  170. main focus of the lowest levels of the Phys class hierarchy. Wrote a new base
  171. class 'PhysClass' which everything will be derived from. It must be as lightweight
  172. as possible since now everything rendered in the game scene must be a PhysClass.
  173. PhysClass
  174. |
  175. ----------|-----------------------------
  176. | |
  177. Decoration Motion
  178. |
  179. Projectile Controllable
  180. Char Vehicle
  181. Dec 1, 1998
  182. Improving the culling linkage system. Physics object now only contain a pointer
  183. to an abstract link type which each culling system can hang anything they want
  184. to on. This is better than the old union inside of the Phys object because some
  185. of these data structures are going to have pointers to allocated memory and I didn't
  186. like the idea of having those kinds of things shadowed inside of a union. The base
  187. CullLinkClass only contains an RTTI function which should rarely need to be called.
  188. Adding Occlusion culling...
  189. Jan 5, 1999
  190. Basic Occlusion culling is working. Adding Load/Save for static scene, re-organizing
  191. so that the AAB stuff can handle things like lights and zones.
  192. Jan 15, 1999
  193. Improving list code to automatically track refs. An object added to a "phys list"
  194. will be automatically Add_Ref'd. Moved the list code into a separate module for
  195. easier reading (physlist.h, cpp)
  196. May 21, 1999
  197. Splitting much of the culling system code out into WWMath so that it can be re-used
  198. by other libraries such as the sound system. Removing "CullableClass" from the
  199. physics library and re-writing the culling stuf to not rely on phys-objects (only
  200. an abstract "cullable" object).
  201. Sept 1, 1999
  202. Making the physics library use the new Persistant-Object save/load code. This means
  203. that each type of PhysClass is a PersistClass now. Each one needs to implement
  204. save/load methods and declare a PersistFactoryClass. The physics system will have
  205. two SaveLoadSubSystems in it. One for saving the data which is completely static
  206. for a level and another for the dynamic data. Things that are treated as 100% static
  207. are: visibility data, pathfinding data, and culling datastructures (but not the
  208. objects in them...)
  209. August 29, 2000
  210. Adding Export_State,Import_State functions which can be used by the App to do
  211. network communication of physics object states.
  212. ****************************************************************************************/
  213. /**
  214. ** PhysClass
  215. ** This is the base class for all objects in the physics system.
  216. */
  217. class PhysClass : public CullableClass, public PersistClass, public MultiListObjectClass
  218. {
  219. public:
  220. PhysClass(void);
  221. // PhysClass(const PhysDefClass & def);
  222. virtual ~PhysClass(void);
  223. void Init(const PhysDefClass & def);
  224. /*
  225. ** DEBUGGING, re-initialize this object because our definition changed
  226. */
  227. virtual void Definition_Changed(void) { }
  228. /*
  229. ** Certain physics objects expire when an internal timer runs out or they are crushed. This function
  230. ** is used to handle informing any observers and putting this object into the destroy list which is
  231. ** processed at the end of each frame
  232. */
  233. bool Expire(void);
  234. /*
  235. ** Timestep function - system informs the object to update itself for the specified
  236. ** amount of time.
  237. */
  238. virtual bool Needs_Timestep(void) { return false; }
  239. virtual void Timestep(float dt) = 0;
  240. virtual void Post_Timestep_Process(void) { }
  241. /*
  242. ** Access to the Position/Orientation state of the object
  243. */
  244. virtual const Matrix3D & Get_Transform(void) const = 0;
  245. virtual void Set_Transform(const Matrix3D & m) = 0;
  246. void Get_Position(Vector3 * set_pos) const { Get_Transform().Get_Translation(set_pos); }
  247. void Set_Position(const Vector3 & pos) { Matrix3D tm = Get_Transform(); tm.Set_Translation(pos); Set_Transform(tm); }
  248. float Get_Facing(void) const { return Get_Transform().Get_Z_Rotation(); }
  249. void Set_Facing(float new_facing);
  250. /*
  251. ** Collision detection - all collideable objects provide the following collision detection
  252. ** functions so that other objects do not pass through them. These functions should test
  253. ** the given primitive against this object's geometric representation.
  254. */
  255. virtual bool Cast_Ray(PhysRayCollisionTestClass & raytest) { return false; }
  256. virtual bool Cast_AABox(PhysAABoxCollisionTestClass & boxtest) { return false; }
  257. virtual bool Cast_OBBox(PhysOBBoxCollisionTestClass & boxtest) { return false; }
  258. virtual bool Intersection_Test(PhysAABoxIntersectionTestClass & test) { return false; }
  259. virtual bool Intersection_Test(PhysOBBoxIntersectionTestClass & test) { return false; }
  260. virtual bool Intersection_Test(PhysMeshIntersectionTestClass & test) { return false; }
  261. /*
  262. ** Inter-Object Geometric Dependency. These functions don't really perform any
  263. ** physics-based motion, only purely kinematic. You can link a moveable physics object
  264. ** (the rider) to another object that it is standing on (the carrier). This will cause
  265. ** the carrier to move the rider whenever it moves (by calling Push).
  266. **
  267. ** Set_Carrier - when a carrier is being destroyed, it tells all riders as it unlinks them
  268. ** Push - carriers push their riders around, also objects not being carried can be pushed
  269. ** Internal_Link_Rider - an object is being attached to you, move him when you move
  270. ** Internal_Unlink_Rider - stop moving this object when you move.
  271. */
  272. virtual void Link_To_Carrier(PhysClass * carrier,RenderObjClass * carrier_sub_obj = NULL) { }
  273. virtual RenderObjClass * Peek_Carrier_Sub_Object(void) { return NULL; }
  274. virtual bool Push(const Vector3 & move) { return false; }
  275. virtual bool Internal_Link_Rider(PhysClass * rider) { return false; }
  276. virtual bool Internal_Unlink_Rider(PhysClass * rider) { return false; }
  277. /*
  278. ** Culling, this function updates the culling box used by the object. The default implementation
  279. ** is to copy the bounding box of the current Model.
  280. */
  281. void Update_Cull_Box(void);
  282. /*
  283. ** Set the model used by this physics object
  284. */
  285. virtual void Set_Model(RenderObjClass * model);
  286. void Set_Model_By_Name(const char * model_type_name);
  287. RenderObjClass * Get_Model(void);
  288. WWINLINE RenderObjClass * Peek_Model(void) { return Model; }
  289. /*
  290. ** Set the name of this physics model instance
  291. */
  292. void Set_Name(const char * name);
  293. const char * Get_Name(void);
  294. /*
  295. ** Instance ID related methods
  296. */
  297. uint32 Get_ID(void) const { return InstanceID; }
  298. void Set_ID(uint32 id) { InstanceID = id; }
  299. /*
  300. ** Vis Object ID. Every phys object can store a vis object id. Static objects will
  301. ** have constant ID's assigned by the vis generation process, dynamic objects will
  302. ** update their id based on their current location.
  303. */
  304. void Set_Vis_Object_ID(int new_id) { VisObjectID = new_id; }
  305. virtual int Get_Vis_Object_ID(void) { return VisObjectID; }
  306. /*
  307. ** This is just a shortcut to rendering the phys object's render object if it has one
  308. */
  309. virtual void Render(RenderInfoClass & rinfo);
  310. virtual void Vis_Render(SpecialRenderInfoClass & rinfo);
  311. /*
  312. ** Lighting system. Each physics object caches its static lighting environment. This cache must be
  313. ** invalidated when the object moves or when static lights near it change state. The simulation code
  314. ** for each physics object will be responsible for invalidating the cache when the object moves. The
  315. ** scene will be responsible for invalidating the caches of objects near lights that change state.
  316. */
  317. void Invalidate_Static_Lighting_Cache(void);
  318. LightEnvironmentClass * Get_Static_Lighting_Environment(void);
  319. /*
  320. ** This is a debugging feature which causes all vis-sector meshes to be rendered
  321. */
  322. virtual void Render_Vis_Meshes(RenderInfoClass & rinfo) { }
  323. /*
  324. ** When rendering shadows in BLOB mode, this function defines the bounds of
  325. ** the blob. Derived classes will implement this to return something like
  326. ** their collision box.
  327. */
  328. virtual void Get_Shadow_Blob_Box(AABoxClass * set_obj_space_box);
  329. /*
  330. ** This function is used to determine whether an object is projecting a shadow.
  331. ** If the object is projecting a shadow, it shouldn't be considered an occluder
  332. ** for the sun.
  333. */
  334. virtual bool Is_Casting_Shadow(void) { return false; }
  335. /*
  336. ** Material Effect Support.
  337. ** As the scene is rendered, the textures being projected onto each object will be
  338. ** linked in through the following interface. Then when this object is rendered,
  339. ** it should push those material passes into the render pipeline. As this is done,
  340. ** the list will be reset. Other user-created material effects can also be
  341. ** linked to the object through this interface.
  342. */
  343. void Add_Effect_To_Me(MaterialEffectClass * effect);
  344. void Remove_Effect_From_Me(MaterialEffectClass * effect);
  345. bool Do_Any_Effects_Suppress_Shadows(void);
  346. /*
  347. ** Set the Collision Group for this physics object. The collision group is an integer
  348. ** between 0 and 15. Collisions between any two groups can be enabled/disabled through
  349. ** the physics system.
  350. */
  351. void Set_Collision_Group(unsigned char group) { group &= COLLISION_MASK; Flags &= ~COLLISION_MASK; Flags |= group; }
  352. unsigned char Get_Collision_Group(void) const { return Flags & COLLISION_MASK; }
  353. /*
  354. ** The IGNOREME state is basically used when the object is processing its move. It
  355. ** is a way of temporarily making the collision system ignore an object (so you don't
  356. ** collide with yourself for example)
  357. */
  358. void Inc_Ignore_Counter(void);
  359. void Dec_Ignore_Counter(void);
  360. bool Is_Ignore_Me(void) const { return ((Flags & IGNORE_MASK) > 0); }
  361. /*
  362. ** The IMMOVABLE state is used to turn off an object's simulation.
  363. */
  364. void Set_Immovable(bool onoff) { Set_Flag(IMMOVABLE,onoff); }
  365. bool Is_Immovable(void) const { return Get_Flag(IMMOVABLE); }
  366. /*
  367. ** Some objects (like light sources) can be disabled.
  368. */
  369. void Set_Disabled(bool onoff) { Set_Flag(DISABLED,onoff); }
  370. bool Is_Disabled(void) const { return Get_Flag(DISABLED); }
  371. /*
  372. ** The Debug Display flag is used (in debug builds) to enable displaying
  373. ** contact points, impulse vectors, etc.
  374. */
  375. void Enable_Debug_Display(bool onoff) { (onoff ? Flags |= DEBUGDISPLAY : Flags &= ~DEBUGDISPLAY); }
  376. bool Is_Debug_Display_Enabled(void) const;
  377. /*
  378. ** User Control. Enabling this flag makes the physics object ingore all
  379. ** physics and just move according to its controller
  380. */
  381. void Enable_User_Control(bool onoff) { Set_Flag(USERCONTROL,onoff); Set_Flag(ASLEEP,false); }
  382. bool Is_User_Control_Enabled(void) const { return Get_Flag(USERCONTROL); }
  383. /*
  384. ** Shadow casting. If this option is enabled, a shadow volume will be
  385. ** calculated for the object each frame
  386. */
  387. void Enable_Shadow_Generation(bool onoff) { Set_Flag(CASTSHADOW,onoff); }
  388. bool Is_Shadow_Generation_Enabled(void) const { return Get_Flag(CASTSHADOW); }
  389. /*
  390. ** Blob Shadow override. There is a shadow mode where all objects get blob
  391. ** shadows except the "main character". This option indicates that this physics
  392. ** object should cast a proper shadow when the shadow mode is "BLOBS_PLUS"
  393. */
  394. void Enable_Force_Projection_Shadow(bool onoff) { Set_Flag(FORCE_PROJECTION_SHADOW,onoff); }
  395. bool Is_Force_Projection_Shadow_Enabled(void) const { return Get_Flag(FORCE_PROJECTION_SHADOW); }
  396. /*
  397. ** DontSave! This is used for transient objects like glass fragments which
  398. ** we don't want to save. There is also a problem with them saving caused by
  399. ** the fact that thier model is procedurally generated and doesn't save...
  400. */
  401. void Enable_Dont_Save(bool onoff) { Set_Flag(DONT_SAVE,onoff); }
  402. bool Is_Dont_Save_Enabled(void) const { return Get_Flag(DONT_SAVE); }
  403. /*
  404. ** Asleep. This indicates that the phyics object has "settled" into a stable
  405. ** configuration and has stopped simulating. Physics objects internally manage this flag.
  406. */
  407. bool Is_Asleep(void) const { return ((Flags & ASLEEP) == ASLEEP); }
  408. void Force_Awake(void) { Set_Flag(ASLEEP,false); }
  409. /*
  410. ** Static-World-Space-Mesh. This flag indicates that the phys object is a static world
  411. ** space mesh (identity transform) and enables some optimizations in the rendering loop.
  412. */
  413. void Enable_Is_World_Space_Mesh(bool onoff) { Set_Flag(IS_WS_MESH,onoff); }
  414. bool Is_World_Space_Mesh(void) { return Get_Flag(IS_WS_MESH); }
  415. /*
  416. ** Is Pre-Lit. This flag indicates that this object has precomputed light
  417. ** maps and does not need to have the static lights applied to it.
  418. */
  419. void Enable_Is_Pre_Lit(bool onoff) { Set_Flag(IS_PRE_LIT,onoff); }
  420. bool Is_Pre_Lit(void); // { return Get_Flag(IS_PRE_LIT) | Model->Get_F; }
  421. /*
  422. ** Is In-the-sun. This flag indicates whether the object is being illuminated by
  423. ** sunlight.
  424. */
  425. void Enable_Is_In_The_Sun(bool onoff) { Set_Flag(IS_IN_THE_SUN,onoff); }
  426. bool Is_In_The_Sun(void) { return Get_Flag(IS_IN_THE_SUN); }
  427. /*
  428. ** Is_State_Dirty. This flag indicates that the physics code has changed the state of
  429. ** this object. It will be set whenever an object changes but it is only cleared by the
  430. ** external user.
  431. */
  432. void Enable_Is_State_Dirty(bool onoff) { Set_Flag(IS_STATE_DIRTY,onoff); }
  433. bool Is_State_Dirty(void) { return Get_Flag(IS_STATE_DIRTY); }
  434. /*
  435. ** Is Object's Simulation Enabled. This flag can be used to disable the physics simulation
  436. ** on an object-by-object basis. The other simulation methods disable whole classes
  437. ** of objects.
  438. */
  439. void Enable_Objects_Simulation(bool onoff) { Set_Flag(SIMULATION_DISABLED,!onoff); }
  440. bool Is_Objects_Simulation_Enabled(void) const { return !Get_Flag(SIMULATION_DISABLED); }
  441. bool Is_Object_Simulating(void) { return Is_Objects_Simulation_Enabled() && !Is_Simulation_Disabled(); }
  442. /*
  443. ** If you install a collision observer, it will be notified of any collisions which occur
  444. ** involving this object. One way to do this is to derive your game objects from
  445. ** CollisionObserverClass so that they can be directly installed here. Currently, there
  446. ** can only be one observer for any physics object. You are responsible for removing
  447. ** the observer before this phys object is destroyed: Set_Observer(NULL)
  448. */
  449. void Set_Observer(PhysObserverClass * o) { Observer = o; }
  450. PhysObserverClass * Get_Observer(void) { return Observer; }
  451. CollisionReactionType Collision_Occurred(CollisionEventClass & event);
  452. /*
  453. ** Definition access. Many physics objects are created from a "definition". The definition
  454. ** object contains constants. If this object has a definition, you can access it here.
  455. */
  456. const PhysDefClass * Get_Definition(void) { return Definition; }
  457. /*
  458. ** Physics RTTI.
  459. */
  460. virtual DynamicPhysClass * As_DynamicPhysClass(void) { return NULL; }
  461. virtual MoveablePhysClass * As_MoveablePhysClass(void) { return NULL; }
  462. virtual Phys3Class * As_Phys3Class(void) { return NULL; }
  463. virtual HumanPhysClass * As_HumanPhysClass(void) { return NULL; }
  464. virtual RigidBodyClass * As_RigidBodyClass(void) { return NULL; }
  465. virtual VehiclePhysClass * As_VehiclePhysClass(void) { return NULL; }
  466. virtual MotorVehicleClass * As_MotorVehicleClass(void) { return NULL; }
  467. virtual WheeledVehicleClass * As_WheeledVehicleClass(void) { return NULL; }
  468. virtual MotorcycleClass * As_MotorcycleClass(void) { return NULL; }
  469. virtual TrackedVehicleClass * As_TrackedVehicleClass(void) { return NULL; }
  470. virtual VTOLVehicleClass * As_VTOLVehicleClass(void) { return NULL; }
  471. virtual StaticPhysClass * As_StaticPhysClass(void) { return NULL; }
  472. virtual StaticAnimPhysClass * As_StaticAnimPhysClass(void) { return NULL; }
  473. virtual ElevatorPhysClass * As_ElevatorPhysClass(void) { return NULL; }
  474. virtual DamageableStaticPhysClass * As_DamageableStaticPhysClass (void) { return NULL; }
  475. virtual DoorPhysClass * As_DoorPhysClass(void) { return NULL; }
  476. virtual DecorationPhysClass * As_DecorationPhysClass(void) { return NULL; }
  477. virtual TimedDecorationPhysClass * As_TimedDecorationPhysClass(void) { return NULL; }
  478. virtual DynamicAnimPhysClass *As_DynamicAnimPhysClass(void) { return NULL; }
  479. virtual LightPhysClass * As_LightPhysClass(void) { return NULL; }
  480. virtual RenderObjPhysClass * As_RenderObjPhysClass(void) { return NULL; }
  481. virtual ProjectileClass * As_ProjectileClass(void) { return NULL; }
  482. virtual AccessiblePhysClass * As_AccessiblePhysClass(void) { return NULL; }
  483. /*
  484. ** Persistant object save/load system
  485. */
  486. virtual bool Save (ChunkSaveClass &csave);
  487. virtual bool Load (ChunkLoadClass &cload);
  488. /*
  489. ** Debug rendering of vectors, points, boxes, etc etc. These functions actually add debug
  490. ** widgets to the physics scene. Use the macros defined at the top of this file in order to
  491. ** have these debug calls removed from the release build.
  492. */
  493. #ifdef WWDEBUG
  494. void Add_Debug_Point(const Vector3 & p,const Vector3 & color);
  495. void Add_Debug_Vector(const Vector3 & p,const Vector3 & v,const Vector3 & color);
  496. void Add_Debug_AABox(const AABoxClass & box,const Vector3 & color,float opacity = 0.25f);
  497. void Add_Debug_OBBox(const OBBoxClass & box,const Vector3 & color,float opacity = 0.25f);
  498. void Add_Debug_Axes(const Matrix3D & transform,const Vector3 & color);
  499. #endif
  500. /*
  501. ** Simulation and Rendering toggles by type. Derived classes implement these functions to test
  502. ** a static flag which is used to indicate whether rendering or simluation of all instances of
  503. ** that class are disabled or not.
  504. */
  505. virtual bool Is_Simulation_Disabled(void) { return false; }
  506. virtual bool Is_Rendering_Disabled(void) { return false; }
  507. /*
  508. ** Umbra Testing
  509. */
  510. #if (UMBRASUPPORT)
  511. Umbra::Object * Peek_Umbra_Object(void) { return UmbraObject; }
  512. #endif
  513. unsigned Get_Last_Visible_Frame() const { return LastVisibleFrame; }
  514. void Set_Last_Visible_Frame(unsigned frame) { LastVisibleFrame=frame; }
  515. protected:
  516. bool Get_Flag(unsigned int flag) const { return ((Flags & flag) == flag); }
  517. void Set_Flag(unsigned int flag,bool onoff) { (onoff ? Flags |= flag : Flags &= ~flag); }
  518. void Push_Effects(RenderInfoClass & rinfo);
  519. void Pop_Effects(RenderInfoClass & rinfo);
  520. virtual void Update_Sun_Status(void);
  521. enum {
  522. COLLISION_MASK = 0x0000000F, // bits for the collision group
  523. IMMOVABLE = 0x00000100, // this object is immovable.
  524. DISABLED = 0x00000200, // Some objects can be disabled (e.g. lights)
  525. DEBUGDISPLAY = 0x00000400, // Render debugging aids (forces, impacts, etc)
  526. USERCONTROL = 0x00000800, // Ignore physics, move according to controller directly
  527. CASTSHADOW = 0x00001000, // Does this object cast a shadow?
  528. FORCE_PROJECTION_SHADOW = 0x00002000, // When the shadow mode is BLOBS_PLUS, this object still uses a "proper" shadow
  529. DONT_SAVE = 0x00004000, // Scene should never save this object (used for transient things like glass fragments)
  530. ASLEEP = 0x00008000, // This object is not moving so its simulation was skipped
  531. IS_WS_MESH = 0x00010000, // Enable the static-world-space-mesh rendering optimizations.
  532. IS_PRE_LIT = 0x00020000, // Is this a light-mapped object that doesn't need static lights applied.
  533. IS_IN_THE_SUN = 0x00040000, // Is this object illuminated by the sun?
  534. IS_STATE_DIRTY = 0x00080000, // This object's state has changed.
  535. STATIC_LIGHTING_DIRTY = 0x00100000, // This object's static lighting cache is dirty
  536. FRICTION_DISABLED = 0x00200000, // Friction is disabled for this object (vehicles disable body-friction when their wheels are in contact)
  537. SIMULATION_DISABLED = 0x00400000, // Turn on/off simulation for this object
  538. IGNORE_SHIFT = 28, // shift count for the 'ignore-me' counter
  539. IGNORE_MASK = 0xF0000000, // mask for the 'ignore-me' counter
  540. DEFAULT_FLAGS = 0,
  541. };
  542. /*
  543. ** flags for things like whether this object is currently being considered immovable
  544. */
  545. unsigned int Flags;
  546. /*
  547. ** Render model
  548. */
  549. RenderObjClass * Model;
  550. /*
  551. ** Optional instance name
  552. */
  553. StringClass Name;
  554. /*
  555. ** Optional instance identifier (unique if non-zero)
  556. */
  557. uint32 InstanceID;
  558. /*
  559. ** Vis Object ID. Every phys object can store a vis object id. Static objects will
  560. ** have constant ID's assigned by the vis generation process, dynamic objects will
  561. ** update their id based on their current location.
  562. */
  563. uint32 VisObjectID;
  564. /*
  565. ** Observer object
  566. */
  567. PhysObserverClass * Observer;
  568. /*
  569. ** Definition object, contains constants which are shared between instances
  570. */
  571. const PhysDefClass * Definition;
  572. /*
  573. ** List of projected textures that are being applied to this object
  574. */
  575. //TexProjListClass ProjectionsOnMe;
  576. RefMaterialEffectListClass MaterialEffectsOnMe;
  577. /*
  578. ** Static lighting cache.
  579. */
  580. LightEnvironmentClass * StaticLightingCache;
  581. /*
  582. ** Frame time at which the sun status was last updated. The sun status is cached and only updated few times per second.
  583. */
  584. unsigned SunStatusLastUpdated;
  585. /*
  586. ** The pscene uses this to figure out if the mesh is visible, to do some physics optimizations.
  587. */
  588. unsigned LastVisibleFrame;
  589. /*
  590. ** UMBRA Testing
  591. */
  592. #if (UMBRASUPPORT)
  593. Umbra::Object * UmbraObject;
  594. #endif
  595. private:
  596. // Not Implemented:
  597. PhysClass(const PhysClass & src);
  598. PhysClass & operator = (const PhysClass & src);
  599. };
  600. inline void PhysClass::Inc_Ignore_Counter(void)
  601. {
  602. int count = (Flags & IGNORE_MASK) >> IGNORE_SHIFT;
  603. count++;
  604. WWASSERT(count < 12);
  605. Flags &= ~IGNORE_MASK;
  606. Flags |= (count << IGNORE_SHIFT);
  607. }
  608. inline void PhysClass::Dec_Ignore_Counter(void)
  609. {
  610. int count = (Flags & IGNORE_MASK) >> IGNORE_SHIFT;
  611. WWASSERT(count > 0);
  612. count--;
  613. Flags &= ~IGNORE_MASK;
  614. Flags |= (count << IGNORE_SHIFT);
  615. }
  616. inline CollisionReactionType PhysClass::Collision_Occurred(CollisionEventClass & event)
  617. {
  618. if (Observer) {
  619. return Observer->Collision_Occurred(event);
  620. } else {
  621. return COLLISION_REACTION_DEFAULT;
  622. }
  623. }
  624. inline void PhysClass::Update_Cull_Box(void)
  625. {
  626. if (Model) {
  627. Set_Cull_Box(Model->Get_Bounding_Box());
  628. }
  629. }
  630. inline void PhysClass::Add_Effect_To_Me(MaterialEffectClass * effect)
  631. {
  632. WWASSERT(effect != NULL);
  633. MaterialEffectsOnMe.Add(effect);
  634. }
  635. inline void PhysClass::Remove_Effect_From_Me(MaterialEffectClass * effect)
  636. {
  637. WWASSERT(effect != NULL);
  638. MaterialEffectsOnMe.Remove(effect);
  639. }
  640. inline bool PhysClass::Is_Pre_Lit(void)
  641. {
  642. if (Model) {
  643. return (Get_Flag(IS_PRE_LIT) | (Model->Has_User_Lighting() != 0));
  644. } else {
  645. return Get_Flag(IS_PRE_LIT);
  646. }
  647. }
  648. /**
  649. ** PhysDefClass - Initialization structure for a PhysClass
  650. */
  651. class PhysDefClass : public DefinitionClass
  652. {
  653. public:
  654. PhysDefClass(void);
  655. // From PersistClass
  656. virtual bool Save(ChunkSaveClass &csave);
  657. virtual bool Load(ChunkLoadClass &cload);
  658. // PhysDef type filtering mechanism
  659. virtual const char * Get_Type_Name(void) { return "PhysDef"; }
  660. virtual bool Is_Type(const char *);
  661. // Validation methods
  662. virtual bool Is_Valid_Config (StringClass &message);
  663. // accessors
  664. const StringClass & Get_Model_Name() { return ModelName; }
  665. bool Get_Is_Pre_Lit() { return IsPreLit; }
  666. // Editable interface requirements
  667. DECLARE_EDITABLE(PhysDefClass,DefinitionClass);
  668. protected:
  669. StringClass ModelName;
  670. bool IsPreLit;
  671. friend class PhysClass;
  672. };
  673. #endif