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__ */