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