]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/d3xp/physics/Physics_Actor.cpp
hello world
[icculus/iodoom3.git] / neo / d3xp / physics / Physics_Actor.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_Base, idPhysics_Actor )
35 END_CLASS
36
37 /*
38 ================
39 idPhysics_Actor::idPhysics_Actor
40 ================
41 */
42 idPhysics_Actor::idPhysics_Actor( void ) {
43         clipModel = NULL;
44         SetClipModelAxis();
45         mass = 100.0f;
46         invMass = 1.0f / mass;
47         masterEntity = NULL;
48         masterYaw = 0.0f;
49         masterDeltaYaw = 0.0f;
50         groundEntityPtr = NULL;
51 }
52
53 /*
54 ================
55 idPhysics_Actor::~idPhysics_Actor
56 ================
57 */
58 idPhysics_Actor::~idPhysics_Actor( void ) {
59         if ( clipModel ) {
60                 delete clipModel;
61                 clipModel = NULL;
62         }
63 }
64
65 /*
66 ================
67 idPhysics_Actor::Save
68 ================
69 */
70 void idPhysics_Actor::Save( idSaveGame *savefile ) const {
71
72         savefile->WriteClipModel( clipModel );
73         savefile->WriteMat3( clipModelAxis );
74
75         savefile->WriteFloat( mass );
76         savefile->WriteFloat( invMass );
77
78         savefile->WriteObject( masterEntity );
79         savefile->WriteFloat( masterYaw );
80         savefile->WriteFloat( masterDeltaYaw );
81
82         groundEntityPtr.Save( savefile );
83 }
84
85 /*
86 ================
87 idPhysics_Actor::Restore
88 ================
89 */
90 void idPhysics_Actor::Restore( idRestoreGame *savefile ) {
91
92         savefile->ReadClipModel( clipModel );
93         savefile->ReadMat3( clipModelAxis );
94
95         savefile->ReadFloat( mass );
96         savefile->ReadFloat( invMass );
97
98         savefile->ReadObject( reinterpret_cast<idClass *&>( masterEntity ) );
99         savefile->ReadFloat( masterYaw );
100         savefile->ReadFloat( masterDeltaYaw );
101
102         groundEntityPtr.Restore( savefile );
103 }
104
105 /*
106 ================
107 idPhysics_Actor::SetClipModelAxis
108 ================
109 */
110 void idPhysics_Actor::SetClipModelAxis( void ) {
111         // align clip model to gravity direction
112         if ( ( gravityNormal[2] == -1.0f ) || ( gravityNormal == vec3_zero ) ) {
113                 clipModelAxis.Identity();
114         }
115         else {
116                 clipModelAxis[2] = -gravityNormal;
117                 clipModelAxis[2].NormalVectors( clipModelAxis[0], clipModelAxis[1] );
118                 clipModelAxis[1] = -clipModelAxis[1];
119         }
120
121         if ( clipModel ) {
122                 clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModelAxis );
123         }
124 }
125
126 /*
127 ================
128 idPhysics_Actor::GetGravityAxis
129 ================
130 */
131 const idMat3 &idPhysics_Actor::GetGravityAxis( void ) const {
132         return clipModelAxis;
133 }
134
135 /*
136 ================
137 idPhysics_Actor::GetMasterDeltaYaw
138 ================
139 */
140 float idPhysics_Actor::GetMasterDeltaYaw( void ) const {
141         return masterDeltaYaw;
142 }
143
144 /*
145 ================
146 idPhysics_Actor::GetGroundEntity
147 ================
148 */
149 idEntity *idPhysics_Actor::GetGroundEntity( void ) const {
150         return groundEntityPtr.GetEntity();
151 }
152
153 /*
154 ================
155 idPhysics_Actor::SetClipModel
156 ================
157 */
158 void idPhysics_Actor::SetClipModel( idClipModel *model, const float density, int id, bool freeOld ) {
159         assert( self );
160         assert( model );                                        // a clip model is required
161         assert( model->IsTraceModel() );        // and it should be a trace model
162         assert( density > 0.0f );                       // density should be valid
163
164         if ( clipModel && clipModel != model && freeOld ) {
165                 delete clipModel;
166         }
167         clipModel = model;
168         clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModelAxis );
169 }
170
171 /*
172 ================
173 idPhysics_Actor::GetClipModel
174 ================
175 */
176 idClipModel *idPhysics_Actor::GetClipModel( int id ) const {
177         return clipModel;
178 }
179
180 /*
181 ================
182 idPhysics_Actor::GetNumClipModels
183 ================
184 */
185 int idPhysics_Actor::GetNumClipModels( void ) const {
186         return 1;
187 }
188
189 /*
190 ================
191 idPhysics_Actor::SetMass
192 ================
193 */
194 void idPhysics_Actor::SetMass( float _mass, int id ) {
195         assert( _mass > 0.0f );
196         mass = _mass;
197         invMass = 1.0f / _mass;
198 }
199
200 /*
201 ================
202 idPhysics_Actor::GetMass
203 ================
204 */
205 float idPhysics_Actor::GetMass( int id ) const {
206         return mass;
207 }
208
209 /*
210 ================
211 idPhysics_Actor::SetClipMask
212 ================
213 */
214 void idPhysics_Actor::SetContents( int contents, int id ) {
215         clipModel->SetContents( contents );
216 }
217
218 /*
219 ================
220 idPhysics_Actor::SetClipMask
221 ================
222 */
223 int idPhysics_Actor::GetContents( int id ) const {
224         return clipModel->GetContents();
225 }
226
227 /*
228 ================
229 idPhysics_Actor::GetBounds
230 ================
231 */
232 const idBounds &idPhysics_Actor::GetBounds( int id ) const {
233         return clipModel->GetBounds();
234 }
235
236 /*
237 ================
238 idPhysics_Actor::GetAbsBounds
239 ================
240 */
241 const idBounds &idPhysics_Actor::GetAbsBounds( int id ) const {
242         return clipModel->GetAbsBounds();
243 }
244
245 /*
246 ================
247 idPhysics_Actor::IsPushable
248 ================
249 */
250 bool idPhysics_Actor::IsPushable( void ) const {
251         return ( masterEntity == NULL );
252 }
253
254 /*
255 ================
256 idPhysics_Actor::GetOrigin
257 ================
258 */
259 const idVec3 &idPhysics_Actor::GetOrigin( int id ) const {
260         return clipModel->GetOrigin();
261 }
262
263 /*
264 ================
265 idPhysics_Player::GetAxis
266 ================
267 */
268 const idMat3 &idPhysics_Actor::GetAxis( int id ) const {
269         return clipModel->GetAxis();
270 }
271
272 /*
273 ================
274 idPhysics_Actor::SetGravity
275 ================
276 */
277 void idPhysics_Actor::SetGravity( const idVec3 &newGravity ) {
278         if ( newGravity != gravityVector ) {
279                 idPhysics_Base::SetGravity( newGravity );
280                 SetClipModelAxis();
281         }
282 }
283
284 /*
285 ================
286 idPhysics_Actor::ClipTranslation
287 ================
288 */
289 void idPhysics_Actor::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const {
290         if ( model ) {
291                 gameLocal.clip.TranslationModel( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation,
292                                                                 clipModel, clipModel->GetAxis(), clipMask,
293                                                                 model->Handle(), model->GetOrigin(), model->GetAxis() );
294         }
295         else {
296                 gameLocal.clip.Translation( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation,
297                                                                 clipModel, clipModel->GetAxis(), clipMask, self );
298         }
299 }
300
301 /*
302 ================
303 idPhysics_Actor::ClipRotation
304 ================
305 */
306 void idPhysics_Actor::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const {
307         if ( model ) {
308                 gameLocal.clip.RotationModel( results, clipModel->GetOrigin(), rotation,
309                                                                 clipModel, clipModel->GetAxis(), clipMask,
310                                                                 model->Handle(), model->GetOrigin(), model->GetAxis() );
311         }
312         else {
313                 gameLocal.clip.Rotation( results, clipModel->GetOrigin(), rotation,
314                                                                 clipModel, clipModel->GetAxis(), clipMask, self );
315         }
316 }
317
318 /*
319 ================
320 idPhysics_Actor::ClipContents
321 ================
322 */
323 int idPhysics_Actor::ClipContents( const idClipModel *model ) const {
324         if ( model ) {
325                 return gameLocal.clip.ContentsModel( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1,
326                                                                         model->Handle(), model->GetOrigin(), model->GetAxis() );
327         }
328         else {
329                 return gameLocal.clip.Contents( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, NULL );
330         }
331 }
332
333 /*
334 ================
335 idPhysics_Actor::DisableClip
336 ================
337 */
338 void idPhysics_Actor::DisableClip( void ) {
339         clipModel->Disable();
340 }
341
342 /*
343 ================
344 idPhysics_Actor::EnableClip
345 ================
346 */
347 void idPhysics_Actor::EnableClip( void ) {
348         clipModel->Enable();
349 }
350
351 /*
352 ================
353 idPhysics_Actor::UnlinkClip
354 ================
355 */
356 void idPhysics_Actor::UnlinkClip( void ) {
357         clipModel->Unlink();
358 }
359
360 /*
361 ================
362 idPhysics_Actor::LinkClip
363 ================
364 */
365 void idPhysics_Actor::LinkClip( void ) {
366         clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModel->GetAxis() );
367 }
368
369 /*
370 ================
371 idPhysics_Actor::EvaluateContacts
372 ================
373 */
374 bool idPhysics_Actor::EvaluateContacts( void ) {
375
376         // get all the ground contacts
377         ClearContacts();
378         AddGroundContacts( clipModel );
379         AddContactEntitiesForContacts();
380
381         return ( contacts.Num() != 0 );
382 }