Physics_Parametric.cpp (29312B)
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_Base, idPhysics_Parametric ) 35 END_CLASS 36 37 38 /* 39 ================ 40 idPhysics_Parametric::Activate 41 ================ 42 */ 43 void idPhysics_Parametric::Activate() { 44 current.atRest = -1; 45 self->BecomeActive( TH_PHYSICS ); 46 } 47 48 /* 49 ================ 50 idPhysics_Parametric::TestIfAtRest 51 ================ 52 */ 53 bool idPhysics_Parametric::TestIfAtRest() const { 54 55 if ( ( current.linearExtrapolation.GetExtrapolationType() & ~EXTRAPOLATION_NOSTOP ) == EXTRAPOLATION_NONE && 56 ( current.angularExtrapolation.GetExtrapolationType() & ~EXTRAPOLATION_NOSTOP ) == EXTRAPOLATION_NONE && 57 current.linearInterpolation.GetDuration() == 0 && 58 current.angularInterpolation.GetDuration() == 0 && 59 current.spline == NULL ) { 60 return true; 61 } 62 63 if ( !current.linearExtrapolation.IsDone( current.time ) ) { 64 return false; 65 } 66 67 if ( !current.angularExtrapolation.IsDone( current.time ) ) { 68 return false; 69 } 70 71 if ( !current.linearInterpolation.IsDone( current.time ) ) { 72 return false; 73 } 74 75 if ( !current.angularInterpolation.IsDone( current.time ) ) { 76 return false; 77 } 78 79 if ( current.spline != NULL && !current.spline->IsDone( current.time ) ) { 80 return false; 81 } 82 83 return true; 84 } 85 86 /* 87 ================ 88 idPhysics_Parametric::Rest 89 ================ 90 */ 91 void idPhysics_Parametric::Rest() { 92 current.atRest = gameLocal.time; 93 self->BecomeInactive( TH_PHYSICS ); 94 } 95 96 /* 97 ================ 98 idPhysics_Parametric::idPhysics_Parametric 99 ================ 100 */ 101 idPhysics_Parametric::idPhysics_Parametric() { 102 103 current.time = gameLocal.time; 104 current.atRest = -1; 105 current.useSplineAngles = false; 106 current.origin.Zero(); 107 current.angles.Zero(); 108 current.axis.Identity(); 109 current.localOrigin.Zero(); 110 current.localAngles.Zero(); 111 current.linearExtrapolation.Init( 0, 0, vec3_zero, vec3_zero, vec3_zero, EXTRAPOLATION_NONE ); 112 current.angularExtrapolation.Init( 0, 0, ang_zero, ang_zero, ang_zero, EXTRAPOLATION_NONE ); 113 current.linearInterpolation.Init( 0, 0, 0, 0, vec3_zero, vec3_zero ); 114 current.angularInterpolation.Init( 0, 0, 0, 0, ang_zero, ang_zero ); 115 current.spline = NULL; 116 current.splineInterpolate.Init( 0, 1, 1, 2, 0, 0 ); 117 118 saved = current; 119 120 isPusher = false; 121 pushFlags = 0; 122 clipModel = NULL; 123 isBlocked = false; 124 memset( &pushResults, 0, sizeof( pushResults ) ); 125 126 hasMaster = false; 127 isOrientated = false; 128 } 129 130 /* 131 ================ 132 idPhysics_Parametric::~idPhysics_Parametric 133 ================ 134 */ 135 idPhysics_Parametric::~idPhysics_Parametric() { 136 if ( clipModel != NULL ) { 137 delete clipModel; 138 clipModel = NULL; 139 } 140 if ( current.spline != NULL ) { 141 delete current.spline; 142 current.spline = NULL; 143 } 144 } 145 146 /* 147 ================ 148 idPhysics_Parametric_SavePState 149 ================ 150 */ 151 void idPhysics_Parametric_SavePState( idSaveGame *savefile, const parametricPState_t &state ) { 152 savefile->WriteInt( state.time ); 153 savefile->WriteInt( state.atRest ); 154 savefile->WriteBool( state.useSplineAngles ); 155 savefile->WriteVec3( state.origin ); 156 savefile->WriteAngles( state.angles ); 157 savefile->WriteMat3( state.axis ); 158 savefile->WriteVec3( state.localOrigin ); 159 savefile->WriteAngles( state.localAngles ); 160 161 savefile->WriteInt( (int)state.linearExtrapolation.GetExtrapolationType() ); 162 savefile->WriteFloat( state.linearExtrapolation.GetStartTime() ); 163 savefile->WriteFloat( state.linearExtrapolation.GetDuration() ); 164 savefile->WriteVec3( state.linearExtrapolation.GetStartValue() ); 165 savefile->WriteVec3( state.linearExtrapolation.GetBaseSpeed() ); 166 savefile->WriteVec3( state.linearExtrapolation.GetSpeed() ); 167 168 savefile->WriteInt( (int)state.angularExtrapolation.GetExtrapolationType() ); 169 savefile->WriteFloat( state.angularExtrapolation.GetStartTime() ); 170 savefile->WriteFloat( state.angularExtrapolation.GetDuration() ); 171 savefile->WriteAngles( state.angularExtrapolation.GetStartValue() ); 172 savefile->WriteAngles( state.angularExtrapolation.GetBaseSpeed() ); 173 savefile->WriteAngles( state.angularExtrapolation.GetSpeed() ); 174 175 savefile->WriteFloat( state.linearInterpolation.GetStartTime() ); 176 savefile->WriteFloat( state.linearInterpolation.GetAcceleration() ); 177 savefile->WriteFloat( state.linearInterpolation.GetDeceleration() ); 178 savefile->WriteFloat( state.linearInterpolation.GetDuration() ); 179 savefile->WriteVec3( state.linearInterpolation.GetStartValue() ); 180 savefile->WriteVec3( state.linearInterpolation.GetEndValue() ); 181 182 savefile->WriteFloat( state.angularInterpolation.GetStartTime() ); 183 savefile->WriteFloat( state.angularInterpolation.GetAcceleration() ); 184 savefile->WriteFloat( state.angularInterpolation.GetDeceleration() ); 185 savefile->WriteFloat( state.angularInterpolation.GetDuration() ); 186 savefile->WriteAngles( state.angularInterpolation.GetStartValue() ); 187 savefile->WriteAngles( state.angularInterpolation.GetEndValue() ); 188 189 // spline is handled by owner 190 191 savefile->WriteFloat( state.splineInterpolate.GetStartTime() ); 192 savefile->WriteFloat( state.splineInterpolate.GetAcceleration() ); 193 savefile->WriteFloat( state.splineInterpolate.GetDuration() ); 194 savefile->WriteFloat( state.splineInterpolate.GetDeceleration() ); 195 savefile->WriteFloat( state.splineInterpolate.GetStartValue() ); 196 savefile->WriteFloat( state.splineInterpolate.GetEndValue() ); 197 } 198 199 /* 200 ================ 201 idPhysics_Parametric_RestorePState 202 ================ 203 */ 204 void idPhysics_Parametric_RestorePState( idRestoreGame *savefile, parametricPState_t &state ) { 205 extrapolation_t etype; 206 float startTime, duration, accelTime, decelTime, startValue, endValue; 207 idVec3 linearStartValue, linearBaseSpeed, linearSpeed, startPos, endPos; 208 idAngles angularStartValue, angularBaseSpeed, angularSpeed, startAng, endAng; 209 210 savefile->ReadInt( state.time ); 211 savefile->ReadInt( state.atRest ); 212 savefile->ReadBool( state.useSplineAngles ); 213 savefile->ReadVec3( state.origin ); 214 savefile->ReadAngles( state.angles ); 215 savefile->ReadMat3( state.axis ); 216 savefile->ReadVec3( state.localOrigin ); 217 savefile->ReadAngles( state.localAngles ); 218 219 savefile->ReadInt( (int &)etype ); 220 savefile->ReadFloat( startTime ); 221 savefile->ReadFloat( duration ); 222 savefile->ReadVec3( linearStartValue ); 223 savefile->ReadVec3( linearBaseSpeed ); 224 savefile->ReadVec3( linearSpeed ); 225 226 state.linearExtrapolation.Init( startTime, duration, linearStartValue, linearBaseSpeed, linearSpeed, etype ); 227 228 savefile->ReadInt( (int &)etype ); 229 savefile->ReadFloat( startTime ); 230 savefile->ReadFloat( duration ); 231 savefile->ReadAngles( angularStartValue ); 232 savefile->ReadAngles( angularBaseSpeed ); 233 savefile->ReadAngles( angularSpeed ); 234 235 state.angularExtrapolation.Init( startTime, duration, angularStartValue, angularBaseSpeed, angularSpeed, etype ); 236 237 savefile->ReadFloat( startTime ); 238 savefile->ReadFloat( accelTime ); 239 savefile->ReadFloat( decelTime ); 240 savefile->ReadFloat( duration ); 241 savefile->ReadVec3( startPos ); 242 savefile->ReadVec3( endPos ); 243 244 state.linearInterpolation.Init( startTime, accelTime, decelTime, duration, startPos, endPos ); 245 246 savefile->ReadFloat( startTime ); 247 savefile->ReadFloat( accelTime ); 248 savefile->ReadFloat( decelTime ); 249 savefile->ReadFloat( duration ); 250 savefile->ReadAngles( startAng ); 251 savefile->ReadAngles( endAng ); 252 253 state.angularInterpolation.Init( startTime, accelTime, decelTime, duration, startAng, endAng ); 254 255 // spline is handled by owner 256 257 savefile->ReadFloat( startTime ); 258 savefile->ReadFloat( accelTime ); 259 savefile->ReadFloat( duration ); 260 savefile->ReadFloat( decelTime ); 261 savefile->ReadFloat( startValue ); 262 savefile->ReadFloat( endValue ); 263 264 state.splineInterpolate.Init( startTime, accelTime, decelTime, duration, startValue, endValue ); 265 } 266 267 /* 268 ================ 269 idPhysics_Parametric::Save 270 ================ 271 */ 272 void idPhysics_Parametric::Save( idSaveGame *savefile ) const { 273 274 idPhysics_Parametric_SavePState( savefile, current ); 275 idPhysics_Parametric_SavePState( savefile, saved ); 276 277 savefile->WriteBool( isPusher ); 278 savefile->WriteClipModel( clipModel ); 279 savefile->WriteInt( pushFlags ); 280 281 savefile->WriteTrace( pushResults ); 282 savefile->WriteBool( isBlocked ); 283 284 savefile->WriteBool( hasMaster ); 285 savefile->WriteBool( isOrientated ); 286 } 287 288 /* 289 ================ 290 idPhysics_Parametric::Restore 291 ================ 292 */ 293 void idPhysics_Parametric::Restore( idRestoreGame *savefile ) { 294 295 idPhysics_Parametric_RestorePState( savefile, current ); 296 idPhysics_Parametric_RestorePState( savefile, saved ); 297 298 savefile->ReadBool( isPusher ); 299 savefile->ReadClipModel( clipModel ); 300 savefile->ReadInt( pushFlags ); 301 302 savefile->ReadTrace( pushResults ); 303 savefile->ReadBool( isBlocked ); 304 305 savefile->ReadBool( hasMaster ); 306 savefile->ReadBool( isOrientated ); 307 } 308 309 /* 310 ================ 311 idPhysics_Parametric::SetPusher 312 ================ 313 */ 314 void idPhysics_Parametric::SetPusher( int flags ) { 315 assert( clipModel ); 316 isPusher = true; 317 pushFlags = flags; 318 } 319 320 /* 321 ================ 322 idPhysics_Parametric::IsPusher 323 ================ 324 */ 325 bool idPhysics_Parametric::IsPusher() const { 326 return isPusher; 327 } 328 329 /* 330 ================ 331 idPhysics_Parametric::SetLinearExtrapolation 332 ================ 333 */ 334 void idPhysics_Parametric::SetLinearExtrapolation( extrapolation_t type, int time, int duration, const idVec3 &base, const idVec3 &speed, const idVec3 &baseSpeed ) { 335 current.time = gameLocal.time; 336 current.linearExtrapolation.Init( time, duration, base, baseSpeed, speed, type ); 337 current.localOrigin = base; 338 Activate(); 339 } 340 341 /* 342 ================ 343 idPhysics_Parametric::SetAngularExtrapolation 344 ================ 345 */ 346 void idPhysics_Parametric::SetAngularExtrapolation( extrapolation_t type, int time, int duration, const idAngles &base, const idAngles &speed, const idAngles &baseSpeed ) { 347 current.time = gameLocal.time; 348 current.angularExtrapolation.Init( time, duration, base, baseSpeed, speed, type ); 349 current.localAngles = base; 350 Activate(); 351 } 352 353 /* 354 ================ 355 idPhysics_Parametric::GetLinearExtrapolationType 356 ================ 357 */ 358 extrapolation_t idPhysics_Parametric::GetLinearExtrapolationType() const { 359 return current.linearExtrapolation.GetExtrapolationType(); 360 } 361 362 /* 363 ================ 364 idPhysics_Parametric::GetAngularExtrapolationType 365 ================ 366 */ 367 extrapolation_t idPhysics_Parametric::GetAngularExtrapolationType() const { 368 return current.angularExtrapolation.GetExtrapolationType(); 369 } 370 371 /* 372 ================ 373 idPhysics_Parametric::SetLinearInterpolation 374 ================ 375 */ 376 void idPhysics_Parametric::SetLinearInterpolation( int time, int accelTime, int decelTime, int duration, const idVec3 &startPos, const idVec3 &endPos ) { 377 current.time = gameLocal.time; 378 current.linearInterpolation.Init( time, accelTime, decelTime, duration, startPos, endPos ); 379 current.localOrigin = startPos; 380 Activate(); 381 } 382 383 /* 384 ================ 385 idPhysics_Parametric::SetAngularInterpolation 386 ================ 387 */ 388 void idPhysics_Parametric::SetAngularInterpolation( int time, int accelTime, int decelTime, int duration, const idAngles &startAng, const idAngles &endAng ) { 389 current.time = gameLocal.time; 390 current.angularInterpolation.Init( time, accelTime, decelTime, duration, startAng, endAng ); 391 current.localAngles = startAng; 392 Activate(); 393 } 394 395 /* 396 ================ 397 idPhysics_Parametric::SetSpline 398 ================ 399 */ 400 void idPhysics_Parametric::SetSpline( idCurve_Spline<idVec3> *spline, int accelTime, int decelTime, bool useSplineAngles ) { 401 if ( current.spline != NULL ) { 402 delete current.spline; 403 current.spline = NULL; 404 } 405 current.spline = spline; 406 if ( current.spline != NULL ) { 407 float startTime = current.spline->GetTime( 0 ); 408 float endTime = current.spline->GetTime( current.spline->GetNumValues() - 1 ); 409 float length = current.spline->GetLengthForTime( endTime ); 410 current.splineInterpolate.Init( startTime, accelTime, decelTime, endTime - startTime, 0.0f, length ); 411 } 412 current.useSplineAngles = useSplineAngles; 413 Activate(); 414 } 415 416 /* 417 ================ 418 idPhysics_Parametric::GetSpline 419 ================ 420 */ 421 idCurve_Spline<idVec3> *idPhysics_Parametric::GetSpline() const { 422 return current.spline; 423 } 424 425 /* 426 ================ 427 idPhysics_Parametric::GetSplineAcceleration 428 ================ 429 */ 430 int idPhysics_Parametric::GetSplineAcceleration() const { 431 return current.splineInterpolate.GetAcceleration(); 432 } 433 434 /* 435 ================ 436 idPhysics_Parametric::GetSplineDeceleration 437 ================ 438 */ 439 int idPhysics_Parametric::GetSplineDeceleration() const { 440 return current.splineInterpolate.GetDeceleration(); 441 } 442 443 /* 444 ================ 445 idPhysics_Parametric::UsingSplineAngles 446 ================ 447 */ 448 bool idPhysics_Parametric::UsingSplineAngles() const { 449 return current.useSplineAngles; 450 } 451 452 /* 453 ================ 454 idPhysics_Parametric::GetLocalOrigin 455 ================ 456 */ 457 void idPhysics_Parametric::GetLocalOrigin( idVec3 &curOrigin ) const { 458 curOrigin = current.localOrigin; 459 } 460 461 /* 462 ================ 463 idPhysics_Parametric::GetLocalAngles 464 ================ 465 */ 466 void idPhysics_Parametric::GetLocalAngles( idAngles &curAngles ) const { 467 curAngles = current.localAngles; 468 } 469 470 /* 471 ================ 472 idPhysics_Parametric::SetClipModel 473 ================ 474 */ 475 void idPhysics_Parametric::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { 476 477 assert( self ); 478 assert( model ); 479 480 if ( clipModel && clipModel != model && freeOld ) { 481 delete clipModel; 482 } 483 clipModel = model; 484 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); 485 } 486 487 /* 488 ================ 489 idPhysics_Parametric::GetClipModel 490 ================ 491 */ 492 idClipModel *idPhysics_Parametric::GetClipModel( int id ) const { 493 return clipModel; 494 } 495 496 /* 497 ================ 498 idPhysics_Parametric::GetNumClipModels 499 ================ 500 */ 501 int idPhysics_Parametric::GetNumClipModels() const { 502 return ( clipModel != NULL ); 503 } 504 505 /* 506 ================ 507 idPhysics_Parametric::SetMass 508 ================ 509 */ 510 void idPhysics_Parametric::SetMass( float mass, int id ) { 511 } 512 513 /* 514 ================ 515 idPhysics_Parametric::GetMass 516 ================ 517 */ 518 float idPhysics_Parametric::GetMass( int id ) const { 519 return 0.0f; 520 } 521 522 /* 523 ================ 524 idPhysics_Parametric::SetClipMask 525 ================ 526 */ 527 void idPhysics_Parametric::SetContents( int contents, int id ) { 528 if ( clipModel ) { 529 clipModel->SetContents( contents ); 530 } 531 } 532 533 /* 534 ================ 535 idPhysics_Parametric::SetClipMask 536 ================ 537 */ 538 int idPhysics_Parametric::GetContents( int id ) const { 539 if ( clipModel ) { 540 return clipModel->GetContents(); 541 } 542 return 0; 543 } 544 545 /* 546 ================ 547 idPhysics_Parametric::GetBounds 548 ================ 549 */ 550 const idBounds &idPhysics_Parametric::GetBounds( int id ) const { 551 if ( clipModel ) { 552 return clipModel->GetBounds(); 553 } 554 return idPhysics_Base::GetBounds(); 555 } 556 557 /* 558 ================ 559 idPhysics_Parametric::GetAbsBounds 560 ================ 561 */ 562 const idBounds &idPhysics_Parametric::GetAbsBounds( int id ) const { 563 if ( clipModel ) { 564 return clipModel->GetAbsBounds(); 565 } 566 return idPhysics_Base::GetAbsBounds(); 567 } 568 569 /* 570 ================ 571 idPhysics_Parametric::Evaluate 572 ================ 573 */ 574 bool idPhysics_Parametric::Evaluate( int timeStepMSec, int endTimeMSec ) { 575 idVec3 oldLocalOrigin, oldOrigin, masterOrigin; 576 idAngles oldLocalAngles, oldAngles; 577 idMat3 oldAxis, masterAxis; 578 579 isBlocked = false; 580 oldLocalOrigin = current.localOrigin; 581 oldOrigin = current.origin; 582 oldLocalAngles = current.localAngles; 583 oldAngles = current.angles; 584 oldAxis = current.axis; 585 586 current.localOrigin.Zero(); 587 current.localAngles.Zero(); 588 589 if ( current.spline != NULL ) { 590 float length = current.splineInterpolate.GetCurrentValue( endTimeMSec ); 591 float t = current.spline->GetTimeForLength( length, 0.01f ); 592 current.localOrigin = current.spline->GetCurrentValue( t ); 593 if ( current.useSplineAngles ) { 594 current.localAngles = current.spline->GetCurrentFirstDerivative( t ).ToAngles(); 595 } 596 } else if ( current.linearInterpolation.GetDuration() != 0 ) { 597 current.localOrigin += current.linearInterpolation.GetCurrentValue( endTimeMSec ); 598 } else { 599 current.localOrigin += current.linearExtrapolation.GetCurrentValue( endTimeMSec ); 600 } 601 602 if ( current.angularInterpolation.GetDuration() != 0 ) { 603 current.localAngles += current.angularInterpolation.GetCurrentValue( endTimeMSec ); 604 } else { 605 current.localAngles += current.angularExtrapolation.GetCurrentValue( endTimeMSec ); 606 } 607 608 current.localAngles.Normalize360(); 609 current.origin = current.localOrigin; 610 current.angles = current.localAngles; 611 current.axis = current.localAngles.ToMat3(); 612 613 if ( hasMaster ) { 614 self->GetMasterPosition( masterOrigin, masterAxis ); 615 if ( masterAxis.IsRotated() ) { 616 current.origin = current.origin * masterAxis + masterOrigin; 617 if ( isOrientated ) { 618 current.axis *= masterAxis; 619 current.angles = current.axis.ToAngles(); 620 } 621 } 622 else { 623 current.origin += masterOrigin; 624 } 625 } 626 627 if ( isPusher ) { 628 629 gameLocal.push.ClipPush( pushResults, self, pushFlags, oldOrigin, oldAxis, current.origin, current.axis ); 630 if ( pushResults.fraction < 1.0f ) { 631 if ( clipModel ) { 632 clipModel->Link( gameLocal.clip, self, 0, oldOrigin, oldAxis ); 633 } 634 current.localOrigin = oldLocalOrigin; 635 current.origin = oldOrigin; 636 current.localAngles = oldLocalAngles; 637 current.angles = oldAngles; 638 current.axis = oldAxis; 639 isBlocked = true; 640 return false; 641 } 642 643 current.angles = current.axis.ToAngles(); 644 } 645 646 if ( clipModel ) { 647 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); 648 } 649 650 current.time = endTimeMSec; 651 652 if ( TestIfAtRest() ) { 653 Rest(); 654 } 655 656 return ( current.origin != oldOrigin || current.axis != oldAxis ); 657 } 658 659 /* 660 ================ 661 Sets the currentInterpolated state based on previous, next, and the fraction. 662 ================ 663 */ 664 bool idPhysics_Parametric::Interpolate( const float fraction ) { 665 666 if( self->GetNumSnapshotsReceived() <= 1 ) { 667 return false; 668 } 669 670 idVec3 oldOrigin = current.origin; 671 idMat3 oldAxis = current.axis; 672 673 const bool hasChanged = InterpolatePhysicsState( current, previous, next, fraction ); 674 675 gameLocal.push.ClipPush( pushResults, self, pushFlags, oldOrigin, oldAxis, current.origin, current.axis ); 676 677 if ( clipModel ) { 678 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); 679 } 680 681 return hasChanged; 682 } 683 684 /* 685 ================ 686 idPhysics_Parametric::UpdateTime 687 ================ 688 */ 689 void idPhysics_Parametric::UpdateTime( int endTimeMSec ) { 690 int timeLeap = endTimeMSec - current.time; 691 692 current.time = endTimeMSec; 693 // move the trajectory start times to sync the trajectory with the current endTime 694 current.linearExtrapolation.SetStartTime( current.linearExtrapolation.GetStartTime() + timeLeap ); 695 current.angularExtrapolation.SetStartTime( current.angularExtrapolation.GetStartTime() + timeLeap ); 696 current.linearInterpolation.SetStartTime( current.linearInterpolation.GetStartTime() + timeLeap ); 697 current.angularInterpolation.SetStartTime( current.angularInterpolation.GetStartTime() + timeLeap ); 698 if ( current.spline != NULL ) { 699 current.spline->ShiftTime( timeLeap ); 700 current.splineInterpolate.SetStartTime( current.splineInterpolate.GetStartTime() + timeLeap ); 701 } 702 } 703 704 /* 705 ================ 706 idPhysics_Parametric::GetTime 707 ================ 708 */ 709 int idPhysics_Parametric::GetTime() const { 710 return current.time; 711 } 712 713 /* 714 ================ 715 idPhysics_Parametric::IsAtRest 716 ================ 717 */ 718 bool idPhysics_Parametric::IsAtRest() const { 719 return current.atRest >= 0; 720 } 721 722 /* 723 ================ 724 idPhysics_Parametric::GetRestStartTime 725 ================ 726 */ 727 int idPhysics_Parametric::GetRestStartTime() const { 728 return current.atRest; 729 } 730 731 /* 732 ================ 733 idPhysics_Parametric::IsPushable 734 ================ 735 */ 736 bool idPhysics_Parametric::IsPushable() const { 737 return false; 738 } 739 740 /* 741 ================ 742 idPhysics_Parametric::SaveState 743 ================ 744 */ 745 void idPhysics_Parametric::SaveState() { 746 saved = current; 747 } 748 749 /* 750 ================ 751 idPhysics_Parametric::RestoreState 752 ================ 753 */ 754 void idPhysics_Parametric::RestoreState() { 755 756 current = saved; 757 758 if ( clipModel ) { 759 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); 760 } 761 } 762 763 /* 764 ================ 765 idPhysics_Parametric::SetOrigin 766 ================ 767 */ 768 void idPhysics_Parametric::SetOrigin( const idVec3 &newOrigin, int id ) { 769 idVec3 masterOrigin; 770 idMat3 masterAxis; 771 772 current.linearExtrapolation.SetStartValue( newOrigin ); 773 current.linearInterpolation.SetStartValue( newOrigin ); 774 775 current.localOrigin = current.linearExtrapolation.GetCurrentValue( current.time ); 776 if ( hasMaster ) { 777 self->GetMasterPosition( masterOrigin, masterAxis ); 778 current.origin = masterOrigin + current.localOrigin * masterAxis; 779 } 780 else { 781 current.origin = current.localOrigin; 782 } 783 if ( clipModel ) { 784 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); 785 } 786 Activate(); 787 } 788 789 /* 790 ================ 791 idPhysics_Parametric::SetAxis 792 ================ 793 */ 794 void idPhysics_Parametric::SetAxis( const idMat3 &newAxis, int id ) { 795 idVec3 masterOrigin; 796 idMat3 masterAxis; 797 798 current.localAngles = newAxis.ToAngles(); 799 800 current.angularExtrapolation.SetStartValue( current.localAngles ); 801 current.angularInterpolation.SetStartValue( current.localAngles ); 802 803 current.localAngles = current.angularExtrapolation.GetCurrentValue( current.time ); 804 if ( hasMaster && isOrientated ) { 805 self->GetMasterPosition( masterOrigin, masterAxis ); 806 current.axis = current.localAngles.ToMat3() * masterAxis; 807 current.angles = current.axis.ToAngles(); 808 } 809 else { 810 current.axis = current.localAngles.ToMat3(); 811 current.angles = current.localAngles; 812 } 813 if ( clipModel ) { 814 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); 815 } 816 Activate(); 817 } 818 819 /* 820 ================ 821 idPhysics_Parametric::Move 822 ================ 823 */ 824 void idPhysics_Parametric::Translate( const idVec3 &translation, int id ) { 825 } 826 827 /* 828 ================ 829 idPhysics_Parametric::Rotate 830 ================ 831 */ 832 void idPhysics_Parametric::Rotate( const idRotation &rotation, int id ) { 833 } 834 835 /* 836 ================ 837 idPhysics_Parametric::GetOrigin 838 ================ 839 */ 840 const idVec3 &idPhysics_Parametric::GetOrigin( int id ) const { 841 return current.origin; 842 } 843 844 /* 845 ================ 846 idPhysics_Parametric::GetAxis 847 ================ 848 */ 849 const idMat3 &idPhysics_Parametric::GetAxis( int id ) const { 850 return current.axis; 851 } 852 853 /* 854 ================ 855 idPhysics_Parametric::GetAngles 856 ================ 857 */ 858 void idPhysics_Parametric::GetAngles( idAngles &curAngles ) const { 859 curAngles = current.angles; 860 } 861 862 /* 863 ================ 864 idPhysics_Parametric::SetLinearVelocity 865 ================ 866 */ 867 void idPhysics_Parametric::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { 868 SetLinearExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, current.origin, newLinearVelocity, vec3_origin ); 869 current.linearInterpolation.Init( 0, 0, 0, 0, vec3_zero, vec3_zero ); 870 Activate(); 871 } 872 873 /* 874 ================ 875 idPhysics_Parametric::SetAngularVelocity 876 ================ 877 */ 878 void idPhysics_Parametric::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { 879 idRotation rotation; 880 idVec3 vec; 881 float angle; 882 883 vec = newAngularVelocity; 884 angle = vec.Normalize(); 885 rotation.Set( vec3_origin, vec, (float) RAD2DEG( angle ) ); 886 887 SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, current.angles, rotation.ToAngles(), ang_zero ); 888 current.angularInterpolation.Init( 0, 0, 0, 0, ang_zero, ang_zero ); 889 Activate(); 890 } 891 892 /* 893 ================ 894 idPhysics_Parametric::GetLinearVelocity 895 ================ 896 */ 897 const idVec3 &idPhysics_Parametric::GetLinearVelocity( int id ) const { 898 static idVec3 curLinearVelocity; 899 900 curLinearVelocity = current.linearExtrapolation.GetCurrentSpeed( gameLocal.time ); 901 return curLinearVelocity; 902 } 903 904 /* 905 ================ 906 idPhysics_Parametric::GetAngularVelocity 907 ================ 908 */ 909 const idVec3 &idPhysics_Parametric::GetAngularVelocity( int id ) const { 910 static idVec3 curAngularVelocity; 911 idAngles angles; 912 913 angles = current.angularExtrapolation.GetCurrentSpeed( gameLocal.time ); 914 curAngularVelocity = angles.ToAngularVelocity(); 915 return curAngularVelocity; 916 } 917 918 /* 919 ================ 920 idPhysics_Parametric::DisableClip 921 ================ 922 */ 923 void idPhysics_Parametric::DisableClip() { 924 if ( clipModel ) { 925 clipModel->Disable(); 926 } 927 } 928 929 /* 930 ================ 931 idPhysics_Parametric::EnableClip 932 ================ 933 */ 934 void idPhysics_Parametric::EnableClip() { 935 if ( clipModel ) { 936 clipModel->Enable(); 937 } 938 } 939 940 /* 941 ================ 942 idPhysics_Parametric::UnlinkClip 943 ================ 944 */ 945 void idPhysics_Parametric::UnlinkClip() { 946 if ( clipModel ) { 947 clipModel->Unlink(); 948 } 949 } 950 951 /* 952 ================ 953 idPhysics_Parametric::LinkClip 954 ================ 955 */ 956 void idPhysics_Parametric::LinkClip() { 957 if ( clipModel ) { 958 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); 959 } 960 } 961 962 /* 963 ================ 964 idPhysics_Parametric::GetBlockingInfo 965 ================ 966 */ 967 const trace_t *idPhysics_Parametric::GetBlockingInfo() const { 968 return ( isBlocked ? &pushResults : NULL ); 969 } 970 971 /* 972 ================ 973 idPhysics_Parametric::GetBlockingEntity 974 ================ 975 */ 976 idEntity *idPhysics_Parametric::GetBlockingEntity() const { 977 if ( isBlocked ) { 978 return gameLocal.entities[ pushResults.c.entityNum ]; 979 } 980 return NULL; 981 } 982 983 /* 984 ================ 985 idPhysics_Parametric::SetMaster 986 ================ 987 */ 988 void idPhysics_Parametric::SetMaster( idEntity *master, const bool orientated ) { 989 idVec3 masterOrigin; 990 idMat3 masterAxis; 991 992 if ( master ) { 993 if ( !hasMaster ) { 994 995 // transform from world space to master space 996 self->GetMasterPosition( masterOrigin, masterAxis ); 997 current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); 998 if ( orientated ) { 999 current.localAngles = ( current.axis * masterAxis.Transpose() ).ToAngles(); 1000 } 1001 else { 1002 current.localAngles = current.axis.ToAngles(); 1003 } 1004 1005 current.linearExtrapolation.SetStartValue( current.localOrigin ); 1006 current.angularExtrapolation.SetStartValue( current.localAngles ); 1007 hasMaster = true; 1008 isOrientated = orientated; 1009 } 1010 } 1011 else { 1012 if ( hasMaster ) { 1013 // transform from master space to world space 1014 current.localOrigin = current.origin; 1015 current.localAngles = current.angles; 1016 SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, current.origin, vec3_origin, vec3_origin ); 1017 SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, current.angles, ang_zero, ang_zero ); 1018 hasMaster = false; 1019 } 1020 } 1021 } 1022 1023 /* 1024 ================ 1025 idPhysics_Parametric::GetLinearEndTime 1026 ================ 1027 */ 1028 int idPhysics_Parametric::GetLinearEndTime() const { 1029 if ( current.spline != NULL ) { 1030 if ( current.spline->GetBoundaryType() != idCurve_Spline<idVec3>::BT_CLOSED ) { 1031 return current.spline->GetTime( current.spline->GetNumValues() - 1 ); 1032 } else { 1033 return 0; 1034 } 1035 } else if ( current.linearInterpolation.GetDuration() != 0 ) { 1036 return current.linearInterpolation.GetEndTime(); 1037 } else { 1038 return current.linearExtrapolation.GetEndTime(); 1039 } 1040 } 1041 1042 /* 1043 ================ 1044 idPhysics_Parametric::GetAngularEndTime 1045 ================ 1046 */ 1047 int idPhysics_Parametric::GetAngularEndTime() const { 1048 if ( current.angularInterpolation.GetDuration() != 0 ) { 1049 return current.angularInterpolation.GetEndTime(); 1050 } else { 1051 return current.angularExtrapolation.GetEndTime(); 1052 } 1053 } 1054 1055 /* 1056 ================ 1057 idPhysics_Parametric::WriteToSnapshot 1058 ================ 1059 */ 1060 void idPhysics_Parametric::WriteToSnapshot( idBitMsg &msg ) const { 1061 1062 const idQuat currentQuat = current.axis.ToQuat(); 1063 1064 WriteFloatArray( msg, current.origin ); 1065 WriteFloatArray( msg, currentQuat ); 1066 } 1067 1068 /* 1069 ================ 1070 idPhysics_Parametric::ReadFromSnapshot 1071 ================ 1072 */ 1073 void idPhysics_Parametric::ReadFromSnapshot( const idBitMsg &msg ) { 1074 1075 previous = next; 1076 1077 next.origin = ReadFloatArray< idVec3 >( msg ); 1078 next.axis = ReadFloatArray< idQuat >( msg ); 1079 1080 if( self->GetNumSnapshotsReceived() <= 1 ) { 1081 current.origin = next.origin; 1082 previous.origin = next.origin; 1083 current.axis = next.axis.ToMat3(); 1084 previous.axis = next.axis; 1085 } 1086 }