Physics_Base.cpp (16687B)
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 #include "../Game_local.h" 33 34 CLASS_DECLARATION( idPhysics, idPhysics_Base ) 35 END_CLASS 36 37 /* 38 ================ 39 idPhysics_Base::idPhysics_Base 40 ================ 41 */ 42 idPhysics_Base::idPhysics_Base() { 43 self = NULL; 44 clipMask = 0; 45 SetGravity( gameLocal.GetGravity() ); 46 ClearContacts(); 47 } 48 49 /* 50 ================ 51 idPhysics_Base::~idPhysics_Base 52 ================ 53 */ 54 idPhysics_Base::~idPhysics_Base() { 55 if ( self && self->GetPhysics() == this ) { 56 self->SetPhysics( NULL ); 57 } 58 idForce::DeletePhysics( this ); 59 ClearContacts(); 60 } 61 62 /* 63 ================ 64 idPhysics_Base::Save 65 ================ 66 */ 67 void idPhysics_Base::Save( idSaveGame *savefile ) const { 68 int i; 69 70 savefile->WriteObject( self ); 71 savefile->WriteInt( clipMask ); 72 savefile->WriteVec3( gravityVector ); 73 savefile->WriteVec3( gravityNormal ); 74 75 savefile->WriteInt( contacts.Num() ); 76 for ( i = 0; i < contacts.Num(); i++ ) { 77 savefile->WriteContactInfo( contacts[i] ); 78 } 79 80 savefile->WriteInt( contactEntities.Num() ); 81 for ( i = 0; i < contactEntities.Num(); i++ ) { 82 contactEntities[i].Save( savefile ); 83 } 84 } 85 86 /* 87 ================ 88 idPhysics_Base::Restore 89 ================ 90 */ 91 void idPhysics_Base::Restore( idRestoreGame *savefile ) { 92 int i, num; 93 94 savefile->ReadObject( reinterpret_cast<idClass *&>( self ) ); 95 savefile->ReadInt( clipMask ); 96 savefile->ReadVec3( gravityVector ); 97 savefile->ReadVec3( gravityNormal ); 98 99 savefile->ReadInt( num ); 100 contacts.SetNum( num ); 101 for ( i = 0; i < contacts.Num(); i++ ) { 102 savefile->ReadContactInfo( contacts[i] ); 103 } 104 105 savefile->ReadInt( num ); 106 contactEntities.SetNum( num ); 107 for ( i = 0; i < contactEntities.Num(); i++ ) { 108 contactEntities[i].Restore( savefile ); 109 } 110 } 111 112 /* 113 ================ 114 idPhysics_Base::SetSelf 115 ================ 116 */ 117 void idPhysics_Base::SetSelf( idEntity *e ) { 118 assert( e ); 119 self = e; 120 } 121 122 /* 123 ================ 124 idPhysics_Base::SetClipModel 125 ================ 126 */ 127 void idPhysics_Base::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { 128 } 129 130 /* 131 ================ 132 idPhysics_Base::GetClipModel 133 ================ 134 */ 135 idClipModel *idPhysics_Base::GetClipModel( int id ) const { 136 return NULL; 137 } 138 139 /* 140 ================ 141 idPhysics_Base::GetNumClipModels 142 ================ 143 */ 144 int idPhysics_Base::GetNumClipModels() const { 145 return 0; 146 } 147 148 /* 149 ================ 150 idPhysics_Base::SetMass 151 ================ 152 */ 153 void idPhysics_Base::SetMass( float mass, int id ) { 154 } 155 156 /* 157 ================ 158 idPhysics_Base::GetMass 159 ================ 160 */ 161 float idPhysics_Base::GetMass( int id ) const { 162 return 0.0f; 163 } 164 165 /* 166 ================ 167 idPhysics_Base::SetContents 168 ================ 169 */ 170 void idPhysics_Base::SetContents( int contents, int id ) { 171 } 172 173 /* 174 ================ 175 idPhysics_Base::SetClipMask 176 ================ 177 */ 178 int idPhysics_Base::GetContents( int id ) const { 179 return 0; 180 } 181 182 /* 183 ================ 184 idPhysics_Base::SetClipMask 185 ================ 186 */ 187 void idPhysics_Base::SetClipMask( int mask, int id ) { 188 clipMask = mask; 189 } 190 191 /* 192 ================ 193 idPhysics_Base::GetClipMask 194 ================ 195 */ 196 int idPhysics_Base::GetClipMask( int id ) const { 197 return clipMask; 198 } 199 200 /* 201 ================ 202 idPhysics_Base::GetBounds 203 ================ 204 */ 205 const idBounds &idPhysics_Base::GetBounds( int id ) const { 206 return bounds_zero; 207 } 208 209 /* 210 ================ 211 idPhysics_Base::GetAbsBounds 212 ================ 213 */ 214 const idBounds &idPhysics_Base::GetAbsBounds( int id ) const { 215 return bounds_zero; 216 } 217 218 /* 219 ================ 220 idPhysics_Base::Evaluate 221 ================ 222 */ 223 bool idPhysics_Base::Evaluate( int timeStepMSec, int endTimeMSec ) { 224 return false; 225 } 226 227 /* 228 ================ 229 idPhysics_Base::Interpolate 230 ================ 231 */ 232 bool idPhysics_Base::Interpolate( const float fraction ) { 233 return false; 234 } 235 236 /* 237 ================ 238 idPhysics_Base::ResetInterpolationState 239 ================ 240 */ 241 void idPhysics_Base::ResetInterpolationState( const idVec3 & origin, const idMat3 & axis ) { 242 243 } 244 245 /* 246 ================ 247 idPhysics_Base::UpdateTime 248 ================ 249 */ 250 void idPhysics_Base::UpdateTime( int endTimeMSec ) { 251 } 252 253 /* 254 ================ 255 idPhysics_Base::GetTime 256 ================ 257 */ 258 int idPhysics_Base::GetTime() const { 259 return 0; 260 } 261 262 /* 263 ================ 264 idPhysics_Base::GetImpactInfo 265 ================ 266 */ 267 void idPhysics_Base::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { 268 memset( info, 0, sizeof( *info ) ); 269 } 270 271 /* 272 ================ 273 idPhysics_Base::ApplyImpulse 274 ================ 275 */ 276 void idPhysics_Base::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { 277 } 278 279 /* 280 ================ 281 idPhysics_Base::AddForce 282 ================ 283 */ 284 void idPhysics_Base::AddForce( const int id, const idVec3 &point, const idVec3 &force ) { 285 } 286 287 /* 288 ================ 289 idPhysics_Base::Activate 290 ================ 291 */ 292 void idPhysics_Base::Activate() { 293 } 294 295 /* 296 ================ 297 idPhysics_Base::PutToRest 298 ================ 299 */ 300 void idPhysics_Base::PutToRest() { 301 } 302 303 /* 304 ================ 305 idPhysics_Base::IsAtRest 306 ================ 307 */ 308 bool idPhysics_Base::IsAtRest() const { 309 return true; 310 } 311 312 /* 313 ================ 314 idPhysics_Base::GetRestStartTime 315 ================ 316 */ 317 int idPhysics_Base::GetRestStartTime() const { 318 return 0; 319 } 320 321 /* 322 ================ 323 idPhysics_Base::IsPushable 324 ================ 325 */ 326 bool idPhysics_Base::IsPushable() const { 327 return true; 328 } 329 330 /* 331 ================ 332 idPhysics_Base::SaveState 333 ================ 334 */ 335 void idPhysics_Base::SaveState() { 336 } 337 338 /* 339 ================ 340 idPhysics_Base::RestoreState 341 ================ 342 */ 343 void idPhysics_Base::RestoreState() { 344 } 345 346 /* 347 ================ 348 idPhysics_Base::SetOrigin 349 ================ 350 */ 351 void idPhysics_Base::SetOrigin( const idVec3 &newOrigin, int id ) { 352 } 353 354 /* 355 ================ 356 idPhysics_Base::SetAxis 357 ================ 358 */ 359 void idPhysics_Base::SetAxis( const idMat3 &newAxis, int id ) { 360 } 361 362 /* 363 ================ 364 idPhysics_Base::Translate 365 ================ 366 */ 367 void idPhysics_Base::Translate( const idVec3 &translation, int id ) { 368 } 369 370 /* 371 ================ 372 idPhysics_Base::Rotate 373 ================ 374 */ 375 void idPhysics_Base::Rotate( const idRotation &rotation, int id ) { 376 } 377 378 /* 379 ================ 380 idPhysics_Base::GetOrigin 381 ================ 382 */ 383 const idVec3 &idPhysics_Base::GetOrigin( int id ) const { 384 return vec3_origin; 385 } 386 387 /* 388 ================ 389 idPhysics_Base::GetAxis 390 ================ 391 */ 392 const idMat3 &idPhysics_Base::GetAxis( int id ) const { 393 return mat3_identity; 394 } 395 396 /* 397 ================ 398 idPhysics_Base::SetLinearVelocity 399 ================ 400 */ 401 void idPhysics_Base::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { 402 } 403 404 /* 405 ================ 406 idPhysics_Base::SetAngularVelocity 407 ================ 408 */ 409 void idPhysics_Base::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { 410 } 411 412 /* 413 ================ 414 idPhysics_Base::GetLinearVelocity 415 ================ 416 */ 417 const idVec3 &idPhysics_Base::GetLinearVelocity( int id ) const { 418 return vec3_origin; 419 } 420 421 /* 422 ================ 423 idPhysics_Base::GetAngularVelocity 424 ================ 425 */ 426 const idVec3 &idPhysics_Base::GetAngularVelocity( int id ) const { 427 return vec3_origin; 428 } 429 430 /* 431 ================ 432 idPhysics_Base::SetGravity 433 ================ 434 */ 435 void idPhysics_Base::SetGravity( const idVec3 &newGravity ) { 436 gravityVector = newGravity; 437 gravityNormal = newGravity; 438 gravityNormal.Normalize(); 439 } 440 441 /* 442 ================ 443 idPhysics_Base::GetGravity 444 ================ 445 */ 446 const idVec3 &idPhysics_Base::GetGravity() const { 447 return gravityVector; 448 } 449 450 /* 451 ================ 452 idPhysics_Base::GetGravityNormal 453 ================ 454 */ 455 const idVec3 &idPhysics_Base::GetGravityNormal() const { 456 return gravityNormal; 457 } 458 459 /* 460 ================ 461 idPhysics_Base::ClipTranslation 462 ================ 463 */ 464 void idPhysics_Base::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { 465 memset( &results, 0, sizeof( trace_t ) ); 466 } 467 468 /* 469 ================ 470 idPhysics_Base::ClipRotation 471 ================ 472 */ 473 void idPhysics_Base::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { 474 memset( &results, 0, sizeof( trace_t ) ); 475 } 476 477 /* 478 ================ 479 idPhysics_Base::ClipContents 480 ================ 481 */ 482 int idPhysics_Base::ClipContents( const idClipModel *model ) const { 483 return 0; 484 } 485 486 /* 487 ================ 488 idPhysics_Base::DisableClip 489 ================ 490 */ 491 void idPhysics_Base::DisableClip() { 492 } 493 494 /* 495 ================ 496 idPhysics_Base::EnableClip 497 ================ 498 */ 499 void idPhysics_Base::EnableClip() { 500 } 501 502 /* 503 ================ 504 idPhysics_Base::UnlinkClip 505 ================ 506 */ 507 void idPhysics_Base::UnlinkClip() { 508 } 509 510 /* 511 ================ 512 idPhysics_Base::LinkClip 513 ================ 514 */ 515 void idPhysics_Base::LinkClip() { 516 } 517 518 /* 519 ================ 520 idPhysics_Base::EvaluateContacts 521 ================ 522 */ 523 bool idPhysics_Base::EvaluateContacts() { 524 return false; 525 } 526 527 /* 528 ================ 529 idPhysics_Base::GetNumContacts 530 ================ 531 */ 532 int idPhysics_Base::GetNumContacts() const { 533 return contacts.Num(); 534 } 535 536 /* 537 ================ 538 idPhysics_Base::GetContact 539 ================ 540 */ 541 const contactInfo_t &idPhysics_Base::GetContact( int num ) const { 542 return contacts[num]; 543 } 544 545 /* 546 ================ 547 idPhysics_Base::ClearContacts 548 ================ 549 */ 550 void idPhysics_Base::ClearContacts() { 551 int i; 552 idEntity *ent; 553 554 for ( i = 0; i < contacts.Num(); i++ ) { 555 ent = gameLocal.entities[ contacts[i].entityNum ]; 556 if ( ent ) { 557 ent->RemoveContactEntity( self ); 558 } 559 } 560 contacts.SetNum( 0 ); 561 } 562 563 /* 564 ================ 565 idPhysics_Base::AddContactEntity 566 ================ 567 */ 568 void idPhysics_Base::AddContactEntity( idEntity *e ) { 569 int i; 570 idEntity *ent; 571 bool found = false; 572 573 for ( i = 0; i < contactEntities.Num(); i++ ) { 574 ent = contactEntities[i].GetEntity(); 575 if ( ent == NULL ) { 576 contactEntities.RemoveIndex( i-- ); 577 } 578 if ( ent == e ) { 579 found = true; 580 } 581 } 582 if ( !found ) { 583 contactEntities.Alloc() = e; 584 } 585 } 586 587 /* 588 ================ 589 idPhysics_Base::RemoveContactEntity 590 ================ 591 */ 592 void idPhysics_Base::RemoveContactEntity( idEntity *e ) { 593 int i; 594 idEntity *ent; 595 596 for ( i = 0; i < contactEntities.Num(); i++ ) { 597 ent = contactEntities[i].GetEntity(); 598 if ( !ent ) { 599 contactEntities.RemoveIndex( i-- ); 600 continue; 601 } 602 if ( ent == e ) { 603 contactEntities.RemoveIndex( i-- ); 604 return; 605 } 606 } 607 } 608 609 /* 610 ================ 611 idPhysics_Base::HasGroundContacts 612 ================ 613 */ 614 bool idPhysics_Base::HasGroundContacts() const { 615 int i; 616 617 for ( i = 0; i < contacts.Num(); i++ ) { 618 if ( contacts[i].normal * -gravityNormal > 0.0f ) { 619 return true; 620 } 621 } 622 return false; 623 } 624 625 /* 626 ================ 627 idPhysics_Base::IsGroundEntity 628 ================ 629 */ 630 bool idPhysics_Base::IsGroundEntity( int entityNum ) const { 631 int i; 632 633 for ( i = 0; i < contacts.Num(); i++ ) { 634 if ( contacts[i].entityNum == entityNum && ( contacts[i].normal * -gravityNormal > 0.0f ) ) { 635 return true; 636 } 637 } 638 return false; 639 } 640 641 /* 642 ================ 643 idPhysics_Base::IsGroundClipModel 644 ================ 645 */ 646 bool idPhysics_Base::IsGroundClipModel( int entityNum, int id ) const { 647 int i; 648 649 for ( i = 0; i < contacts.Num(); i++ ) { 650 if ( contacts[i].entityNum == entityNum && contacts[i].id == id && ( contacts[i].normal * -gravityNormal > 0.0f ) ) { 651 return true; 652 } 653 } 654 return false; 655 } 656 657 /* 658 ================ 659 idPhysics_Base::SetPushed 660 ================ 661 */ 662 void idPhysics_Base::SetPushed( int deltaTime ) { 663 } 664 665 /* 666 ================ 667 idPhysics_Base::GetPushedLinearVelocity 668 ================ 669 */ 670 const idVec3 &idPhysics_Base::GetPushedLinearVelocity( const int id ) const { 671 return vec3_origin; 672 } 673 674 /* 675 ================ 676 idPhysics_Base::GetPushedAngularVelocity 677 ================ 678 */ 679 const idVec3 &idPhysics_Base::GetPushedAngularVelocity( const int id ) const { 680 return vec3_origin; 681 } 682 683 /* 684 ================ 685 idPhysics_Base::SetMaster 686 ================ 687 */ 688 void idPhysics_Base::SetMaster( idEntity *master, const bool orientated ) { 689 } 690 691 /* 692 ================ 693 idPhysics_Base::GetBlockingInfo 694 ================ 695 */ 696 const trace_t *idPhysics_Base::GetBlockingInfo() const { 697 return NULL; 698 } 699 700 /* 701 ================ 702 idPhysics_Base::GetBlockingEntity 703 ================ 704 */ 705 idEntity *idPhysics_Base::GetBlockingEntity() const { 706 return NULL; 707 } 708 709 /* 710 ================ 711 idPhysics_Base::GetLinearEndTime 712 ================ 713 */ 714 int idPhysics_Base::GetLinearEndTime() const { 715 return 0; 716 } 717 718 /* 719 ================ 720 idPhysics_Base::GetAngularEndTime 721 ================ 722 */ 723 int idPhysics_Base::GetAngularEndTime() const { 724 return 0; 725 } 726 727 /* 728 ================ 729 idPhysics_Base::AddGroundContacts 730 ================ 731 */ 732 void idPhysics_Base::AddGroundContacts( const idClipModel *clipModel ) { 733 idVec6 dir; 734 int index, num; 735 736 index = contacts.Num(); 737 contacts.SetNum( index + 10 ); 738 739 dir.SubVec3(0) = gravityNormal; 740 dir.SubVec3(1) = vec3_origin; 741 num = gameLocal.clip.Contacts( &contacts[index], 10, clipModel->GetOrigin(), 742 dir, CONTACT_EPSILON, clipModel, clipModel->GetAxis(), clipMask, self ); 743 contacts.SetNum( index + num ); 744 } 745 746 /* 747 ================ 748 idPhysics_Base::AddContactEntitiesForContacts 749 ================ 750 */ 751 void idPhysics_Base::AddContactEntitiesForContacts() { 752 int i; 753 idEntity *ent; 754 755 for ( i = 0; i < contacts.Num(); i++ ) { 756 ent = gameLocal.entities[ contacts[i].entityNum ]; 757 if ( ent && ent != self ) { 758 ent->AddContactEntity( self ); 759 } 760 } 761 } 762 763 /* 764 ================ 765 idPhysics_Base::ActivateContactEntities 766 ================ 767 */ 768 void idPhysics_Base::ActivateContactEntities() { 769 int i; 770 idEntity *ent; 771 772 for ( i = 0; i < contactEntities.Num(); i++ ) { 773 ent = contactEntities[i].GetEntity(); 774 if ( ent ) { 775 ent->ActivatePhysics( self ); 776 } else { 777 contactEntities.RemoveIndex( i-- ); 778 } 779 } 780 } 781 782 /* 783 ================ 784 idPhysics_Base::IsOutsideWorld 785 ================ 786 */ 787 bool idPhysics_Base::IsOutsideWorld() const { 788 if ( !gameLocal.clip.GetWorldBounds().Expand( 128.0f ).IntersectsBounds( GetAbsBounds() ) ) { 789 return true; 790 } 791 return false; 792 } 793 794 /* 795 ================ 796 idPhysics_Base::DrawVelocity 797 ================ 798 */ 799 void idPhysics_Base::DrawVelocity( int id, float linearScale, float angularScale ) const { 800 idVec3 dir, org, vec, start, end; 801 idMat3 axis; 802 float length, a; 803 804 dir = GetLinearVelocity( id ); 805 dir *= linearScale; 806 if ( dir.LengthSqr() > Square( 0.1f ) ) { 807 dir = dir.Truncate( 10.0f ); 808 org = GetOrigin( id ); 809 gameRenderWorld->DebugArrow( colorRed, org, org + dir, 1 ); 810 } 811 812 dir = GetAngularVelocity( id ); 813 length = dir.Normalize(); 814 length *= angularScale; 815 if ( length > 0.1f ) { 816 if ( length < 60.0f ) { 817 length = 60.0f; 818 } 819 else if ( length > 360.0f ) { 820 length = 360.0f; 821 } 822 axis = GetAxis( id ); 823 vec = axis[2]; 824 if ( idMath::Fabs( dir * vec ) > 0.99f ) { 825 vec = axis[0]; 826 } 827 vec -= vec * dir * vec; 828 vec.Normalize(); 829 vec *= 4.0f; 830 start = org + vec; 831 for ( a = 20.0f; a < length; a += 20.0f ) { 832 end = org + idRotation( vec3_origin, dir, -a ).ToMat3() * vec; 833 gameRenderWorld->DebugLine( colorBlue, start, end, 1 ); 834 start = end; 835 } 836 end = org + idRotation( vec3_origin, dir, -length ).ToMat3() * vec; 837 gameRenderWorld->DebugArrow( colorBlue, start, end, 1 ); 838 } 839 } 840 841 /* 842 ================ 843 idPhysics_Base::WriteToSnapshot 844 ================ 845 */ 846 void idPhysics_Base::WriteToSnapshot( idBitMsg &msg ) const { 847 } 848 849 /* 850 ================ 851 idPhysics_Base::ReadFromSnapshot 852 ================ 853 */ 854 void idPhysics_Base::ReadFromSnapshot( const idBitMsg &msg ) { 855 }