mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-15 23:21:40 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
825
Code/wwphys/phys.h
Normal file
825
Code/wwphys/phys.h
Normal file
@@ -0,0 +1,825 @@
|
||||
/*
|
||||
** 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
|
||||
Reference in New Issue
Block a user