DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

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 }