DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

Physics_RigidBody.h (8406B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #ifndef __PHYSICS_RIGIDBODY_H__
     30 #define __PHYSICS_RIGIDBODY_H__
     31 
     32 /*
     33 ===================================================================================
     34 
     35 	Rigid body physics
     36 
     37 	Employs an impulse based dynamic simulation which is not very accurate but
     38 	relatively fast and still reliable due to the continuous collision detection.
     39 
     40 ===================================================================================
     41 */
     42 
     43 extern const float	RB_VELOCITY_MAX;
     44 extern const int	RB_VELOCITY_TOTAL_BITS;
     45 extern const int	RB_VELOCITY_EXPONENT_BITS;
     46 extern const int	RB_VELOCITY_MANTISSA_BITS;
     47 
     48 typedef struct rididBodyIState_s {
     49 	idVec3					position;					// position of trace model
     50 	idMat3					orientation;				// orientation of trace model
     51 	idVec3					linearMomentum;				// translational momentum relative to center of mass
     52 	idVec3					angularMomentum;			// rotational momentum relative to center of mass
     53 
     54 	rididBodyIState_s() :
     55 		position( vec3_zero ),
     56 		orientation( mat3_identity ),
     57 		linearMomentum( vec3_zero ),
     58 		angularMomentum( vec3_zero ) {
     59 	}
     60 } rigidBodyIState_t;
     61 
     62 typedef struct rigidBodyPState_s {
     63 	int						atRest;						// set when simulation is suspended
     64 	float					lastTimeStep;				// length of last time step
     65 	idVec3					localOrigin;				// origin relative to master
     66 	idMat3					localAxis;					// axis relative to master
     67 	idVec6					pushVelocity;				// push velocity
     68 	idVec3					externalForce;				// external force relative to center of mass
     69 	idVec3					externalTorque;				// external torque relative to center of mass
     70 	rigidBodyIState_t		i;							// state used for integration
     71 
     72 	rigidBodyPState_s() :
     73 		atRest( true ),
     74 		lastTimeStep( 0 ),
     75 		localOrigin( vec3_zero ),
     76 		localAxis( mat3_identity ),
     77 		pushVelocity( vec6_zero ),
     78 		externalForce( vec3_zero ),
     79 		externalTorque( vec3_zero ) {
     80 	}
     81 } rigidBodyPState_t;
     82 
     83 class idPhysics_RigidBody : public idPhysics_Base {
     84 
     85 public:
     86 
     87 	CLASS_PROTOTYPE( idPhysics_RigidBody );
     88 
     89 							idPhysics_RigidBody();
     90 							~idPhysics_RigidBody();
     91 
     92 	void					Save( idSaveGame *savefile ) const;
     93 	void					Restore( idRestoreGame *savefile );
     94 
     95 							// initialisation
     96 	void					SetFriction( const float linear, const float angular, const float contact );
     97 	void					SetBouncyness( const float b );
     98 							// same as above but drop to the floor first
     99 	void					DropToFloor();
    100 							// no contact determination and contact friction
    101 	void					NoContact();
    102 							// enable/disable activation by impact
    103 	void					EnableImpact();
    104 	void					DisableImpact();
    105 
    106 public:	// common physics interface
    107 	void					SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true );
    108 	idClipModel *			GetClipModel( int id = 0 ) const;
    109 	int						GetNumClipModels() const;
    110 
    111 	void					SetMass( float mass, int id = -1 );
    112 	float					GetMass( int id = -1 ) const;
    113 
    114 	void					SetContents( int contents, int id = -1 );
    115 	int						GetContents( int id = -1 ) const;
    116 
    117 	const idBounds &		GetBounds( int id = -1 ) const;
    118 	const idBounds &		GetAbsBounds( int id = -1 ) const;
    119 
    120 	bool					Evaluate( int timeStepMSec, int endTimeMSec );
    121 	bool					Interpolate( const float fraction );
    122 	void					ResetInterpolationState( const idVec3 & origin, const idMat3 & axis );
    123 	void					UpdateTime( int endTimeMSec );
    124 	int						GetTime() const;
    125 
    126 	void					GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const;
    127 	void					ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse );
    128 	void					AddForce( const int id, const idVec3 &point, const idVec3 &force );
    129 	void					Activate();
    130 	void					PutToRest();
    131 	bool					IsAtRest() const;
    132 	int						GetRestStartTime() const;
    133 	bool					IsPushable() const;
    134 
    135 	void					SaveState();
    136 	void					RestoreState();
    137 
    138 	void					SetOrigin( const idVec3 &newOrigin, int id = -1 );
    139 	void					SetAxis( const idMat3 &newAxis, int id = -1 );
    140 
    141 	void					Translate( const idVec3 &translation, int id = -1 );
    142 	void					Rotate( const idRotation &rotation, int id = -1 );
    143 
    144 	const idVec3 &			GetOrigin( int id = 0 ) const;
    145 	const idMat3 &			GetAxis( int id = 0 ) const;
    146 
    147 	void					SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 );
    148 	void					SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 );
    149 
    150 	const idVec3 &			GetLinearVelocity( int id = 0 ) const;
    151 	const idVec3 &			GetAngularVelocity( int id = 0 ) const;
    152 
    153 	void					ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const;
    154 	void					ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const;
    155 	int						ClipContents( const idClipModel *model ) const;
    156 
    157 	void					DisableClip();
    158 	void					EnableClip();
    159 
    160 	void					UnlinkClip();
    161 	void					LinkClip();
    162 
    163 	bool					EvaluateContacts();
    164 
    165 	void					SetPushed( int deltaTime );
    166 	const idVec3 &			GetPushedLinearVelocity( const int id = 0 ) const;
    167 	const idVec3 &			GetPushedAngularVelocity( const int id = 0 ) const;
    168 
    169 	void					SetMaster( idEntity *master, const bool orientated );
    170 
    171 	void					WriteToSnapshot( idBitMsg &msg ) const;
    172 	void					ReadFromSnapshot( const idBitMsg &msg );
    173 
    174 private:
    175 	// state of the rigid body
    176 	rigidBodyPState_t		current;
    177 	rigidBodyPState_t		saved;
    178 
    179 	// states for client interpolation
    180 	rigidBodyPState_t		previous;
    181 	rigidBodyPState_t		next;
    182 
    183 	// rigid body properties
    184 	float					linearFriction;				// translational friction
    185 	float					angularFriction;			// rotational friction
    186 	float					contactFriction;			// friction with contact surfaces
    187 	float					bouncyness;					// bouncyness
    188 	idClipModel *			clipModel;					// clip model used for collision detection
    189 
    190 	// derived properties
    191 	float					mass;						// mass of body
    192 	float					inverseMass;				// 1 / mass
    193 	idVec3					centerOfMass;				// center of mass of trace model
    194 	idMat3					inertiaTensor;				// mass distribution
    195 	idMat3					inverseInertiaTensor;		// inverse inertia tensor
    196 
    197 	idODE *					integrator;					// integrator
    198 	bool					dropToFloor;				// true if dropping to the floor and putting to rest
    199 	bool					testSolid;					// true if testing for solid when dropping to the floor
    200 	bool					noImpact;					// if true do not activate when another object collides
    201 	bool					noContact;					// if true do not determine contacts and no contact friction
    202 
    203 	// master
    204 	bool					hasMaster;
    205 	bool					isOrientated;
    206 
    207 private:
    208 	friend void				RigidBodyDerivatives( const float t, const void *clientData, const float *state, float *derivatives );
    209 	void					Integrate( const float deltaTime, rigidBodyPState_t &next );
    210 	bool					CheckForCollisions( const float deltaTime, rigidBodyPState_t &next, trace_t &collision );
    211 	bool					CollisionImpulse( const trace_t &collision, idVec3 &impulse );
    212 	void					ContactFriction( float deltaTime );
    213 	void					DropToFloorAndRest();
    214 	bool					TestIfAtRest() const;
    215 	void					Rest();
    216 	void					DebugDraw();
    217 };
    218 
    219 #endif /* !__PHYSICS_RIGIDBODY_H__ */