Physics_Actor.cpp (9056B)
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 #pragma hdrstop 30 #include "../../idlib/precompiled.h" 31 32 33 #include "../Game_local.h" 34 35 CLASS_DECLARATION( idPhysics_Base, idPhysics_Actor ) 36 END_CLASS 37 38 /* 39 ================ 40 idPhysics_Actor::idPhysics_Actor 41 ================ 42 */ 43 idPhysics_Actor::idPhysics_Actor() { 44 clipModel = NULL; 45 SetClipModelAxis(); 46 mass = 100.0f; 47 invMass = 1.0f / mass; 48 masterEntity = NULL; 49 masterYaw = 0.0f; 50 masterDeltaYaw = 0.0f; 51 groundEntityPtr = NULL; 52 } 53 54 /* 55 ================ 56 idPhysics_Actor::~idPhysics_Actor 57 ================ 58 */ 59 idPhysics_Actor::~idPhysics_Actor() { 60 if ( clipModel ) { 61 delete clipModel; 62 clipModel = NULL; 63 } 64 } 65 66 /* 67 ================ 68 idPhysics_Actor::Save 69 ================ 70 */ 71 void idPhysics_Actor::Save( idSaveGame *savefile ) const { 72 73 savefile->WriteClipModel( clipModel ); 74 savefile->WriteMat3( clipModelAxis ); 75 76 savefile->WriteFloat( mass ); 77 savefile->WriteFloat( invMass ); 78 79 savefile->WriteObject( masterEntity ); 80 savefile->WriteFloat( masterYaw ); 81 savefile->WriteFloat( masterDeltaYaw ); 82 83 groundEntityPtr.Save( savefile ); 84 } 85 86 /* 87 ================ 88 idPhysics_Actor::Restore 89 ================ 90 */ 91 void idPhysics_Actor::Restore( idRestoreGame *savefile ) { 92 93 savefile->ReadClipModel( clipModel ); 94 savefile->ReadMat3( clipModelAxis ); 95 96 savefile->ReadFloat( mass ); 97 savefile->ReadFloat( invMass ); 98 99 savefile->ReadObject( reinterpret_cast<idClass *&>( masterEntity ) ); 100 savefile->ReadFloat( masterYaw ); 101 savefile->ReadFloat( masterDeltaYaw ); 102 103 groundEntityPtr.Restore( savefile ); 104 } 105 106 /* 107 ================ 108 idPhysics_Actor::SetClipModelAxis 109 ================ 110 */ 111 void idPhysics_Actor::SetClipModelAxis() { 112 // align clip model to gravity direction 113 if ( ( gravityNormal[2] == -1.0f ) || ( gravityNormal == vec3_zero ) ) { 114 clipModelAxis.Identity(); 115 } 116 else { 117 clipModelAxis[2] = -gravityNormal; 118 clipModelAxis[2].NormalVectors( clipModelAxis[0], clipModelAxis[1] ); 119 clipModelAxis[1] = -clipModelAxis[1]; 120 } 121 122 if ( clipModel ) { 123 clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModelAxis ); 124 } 125 } 126 127 /* 128 ================ 129 idPhysics_Actor::GetGravityAxis 130 ================ 131 */ 132 const idMat3 &idPhysics_Actor::GetGravityAxis() const { 133 return clipModelAxis; 134 } 135 136 /* 137 ================ 138 idPhysics_Actor::GetMasterDeltaYaw 139 ================ 140 */ 141 float idPhysics_Actor::GetMasterDeltaYaw() const { 142 return masterDeltaYaw; 143 } 144 145 /* 146 ================ 147 idPhysics_Actor::GetGroundEntity 148 ================ 149 */ 150 idEntity *idPhysics_Actor::GetGroundEntity() const { 151 return groundEntityPtr.GetEntity(); 152 } 153 154 /* 155 ================ 156 idPhysics_Actor::SetClipModel 157 ================ 158 */ 159 void idPhysics_Actor::SetClipModel( idClipModel *model, const float density, int id, bool freeOld ) { 160 assert( self ); 161 assert( model ); // a clip model is required 162 assert( model->IsTraceModel() ); // and it should be a trace model 163 assert( density > 0.0f ); // density should be valid 164 165 if ( clipModel && clipModel != model && freeOld ) { 166 delete clipModel; 167 } 168 clipModel = model; 169 clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModelAxis ); 170 } 171 172 /* 173 ================ 174 idPhysics_Actor::GetClipModel 175 ================ 176 */ 177 idClipModel *idPhysics_Actor::GetClipModel( int id ) const { 178 return clipModel; 179 } 180 181 /* 182 ================ 183 idPhysics_Actor::GetNumClipModels 184 ================ 185 */ 186 int idPhysics_Actor::GetNumClipModels() const { 187 return 1; 188 } 189 190 /* 191 ================ 192 idPhysics_Actor::SetMass 193 ================ 194 */ 195 void idPhysics_Actor::SetMass( float _mass, int id ) { 196 assert( _mass > 0.0f ); 197 mass = _mass; 198 invMass = 1.0f / _mass; 199 } 200 201 /* 202 ================ 203 idPhysics_Actor::GetMass 204 ================ 205 */ 206 float idPhysics_Actor::GetMass( int id ) const { 207 return mass; 208 } 209 210 /* 211 ================ 212 idPhysics_Actor::SetClipMask 213 ================ 214 */ 215 void idPhysics_Actor::SetContents( int contents, int id ) { 216 clipModel->SetContents( contents ); 217 } 218 219 /* 220 ================ 221 idPhysics_Actor::SetClipMask 222 ================ 223 */ 224 int idPhysics_Actor::GetContents( int id ) const { 225 return clipModel->GetContents(); 226 } 227 228 /* 229 ================ 230 idPhysics_Actor::GetBounds 231 ================ 232 */ 233 const idBounds &idPhysics_Actor::GetBounds( int id ) const { 234 return clipModel->GetBounds(); 235 } 236 237 /* 238 ================ 239 idPhysics_Actor::GetAbsBounds 240 ================ 241 */ 242 const idBounds &idPhysics_Actor::GetAbsBounds( int id ) const { 243 return clipModel->GetAbsBounds(); 244 } 245 246 /* 247 ================ 248 idPhysics_Actor::IsPushable 249 ================ 250 */ 251 bool idPhysics_Actor::IsPushable() const { 252 return ( masterEntity == NULL ); 253 } 254 255 /* 256 ================ 257 idPhysics_Actor::GetOrigin 258 ================ 259 */ 260 const idVec3 &idPhysics_Actor::GetOrigin( int id ) const { 261 return clipModel->GetOrigin(); 262 } 263 264 /* 265 ================ 266 idPhysics_Player::GetAxis 267 ================ 268 */ 269 const idMat3 &idPhysics_Actor::GetAxis( int id ) const { 270 return clipModel->GetAxis(); 271 } 272 273 /* 274 ================ 275 idPhysics_Actor::SetGravity 276 ================ 277 */ 278 void idPhysics_Actor::SetGravity( const idVec3 &newGravity ) { 279 if ( newGravity != gravityVector ) { 280 idPhysics_Base::SetGravity( newGravity ); 281 SetClipModelAxis(); 282 } 283 } 284 285 /* 286 ================ 287 idPhysics_Actor::ClipTranslation 288 ================ 289 */ 290 void idPhysics_Actor::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { 291 if ( model ) { 292 gameLocal.clip.TranslationModel( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, 293 clipModel, clipModel->GetAxis(), clipMask, 294 model->Handle(), model->GetOrigin(), model->GetAxis() ); 295 } 296 else { 297 gameLocal.clip.Translation( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, 298 clipModel, clipModel->GetAxis(), clipMask, self ); 299 } 300 } 301 302 /* 303 ================ 304 idPhysics_Actor::ClipRotation 305 ================ 306 */ 307 void idPhysics_Actor::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { 308 if ( model ) { 309 gameLocal.clip.RotationModel( results, clipModel->GetOrigin(), rotation, 310 clipModel, clipModel->GetAxis(), clipMask, 311 model->Handle(), model->GetOrigin(), model->GetAxis() ); 312 } 313 else { 314 gameLocal.clip.Rotation( results, clipModel->GetOrigin(), rotation, 315 clipModel, clipModel->GetAxis(), clipMask, self ); 316 } 317 } 318 319 /* 320 ================ 321 idPhysics_Actor::ClipContents 322 ================ 323 */ 324 int idPhysics_Actor::ClipContents( const idClipModel *model ) const { 325 if ( model ) { 326 return gameLocal.clip.ContentsModel( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, 327 model->Handle(), model->GetOrigin(), model->GetAxis() ); 328 } 329 else { 330 return gameLocal.clip.Contents( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, NULL ); 331 } 332 } 333 334 /* 335 ================ 336 idPhysics_Actor::DisableClip 337 ================ 338 */ 339 void idPhysics_Actor::DisableClip() { 340 clipModel->Disable(); 341 } 342 343 /* 344 ================ 345 idPhysics_Actor::EnableClip 346 ================ 347 */ 348 void idPhysics_Actor::EnableClip() { 349 clipModel->Enable(); 350 } 351 352 /* 353 ================ 354 idPhysics_Actor::UnlinkClip 355 ================ 356 */ 357 void idPhysics_Actor::UnlinkClip() { 358 clipModel->Unlink(); 359 } 360 361 /* 362 ================ 363 idPhysics_Actor::LinkClip 364 ================ 365 */ 366 void idPhysics_Actor::LinkClip() { 367 clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModel->GetAxis() ); 368 } 369 370 /* 371 ================ 372 idPhysics_Actor::EvaluateContacts 373 ================ 374 */ 375 bool idPhysics_Actor::EvaluateContacts() { 376 377 // get all the ground contacts 378 ClearContacts(); 379 AddGroundContacts( clipModel ); 380 AddContactEntitiesForContacts(); 381 382 return ( contacts.Num() != 0 ); 383 }