| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** 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 ***
- ***********************************************************************************************
- * *
- * Project Name : WWPhys *
- * *
- * $Archive:: /Commando/Code/wwphys/phys.h $*
- * *
- * Author:: Greg Hjelstrom *
- * *
- * $Modtime:: 3/08/02 5:01p $*
- * *
- * $Revision:: 89 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #ifndef PHYS_H
- #define PHYS_H
- #include "always.h"
- #include "refcount.h"
- #include "matrix3d.h"
- #include "physobserver.h"
- #include "cullsys.h"
- #include "rendobj.h"
- #include "widgetuser.h"
- #include "persist.h"
- #include "editable.h"
- #include "definition.h"
- #include "multilist.h"
- #include "phystexproject.h"
- #include "wwstring.h"
- #include "materialeffect.h"
- #include "materialeffectlist.h"
- #include "wwstring.h"
- #include "umbrasupport.h"
- class CullSystemClass;
- class CullLinkClass;
- class MonoClass;
- class AABoxClass;
- class CameraClass;
- class srScene;
- class srGERD;
- class RenderInfoClass;
- class SpecialRenderInfoClass;
- class PhysClass;
- class PhysRayCollisionTestClass;
- class PhysAABoxCollisionTestClass;
- class PhysOBBoxCollisionTestClass;
- class PhysAABoxIntersectionTestClass;
- class PhysOBBoxIntersectionTestClass;
- class PhysMeshIntersectionTestClass;
- class AABTreeNodeClass;
- class CullLinkClass;
- class BitStreamClass;
- class LightEnvironmentClass;
- class DynamicPhysClass;
- class MoveablePhysClass;
- class Phys3Class;
- class HumanPhysClass;
- class RigidBodyClass;
- class VehiclePhysClass;
- class MotorVehicleClass;
- class WheeledVehicleClass;
- class MotorcycleClass;
- class TrackedVehicleClass;
- class VTOLVehicleClass;
- class StaticPhysClass;
- class StaticAnimPhysClass;
- class RenderObjPhysClass;
- class DecorationPhysClass;
- class TimedDecorationPhysClass;
- class DynamicAnimPhysClass;
- class RenderObjPhysClass;
- class ProjectileClass;
- class LightPhysClass;
- class ElevatorPhysClass;
- class DamageableStaticPhysClass;
- class DoorPhysClass;
- class AccessiblePhysClass;
- class PhysDefClass;
- #if (UMBRASUPPORT)
- namespace Umbra { class Object; }
- #endif
- /*
- ** Macros for rendering debug widgets. In the release build, these will automatically
- ** be removed. These macros can be used inside a member function of any physics object
- ** or by calling them through a pointer to a physics object e.g. my_phys_obj->DEBUG_RENDER_POINT(...)
- */
- #ifdef WWDEBUG
- #define DEBUG_RENDER_POINT(v,c) Add_Debug_Point(v,c)
- #define DEBUG_RENDER_VECTOR(p,v,c) Add_Debug_Vector(p,v,c)
- #define DEBUG_RENDER_AABOX(box,c,o) Add_Debug_AABox(box,c,o)
- #define DEBUG_RENDER_OBBOX(box,c,o) Add_Debug_OBBox(box,c,o)
- #define DEBUG_RENDER_AXES(tm,c) Add_Debug_Axes(tm,c)
- #else
- #define DEBUG_RENDER_POINT(v,c)
- #define DEBUG_RENDER_VECTOR(p,v,c)
- #define DEBUG_RENDER_AABOX(box,c,o)
- #define DEBUG_RENDER_OBBOX(box,c,o)
- #define DEBUG_RENDER_AXES(tm,c)
- #endif
- /***************************************************************************************
- Physics Class Hierarchy (Pre-Apr 98):
- ------------------------------------
-
- PhysObjClass
- |_______________________________
- | |
- MoveableObjClass TerrainPhysClass
- ____________|_______________________________________
- | | |
- Phys4Class Phys6Class Phys3Class
- | |
- CharPhysClass ______________|______________________________________
- | | |
- WheeledPhysClass TrackedPhysClass HoverPhysClass
-
- Physics Class Hierarchy (Apr 98):
- ---------------------------------
- MoveableObjClass RefCountClass CollideableObjClass
- | | |
- |_________________|________________|
- |
- PhysObjClass
- |
- __________________|_________________________________________________________________
- | | | |
- ProjectileClass Phys4Class Phys6Class TerrainPhysClass
- | ___|_________________________________
- | | | |
- CharPhysClass WheeledPhysClass TrackedPhysClass HoverPhysClass
-
- NOTES:
-
- - CollideableClass and MoveableClass are organizational only. I could just
- put all of their interfaces directly into PhysObjClass.
- - TerrainPhysClass's never move and are complex meshes which do polygon-level
- collision detection
- - Projectiles can never be collided with, they collide with others, they
- - Physics system should store all "Collideable" objects in a list or
- actually in a spatial data structure for collision checking.
- - Physics system should also store all "Moveable" objects in another list
- for updating everything's motions (or should that be up to the game engine?)
-
- - Bullets are Phys3Class's, nothing can collide with them, they will use
- ray casting for collision, they do not have "size" or "orientation"
- - TerrainPhys is a big object that doesn't move and has complex geometry.
- - A lot of things will be Phys4Classes, these are axis-aligned boxes to
- the collision system. They can move in x,y, and z and rotate inside their box
- Physics Class Hierarchy (Sept 98):
- ----------------------------------
- PhysClass Hierarchy:
- Starting from scratch in some respects. Culling and collision detection is the
- main focus of the lowest levels of the Phys class hierarchy. Wrote a new base
- class 'PhysClass' which everything will be derived from. It must be as lightweight
- as possible since now everything rendered in the game scene must be a PhysClass.
- PhysClass
- |
- ----------|-----------------------------
- | |
- Decoration Motion
- |
-
- Projectile Controllable
-
- Char Vehicle
- Dec 1, 1998
- Improving the culling linkage system. Physics object now only contain a pointer
- to an abstract link type which each culling system can hang anything they want
- to on. This is better than the old union inside of the Phys object because some
- of these data structures are going to have pointers to allocated memory and I didn't
- like the idea of having those kinds of things shadowed inside of a union. The base
- CullLinkClass only contains an RTTI function which should rarely need to be called.
- Adding Occlusion culling...
- Jan 5, 1999
- Basic Occlusion culling is working. Adding Load/Save for static scene, re-organizing
- so that the AAB stuff can handle things like lights and zones.
- Jan 15, 1999
- Improving list code to automatically track refs. An object added to a "phys list"
- will be automatically Add_Ref'd. Moved the list code into a separate module for
- easier reading (physlist.h, cpp)
- May 21, 1999
-
- Splitting much of the culling system code out into WWMath so that it can be re-used
- by other libraries such as the sound system. Removing "CullableClass" from the
- physics library and re-writing the culling stuf to not rely on phys-objects (only
- an abstract "cullable" object).
- Sept 1, 1999
- Making the physics library use the new Persistant-Object save/load code. This means
- that each type of PhysClass is a PersistClass now. Each one needs to implement
- save/load methods and declare a PersistFactoryClass. The physics system will have
- two SaveLoadSubSystems in it. One for saving the data which is completely static
- for a level and another for the dynamic data. Things that are treated as 100% static
- are: visibility data, pathfinding data, and culling datastructures (but not the
- objects in them...)
- August 29, 2000
- Adding Export_State,Import_State functions which can be used by the App to do
- network communication of physics object states.
- ****************************************************************************************/
- /**
- ** PhysClass
- ** This is the base class for all objects in the physics system.
- */
- class PhysClass : public CullableClass, public PersistClass, public MultiListObjectClass
- {
- public:
- PhysClass(void);
- // PhysClass(const PhysDefClass & def);
- virtual ~PhysClass(void);
- void Init(const PhysDefClass & def);
- /*
- ** DEBUGGING, re-initialize this object because our definition changed
- */
- virtual void Definition_Changed(void) { }
-
- /*
- ** Certain physics objects expire when an internal timer runs out or they are crushed. This function
- ** is used to handle informing any observers and putting this object into the destroy list which is
- ** processed at the end of each frame
- */
- bool Expire(void);
- /*
- ** Timestep function - system informs the object to update itself for the specified
- ** amount of time.
- */
- virtual bool Needs_Timestep(void) { return false; }
- virtual void Timestep(float dt) = 0;
- virtual void Post_Timestep_Process(void) { }
- /*
- ** Access to the Position/Orientation state of the object
- */
- virtual const Matrix3D & Get_Transform(void) const = 0;
- virtual void Set_Transform(const Matrix3D & m) = 0;
- void Get_Position(Vector3 * set_pos) const { Get_Transform().Get_Translation(set_pos); }
- void Set_Position(const Vector3 & pos) { Matrix3D tm = Get_Transform(); tm.Set_Translation(pos); Set_Transform(tm); }
- float Get_Facing(void) const { return Get_Transform().Get_Z_Rotation(); }
- void Set_Facing(float new_facing);
- /*
- ** Collision detection - all collideable objects provide the following collision detection
- ** functions so that other objects do not pass through them. These functions should test
- ** the given primitive against this object's geometric representation.
- */
- virtual bool Cast_Ray(PhysRayCollisionTestClass & raytest) { return false; }
- virtual bool Cast_AABox(PhysAABoxCollisionTestClass & boxtest) { return false; }
- virtual bool Cast_OBBox(PhysOBBoxCollisionTestClass & boxtest) { return false; }
- virtual bool Intersection_Test(PhysAABoxIntersectionTestClass & test) { return false; }
- virtual bool Intersection_Test(PhysOBBoxIntersectionTestClass & test) { return false; }
- virtual bool Intersection_Test(PhysMeshIntersectionTestClass & test) { return false; }
- /*
- ** Inter-Object Geometric Dependency. These functions don't really perform any
- ** physics-based motion, only purely kinematic. You can link a moveable physics object
- ** (the rider) to another object that it is standing on (the carrier). This will cause
- ** the carrier to move the rider whenever it moves (by calling Push).
- **
- ** Set_Carrier - when a carrier is being destroyed, it tells all riders as it unlinks them
- ** Push - carriers push their riders around, also objects not being carried can be pushed
- ** Internal_Link_Rider - an object is being attached to you, move him when you move
- ** Internal_Unlink_Rider - stop moving this object when you move.
- */
- virtual void Link_To_Carrier(PhysClass * carrier,RenderObjClass * carrier_sub_obj = NULL) { }
- virtual RenderObjClass * Peek_Carrier_Sub_Object(void) { return NULL; }
- virtual bool Push(const Vector3 & move) { return false; }
-
- virtual bool Internal_Link_Rider(PhysClass * rider) { return false; }
- virtual bool Internal_Unlink_Rider(PhysClass * rider) { return false; }
- /*
- ** Culling, this function updates the culling box used by the object. The default implementation
- ** is to copy the bounding box of the current Model.
- */
- void Update_Cull_Box(void);
- /*
- ** Set the model used by this physics object
- */
- virtual void Set_Model(RenderObjClass * model);
- void Set_Model_By_Name(const char * model_type_name);
- RenderObjClass * Get_Model(void);
- WWINLINE RenderObjClass * Peek_Model(void) { return Model; }
- /*
- ** Set the name of this physics model instance
- */
- void Set_Name(const char * name);
- const char * Get_Name(void);
- /*
- ** Instance ID related methods
- */
- uint32 Get_ID(void) const { return InstanceID; }
- void Set_ID(uint32 id) { InstanceID = id; }
- /*
- ** Vis Object ID. Every phys object can store a vis object id. Static objects will
- ** have constant ID's assigned by the vis generation process, dynamic objects will
- ** update their id based on their current location.
- */
- void Set_Vis_Object_ID(int new_id) { VisObjectID = new_id; }
- virtual int Get_Vis_Object_ID(void) { return VisObjectID; }
- /*
- ** This is just a shortcut to rendering the phys object's render object if it has one
- */
- virtual void Render(RenderInfoClass & rinfo);
- virtual void Vis_Render(SpecialRenderInfoClass & rinfo);
-
- /*
- ** Lighting system. Each physics object caches its static lighting environment. This cache must be
- ** invalidated when the object moves or when static lights near it change state. The simulation code
- ** for each physics object will be responsible for invalidating the cache when the object moves. The
- ** scene will be responsible for invalidating the caches of objects near lights that change state.
- */
- void Invalidate_Static_Lighting_Cache(void);
- LightEnvironmentClass * Get_Static_Lighting_Environment(void);
- /*
- ** This is a debugging feature which causes all vis-sector meshes to be rendered
- */
- virtual void Render_Vis_Meshes(RenderInfoClass & rinfo) { }
- /*
- ** When rendering shadows in BLOB mode, this function defines the bounds of
- ** the blob. Derived classes will implement this to return something like
- ** their collision box.
- */
- virtual void Get_Shadow_Blob_Box(AABoxClass * set_obj_space_box);
- /*
- ** This function is used to determine whether an object is projecting a shadow.
- ** If the object is projecting a shadow, it shouldn't be considered an occluder
- ** for the sun.
- */
- virtual bool Is_Casting_Shadow(void) { return false; }
- /*
- ** Material Effect Support.
- ** As the scene is rendered, the textures being projected onto each object will be
- ** linked in through the following interface. Then when this object is rendered,
- ** it should push those material passes into the render pipeline. As this is done,
- ** the list will be reset. Other user-created material effects can also be
- ** linked to the object through this interface.
- */
- void Add_Effect_To_Me(MaterialEffectClass * effect);
- void Remove_Effect_From_Me(MaterialEffectClass * effect);
- bool Do_Any_Effects_Suppress_Shadows(void);
- /*
- ** Set the Collision Group for this physics object. The collision group is an integer
- ** between 0 and 15. Collisions between any two groups can be enabled/disabled through
- ** the physics system.
- */
- void Set_Collision_Group(unsigned char group) { group &= COLLISION_MASK; Flags &= ~COLLISION_MASK; Flags |= group; }
- unsigned char Get_Collision_Group(void) const { return Flags & COLLISION_MASK; }
- /*
- ** The IGNOREME state is basically used when the object is processing its move. It
- ** is a way of temporarily making the collision system ignore an object (so you don't
- ** collide with yourself for example)
- */
- void Inc_Ignore_Counter(void);
- void Dec_Ignore_Counter(void);
- bool Is_Ignore_Me(void) const { return ((Flags & IGNORE_MASK) > 0); }
- /*
- ** The IMMOVABLE state is used to turn off an object's simulation.
- */
- void Set_Immovable(bool onoff) { Set_Flag(IMMOVABLE,onoff); }
- bool Is_Immovable(void) const { return Get_Flag(IMMOVABLE); }
- /*
- ** Some objects (like light sources) can be disabled.
- */
- void Set_Disabled(bool onoff) { Set_Flag(DISABLED,onoff); }
- bool Is_Disabled(void) const { return Get_Flag(DISABLED); }
- /*
- ** The Debug Display flag is used (in debug builds) to enable displaying
- ** contact points, impulse vectors, etc.
- */
- void Enable_Debug_Display(bool onoff) { (onoff ? Flags |= DEBUGDISPLAY : Flags &= ~DEBUGDISPLAY); }
- bool Is_Debug_Display_Enabled(void) const;
- /*
- ** User Control. Enabling this flag makes the physics object ingore all
- ** physics and just move according to its controller
- */
- void Enable_User_Control(bool onoff) { Set_Flag(USERCONTROL,onoff); Set_Flag(ASLEEP,false); }
- bool Is_User_Control_Enabled(void) const { return Get_Flag(USERCONTROL); }
- /*
- ** Shadow casting. If this option is enabled, a shadow volume will be
- ** calculated for the object each frame
- */
- void Enable_Shadow_Generation(bool onoff) { Set_Flag(CASTSHADOW,onoff); }
- bool Is_Shadow_Generation_Enabled(void) const { return Get_Flag(CASTSHADOW); }
- /*
- ** Blob Shadow override. There is a shadow mode where all objects get blob
- ** shadows except the "main character". This option indicates that this physics
- ** object should cast a proper shadow when the shadow mode is "BLOBS_PLUS"
- */
- void Enable_Force_Projection_Shadow(bool onoff) { Set_Flag(FORCE_PROJECTION_SHADOW,onoff); }
- bool Is_Force_Projection_Shadow_Enabled(void) const { return Get_Flag(FORCE_PROJECTION_SHADOW); }
- /*
- ** DontSave! This is used for transient objects like glass fragments which
- ** we don't want to save. There is also a problem with them saving caused by
- ** the fact that thier model is procedurally generated and doesn't save...
- */
- void Enable_Dont_Save(bool onoff) { Set_Flag(DONT_SAVE,onoff); }
- bool Is_Dont_Save_Enabled(void) const { return Get_Flag(DONT_SAVE); }
- /*
- ** Asleep. This indicates that the phyics object has "settled" into a stable
- ** configuration and has stopped simulating. Physics objects internally manage this flag.
- */
- bool Is_Asleep(void) const { return ((Flags & ASLEEP) == ASLEEP); }
- void Force_Awake(void) { Set_Flag(ASLEEP,false); }
- /*
- ** Static-World-Space-Mesh. This flag indicates that the phys object is a static world
- ** space mesh (identity transform) and enables some optimizations in the rendering loop.
- */
- void Enable_Is_World_Space_Mesh(bool onoff) { Set_Flag(IS_WS_MESH,onoff); }
- bool Is_World_Space_Mesh(void) { return Get_Flag(IS_WS_MESH); }
- /*
- ** Is Pre-Lit. This flag indicates that this object has precomputed light
- ** maps and does not need to have the static lights applied to it.
- */
- void Enable_Is_Pre_Lit(bool onoff) { Set_Flag(IS_PRE_LIT,onoff); }
- bool Is_Pre_Lit(void); // { return Get_Flag(IS_PRE_LIT) | Model->Get_F; }
- /*
- ** Is In-the-sun. This flag indicates whether the object is being illuminated by
- ** sunlight.
- */
- void Enable_Is_In_The_Sun(bool onoff) { Set_Flag(IS_IN_THE_SUN,onoff); }
- bool Is_In_The_Sun(void) { return Get_Flag(IS_IN_THE_SUN); }
- /*
- ** Is_State_Dirty. This flag indicates that the physics code has changed the state of
- ** this object. It will be set whenever an object changes but it is only cleared by the
- ** external user.
- */
- void Enable_Is_State_Dirty(bool onoff) { Set_Flag(IS_STATE_DIRTY,onoff); }
- bool Is_State_Dirty(void) { return Get_Flag(IS_STATE_DIRTY); }
- /*
- ** Is Object's Simulation Enabled. This flag can be used to disable the physics simulation
- ** on an object-by-object basis. The other simulation methods disable whole classes
- ** of objects.
- */
- void Enable_Objects_Simulation(bool onoff) { Set_Flag(SIMULATION_DISABLED,!onoff); }
- bool Is_Objects_Simulation_Enabled(void) const { return !Get_Flag(SIMULATION_DISABLED); }
- bool Is_Object_Simulating(void) { return Is_Objects_Simulation_Enabled() && !Is_Simulation_Disabled(); }
- /*
- ** If you install a collision observer, it will be notified of any collisions which occur
- ** involving this object. One way to do this is to derive your game objects from
- ** CollisionObserverClass so that they can be directly installed here. Currently, there
- ** can only be one observer for any physics object. You are responsible for removing
- ** the observer before this phys object is destroyed: Set_Observer(NULL)
- */
- void Set_Observer(PhysObserverClass * o) { Observer = o; }
- PhysObserverClass * Get_Observer(void) { return Observer; }
- CollisionReactionType Collision_Occurred(CollisionEventClass & event);
- /*
- ** Definition access. Many physics objects are created from a "definition". The definition
- ** object contains constants. If this object has a definition, you can access it here.
- */
- const PhysDefClass * Get_Definition(void) { return Definition; }
- /*
- ** Physics RTTI.
- */
- virtual DynamicPhysClass * As_DynamicPhysClass(void) { return NULL; }
- virtual MoveablePhysClass * As_MoveablePhysClass(void) { return NULL; }
- virtual Phys3Class * As_Phys3Class(void) { return NULL; }
- virtual HumanPhysClass * As_HumanPhysClass(void) { return NULL; }
- virtual RigidBodyClass * As_RigidBodyClass(void) { return NULL; }
- virtual VehiclePhysClass * As_VehiclePhysClass(void) { return NULL; }
- virtual MotorVehicleClass * As_MotorVehicleClass(void) { return NULL; }
- virtual WheeledVehicleClass * As_WheeledVehicleClass(void) { return NULL; }
- virtual MotorcycleClass * As_MotorcycleClass(void) { return NULL; }
- virtual TrackedVehicleClass * As_TrackedVehicleClass(void) { return NULL; }
- virtual VTOLVehicleClass * As_VTOLVehicleClass(void) { return NULL; }
- virtual StaticPhysClass * As_StaticPhysClass(void) { return NULL; }
- virtual StaticAnimPhysClass * As_StaticAnimPhysClass(void) { return NULL; }
- virtual ElevatorPhysClass * As_ElevatorPhysClass(void) { return NULL; }
- virtual DamageableStaticPhysClass * As_DamageableStaticPhysClass (void) { return NULL; }
- virtual DoorPhysClass * As_DoorPhysClass(void) { return NULL; }
- virtual DecorationPhysClass * As_DecorationPhysClass(void) { return NULL; }
- virtual TimedDecorationPhysClass * As_TimedDecorationPhysClass(void) { return NULL; }
- virtual DynamicAnimPhysClass *As_DynamicAnimPhysClass(void) { return NULL; }
- virtual LightPhysClass * As_LightPhysClass(void) { return NULL; }
- virtual RenderObjPhysClass * As_RenderObjPhysClass(void) { return NULL; }
- virtual ProjectileClass * As_ProjectileClass(void) { return NULL; }
- virtual AccessiblePhysClass * As_AccessiblePhysClass(void) { return NULL; }
- /*
- ** Persistant object save/load system
- */
- virtual bool Save (ChunkSaveClass &csave);
- virtual bool Load (ChunkLoadClass &cload);
- /*
- ** Debug rendering of vectors, points, boxes, etc etc. These functions actually add debug
- ** widgets to the physics scene. Use the macros defined at the top of this file in order to
- ** have these debug calls removed from the release build.
- */
- #ifdef WWDEBUG
- void Add_Debug_Point(const Vector3 & p,const Vector3 & color);
- void Add_Debug_Vector(const Vector3 & p,const Vector3 & v,const Vector3 & color);
- void Add_Debug_AABox(const AABoxClass & box,const Vector3 & color,float opacity = 0.25f);
- void Add_Debug_OBBox(const OBBoxClass & box,const Vector3 & color,float opacity = 0.25f);
- void Add_Debug_Axes(const Matrix3D & transform,const Vector3 & color);
- #endif
- /*
- ** Simulation and Rendering toggles by type. Derived classes implement these functions to test
- ** a static flag which is used to indicate whether rendering or simluation of all instances of
- ** that class are disabled or not.
- */
- virtual bool Is_Simulation_Disabled(void) { return false; }
- virtual bool Is_Rendering_Disabled(void) { return false; }
- /*
- ** Umbra Testing
- */
- #if (UMBRASUPPORT)
- Umbra::Object * Peek_Umbra_Object(void) { return UmbraObject; }
- #endif
- unsigned Get_Last_Visible_Frame() const { return LastVisibleFrame; }
- void Set_Last_Visible_Frame(unsigned frame) { LastVisibleFrame=frame; }
- protected:
- bool Get_Flag(unsigned int flag) const { return ((Flags & flag) == flag); }
- void Set_Flag(unsigned int flag,bool onoff) { (onoff ? Flags |= flag : Flags &= ~flag); }
-
- void Push_Effects(RenderInfoClass & rinfo);
- void Pop_Effects(RenderInfoClass & rinfo);
- virtual void Update_Sun_Status(void);
- enum {
- COLLISION_MASK = 0x0000000F, // bits for the collision group
- IMMOVABLE = 0x00000100, // this object is immovable.
- DISABLED = 0x00000200, // Some objects can be disabled (e.g. lights)
- DEBUGDISPLAY = 0x00000400, // Render debugging aids (forces, impacts, etc)
- USERCONTROL = 0x00000800, // Ignore physics, move according to controller directly
- CASTSHADOW = 0x00001000, // Does this object cast a shadow?
- FORCE_PROJECTION_SHADOW = 0x00002000, // When the shadow mode is BLOBS_PLUS, this object still uses a "proper" shadow
- DONT_SAVE = 0x00004000, // Scene should never save this object (used for transient things like glass fragments)
- ASLEEP = 0x00008000, // This object is not moving so its simulation was skipped
- IS_WS_MESH = 0x00010000, // Enable the static-world-space-mesh rendering optimizations.
- IS_PRE_LIT = 0x00020000, // Is this a light-mapped object that doesn't need static lights applied.
- IS_IN_THE_SUN = 0x00040000, // Is this object illuminated by the sun?
- IS_STATE_DIRTY = 0x00080000, // This object's state has changed.
- STATIC_LIGHTING_DIRTY = 0x00100000, // This object's static lighting cache is dirty
- FRICTION_DISABLED = 0x00200000, // Friction is disabled for this object (vehicles disable body-friction when their wheels are in contact)
- SIMULATION_DISABLED = 0x00400000, // Turn on/off simulation for this object
- IGNORE_SHIFT = 28, // shift count for the 'ignore-me' counter
- IGNORE_MASK = 0xF0000000, // mask for the 'ignore-me' counter
- DEFAULT_FLAGS = 0,
- };
- /*
- ** flags for things like whether this object is currently being considered immovable
- */
- unsigned int Flags;
-
- /*
- ** Render model
- */
- RenderObjClass * Model;
- /*
- ** Optional instance name
- */
- StringClass Name;
- /*
- ** Optional instance identifier (unique if non-zero)
- */
- uint32 InstanceID;
- /*
- ** Vis Object ID. Every phys object can store a vis object id. Static objects will
- ** have constant ID's assigned by the vis generation process, dynamic objects will
- ** update their id based on their current location.
- */
- uint32 VisObjectID;
- /*
- ** Observer object
- */
- PhysObserverClass * Observer;
- /*
- ** Definition object, contains constants which are shared between instances
- */
- const PhysDefClass * Definition;
- /*
- ** List of projected textures that are being applied to this object
- */
- //TexProjListClass ProjectionsOnMe;
- RefMaterialEffectListClass MaterialEffectsOnMe;
- /*
- ** Static lighting cache.
- */
- LightEnvironmentClass * StaticLightingCache;
- /*
- ** Frame time at which the sun status was last updated. The sun status is cached and only updated few times per second.
- */
- unsigned SunStatusLastUpdated;
- /*
- ** The pscene uses this to figure out if the mesh is visible, to do some physics optimizations.
- */
- unsigned LastVisibleFrame;
- /*
- ** UMBRA Testing
- */
- #if (UMBRASUPPORT)
- Umbra::Object * UmbraObject;
- #endif
- private:
- // Not Implemented:
- PhysClass(const PhysClass & src);
- PhysClass & operator = (const PhysClass & src);
- };
- inline void PhysClass::Inc_Ignore_Counter(void)
- {
- int count = (Flags & IGNORE_MASK) >> IGNORE_SHIFT;
- count++;
- WWASSERT(count < 12);
- Flags &= ~IGNORE_MASK;
- Flags |= (count << IGNORE_SHIFT);
- }
- inline void PhysClass::Dec_Ignore_Counter(void)
- {
- int count = (Flags & IGNORE_MASK) >> IGNORE_SHIFT;
- WWASSERT(count > 0);
- count--;
- Flags &= ~IGNORE_MASK;
- Flags |= (count << IGNORE_SHIFT);
- }
- inline CollisionReactionType PhysClass::Collision_Occurred(CollisionEventClass & event)
- {
- if (Observer) {
- return Observer->Collision_Occurred(event);
- } else {
- return COLLISION_REACTION_DEFAULT;
- }
- }
- inline void PhysClass::Update_Cull_Box(void)
- {
- if (Model) {
- Set_Cull_Box(Model->Get_Bounding_Box());
- }
- }
- inline void PhysClass::Add_Effect_To_Me(MaterialEffectClass * effect)
- {
- WWASSERT(effect != NULL);
- MaterialEffectsOnMe.Add(effect);
- }
- inline void PhysClass::Remove_Effect_From_Me(MaterialEffectClass * effect)
- {
- WWASSERT(effect != NULL);
- MaterialEffectsOnMe.Remove(effect);
- }
- inline bool PhysClass::Is_Pre_Lit(void)
- {
- if (Model) {
- return (Get_Flag(IS_PRE_LIT) | (Model->Has_User_Lighting() != 0));
- } else {
- return Get_Flag(IS_PRE_LIT);
- }
- }
- /**
- ** PhysDefClass - Initialization structure for a PhysClass
- */
- class PhysDefClass : public DefinitionClass
- {
- public:
-
- PhysDefClass(void);
-
- // From PersistClass
- virtual bool Save(ChunkSaveClass &csave);
- virtual bool Load(ChunkLoadClass &cload);
-
- // PhysDef type filtering mechanism
- virtual const char * Get_Type_Name(void) { return "PhysDef"; }
- virtual bool Is_Type(const char *);
- // Validation methods
- virtual bool Is_Valid_Config (StringClass &message);
- // accessors
- const StringClass & Get_Model_Name() { return ModelName; }
- bool Get_Is_Pre_Lit() { return IsPreLit; }
-
- // Editable interface requirements
- DECLARE_EDITABLE(PhysDefClass,DefinitionClass);
- protected:
-
- StringClass ModelName;
- bool IsPreLit;
-
- friend class PhysClass;
- };
- #endif
|