2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 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.
14 Doom 3 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.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 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 Source Code. If not, please request a copy in writing from id Software at the address below.
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.
26 ===========================================================================
29 #include "../../idlib/precompiled.h"
32 #include "../Game_local.h"
34 CLASS_DECLARATION( idPhysics, idPhysics_Static )
39 idPhysics_Static::idPhysics_Static
42 idPhysics_Static::idPhysics_Static( void ) {
45 current.origin.Zero();
46 current.axis.Identity();
47 current.localOrigin.Zero();
48 current.localAxis.Identity();
55 idPhysics_Static::~idPhysics_Static
58 idPhysics_Static::~idPhysics_Static( void ) {
59 if ( self && self->GetPhysics() == this ) {
60 self->SetPhysics( NULL );
62 idForce::DeletePhysics( this );
70 idPhysics_Static::Save
73 void idPhysics_Static::Save( idSaveGame *savefile ) const {
74 savefile->WriteObject( self );
76 savefile->WriteVec3( current.origin );
77 savefile->WriteMat3( current.axis );
78 savefile->WriteVec3( current.localOrigin );
79 savefile->WriteMat3( current.localAxis );
80 savefile->WriteClipModel( clipModel );
82 savefile->WriteBool( hasMaster );
83 savefile->WriteBool( isOrientated );
88 idPhysics_Static::Restore
91 void idPhysics_Static::Restore( idRestoreGame *savefile ) {
92 savefile->ReadObject( reinterpret_cast<idClass *&>( self ) );
94 savefile->ReadVec3( current.origin );
95 savefile->ReadMat3( current.axis );
96 savefile->ReadVec3( current.localOrigin );
97 savefile->ReadMat3( current.localAxis );
98 savefile->ReadClipModel( clipModel );
100 savefile->ReadBool( hasMaster );
101 savefile->ReadBool( isOrientated );
106 idPhysics_Static::SetSelf
109 void idPhysics_Static::SetSelf( idEntity *e ) {
116 idPhysics_Static::SetClipModel
119 void idPhysics_Static::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) {
122 if ( clipModel && clipModel != model && freeOld ) {
127 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
133 idPhysics_Static::GetClipModel
136 idClipModel *idPhysics_Static::GetClipModel( int id ) const {
140 return gameLocal.clip.DefaultClipModel();
145 idPhysics_Static::GetNumClipModels
148 int idPhysics_Static::GetNumClipModels( void ) const {
149 return ( clipModel != NULL );
154 idPhysics_Static::SetMass
157 void idPhysics_Static::SetMass( float mass, int id ) {
162 idPhysics_Static::GetMass
165 float idPhysics_Static::GetMass( int id ) const {
171 idPhysics_Static::SetContents
174 void idPhysics_Static::SetContents( int contents, int id ) {
176 clipModel->SetContents( contents );
182 idPhysics_Static::GetContents
185 int idPhysics_Static::GetContents( int id ) const {
187 return clipModel->GetContents();
194 idPhysics_Static::SetClipMask
197 void idPhysics_Static::SetClipMask( int mask, int id ) {
202 idPhysics_Static::GetClipMask
205 int idPhysics_Static::GetClipMask( int id ) const {
211 idPhysics_Static::GetBounds
214 const idBounds &idPhysics_Static::GetBounds( int id ) const {
216 return clipModel->GetBounds();
223 idPhysics_Static::GetAbsBounds
226 const idBounds &idPhysics_Static::GetAbsBounds( int id ) const {
227 static idBounds absBounds;
230 return clipModel->GetAbsBounds();
232 absBounds[0] = absBounds[1] = current.origin;
238 idPhysics_Static::Evaluate
241 bool idPhysics_Static::Evaluate( int timeStepMSec, int endTimeMSec ) {
242 idVec3 masterOrigin, oldOrigin;
243 idMat3 masterAxis, oldAxis;
247 oldOrigin = current.origin;
248 oldAxis = current.axis;
250 self->GetMasterPosition( masterOrigin, masterAxis );
251 current.origin = masterOrigin + current.localOrigin * masterAxis;
252 if ( isOrientated ) {
253 current.axis = current.localAxis * masterAxis;
255 current.axis = current.localAxis;
258 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
261 return ( current.origin != oldOrigin || current.axis != oldAxis );
268 idPhysics_Static::UpdateTime
271 void idPhysics_Static::UpdateTime( int endTimeMSec ) {
276 idPhysics_Static::GetTime
279 int idPhysics_Static::GetTime( void ) const {
285 idPhysics_Static::GetImpactInfo
288 void idPhysics_Static::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const {
289 memset( info, 0, sizeof( *info ) );
294 idPhysics_Static::ApplyImpulse
297 void idPhysics_Static::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) {
302 idPhysics_Static::AddForce
305 void idPhysics_Static::AddForce( const int id, const idVec3 &point, const idVec3 &force ) {
310 idPhysics_Static::Activate
313 void idPhysics_Static::Activate( void ) {
318 idPhysics_Static::PutToRest
321 void idPhysics_Static::PutToRest( void ) {
326 idPhysics_Static::IsAtRest
329 bool idPhysics_Static::IsAtRest( void ) const {
335 idPhysics_Static::GetRestStartTime
338 int idPhysics_Static::GetRestStartTime( void ) const {
344 idPhysics_Static::IsPushable
347 bool idPhysics_Static::IsPushable( void ) const {
353 idPhysics_Static::SaveState
356 void idPhysics_Static::SaveState( void ) {
361 idPhysics_Static::RestoreState
364 void idPhysics_Static::RestoreState( void ) {
369 idPhysics_Static::SetOrigin
372 void idPhysics_Static::SetOrigin( const idVec3 &newOrigin, int id ) {
376 current.localOrigin = newOrigin;
379 self->GetMasterPosition( masterOrigin, masterAxis );
380 current.origin = masterOrigin + newOrigin * masterAxis;
382 current.origin = newOrigin;
386 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
392 idPhysics_Static::SetAxis
395 void idPhysics_Static::SetAxis( const idMat3 &newAxis, int id ) {
399 current.localAxis = newAxis;
401 if ( hasMaster && isOrientated ) {
402 self->GetMasterPosition( masterOrigin, masterAxis );
403 current.axis = newAxis * masterAxis;
405 current.axis = newAxis;
409 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
415 idPhysics_Static::Translate
418 void idPhysics_Static::Translate( const idVec3 &translation, int id ) {
419 current.localOrigin += translation;
420 current.origin += translation;
423 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
429 idPhysics_Static::Rotate
432 void idPhysics_Static::Rotate( const idRotation &rotation, int id ) {
436 current.origin *= rotation;
437 current.axis *= rotation.ToMat3();
440 self->GetMasterPosition( masterOrigin, masterAxis );
441 current.localAxis *= rotation.ToMat3();
442 current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose();
444 current.localAxis = current.axis;
445 current.localOrigin = current.origin;
449 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
455 idPhysics_Static::GetOrigin
458 const idVec3 &idPhysics_Static::GetOrigin( int id ) const {
459 return current.origin;
464 idPhysics_Static::GetAxis
467 const idMat3 &idPhysics_Static::GetAxis( int id ) const {
473 idPhysics_Static::SetLinearVelocity
476 void idPhysics_Static::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) {
481 idPhysics_Static::SetAngularVelocity
484 void idPhysics_Static::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) {
489 idPhysics_Static::GetLinearVelocity
492 const idVec3 &idPhysics_Static::GetLinearVelocity( int id ) const {
498 idPhysics_Static::GetAngularVelocity
501 const idVec3 &idPhysics_Static::GetAngularVelocity( int id ) const {
507 idPhysics_Static::SetGravity
510 void idPhysics_Static::SetGravity( const idVec3 &newGravity ) {
515 idPhysics_Static::GetGravity
518 const idVec3 &idPhysics_Static::GetGravity( void ) const {
519 static idVec3 gravity( 0, 0, -g_gravity.GetFloat() );
525 idPhysics_Static::GetGravityNormal
528 const idVec3 &idPhysics_Static::GetGravityNormal( void ) const {
529 static idVec3 gravity( 0, 0, -1 );
535 idPhysics_Static::ClipTranslation
538 void idPhysics_Static::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const {
540 gameLocal.clip.TranslationModel( results, current.origin, current.origin + translation,
541 clipModel, current.axis, MASK_SOLID, model->Handle(), model->GetOrigin(), model->GetAxis() );
543 gameLocal.clip.Translation( results, current.origin, current.origin + translation,
544 clipModel, current.axis, MASK_SOLID, self );
550 idPhysics_Static::ClipRotation
553 void idPhysics_Static::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const {
555 gameLocal.clip.RotationModel( results, current.origin, rotation,
556 clipModel, current.axis, MASK_SOLID, model->Handle(), model->GetOrigin(), model->GetAxis() );
558 gameLocal.clip.Rotation( results, current.origin, rotation, clipModel, current.axis, MASK_SOLID, self );
564 idPhysics_Static::ClipContents
567 int idPhysics_Static::ClipContents( const idClipModel *model ) const {
570 return gameLocal.clip.ContentsModel( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1,
571 model->Handle(), model->GetOrigin(), model->GetAxis() );
573 return gameLocal.clip.Contents( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, NULL );
581 idPhysics_Static::DisableClip
584 void idPhysics_Static::DisableClip( void ) {
586 clipModel->Disable();
592 idPhysics_Static::EnableClip
595 void idPhysics_Static::EnableClip( void ) {
603 idPhysics_Static::UnlinkClip
606 void idPhysics_Static::UnlinkClip( void ) {
614 idPhysics_Static::LinkClip
617 void idPhysics_Static::LinkClip( void ) {
619 clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
625 idPhysics_Static::EvaluateContacts
628 bool idPhysics_Static::EvaluateContacts( void ) {
634 idPhysics_Static::GetNumContacts
637 int idPhysics_Static::GetNumContacts( void ) const {
643 idPhysics_Static::GetContact
646 const contactInfo_t &idPhysics_Static::GetContact( int num ) const {
647 static contactInfo_t info;
648 memset( &info, 0, sizeof( info ) );
654 idPhysics_Static::ClearContacts
657 void idPhysics_Static::ClearContacts( void ) {
662 idPhysics_Static::AddContactEntity
665 void idPhysics_Static::AddContactEntity( idEntity *e ) {
670 idPhysics_Static::RemoveContactEntity
673 void idPhysics_Static::RemoveContactEntity( idEntity *e ) {
678 idPhysics_Static::HasGroundContacts
681 bool idPhysics_Static::HasGroundContacts( void ) const {
687 idPhysics_Static::IsGroundEntity
690 bool idPhysics_Static::IsGroundEntity( int entityNum ) const {
696 idPhysics_Static::IsGroundClipModel
699 bool idPhysics_Static::IsGroundClipModel( int entityNum, int id ) const {
705 idPhysics_Static::SetPushed
708 void idPhysics_Static::SetPushed( int deltaTime ) {
713 idPhysics_Static::GetPushedLinearVelocity
716 const idVec3 &idPhysics_Static::GetPushedLinearVelocity( const int id ) const {
722 idPhysics_Static::GetPushedAngularVelocity
725 const idVec3 &idPhysics_Static::GetPushedAngularVelocity( const int id ) const {
731 idPhysics_Static::SetMaster
734 void idPhysics_Static::SetMaster( idEntity *master, const bool orientated ) {
740 // transform from world space to master space
741 self->GetMasterPosition( masterOrigin, masterAxis );
742 current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose();
744 current.localAxis = current.axis * masterAxis.Transpose();
746 current.localAxis = current.axis;
749 isOrientated = orientated;
760 idPhysics_Static::GetBlockingInfo
763 const trace_t *idPhysics_Static::GetBlockingInfo( void ) const {
769 idPhysics_Static::GetBlockingEntity
772 idEntity *idPhysics_Static::GetBlockingEntity( void ) const {
778 idPhysics_Static::GetLinearEndTime
781 int idPhysics_Static::GetLinearEndTime( void ) const {
787 idPhysics_Static::GetAngularEndTime
790 int idPhysics_Static::GetAngularEndTime( void ) const {
796 idPhysics_Static::WriteToSnapshot
799 void idPhysics_Static::WriteToSnapshot( idBitMsgDelta &msg ) const {
800 idCQuat quat, localQuat;
802 quat = current.axis.ToCQuat();
803 localQuat = current.localAxis.ToCQuat();
805 msg.WriteFloat( current.origin[0] );
806 msg.WriteFloat( current.origin[1] );
807 msg.WriteFloat( current.origin[2] );
808 msg.WriteFloat( quat.x );
809 msg.WriteFloat( quat.y );
810 msg.WriteFloat( quat.z );
811 msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] );
812 msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] );
813 msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] );
814 msg.WriteDeltaFloat( quat.x, localQuat.x );
815 msg.WriteDeltaFloat( quat.y, localQuat.y );
816 msg.WriteDeltaFloat( quat.z, localQuat.z );
821 idPhysics_Base::ReadFromSnapshot
824 void idPhysics_Static::ReadFromSnapshot( const idBitMsgDelta &msg ) {
825 idCQuat quat, localQuat;
827 current.origin[0] = msg.ReadFloat();
828 current.origin[1] = msg.ReadFloat();
829 current.origin[2] = msg.ReadFloat();
830 quat.x = msg.ReadFloat();
831 quat.y = msg.ReadFloat();
832 quat.z = msg.ReadFloat();
833 current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] );
834 current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] );
835 current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] );
836 localQuat.x = msg.ReadDeltaFloat( quat.x );
837 localQuat.y = msg.ReadDeltaFloat( quat.y );
838 localQuat.z = msg.ReadDeltaFloat( quat.z );
840 current.axis = quat.ToMat3();
841 current.localAxis = localQuat.ToMat3();