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 "sys/platform.h"
30 #include "idlib/math/Quat.h"
31
32 #include "gamesys/SysCvar.h"
33 #include "physics/Force.h"
34 #include "Entity.h"
35
36 #include "physics/Physics_StaticMulti.h"
37
38 CLASS_DECLARATION( idPhysics, idPhysics_StaticMulti )
39 END_CLASS
40
41 staticPState_t defaultState;
42
43
44 /*
45 ================
46 idPhysics_StaticMulti::idPhysics_StaticMulti
47 ================
48 */
idPhysics_StaticMulti(void)49 idPhysics_StaticMulti::idPhysics_StaticMulti( void ) {
50 self = NULL;
51 hasMaster = false;
52 isOrientated = false;
53
54 defaultState.origin.Zero();
55 defaultState.axis.Identity();
56 defaultState.localOrigin.Zero();
57 defaultState.localAxis.Identity();
58
59 current.SetNum( 1 );
60 current[0] = defaultState;
61 clipModels.SetNum( 1 );
62 clipModels[0] = NULL;
63 }
64
65 /*
66 ================
67 idPhysics_StaticMulti::~idPhysics_StaticMulti
68 ================
69 */
~idPhysics_StaticMulti(void)70 idPhysics_StaticMulti::~idPhysics_StaticMulti( void ) {
71 if ( self && self->GetPhysics() == this ) {
72 self->SetPhysics( NULL );
73 }
74 idForce::DeletePhysics( this );
75 for ( int i = 0; i < clipModels.Num(); i++ ) {
76 delete clipModels[i];
77 }
78 }
79
80 /*
81 ================
82 idPhysics_StaticMulti::Save
83 ================
84 */
Save(idSaveGame * savefile) const85 void idPhysics_StaticMulti::Save( idSaveGame *savefile ) const {
86 int i;
87
88 savefile->WriteObject( self );
89
90 savefile->WriteInt(current.Num());
91 for ( i = 0; i < current.Num(); i++ ) {
92 savefile->WriteVec3( current[i].origin );
93 savefile->WriteMat3( current[i].axis );
94 savefile->WriteVec3( current[i].localOrigin );
95 savefile->WriteMat3( current[i].localAxis );
96 }
97
98 savefile->WriteInt( clipModels.Num() );
99 for ( i = 0; i < clipModels.Num(); i++ ) {
100 savefile->WriteClipModel( clipModels[i] );
101 }
102
103 savefile->WriteBool(hasMaster);
104 savefile->WriteBool(isOrientated);
105 }
106
107 /*
108 ================
109 idPhysics_StaticMulti::Restore
110 ================
111 */
Restore(idRestoreGame * savefile)112 void idPhysics_StaticMulti::Restore( idRestoreGame *savefile ) {
113 int i, num;
114
115 savefile->ReadObject( reinterpret_cast<idClass *&>( self ) );
116
117 savefile->ReadInt(num);
118 current.AssureSize( num );
119 for ( i = 0; i < num; i++ ) {
120 savefile->ReadVec3( current[i].origin );
121 savefile->ReadMat3( current[i].axis );
122 savefile->ReadVec3( current[i].localOrigin );
123 savefile->ReadMat3( current[i].localAxis );
124 }
125
126 savefile->ReadInt(num);
127 clipModels.SetNum( num );
128 for ( i = 0; i < num; i++ ) {
129 savefile->ReadClipModel( clipModels[i] );
130 }
131
132 savefile->ReadBool(hasMaster);
133 savefile->ReadBool(isOrientated);
134 }
135
136 /*
137 ================
138 idPhysics_StaticMulti::SetSelf
139 ================
140 */
SetSelf(idEntity * e)141 void idPhysics_StaticMulti::SetSelf( idEntity *e ) {
142 assert( e );
143 self = e;
144 }
145
146 /*
147 ================
148 idPhysics_StaticMulti::RemoveIndex
149 ================
150 */
RemoveIndex(int id,bool freeClipModel)151 void idPhysics_StaticMulti::RemoveIndex( int id, bool freeClipModel ) {
152 if ( id < 0 || id >= clipModels.Num() ) {
153 return;
154 }
155 if ( clipModels[id] && freeClipModel ) {
156 delete clipModels[id];
157 clipModels[id] = NULL;
158 }
159 clipModels.RemoveIndex( id );
160 current.RemoveIndex( id );
161 }
162
163 /*
164 ================
165 idPhysics_StaticMulti::SetClipModel
166 ================
167 */
SetClipModel(idClipModel * model,float density,int id,bool freeOld)168 void idPhysics_StaticMulti::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) {
169 int i;
170
171 assert( self );
172
173 if ( id >= clipModels.Num() ) {
174 current.AssureSize( id+1, defaultState );
175 clipModels.AssureSize( id+1, NULL );
176 }
177
178 if ( clipModels[id] && clipModels[id] != model && freeOld ) {
179 delete clipModels[id];
180 }
181 clipModels[id] = model;
182 if ( clipModels[id] ) {
183 clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis );
184 }
185
186 for ( i = clipModels.Num() - 1; i >= 1; i-- ) {
187 if ( clipModels[i] ) {
188 break;
189 }
190 }
191 current.SetNum( i+1, false );
192 clipModels.SetNum( i+1, false );
193 }
194
195 /*
196 ================
197 idPhysics_StaticMulti::GetClipModel
198 ================
199 */
GetClipModel(int id) const200 idClipModel *idPhysics_StaticMulti::GetClipModel( int id ) const {
201 if ( id >= 0 && id < clipModels.Num() && clipModels[id] ) {
202 return clipModels[id];
203 }
204 return gameLocal.clip.DefaultClipModel();
205 }
206
207 /*
208 ================
209 idPhysics_StaticMulti::GetNumClipModels
210 ================
211 */
GetNumClipModels(void) const212 int idPhysics_StaticMulti::GetNumClipModels( void ) const {
213 return clipModels.Num();
214 }
215
216 /*
217 ================
218 idPhysics_StaticMulti::SetMass
219 ================
220 */
SetMass(float mass,int id)221 void idPhysics_StaticMulti::SetMass( float mass, int id ) {
222 }
223
224 /*
225 ================
226 idPhysics_StaticMulti::GetMass
227 ================
228 */
GetMass(int id) const229 float idPhysics_StaticMulti::GetMass( int id ) const {
230 return 0.0f;
231 }
232
233 /*
234 ================
235 idPhysics_StaticMulti::SetContents
236 ================
237 */
SetContents(int contents,int id)238 void idPhysics_StaticMulti::SetContents( int contents, int id ) {
239 int i;
240
241 if ( id >= 0 && id < clipModels.Num() ) {
242 if ( clipModels[id] ) {
243 clipModels[id]->SetContents( contents );
244 }
245 } else if ( id == -1 ) {
246 for ( i = 0; i < clipModels.Num(); i++ ) {
247 if ( clipModels[i] ) {
248 clipModels[i]->SetContents( contents );
249 }
250 }
251 }
252 }
253
254 /*
255 ================
256 idPhysics_StaticMulti::GetContents
257 ================
258 */
GetContents(int id) const259 int idPhysics_StaticMulti::GetContents( int id ) const {
260 int i, contents = 0;
261
262 if ( id >= 0 && id < clipModels.Num() ) {
263 if ( clipModels[id] ) {
264 contents = clipModels[id]->GetContents();
265 }
266 } else if ( id == -1 ) {
267 for ( i = 0; i < clipModels.Num(); i++ ) {
268 if ( clipModels[i] ) {
269 contents |= clipModels[i]->GetContents();
270 }
271 }
272 }
273 return contents;
274 }
275
276 /*
277 ================
278 idPhysics_StaticMulti::SetClipMask
279 ================
280 */
SetClipMask(int mask,int id)281 void idPhysics_StaticMulti::SetClipMask( int mask, int id ) {
282 }
283
284 /*
285 ================
286 idPhysics_StaticMulti::GetClipMask
287 ================
288 */
GetClipMask(int id) const289 int idPhysics_StaticMulti::GetClipMask( int id ) const {
290 return 0;
291 }
292
293 /*
294 ================
295 idPhysics_StaticMulti::GetBounds
296 ================
297 */
GetBounds(int id) const298 const idBounds &idPhysics_StaticMulti::GetBounds( int id ) const {
299 int i;
300 static idBounds bounds;
301
302 if ( id >= 0 && id < clipModels.Num() ) {
303 if ( clipModels[id] ) {
304 return clipModels[id]->GetBounds();
305 }
306 }
307 if ( id == -1 ) {
308 bounds.Clear();
309 for ( i = 0; i < clipModels.Num(); i++ ) {
310 if ( clipModels[i] ) {
311 bounds.AddBounds( clipModels[i]->GetAbsBounds() );
312 }
313 }
314 for ( i = 0; i < clipModels.Num(); i++ ) {
315 if ( clipModels[i] ) {
316 bounds[0] -= clipModels[i]->GetOrigin();
317 bounds[1] -= clipModels[i]->GetOrigin();
318 break;
319 }
320 }
321 return bounds;
322 }
323 return bounds_zero;
324 }
325
326 /*
327 ================
328 idPhysics_StaticMulti::GetAbsBounds
329 ================
330 */
GetAbsBounds(int id) const331 const idBounds &idPhysics_StaticMulti::GetAbsBounds( int id ) const {
332 int i;
333 static idBounds absBounds;
334
335 if ( id >= 0 && id < clipModels.Num() ) {
336 if ( clipModels[id] ) {
337 return clipModels[id]->GetAbsBounds();
338 }
339 }
340 if ( id == -1 ) {
341 absBounds.Clear();
342 for ( i = 0; i < clipModels.Num(); i++ ) {
343 if ( clipModels[i] ) {
344 absBounds.AddBounds( clipModels[i]->GetAbsBounds() );
345 }
346 }
347 return absBounds;
348 }
349 return bounds_zero;
350 }
351
352 /*
353 ================
354 idPhysics_StaticMulti::Evaluate
355 ================
356 */
Evaluate(int timeStepMSec,int endTimeMSec)357 bool idPhysics_StaticMulti::Evaluate( int timeStepMSec, int endTimeMSec ) {
358 int i;
359 idVec3 masterOrigin;
360 idMat3 masterAxis;
361
362 if ( hasMaster ) {
363 self->GetMasterPosition( masterOrigin, masterAxis );
364 for ( i = 0; i < clipModels.Num(); i++ ) {
365 current[i].origin = masterOrigin + current[i].localOrigin * masterAxis;
366 if ( isOrientated ) {
367 current[i].axis = current[i].localAxis * masterAxis;
368 } else {
369 current[i].axis = current[i].localAxis;
370 }
371 if ( clipModels[i] ) {
372 clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis );
373 }
374 }
375
376 // FIXME: return false if master did not move
377 return true;
378 }
379 return false;
380 }
381
382 /*
383 ================
384 idPhysics_StaticMulti::UpdateTime
385 ================
386 */
UpdateTime(int endTimeMSec)387 void idPhysics_StaticMulti::UpdateTime( int endTimeMSec ) {
388 }
389
390 /*
391 ================
392 idPhysics_StaticMulti::GetTime
393 ================
394 */
GetTime(void) const395 int idPhysics_StaticMulti::GetTime( void ) const {
396 return 0;
397 }
398
399 /*
400 ================
401 idPhysics_StaticMulti::GetImpactInfo
402 ================
403 */
GetImpactInfo(const int id,const idVec3 & point,impactInfo_t * info) const404 void idPhysics_StaticMulti::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const {
405 memset( info, 0, sizeof( *info ) );
406 }
407
408 /*
409 ================
410 idPhysics_StaticMulti::ApplyImpulse
411 ================
412 */
ApplyImpulse(const int id,const idVec3 & point,const idVec3 & impulse)413 void idPhysics_StaticMulti::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) {
414 }
415
416 /*
417 ================
418 idPhysics_StaticMulti::AddForce
419 ================
420 */
AddForce(const int id,const idVec3 & point,const idVec3 & force)421 void idPhysics_StaticMulti::AddForce( const int id, const idVec3 &point, const idVec3 &force ) {
422 }
423
424 /*
425 ================
426 idPhysics_StaticMulti::Activate
427 ================
428 */
Activate(void)429 void idPhysics_StaticMulti::Activate( void ) {
430 }
431
432 /*
433 ================
434 idPhysics_StaticMulti::PutToRest
435 ================
436 */
PutToRest(void)437 void idPhysics_StaticMulti::PutToRest( void ) {
438 }
439
440 /*
441 ================
442 idPhysics_StaticMulti::IsAtRest
443 ================
444 */
IsAtRest(void) const445 bool idPhysics_StaticMulti::IsAtRest( void ) const {
446 return true;
447 }
448
449 /*
450 ================
451 idPhysics_StaticMulti::GetRestStartTime
452 ================
453 */
GetRestStartTime(void) const454 int idPhysics_StaticMulti::GetRestStartTime( void ) const {
455 return 0;
456 }
457
458 /*
459 ================
460 idPhysics_StaticMulti::IsPushable
461 ================
462 */
IsPushable(void) const463 bool idPhysics_StaticMulti::IsPushable( void ) const {
464 return false;
465 }
466
467 /*
468 ================
469 idPhysics_StaticMulti::SaveState
470 ================
471 */
SaveState(void)472 void idPhysics_StaticMulti::SaveState( void ) {
473 }
474
475 /*
476 ================
477 idPhysics_StaticMulti::RestoreState
478 ================
479 */
RestoreState(void)480 void idPhysics_StaticMulti::RestoreState( void ) {
481 }
482
483 /*
484 ================
485 idPhysics_StaticMulti::SetOrigin
486 ================
487 */
SetOrigin(const idVec3 & newOrigin,int id)488 void idPhysics_StaticMulti::SetOrigin( const idVec3 &newOrigin, int id ) {
489 idVec3 masterOrigin;
490 idMat3 masterAxis;
491
492 if ( id >= 0 && id < clipModels.Num() ) {
493 current[id].localOrigin = newOrigin;
494 if ( hasMaster ) {
495 self->GetMasterPosition( masterOrigin, masterAxis );
496 current[id].origin = masterOrigin + newOrigin * masterAxis;
497 } else {
498 current[id].origin = newOrigin;
499 }
500 if ( clipModels[id] ) {
501 clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis );
502 }
503 } else if ( id == -1 ) {
504 if ( hasMaster ) {
505 self->GetMasterPosition( masterOrigin, masterAxis );
506 Translate( masterOrigin + masterAxis * newOrigin - current[0].origin );
507 } else {
508 Translate( newOrigin - current[0].origin );
509 }
510 }
511 }
512
513 /*
514 ================
515 idPhysics_StaticMulti::SetAxis
516 ================
517 */
SetAxis(const idMat3 & newAxis,int id)518 void idPhysics_StaticMulti::SetAxis( const idMat3 &newAxis, int id ) {
519 idVec3 masterOrigin;
520 idMat3 masterAxis;
521
522 if ( id >= 0 && id < clipModels.Num() ) {
523 current[id].localAxis = newAxis;
524 if ( hasMaster && isOrientated ) {
525 self->GetMasterPosition( masterOrigin, masterAxis );
526 current[id].axis = newAxis * masterAxis;
527 } else {
528 current[id].axis = newAxis;
529 }
530 if ( clipModels[id] ) {
531 clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis );
532 }
533 } else if ( id == -1 ) {
534 idMat3 axis;
535 idRotation rotation;
536
537 if ( hasMaster ) {
538 self->GetMasterPosition( masterOrigin, masterAxis );
539 axis = current[0].axis.Transpose() * ( newAxis * masterAxis );
540 } else {
541 axis = current[0].axis.Transpose() * newAxis;
542 }
543 rotation = axis.ToRotation();
544 rotation.SetOrigin( current[0].origin );
545
546 Rotate( rotation );
547 }
548 }
549
550 /*
551 ================
552 idPhysics_StaticMulti::Translate
553 ================
554 */
Translate(const idVec3 & translation,int id)555 void idPhysics_StaticMulti::Translate( const idVec3 &translation, int id ) {
556 int i;
557
558 if ( id >= 0 && id < clipModels.Num() ) {
559 current[id].localOrigin += translation;
560 current[id].origin += translation;
561
562 if ( clipModels[id] ) {
563 clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis );
564 }
565 } else if ( id == -1 ) {
566 for ( i = 0; i < clipModels.Num(); i++ ) {
567 current[i].localOrigin += translation;
568 current[i].origin += translation;
569
570 if ( clipModels[i] ) {
571 clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis );
572 }
573 }
574 }
575 }
576
577 /*
578 ================
579 idPhysics_StaticMulti::Rotate
580 ================
581 */
Rotate(const idRotation & rotation,int id)582 void idPhysics_StaticMulti::Rotate( const idRotation &rotation, int id ) {
583 int i;
584 idVec3 masterOrigin;
585 idMat3 masterAxis;
586
587 if ( id >= 0 && id < clipModels.Num() ) {
588 current[id].origin *= rotation;
589 current[id].axis *= rotation.ToMat3();
590
591 if ( hasMaster ) {
592 self->GetMasterPosition( masterOrigin, masterAxis );
593 current[id].localAxis *= rotation.ToMat3();
594 current[id].localOrigin = ( current[id].origin - masterOrigin ) * masterAxis.Transpose();
595 } else {
596 current[id].localAxis = current[id].axis;
597 current[id].localOrigin = current[id].origin;
598 }
599
600 if ( clipModels[id] ) {
601 clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis );
602 }
603 } else if ( id == -1 ) {
604 for ( i = 0; i < clipModels.Num(); i++ ) {
605 current[i].origin *= rotation;
606 current[i].axis *= rotation.ToMat3();
607
608 if ( hasMaster ) {
609 self->GetMasterPosition( masterOrigin, masterAxis );
610 current[i].localAxis *= rotation.ToMat3();
611 current[i].localOrigin = ( current[i].origin - masterOrigin ) * masterAxis.Transpose();
612 } else {
613 current[i].localAxis = current[i].axis;
614 current[i].localOrigin = current[i].origin;
615 }
616
617 if ( clipModels[i] ) {
618 clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis );
619 }
620 }
621 }
622 }
623
624 /*
625 ================
626 idPhysics_StaticMulti::GetOrigin
627 ================
628 */
GetOrigin(int id) const629 const idVec3 &idPhysics_StaticMulti::GetOrigin( int id ) const {
630 if ( id >= 0 && id < clipModels.Num() ) {
631 return current[id].origin;
632 }
633 if ( clipModels.Num() ) {
634 return current[0].origin;
635 } else {
636 return vec3_origin;
637 }
638 }
639
640 /*
641 ================
642 idPhysics_StaticMulti::GetAxis
643 ================
644 */
GetAxis(int id) const645 const idMat3 &idPhysics_StaticMulti::GetAxis( int id ) const {
646 if ( id >= 0 && id < clipModels.Num() ) {
647 return current[id].axis;
648 }
649 if ( clipModels.Num() ) {
650 return current[0].axis;
651 } else {
652 return mat3_identity;
653 }
654 }
655
656 /*
657 ================
658 idPhysics_StaticMulti::SetLinearVelocity
659 ================
660 */
SetLinearVelocity(const idVec3 & newLinearVelocity,int id)661 void idPhysics_StaticMulti::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) {
662 }
663
664 /*
665 ================
666 idPhysics_StaticMulti::SetAngularVelocity
667 ================
668 */
SetAngularVelocity(const idVec3 & newAngularVelocity,int id)669 void idPhysics_StaticMulti::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) {
670 }
671
672 /*
673 ================
674 idPhysics_StaticMulti::GetLinearVelocity
675 ================
676 */
GetLinearVelocity(int id) const677 const idVec3 &idPhysics_StaticMulti::GetLinearVelocity( int id ) const {
678 return vec3_origin;
679 }
680
681 /*
682 ================
683 idPhysics_StaticMulti::GetAngularVelocity
684 ================
685 */
GetAngularVelocity(int id) const686 const idVec3 &idPhysics_StaticMulti::GetAngularVelocity( int id ) const {
687 return vec3_origin;
688 }
689
690 /*
691 ================
692 idPhysics_StaticMulti::SetGravity
693 ================
694 */
SetGravity(const idVec3 & newGravity)695 void idPhysics_StaticMulti::SetGravity( const idVec3 &newGravity ) {
696 }
697
698 /*
699 ================
700 idPhysics_StaticMulti::GetGravity
701 ================
702 */
GetGravity(void) const703 const idVec3 &idPhysics_StaticMulti::GetGravity( void ) const {
704 static idVec3 gravity( 0, 0, -g_gravity.GetFloat() );
705 return gravity;
706 }
707
708 /*
709 ================
710 idPhysics_StaticMulti::GetGravityNormal
711 ================
712 */
GetGravityNormal(void) const713 const idVec3 &idPhysics_StaticMulti::GetGravityNormal( void ) const {
714 static idVec3 gravity( 0, 0, -1 );
715 return gravity;
716 }
717
718 /*
719 ================
720 idPhysics_StaticMulti::ClipTranslation
721 ================
722 */
ClipTranslation(trace_t & results,const idVec3 & translation,const idClipModel * model) const723 void idPhysics_StaticMulti::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const {
724 memset( &results, 0, sizeof( trace_t ) );
725 gameLocal.Warning( "idPhysics_StaticMulti::ClipTranslation called" );
726 }
727
728 /*
729 ================
730 idPhysics_StaticMulti::ClipRotation
731 ================
732 */
ClipRotation(trace_t & results,const idRotation & rotation,const idClipModel * model) const733 void idPhysics_StaticMulti::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const {
734 memset( &results, 0, sizeof( trace_t ) );
735 gameLocal.Warning( "idPhysics_StaticMulti::ClipRotation called" );
736 }
737
738 /*
739 ================
740 idPhysics_StaticMulti::ClipContents
741 ================
742 */
ClipContents(const idClipModel * model) const743 int idPhysics_StaticMulti::ClipContents( const idClipModel *model ) const {
744 int i, contents;
745
746 contents = 0;
747 for ( i = 0; i < clipModels.Num(); i++ ) {
748 if ( clipModels[i] ) {
749 if ( model ) {
750 contents |= gameLocal.clip.ContentsModel( clipModels[i]->GetOrigin(), clipModels[i], clipModels[i]->GetAxis(), -1,
751 model->Handle(), model->GetOrigin(), model->GetAxis() );
752 } else {
753 contents |= gameLocal.clip.Contents( clipModels[i]->GetOrigin(), clipModels[i], clipModels[i]->GetAxis(), -1, NULL );
754 }
755 }
756 }
757 return contents;
758 }
759
760 /*
761 ================
762 idPhysics_StaticMulti::DisableClip
763 ================
764 */
DisableClip(void)765 void idPhysics_StaticMulti::DisableClip( void ) {
766 int i;
767
768 for ( i = 0; i < clipModels.Num(); i++ ) {
769 if ( clipModels[i] ) {
770 clipModels[i]->Disable();
771 }
772 }
773 }
774
775 /*
776 ================
777 idPhysics_StaticMulti::EnableClip
778 ================
779 */
EnableClip(void)780 void idPhysics_StaticMulti::EnableClip( void ) {
781 int i;
782
783 for ( i = 0; i < clipModels.Num(); i++ ) {
784 if ( clipModels[i] ) {
785 clipModels[i]->Enable();
786 }
787 }
788 }
789
790 /*
791 ================
792 idPhysics_StaticMulti::UnlinkClip
793 ================
794 */
UnlinkClip(void)795 void idPhysics_StaticMulti::UnlinkClip( void ) {
796 int i;
797
798 for ( i = 0; i < clipModels.Num(); i++ ) {
799 if ( clipModels[i] ) {
800 clipModels[i]->Unlink();
801 }
802 }
803 }
804
805 /*
806 ================
807 idPhysics_StaticMulti::LinkClip
808 ================
809 */
LinkClip(void)810 void idPhysics_StaticMulti::LinkClip( void ) {
811 int i;
812
813 for ( i = 0; i < clipModels.Num(); i++ ) {
814 if ( clipModels[i] ) {
815 clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis );
816 }
817 }
818 }
819
820 /*
821 ================
822 idPhysics_StaticMulti::EvaluateContacts
823 ================
824 */
EvaluateContacts(void)825 bool idPhysics_StaticMulti::EvaluateContacts( void ) {
826 return false;
827 }
828
829 /*
830 ================
831 idPhysics_StaticMulti::GetNumContacts
832 ================
833 */
GetNumContacts(void) const834 int idPhysics_StaticMulti::GetNumContacts( void ) const {
835 return 0;
836 }
837
838 /*
839 ================
840 idPhysics_StaticMulti::GetContact
841 ================
842 */
GetContact(int num) const843 const contactInfo_t &idPhysics_StaticMulti::GetContact( int num ) const {
844 static contactInfo_t info;
845 memset( &info, 0, sizeof( info ) );
846 return info;
847 }
848
849 /*
850 ================
851 idPhysics_StaticMulti::ClearContacts
852 ================
853 */
ClearContacts(void)854 void idPhysics_StaticMulti::ClearContacts( void ) {
855 }
856
857 /*
858 ================
859 idPhysics_StaticMulti::AddContactEntity
860 ================
861 */
AddContactEntity(idEntity * e)862 void idPhysics_StaticMulti::AddContactEntity( idEntity *e ) {
863 }
864
865 /*
866 ================
867 idPhysics_StaticMulti::RemoveContactEntity
868 ================
869 */
RemoveContactEntity(idEntity * e)870 void idPhysics_StaticMulti::RemoveContactEntity( idEntity *e ) {
871 }
872
873 /*
874 ================
875 idPhysics_StaticMulti::HasGroundContacts
876 ================
877 */
HasGroundContacts(void) const878 bool idPhysics_StaticMulti::HasGroundContacts( void ) const {
879 return false;
880 }
881
882 /*
883 ================
884 idPhysics_StaticMulti::IsGroundEntity
885 ================
886 */
IsGroundEntity(int entityNum) const887 bool idPhysics_StaticMulti::IsGroundEntity( int entityNum ) const {
888 return false;
889 }
890
891 /*
892 ================
893 idPhysics_StaticMulti::IsGroundClipModel
894 ================
895 */
IsGroundClipModel(int entityNum,int id) const896 bool idPhysics_StaticMulti::IsGroundClipModel( int entityNum, int id ) const {
897 return false;
898 }
899
900 /*
901 ================
902 idPhysics_StaticMulti::SetPushed
903 ================
904 */
SetPushed(int deltaTime)905 void idPhysics_StaticMulti::SetPushed( int deltaTime ) {
906 }
907
908 /*
909 ================
910 idPhysics_StaticMulti::GetPushedLinearVelocity
911 ================
912 */
GetPushedLinearVelocity(const int id) const913 const idVec3 &idPhysics_StaticMulti::GetPushedLinearVelocity( const int id ) const {
914 return vec3_origin;
915 }
916
917 /*
918 ================
919 idPhysics_StaticMulti::GetPushedAngularVelocity
920 ================
921 */
GetPushedAngularVelocity(const int id) const922 const idVec3 &idPhysics_StaticMulti::GetPushedAngularVelocity( const int id ) const {
923 return vec3_origin;
924 }
925
926 /*
927 ================
928 idPhysics_StaticMulti::SetMaster
929 ================
930 */
SetMaster(idEntity * master,const bool orientated)931 void idPhysics_StaticMulti::SetMaster( idEntity *master, const bool orientated ) {
932 int i;
933 idVec3 masterOrigin;
934 idMat3 masterAxis;
935
936 if ( master ) {
937 if ( !hasMaster ) {
938 // transform from world space to master space
939 self->GetMasterPosition( masterOrigin, masterAxis );
940 for ( i = 0; i < clipModels.Num(); i++ ) {
941 current[i].localOrigin = ( current[i].origin - masterOrigin ) * masterAxis.Transpose();
942 if ( orientated ) {
943 current[i].localAxis = current[i].axis * masterAxis.Transpose();
944 } else {
945 current[i].localAxis = current[i].axis;
946 }
947 }
948 hasMaster = true;
949 isOrientated = orientated;
950 }
951 } else {
952 if ( hasMaster ) {
953 hasMaster = false;
954 }
955 }
956 }
957
958 /*
959 ================
960 idPhysics_StaticMulti::GetBlockingInfo
961 ================
962 */
GetBlockingInfo(void) const963 const trace_t *idPhysics_StaticMulti::GetBlockingInfo( void ) const {
964 return NULL;
965 }
966
967 /*
968 ================
969 idPhysics_StaticMulti::GetBlockingEntity
970 ================
971 */
GetBlockingEntity(void) const972 idEntity *idPhysics_StaticMulti::GetBlockingEntity( void ) const {
973 return NULL;
974 }
975
976 /*
977 ================
978 idPhysics_StaticMulti::GetLinearEndTime
979 ================
980 */
GetLinearEndTime(void) const981 int idPhysics_StaticMulti::GetLinearEndTime( void ) const {
982 return 0;
983 }
984
985 /*
986 ================
987 idPhysics_StaticMulti::GetAngularEndTime
988 ================
989 */
GetAngularEndTime(void) const990 int idPhysics_StaticMulti::GetAngularEndTime( void ) const {
991 return 0;
992 }
993
994 /*
995 ================
996 idPhysics_StaticMulti::WriteToSnapshot
997 ================
998 */
WriteToSnapshot(idBitMsgDelta & msg) const999 void idPhysics_StaticMulti::WriteToSnapshot( idBitMsgDelta &msg ) const {
1000 int i;
1001 idCQuat quat, localQuat;
1002
1003 msg.WriteByte( current.Num() );
1004
1005 for ( i = 0; i < current.Num(); i++ ) {
1006 quat = current[i].axis.ToCQuat();
1007 localQuat = current[i].localAxis.ToCQuat();
1008
1009 msg.WriteFloat( current[i].origin[0] );
1010 msg.WriteFloat( current[i].origin[1] );
1011 msg.WriteFloat( current[i].origin[2] );
1012 msg.WriteFloat( quat.x );
1013 msg.WriteFloat( quat.y );
1014 msg.WriteFloat( quat.z );
1015 msg.WriteDeltaFloat( current[i].origin[0], current[i].localOrigin[0] );
1016 msg.WriteDeltaFloat( current[i].origin[1], current[i].localOrigin[1] );
1017 msg.WriteDeltaFloat( current[i].origin[2], current[i].localOrigin[2] );
1018 msg.WriteDeltaFloat( quat.x, localQuat.x );
1019 msg.WriteDeltaFloat( quat.y, localQuat.y );
1020 msg.WriteDeltaFloat( quat.z, localQuat.z );
1021 }
1022 }
1023
1024 /*
1025 ================
1026 idPhysics_StaticMulti::ReadFromSnapshot
1027 ================
1028 */
ReadFromSnapshot(const idBitMsgDelta & msg)1029 void idPhysics_StaticMulti::ReadFromSnapshot( const idBitMsgDelta &msg ) {
1030 int i, num id_attribute((unused));
1031 idCQuat quat, localQuat;
1032
1033 num = msg.ReadByte();
1034 assert( num == current.Num() );
1035
1036 for ( i = 0; i < current.Num(); i++ ) {
1037 current[i].origin[0] = msg.ReadFloat();
1038 current[i].origin[1] = msg.ReadFloat();
1039 current[i].origin[2] = msg.ReadFloat();
1040 quat.x = msg.ReadFloat();
1041 quat.y = msg.ReadFloat();
1042 quat.z = msg.ReadFloat();
1043 current[i].localOrigin[0] = msg.ReadDeltaFloat( current[i].origin[0] );
1044 current[i].localOrigin[1] = msg.ReadDeltaFloat( current[i].origin[1] );
1045 current[i].localOrigin[2] = msg.ReadDeltaFloat( current[i].origin[2] );
1046 localQuat.x = msg.ReadDeltaFloat( quat.x );
1047 localQuat.y = msg.ReadDeltaFloat( quat.y );
1048 localQuat.z = msg.ReadDeltaFloat( quat.z );
1049
1050 current[i].axis = quat.ToMat3();
1051 current[i].localAxis = localQuat.ToMat3();
1052 }
1053 }
1054