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