hello world

This commit is contained in:
Timothee 'TTimo' Besset
2011-11-22 15:28:15 -06:00
commit fb1609f554
2155 changed files with 1017022 additions and 0 deletions

1666
neo/game/physics/Clip.cpp Normal file

File diff suppressed because it is too large Load Diff

352
neo/game/physics/Clip.h Normal file
View File

@@ -0,0 +1,352 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __CLIP_H__
#define __CLIP_H__
/*
===============================================================================
Handles collision detection with the world and between physics objects.
===============================================================================
*/
#define CLIPMODEL_ID_TO_JOINT_HANDLE( id ) ( ( id ) >= 0 ? INVALID_JOINT : ((jointHandle_t) ( -1 - id )) )
#define JOINT_HANDLE_TO_CLIPMODEL_ID( id ) ( -1 - id )
class idClip;
class idClipModel;
class idEntity;
//===============================================================
//
// idClipModel
//
//===============================================================
class idClipModel {
friend class idClip;
public:
idClipModel( void );
explicit idClipModel( const char *name );
explicit idClipModel( const idTraceModel &trm );
explicit idClipModel( const int renderModelHandle );
explicit idClipModel( const idClipModel *model );
~idClipModel( void );
bool LoadModel( const char *name );
void LoadModel( const idTraceModel &trm );
void LoadModel( const int renderModelHandle );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Link( idClip &clp ); // must have been linked with an entity and id before
void Link( idClip &clp, idEntity *ent, int newId, const idVec3 &newOrigin, const idMat3 &newAxis, int renderModelHandle = -1 );
void Unlink( void ); // unlink from sectors
void SetPosition( const idVec3 &newOrigin, const idMat3 &newAxis ); // unlinks the clip model
void Translate( const idVec3 &translation ); // unlinks the clip model
void Rotate( const idRotation &rotation ); // unlinks the clip model
void Enable( void ); // enable for clipping
void Disable( void ); // keep linked but disable for clipping
void SetMaterial( const idMaterial *m );
const idMaterial * GetMaterial( void ) const;
void SetContents( int newContents ); // override contents
int GetContents( void ) const;
void SetEntity( idEntity *newEntity );
idEntity * GetEntity( void ) const;
void SetId( int newId );
int GetId( void ) const;
void SetOwner( idEntity *newOwner );
idEntity * GetOwner( void ) const;
const idBounds & GetBounds( void ) const;
const idBounds & GetAbsBounds( void ) const;
const idVec3 & GetOrigin( void ) const;
const idMat3 & GetAxis( void ) const;
bool IsTraceModel( void ) const; // returns true if this is a trace model
bool IsRenderModel( void ) const; // returns true if this is a render model
bool IsLinked( void ) const; // returns true if the clip model is linked
bool IsEnabled( void ) const; // returns true if enabled for collision detection
bool IsEqual( const idTraceModel &trm ) const;
cmHandle_t Handle( void ) const; // returns handle used to collide vs this model
const idTraceModel * GetTraceModel( void ) const;
void GetMassProperties( const float density, float &mass, idVec3 &centerOfMass, idMat3 &inertiaTensor ) const;
static cmHandle_t CheckModel( const char *name );
static void ClearTraceModelCache( void );
static int TraceModelCacheSize( void );
static void SaveTraceModels( idSaveGame *savefile );
static void RestoreTraceModels( idRestoreGame *savefile );
private:
bool enabled; // true if this clip model is used for clipping
idEntity * entity; // entity using this clip model
int id; // id for entities that use multiple clip models
idEntity * owner; // owner of the entity that owns this clip model
idVec3 origin; // origin of clip model
idMat3 axis; // orientation of clip model
idBounds bounds; // bounds
idBounds absBounds; // absolute bounds
const idMaterial * material; // material for trace models
int contents; // all contents ored together
cmHandle_t collisionModelHandle; // handle to collision model
int traceModelIndex; // trace model used for collision detection
int renderModelHandle; // render model def handle
struct clipLink_s * clipLinks; // links into sectors
int touchCount;
void Init( void ); // initialize
void Link_r( struct clipSector_s *node );
static int AllocTraceModel( const idTraceModel &trm );
static void FreeTraceModel( int traceModelIndex );
static idTraceModel * GetCachedTraceModel( int traceModelIndex );
static int GetTraceModelHashKey( const idTraceModel &trm );
};
ID_INLINE void idClipModel::Translate( const idVec3 &translation ) {
Unlink();
origin += translation;
}
ID_INLINE void idClipModel::Rotate( const idRotation &rotation ) {
Unlink();
origin *= rotation;
axis *= rotation.ToMat3();
}
ID_INLINE void idClipModel::Enable( void ) {
enabled = true;
}
ID_INLINE void idClipModel::Disable( void ) {
enabled = false;
}
ID_INLINE void idClipModel::SetMaterial( const idMaterial *m ) {
material = m;
}
ID_INLINE const idMaterial * idClipModel::GetMaterial( void ) const {
return material;
}
ID_INLINE void idClipModel::SetContents( int newContents ) {
contents = newContents;
}
ID_INLINE int idClipModel::GetContents( void ) const {
return contents;
}
ID_INLINE void idClipModel::SetEntity( idEntity *newEntity ) {
entity = newEntity;
}
ID_INLINE idEntity *idClipModel::GetEntity( void ) const {
return entity;
}
ID_INLINE void idClipModel::SetId( int newId ) {
id = newId;
}
ID_INLINE int idClipModel::GetId( void ) const {
return id;
}
ID_INLINE void idClipModel::SetOwner( idEntity *newOwner ) {
owner = newOwner;
}
ID_INLINE idEntity *idClipModel::GetOwner( void ) const {
return owner;
}
ID_INLINE const idBounds &idClipModel::GetBounds( void ) const {
return bounds;
}
ID_INLINE const idBounds &idClipModel::GetAbsBounds( void ) const {
return absBounds;
}
ID_INLINE const idVec3 &idClipModel::GetOrigin( void ) const {
return origin;
}
ID_INLINE const idMat3 &idClipModel::GetAxis( void ) const {
return axis;
}
ID_INLINE bool idClipModel::IsRenderModel( void ) const {
return ( renderModelHandle != -1 );
}
ID_INLINE bool idClipModel::IsTraceModel( void ) const {
return ( traceModelIndex != -1 );
}
ID_INLINE bool idClipModel::IsLinked( void ) const {
return ( clipLinks != NULL );
}
ID_INLINE bool idClipModel::IsEnabled( void ) const {
return enabled;
}
ID_INLINE bool idClipModel::IsEqual( const idTraceModel &trm ) const {
return ( traceModelIndex != -1 && *GetCachedTraceModel( traceModelIndex ) == trm );
}
ID_INLINE const idTraceModel *idClipModel::GetTraceModel( void ) const {
if ( !IsTraceModel() ) {
return NULL;
}
return idClipModel::GetCachedTraceModel( traceModelIndex );
}
//===============================================================
//
// idClip
//
//===============================================================
class idClip {
friend class idClipModel;
public:
idClip( void );
void Init( void );
void Shutdown( void );
// clip versus the rest of the world
bool Translation( trace_t &results, const idVec3 &start, const idVec3 &end,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
bool Rotation( trace_t &results, const idVec3 &start, const idRotation &rotation,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
bool Motion( trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
int Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
int Contents( const idVec3 &start,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
// special case translations versus the rest of the world
bool TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end,
int contentMask, const idEntity *passEntity );
bool TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds,
int contentMask, const idEntity *passEntity );
// clip versus a specific model
void TranslationModel( trace_t &results, const idVec3 &start, const idVec3 &end,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
void RotationModel( trace_t &results, const idVec3 &start, const idRotation &rotation,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
int ContactsModel( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
int ContentsModel( const idVec3 &start,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
// clip versus all entities but not the world
void TranslationEntities( trace_t &results, const idVec3 &start, const idVec3 &end,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
// get a contact feature
bool GetModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding ) const;
// get entities/clip models within or touching the given bounds
int EntitiesTouchingBounds( const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount ) const;
int ClipModelsTouchingBounds( const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount ) const;
const idBounds & GetWorldBounds( void ) const;
idClipModel * DefaultClipModel( void );
// stats and debug drawing
void PrintStatistics( void );
void DrawClipModels( const idVec3 &eye, const float radius, const idEntity *passEntity );
bool DrawModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, int lifetime ) const;
private:
int numClipSectors;
struct clipSector_s * clipSectors;
idBounds worldBounds;
idClipModel temporaryClipModel;
idClipModel defaultClipModel;
mutable int touchCount;
// statistics
int numTranslations;
int numRotations;
int numMotions;
int numRenderModelTraces;
int numContents;
int numContacts;
private:
struct clipSector_s * CreateClipSectors_r( const int depth, const idBounds &bounds, idVec3 &maxSector );
void ClipModelsTouchingBounds_r( const struct clipSector_s *node, struct listParms_s &parms ) const;
const idTraceModel * TraceModelForClipModel( const idClipModel *mdl ) const;
int GetTraceClipModels( const idBounds &bounds, int contentMask, const idEntity *passEntity, idClipModel **clipModelList ) const;
void TraceRenderModel( trace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, const idMat3 &axis, idClipModel *touch ) const;
};
ID_INLINE bool idClip::TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end, int contentMask, const idEntity *passEntity ) {
Translation( results, start, end, NULL, mat3_identity, contentMask, passEntity );
return ( results.fraction < 1.0f );
}
ID_INLINE bool idClip::TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, int contentMask, const idEntity *passEntity ) {
temporaryClipModel.LoadModel( idTraceModel( bounds ) );
Translation( results, start, end, &temporaryClipModel, mat3_identity, contentMask, passEntity );
return ( results.fraction < 1.0f );
}
ID_INLINE const idBounds & idClip::GetWorldBounds( void ) const {
return worldBounds;
}
ID_INLINE idClipModel *idClip::DefaultClipModel( void ) {
return &defaultClipModel;
}
#endif /* !__CLIP_H__ */

View File

@@ -0,0 +1,93 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
CLASS_DECLARATION( idClass, idForce )
END_CLASS
idList<idForce*> idForce::forceList;
/*
================
idForce::idForce
================
*/
idForce::idForce( void ) {
forceList.Append( this );
}
/*
================
idForce::~idForce
================
*/
idForce::~idForce( void ) {
forceList.Remove( this );
}
/*
================
idForce::DeletePhysics
================
*/
void idForce::DeletePhysics( const idPhysics *phys ) {
int i;
for ( i = 0; i < forceList.Num(); i++ ) {
forceList[i]->RemovePhysics( phys );
}
}
/*
================
idForce::ClearForceList
================
*/
void idForce::ClearForceList( void ) {
forceList.Clear();
}
/*
================
idForce::Evaluate
================
*/
void idForce::Evaluate( int time ) {
}
/*
================
idForce::RemovePhysics
================
*/
void idForce::RemovePhysics( const idPhysics *phys ) {
}

66
neo/game/physics/Force.h Normal file
View File

@@ -0,0 +1,66 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __FORCE_H__
#define __FORCE_H__
/*
===============================================================================
Force base class
A force object applies a force to a physics object.
===============================================================================
*/
class idEntity;
class idPhysics;
class idForce : public idClass {
public:
CLASS_PROTOTYPE( idForce );
idForce( void );
virtual ~idForce( void );
static void DeletePhysics( const idPhysics *phys );
static void ClearForceList( void );
public: // common force interface
// evalulate the force up to the given time
virtual void Evaluate( int time );
// removes any pointers to the physics object
virtual void RemovePhysics( const idPhysics *phys );
private:
static idList<idForce*> forceList;
};
#endif /* !__FORCE_H__ */

View File

@@ -0,0 +1,135 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
CLASS_DECLARATION( idForce, idForce_Constant )
END_CLASS
/*
================
idForce_Constant::idForce_Constant
================
*/
idForce_Constant::idForce_Constant( void ) {
force = vec3_zero;
physics = NULL;
id = 0;
point = vec3_zero;
}
/*
================
idForce_Constant::~idForce_Constant
================
*/
idForce_Constant::~idForce_Constant( void ) {
}
/*
================
idForce_Constant::Save
================
*/
void idForce_Constant::Save( idSaveGame *savefile ) const {
savefile->WriteVec3( force );
savefile->WriteInt( id );
savefile->WriteVec3( point );
}
/*
================
idForce_Constant::Restore
================
*/
void idForce_Constant::Restore( idRestoreGame *savefile ) {
// Owner needs to call SetPhysics!!
savefile->ReadVec3( force );
savefile->ReadInt( id );
savefile->ReadVec3( point );
}
/*
================
idForce_Constant::SetPosition
================
*/
void idForce_Constant::SetPosition( idPhysics *physics, int id, const idVec3 &point ) {
this->physics = physics;
this->id = id;
this->point = point;
}
/*
================
idForce_Constant::SetForce
================
*/
void idForce_Constant::SetForce( const idVec3 &force ) {
this->force = force;
}
/*
================
idForce_Constant::SetPhysics
================
*/
void idForce_Constant::SetPhysics( idPhysics *physics ) {
this->physics = physics;
}
/*
================
idForce_Constant::Evaluate
================
*/
void idForce_Constant::Evaluate( int time ) {
idVec3 p;
if ( !physics ) {
return;
}
p = physics->GetOrigin( id ) + point * physics->GetAxis( id );
physics->AddForce( id, p, force );
}
/*
================
idForce_Constant::RemovePhysics
================
*/
void idForce_Constant::RemovePhysics( const idPhysics *phys ) {
if ( physics == phys ) {
physics = NULL;
}
}

View File

@@ -0,0 +1,71 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __FORCE_CONSTANT_H__
#define __FORCE_CONSTANT_H__
/*
===============================================================================
Constant force
===============================================================================
*/
class idForce_Constant : public idForce {
public:
CLASS_PROTOTYPE( idForce_Constant );
idForce_Constant( void );
virtual ~idForce_Constant( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
// constant force
void SetForce( const idVec3 &force );
// set force position
void SetPosition( idPhysics *physics, int id, const idVec3 &point );
void SetPhysics( idPhysics *physics );
public: // common force interface
virtual void Evaluate( int time );
virtual void RemovePhysics( const idPhysics *phys );
private:
// force properties
idVec3 force;
idPhysics * physics;
int id;
idVec3 point;
};
#endif /* !__FORCE_CONSTANT_H__ */

View File

@@ -0,0 +1,155 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
CLASS_DECLARATION( idForce, idForce_Drag )
END_CLASS
/*
================
idForce_Drag::idForce_Drag
================
*/
idForce_Drag::idForce_Drag( void ) {
damping = 0.5f;
dragPosition = vec3_zero;
physics = NULL;
id = 0;
p = vec3_zero;
dragPosition = vec3_zero;
}
/*
================
idForce_Drag::~idForce_Drag
================
*/
idForce_Drag::~idForce_Drag( void ) {
}
/*
================
idForce_Drag::Init
================
*/
void idForce_Drag::Init( float damping ) {
if ( damping >= 0.0f && damping < 1.0f ) {
this->damping = damping;
}
}
/*
================
idForce_Drag::SetPhysics
================
*/
void idForce_Drag::SetPhysics( idPhysics *phys, int id, const idVec3 &p ) {
this->physics = phys;
this->id = id;
this->p = p;
}
/*
================
idForce_Drag::SetDragPosition
================
*/
void idForce_Drag::SetDragPosition( const idVec3 &pos ) {
this->dragPosition = pos;
}
/*
================
idForce_Drag::GetDragPosition
================
*/
const idVec3 &idForce_Drag::GetDragPosition( void ) const {
return this->dragPosition;
}
/*
================
idForce_Drag::GetDraggedPosition
================
*/
const idVec3 idForce_Drag::GetDraggedPosition( void ) const {
return ( physics->GetOrigin( id ) + p * physics->GetAxis( id ) );
}
/*
================
idForce_Drag::Evaluate
================
*/
void idForce_Drag::Evaluate( int time ) {
float l1, l2, mass;
idVec3 dragOrigin, dir1, dir2, velocity, centerOfMass;
idMat3 inertiaTensor;
idRotation rotation;
idClipModel *clipModel;
if ( !physics ) {
return;
}
clipModel = physics->GetClipModel( id );
if ( clipModel != NULL && clipModel->IsTraceModel() ) {
clipModel->GetMassProperties( 1.0f, mass, centerOfMass, inertiaTensor );
} else {
centerOfMass.Zero();
}
centerOfMass = physics->GetOrigin( id ) + centerOfMass * physics->GetAxis( id );
dragOrigin = physics->GetOrigin( id ) + p * physics->GetAxis( id );
dir1 = dragPosition - centerOfMass;
dir2 = dragOrigin - centerOfMass;
l1 = dir1.Normalize();
l2 = dir2.Normalize();
rotation.Set( centerOfMass, dir2.Cross( dir1 ), RAD2DEG( idMath::ACos( dir1 * dir2 ) ) );
physics->SetAngularVelocity( rotation.ToAngularVelocity() / MS2SEC( USERCMD_MSEC ), id );
velocity = physics->GetLinearVelocity( id ) * damping + dir1 * ( ( l1 - l2 ) * ( 1.0f - damping ) / MS2SEC( USERCMD_MSEC ) );
physics->SetLinearVelocity( velocity, id );
}
/*
================
idForce_Drag::RemovePhysics
================
*/
void idForce_Drag::RemovePhysics( const idPhysics *phys ) {
if ( physics == phys ) {
physics = NULL;
}
}

View File

@@ -0,0 +1,74 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __FORCE_DRAG_H__
#define __FORCE_DRAG_H__
/*
===============================================================================
Drag force
===============================================================================
*/
class idForce_Drag : public idForce {
public:
CLASS_PROTOTYPE( idForce_Drag );
idForce_Drag( void );
virtual ~idForce_Drag( void );
// initialize the drag force
void Init( float damping );
// set physics object being dragged
void SetPhysics( idPhysics *physics, int id, const idVec3 &p );
// set position to drag towards
void SetDragPosition( const idVec3 &pos );
// get the position dragged towards
const idVec3 & GetDragPosition( void ) const;
// get the position on the dragged physics object
const idVec3 GetDraggedPosition( void ) const;
public: // common force interface
virtual void Evaluate( int time );
virtual void RemovePhysics( const idPhysics *phys );
private:
// properties
float damping;
// positioning
idPhysics * physics; // physics object
int id; // clip model id of physics object
idVec3 p; // position on clip model
idVec3 dragPosition; // drag towards this position
};
#endif /* !__FORCE_DRAG_H__ */

View File

@@ -0,0 +1,257 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
CLASS_DECLARATION( idForce, idForce_Field )
END_CLASS
/*
================
idForce_Field::idForce_Field
================
*/
idForce_Field::idForce_Field( void ) {
type = FORCEFIELD_UNIFORM;
applyType = FORCEFIELD_APPLY_FORCE;
magnitude = 0.0f;
dir.Set( 0, 0, 1 );
randomTorque = 0.0f;
playerOnly = false;
monsterOnly = false;
clipModel = NULL;
}
/*
================
idForce_Field::~idForce_Field
================
*/
idForce_Field::~idForce_Field( void ) {
if ( this->clipModel ) {
delete this->clipModel;
}
}
/*
================
idForce_Field::Save
================
*/
void idForce_Field::Save( idSaveGame *savefile ) const {
savefile->WriteInt( type );
savefile->WriteInt( applyType);
savefile->WriteFloat( magnitude );
savefile->WriteVec3( dir );
savefile->WriteFloat( randomTorque );
savefile->WriteBool( playerOnly );
savefile->WriteBool( monsterOnly );
savefile->WriteClipModel( clipModel );
}
/*
================
idForce_Field::Restore
================
*/
void idForce_Field::Restore( idRestoreGame *savefile ) {
savefile->ReadInt( (int &)type );
savefile->ReadInt( (int &)applyType);
savefile->ReadFloat( magnitude );
savefile->ReadVec3( dir );
savefile->ReadFloat( randomTorque );
savefile->ReadBool( playerOnly );
savefile->ReadBool( monsterOnly );
savefile->ReadClipModel( clipModel );
}
/*
================
idForce_Field::SetClipModel
================
*/
void idForce_Field::SetClipModel( idClipModel *clipModel ) {
if ( this->clipModel && clipModel != this->clipModel ) {
delete this->clipModel;
}
this->clipModel = clipModel;
}
/*
================
idForce_Field::Uniform
================
*/
void idForce_Field::Uniform( const idVec3 &force ) {
dir = force;
magnitude = dir.Normalize();
type = FORCEFIELD_UNIFORM;
}
/*
================
idForce_Field::Explosion
================
*/
void idForce_Field::Explosion( float force ) {
magnitude = force;
type = FORCEFIELD_EXPLOSION;
}
/*
================
idForce_Field::Implosion
================
*/
void idForce_Field::Implosion( float force ) {
magnitude = force;
type = FORCEFIELD_IMPLOSION;
}
/*
================
idForce_Field::RandomTorque
================
*/
void idForce_Field::RandomTorque( float force ) {
randomTorque = force;
}
/*
================
idForce_Field::Evaluate
================
*/
void idForce_Field::Evaluate( int time ) {
int numClipModels, i;
idBounds bounds;
idVec3 force, torque, angularVelocity;
idClipModel *cm, *clipModelList[ MAX_GENTITIES ];
assert( clipModel );
bounds.FromTransformedBounds( clipModel->GetBounds(), clipModel->GetOrigin(), clipModel->GetAxis() );
numClipModels = gameLocal.clip.ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES );
for ( i = 0; i < numClipModels; i++ ) {
cm = clipModelList[ i ];
if ( !cm->IsTraceModel() ) {
continue;
}
idEntity *entity = cm->GetEntity();
if ( !entity ) {
continue;
}
idPhysics *physics = entity->GetPhysics();
if ( playerOnly ) {
if ( !physics->IsType( idPhysics_Player::Type ) ) {
continue;
}
} else if ( monsterOnly ) {
if ( !physics->IsType( idPhysics_Monster::Type ) ) {
continue;
}
}
if ( !gameLocal.clip.ContentsModel( cm->GetOrigin(), cm, cm->GetAxis(), -1,
clipModel->Handle(), clipModel->GetOrigin(), clipModel->GetAxis() ) ) {
continue;
}
switch( type ) {
case FORCEFIELD_UNIFORM: {
force = dir;
break;
}
case FORCEFIELD_EXPLOSION: {
force = cm->GetOrigin() - clipModel->GetOrigin();
force.Normalize();
break;
}
case FORCEFIELD_IMPLOSION: {
force = clipModel->GetOrigin() - cm->GetOrigin();
force.Normalize();
break;
}
default: {
gameLocal.Error( "idForce_Field: invalid type" );
break;
}
}
if ( randomTorque != 0.0f ) {
torque[0] = gameLocal.random.CRandomFloat();
torque[1] = gameLocal.random.CRandomFloat();
torque[2] = gameLocal.random.CRandomFloat();
if ( torque.Normalize() == 0.0f ) {
torque[2] = 1.0f;
}
}
switch( applyType ) {
case FORCEFIELD_APPLY_FORCE: {
if ( randomTorque != 0.0f ) {
entity->AddForce( gameLocal.world, cm->GetId(), cm->GetOrigin() + torque.Cross( dir ) * randomTorque, dir * magnitude );
}
else {
entity->AddForce( gameLocal.world, cm->GetId(), cm->GetOrigin(), force * magnitude );
}
break;
}
case FORCEFIELD_APPLY_VELOCITY: {
physics->SetLinearVelocity( force * magnitude, cm->GetId() );
if ( randomTorque != 0.0f ) {
angularVelocity = physics->GetAngularVelocity( cm->GetId() );
physics->SetAngularVelocity( 0.5f * (angularVelocity + torque * randomTorque), cm->GetId() );
}
break;
}
case FORCEFIELD_APPLY_IMPULSE: {
if ( randomTorque != 0.0f ) {
entity->ApplyImpulse( gameLocal.world, cm->GetId(), cm->GetOrigin() + torque.Cross( dir ) * randomTorque, dir * magnitude );
}
else {
entity->ApplyImpulse( gameLocal.world, cm->GetId(), cm->GetOrigin(), force * magnitude );
}
break;
}
default: {
gameLocal.Error( "idForce_Field: invalid apply type" );
break;
}
}
}
}

View File

@@ -0,0 +1,94 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __FORCE_FIELD_H__
#define __FORCE_FIELD_H__
/*
===============================================================================
Force field
===============================================================================
*/
enum forceFieldType {
FORCEFIELD_UNIFORM,
FORCEFIELD_EXPLOSION,
FORCEFIELD_IMPLOSION
};
enum forceFieldApplyType {
FORCEFIELD_APPLY_FORCE,
FORCEFIELD_APPLY_VELOCITY,
FORCEFIELD_APPLY_IMPULSE
};
class idForce_Field : public idForce {
public:
CLASS_PROTOTYPE( idForce_Field );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
idForce_Field( void );
virtual ~idForce_Field( void );
// uniform constant force
void Uniform( const idVec3 &force );
// explosion from clip model origin
void Explosion( float force );
// implosion towards clip model origin
void Implosion( float force );
// add random torque
void RandomTorque( float force );
// should the force field apply a force, velocity or impulse
void SetApplyType( const forceFieldApplyType type ) { applyType = type; }
// make the force field only push players
void SetPlayerOnly( bool set ) { playerOnly = set; }
// make the force field only push monsters
void SetMonsterOnly( bool set ) { monsterOnly = set; }
// clip model describing the extents of the force field
void SetClipModel( idClipModel *clipModel );
public: // common force interface
virtual void Evaluate( int time );
private:
// force properties
forceFieldType type;
forceFieldApplyType applyType;
float magnitude;
idVec3 dir;
float randomTorque;
bool playerOnly;
bool monsterOnly;
idClipModel * clipModel;
};
#endif /* !__FORCE_FIELD_H__ */

View File

@@ -0,0 +1,165 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
CLASS_DECLARATION( idForce, idForce_Spring )
END_CLASS
/*
================
idForce_Spring::idForce_Spring
================
*/
idForce_Spring::idForce_Spring( void ) {
Kstretch = 100.0f;
Kcompress = 100.0f;
damping = 0.0f;
restLength = 0.0f;
physics1 = NULL;
id1 = 0;
p1 = vec3_zero;
physics2 = NULL;
id2 = 0;
p2 = vec3_zero;
}
/*
================
idForce_Spring::~idForce_Spring
================
*/
idForce_Spring::~idForce_Spring( void ) {
}
/*
================
idForce_Spring::InitSpring
================
*/
void idForce_Spring::InitSpring( float Kstretch, float Kcompress, float damping, float restLength ) {
this->Kstretch = Kstretch;
this->Kcompress = Kcompress;
this->damping = damping;
this->restLength = restLength;
}
/*
================
idForce_Spring::SetPosition
================
*/
void idForce_Spring::SetPosition( idPhysics *physics1, int id1, const idVec3 &p1, idPhysics *physics2, int id2, const idVec3 &p2 ) {
this->physics1 = physics1;
this->id1 = id1;
this->p1 = p1;
this->physics2 = physics2;
this->id2 = id2;
this->p2 = p2;
}
/*
================
idForce_Spring::Evaluate
================
*/
void idForce_Spring::Evaluate( int time ) {
float length;
idMat3 axis;
idVec3 pos1, pos2, velocity1, velocity2, force, dampingForce;
impactInfo_t info;
pos1 = p1;
pos2 = p2;
velocity1 = velocity2 = vec3_origin;
if ( physics1 ) {
axis = physics1->GetAxis( id1 );
pos1 = physics1->GetOrigin( id1 );
pos1 += p1 * axis;
if ( damping > 0.0f ) {
physics1->GetImpactInfo( id1, pos1, &info );
velocity1 = info.velocity;
}
}
if ( physics2 ) {
axis = physics2->GetAxis( id2 );
pos2 = physics2->GetOrigin( id2 );
pos2 += p2 * axis;
if ( damping > 0.0f ) {
physics2->GetImpactInfo( id2, pos2, &info );
velocity2 = info.velocity;
}
}
force = pos2 - pos1;
dampingForce = ( damping * ( ((velocity2 - velocity1) * force) / (force * force) ) ) * force;
length = force.Normalize();
// if the spring is stretched
if ( length > restLength ) {
if ( Kstretch > 0.0f ) {
force = ( Square( length - restLength ) * Kstretch ) * force - dampingForce;
if ( physics1 ) {
physics1->AddForce( id1, pos1, force );
}
if ( physics2 ) {
physics2->AddForce( id2, pos2, -force );
}
}
}
else {
if ( Kcompress > 0.0f ) {
force = ( Square( length - restLength ) * Kcompress ) * force - dampingForce;
if ( physics1 ) {
physics1->AddForce( id1, pos1, -force );
}
if ( physics2 ) {
physics2->AddForce( id2, pos2, force );
}
}
}
}
/*
================
idForce_Spring::RemovePhysics
================
*/
void idForce_Spring::RemovePhysics( const idPhysics *phys ) {
if ( physics1 == phys ) {
physics1 = NULL;
}
if ( physics2 == phys ) {
physics2 = NULL;
}
}

View File

@@ -0,0 +1,75 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __FORCE_SPRING_H__
#define __FORCE_SPRING_H__
/*
===============================================================================
Spring force
===============================================================================
*/
class idForce_Spring : public idForce {
public:
CLASS_PROTOTYPE( idForce_Spring );
idForce_Spring( void );
virtual ~idForce_Spring( void );
// initialize the spring
void InitSpring( float Kstretch, float Kcompress, float damping, float restLength );
// set the entities and positions on these entities the spring is attached to
void SetPosition( idPhysics *physics1, int id1, const idVec3 &p1,
idPhysics *physics2, int id2, const idVec3 &p2 );
public: // common force interface
virtual void Evaluate( int time );
virtual void RemovePhysics( const idPhysics *phys );
private:
// spring properties
float Kstretch;
float Kcompress;
float damping;
float restLength;
// positioning
idPhysics * physics1; // first physics object
int id1; // clip model id of first physics object
idVec3 p1; // position on clip model
idPhysics * physics2; // second physics object
int id2; // clip model id of second physics object
idVec3 p2; // position on clip model
};
#endif /* !__FORCE_SPRING_H__ */

View File

@@ -0,0 +1,80 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
ABSTRACT_DECLARATION( idClass, idPhysics )
END_CLASS
/*
================
idPhysics::~idPhysics
================
*/
idPhysics::~idPhysics( void ) {
}
/*
================
idPhysics::Save
================
*/
void idPhysics::Save( idSaveGame *savefile ) const {
}
/*
================
idPhysics::Restore
================
*/
void idPhysics::Restore( idRestoreGame *savefile ) {
}
/*
================
idPhysics::SetClipBox
================
*/
void idPhysics::SetClipBox( const idBounds &bounds, float density ) {
SetClipModel( new idClipModel( idTraceModel( bounds ) ), density );
}
/*
================
idPhysics::SnapTimeToPhysicsFrame
================
*/
int idPhysics::SnapTimeToPhysicsFrame( int t ) {
int s;
s = t + USERCMD_MSEC - 1;
return ( s - s % USERCMD_MSEC );
}

183
neo/game/physics/Physics.h Normal file
View File

@@ -0,0 +1,183 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __PHYSICS_H__
#define __PHYSICS_H__
/*
===============================================================================
Physics abstract class
A physics object is a tool to manipulate the position and orientation of
an entity. The physics object is a container for idClipModels used for
collision detection. The physics deals with moving these collision models
through the world according to the laws of physics or other rules.
The mass of a clip model is the volume of the clip model times the density.
An arbitrary mass can however be set for specific clip models or the
whole physics object. The contents of a clip model is a set of bit flags
that define the contents. The clip mask defines the contents a clip model
collides with.
The linear velocity of a physics object is a vector that defines the
translation of the center of mass in units per second. The angular velocity
of a physics object is a vector that passes through the center of mass. The
direction of this vector defines the axis of rotation and the magnitude
defines the rate of rotation about the axis in radians per second.
The gravity is the change in velocity per second due to gravitational force.
Entities update their visual position and orientation from the physics
using GetOrigin() and GetAxis(). Direct origin and axis changes of
entities should go through the physics. In other words the physics origin
and axis are updated first and the entity updates it's visual position
from the physics.
===============================================================================
*/
#define CONTACT_EPSILON 0.25f // maximum contact seperation distance
class idEntity;
typedef struct impactInfo_s {
float invMass; // inverse mass
idMat3 invInertiaTensor; // inverse inertia tensor
idVec3 position; // impact position relative to center of mass
idVec3 velocity; // velocity at the impact position
} impactInfo_t;
class idPhysics : public idClass {
public:
ABSTRACT_PROTOTYPE( idPhysics );
virtual ~idPhysics( void );
static int SnapTimeToPhysicsFrame( int t );
// Must not be virtual
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
public: // common physics interface
// set pointer to entity using physics
virtual void SetSelf( idEntity *e ) = 0;
// clip models
virtual void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ) = 0;
virtual void SetClipBox( const idBounds &bounds, float density );
virtual idClipModel * GetClipModel( int id = 0 ) const = 0;
virtual int GetNumClipModels( void ) const = 0;
// get/set the mass of a specific clip model or the whole physics object
virtual void SetMass( float mass, int id = -1 ) = 0;
virtual float GetMass( int id = -1 ) const = 0;
// get/set the contents of a specific clip model or the whole physics object
virtual void SetContents( int contents, int id = -1 ) = 0;
virtual int GetContents( int id = -1 ) const = 0;
// get/set the contents a specific clip model or the whole physics object collides with
virtual void SetClipMask( int mask, int id = -1 ) = 0;
virtual int GetClipMask( int id = -1 ) const = 0;
// get the bounds of a specific clip model or the whole physics object
virtual const idBounds & GetBounds( int id = -1 ) const = 0;
virtual const idBounds & GetAbsBounds( int id = -1 ) const = 0;
// evaluate the physics with the given time step, returns true if the object moved
virtual bool Evaluate( int timeStepMSec, int endTimeMSec ) = 0;
// update the time without moving
virtual void UpdateTime( int endTimeMSec ) = 0;
// get the last physics update time
virtual int GetTime( void ) const = 0;
// collision interaction between different physics objects
virtual void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const = 0;
virtual void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) = 0;
virtual void AddForce( const int id, const idVec3 &point, const idVec3 &force ) = 0;
virtual void Activate( void ) = 0;
virtual void PutToRest( void ) = 0;
virtual bool IsAtRest( void ) const = 0;
virtual int GetRestStartTime( void ) const = 0;
virtual bool IsPushable( void ) const = 0;
// save and restore the physics state
virtual void SaveState( void ) = 0;
virtual void RestoreState( void ) = 0;
// set the position and orientation in master space or world space if no master set
virtual void SetOrigin( const idVec3 &newOrigin, int id = -1 ) = 0;
virtual void SetAxis( const idMat3 &newAxis, int id = -1 ) = 0;
// translate or rotate the physics object in world space
virtual void Translate( const idVec3 &translation, int id = -1 ) = 0;
virtual void Rotate( const idRotation &rotation, int id = -1 ) = 0;
// get the position and orientation in world space
virtual const idVec3 & GetOrigin( int id = 0 ) const = 0;
virtual const idMat3 & GetAxis( int id = 0 ) const = 0;
// set linear and angular velocity
virtual void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ) = 0;
virtual void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ) = 0;
// get linear and angular velocity
virtual const idVec3 & GetLinearVelocity( int id = 0 ) const = 0;
virtual const idVec3 & GetAngularVelocity( int id = 0 ) const = 0;
// gravity
virtual void SetGravity( const idVec3 &newGravity ) = 0;
virtual const idVec3 & GetGravity( void ) const = 0;
virtual const idVec3 & GetGravityNormal( void ) const = 0;
// get first collision when translating or rotating this physics object
virtual void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const = 0;
virtual void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const = 0;
virtual int ClipContents( const idClipModel *model ) const = 0;
// disable/enable the clip models contained by this physics object
virtual void DisableClip( void ) = 0;
virtual void EnableClip( void ) = 0;
// link/unlink the clip models contained by this physics object
virtual void UnlinkClip( void ) = 0;
virtual void LinkClip( void ) = 0;
// contacts
virtual bool EvaluateContacts( void ) = 0;
virtual int GetNumContacts( void ) const = 0;
virtual const contactInfo_t &GetContact( int num ) const = 0;
virtual void ClearContacts( void ) = 0;
virtual void AddContactEntity( idEntity *e ) = 0;
virtual void RemoveContactEntity( idEntity *e ) = 0;
// ground contacts
virtual bool HasGroundContacts( void ) const = 0;
virtual bool IsGroundEntity( int entityNum ) const = 0;
virtual bool IsGroundClipModel( int entityNum, int id ) const = 0;
// set the master entity for objects bound to a master
virtual void SetMaster( idEntity *master, const bool orientated = true ) = 0;
// set pushed state
virtual void SetPushed( int deltaTime ) = 0;
virtual const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const = 0;
virtual const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const = 0;
// get blocking info, returns NULL if the object is not blocked
virtual const trace_t * GetBlockingInfo( void ) const = 0;
virtual idEntity * GetBlockingEntity( void ) const = 0;
// movement end times in msec for reached events at the end of predefined motion
virtual int GetLinearEndTime( void ) const = 0;
virtual int GetAngularEndTime( void ) const = 0;
// networking
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const = 0;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg ) = 0;
};
#endif /* !__PHYSICS_H__ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,382 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
CLASS_DECLARATION( idPhysics_Base, idPhysics_Actor )
END_CLASS
/*
================
idPhysics_Actor::idPhysics_Actor
================
*/
idPhysics_Actor::idPhysics_Actor( void ) {
clipModel = NULL;
SetClipModelAxis();
mass = 100.0f;
invMass = 1.0f / mass;
masterEntity = NULL;
masterYaw = 0.0f;
masterDeltaYaw = 0.0f;
groundEntityPtr = NULL;
}
/*
================
idPhysics_Actor::~idPhysics_Actor
================
*/
idPhysics_Actor::~idPhysics_Actor( void ) {
if ( clipModel ) {
delete clipModel;
clipModel = NULL;
}
}
/*
================
idPhysics_Actor::Save
================
*/
void idPhysics_Actor::Save( idSaveGame *savefile ) const {
savefile->WriteClipModel( clipModel );
savefile->WriteMat3( clipModelAxis );
savefile->WriteFloat( mass );
savefile->WriteFloat( invMass );
savefile->WriteObject( masterEntity );
savefile->WriteFloat( masterYaw );
savefile->WriteFloat( masterDeltaYaw );
groundEntityPtr.Save( savefile );
}
/*
================
idPhysics_Actor::Restore
================
*/
void idPhysics_Actor::Restore( idRestoreGame *savefile ) {
savefile->ReadClipModel( clipModel );
savefile->ReadMat3( clipModelAxis );
savefile->ReadFloat( mass );
savefile->ReadFloat( invMass );
savefile->ReadObject( reinterpret_cast<idClass *&>( masterEntity ) );
savefile->ReadFloat( masterYaw );
savefile->ReadFloat( masterDeltaYaw );
groundEntityPtr.Restore( savefile );
}
/*
================
idPhysics_Actor::SetClipModelAxis
================
*/
void idPhysics_Actor::SetClipModelAxis( void ) {
// align clip model to gravity direction
if ( ( gravityNormal[2] == -1.0f ) || ( gravityNormal == vec3_zero ) ) {
clipModelAxis.Identity();
}
else {
clipModelAxis[2] = -gravityNormal;
clipModelAxis[2].NormalVectors( clipModelAxis[0], clipModelAxis[1] );
clipModelAxis[1] = -clipModelAxis[1];
}
if ( clipModel ) {
clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModelAxis );
}
}
/*
================
idPhysics_Actor::GetGravityAxis
================
*/
const idMat3 &idPhysics_Actor::GetGravityAxis( void ) const {
return clipModelAxis;
}
/*
================
idPhysics_Actor::GetMasterDeltaYaw
================
*/
float idPhysics_Actor::GetMasterDeltaYaw( void ) const {
return masterDeltaYaw;
}
/*
================
idPhysics_Actor::GetGroundEntity
================
*/
idEntity *idPhysics_Actor::GetGroundEntity( void ) const {
return groundEntityPtr.GetEntity();
}
/*
================
idPhysics_Actor::SetClipModel
================
*/
void idPhysics_Actor::SetClipModel( idClipModel *model, const float density, int id, bool freeOld ) {
assert( self );
assert( model ); // a clip model is required
assert( model->IsTraceModel() ); // and it should be a trace model
assert( density > 0.0f ); // density should be valid
if ( clipModel && clipModel != model && freeOld ) {
delete clipModel;
}
clipModel = model;
clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModelAxis );
}
/*
================
idPhysics_Actor::GetClipModel
================
*/
idClipModel *idPhysics_Actor::GetClipModel( int id ) const {
return clipModel;
}
/*
================
idPhysics_Actor::GetNumClipModels
================
*/
int idPhysics_Actor::GetNumClipModels( void ) const {
return 1;
}
/*
================
idPhysics_Actor::SetMass
================
*/
void idPhysics_Actor::SetMass( float _mass, int id ) {
assert( _mass > 0.0f );
mass = _mass;
invMass = 1.0f / _mass;
}
/*
================
idPhysics_Actor::GetMass
================
*/
float idPhysics_Actor::GetMass( int id ) const {
return mass;
}
/*
================
idPhysics_Actor::SetClipMask
================
*/
void idPhysics_Actor::SetContents( int contents, int id ) {
clipModel->SetContents( contents );
}
/*
================
idPhysics_Actor::SetClipMask
================
*/
int idPhysics_Actor::GetContents( int id ) const {
return clipModel->GetContents();
}
/*
================
idPhysics_Actor::GetBounds
================
*/
const idBounds &idPhysics_Actor::GetBounds( int id ) const {
return clipModel->GetBounds();
}
/*
================
idPhysics_Actor::GetAbsBounds
================
*/
const idBounds &idPhysics_Actor::GetAbsBounds( int id ) const {
return clipModel->GetAbsBounds();
}
/*
================
idPhysics_Actor::IsPushable
================
*/
bool idPhysics_Actor::IsPushable( void ) const {
return ( masterEntity == NULL );
}
/*
================
idPhysics_Actor::GetOrigin
================
*/
const idVec3 &idPhysics_Actor::GetOrigin( int id ) const {
return clipModel->GetOrigin();
}
/*
================
idPhysics_Player::GetAxis
================
*/
const idMat3 &idPhysics_Actor::GetAxis( int id ) const {
return clipModel->GetAxis();
}
/*
================
idPhysics_Actor::SetGravity
================
*/
void idPhysics_Actor::SetGravity( const idVec3 &newGravity ) {
if ( newGravity != gravityVector ) {
idPhysics_Base::SetGravity( newGravity );
SetClipModelAxis();
}
}
/*
================
idPhysics_Actor::ClipTranslation
================
*/
void idPhysics_Actor::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const {
if ( model ) {
gameLocal.clip.TranslationModel( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation,
clipModel, clipModel->GetAxis(), clipMask,
model->Handle(), model->GetOrigin(), model->GetAxis() );
}
else {
gameLocal.clip.Translation( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation,
clipModel, clipModel->GetAxis(), clipMask, self );
}
}
/*
================
idPhysics_Actor::ClipRotation
================
*/
void idPhysics_Actor::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const {
if ( model ) {
gameLocal.clip.RotationModel( results, clipModel->GetOrigin(), rotation,
clipModel, clipModel->GetAxis(), clipMask,
model->Handle(), model->GetOrigin(), model->GetAxis() );
}
else {
gameLocal.clip.Rotation( results, clipModel->GetOrigin(), rotation,
clipModel, clipModel->GetAxis(), clipMask, self );
}
}
/*
================
idPhysics_Actor::ClipContents
================
*/
int idPhysics_Actor::ClipContents( const idClipModel *model ) const {
if ( model ) {
return gameLocal.clip.ContentsModel( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1,
model->Handle(), model->GetOrigin(), model->GetAxis() );
}
else {
return gameLocal.clip.Contents( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, NULL );
}
}
/*
================
idPhysics_Actor::DisableClip
================
*/
void idPhysics_Actor::DisableClip( void ) {
clipModel->Disable();
}
/*
================
idPhysics_Actor::EnableClip
================
*/
void idPhysics_Actor::EnableClip( void ) {
clipModel->Enable();
}
/*
================
idPhysics_Actor::UnlinkClip
================
*/
void idPhysics_Actor::UnlinkClip( void ) {
clipModel->Unlink();
}
/*
================
idPhysics_Actor::LinkClip
================
*/
void idPhysics_Actor::LinkClip( void ) {
clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModel->GetAxis() );
}
/*
================
idPhysics_Actor::EvaluateContacts
================
*/
bool idPhysics_Actor::EvaluateContacts( void ) {
// get all the ground contacts
ClearContacts();
AddGroundContacts( clipModel );
AddContactEntitiesForContacts();
return ( contacts.Num() != 0 );
}

View File

@@ -0,0 +1,113 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __PHYSICS_ACTOR_H__
#define __PHYSICS_ACTOR_H__
/*
===================================================================================
Actor physics base class
An actor typically uses one collision model which is aligned with the gravity
direction. The collision model is usually a simple box with the origin at the
bottom center.
===================================================================================
*/
class idPhysics_Actor : public idPhysics_Base {
public:
CLASS_PROTOTYPE( idPhysics_Actor );
idPhysics_Actor( void );
~idPhysics_Actor( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
// get delta yaw of master
float GetMasterDeltaYaw( void ) const;
// returns the ground entity
idEntity * GetGroundEntity( void ) const;
// align the clip model with the gravity direction
void SetClipModelAxis( void );
public: // common physics interface
void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true );
idClipModel * GetClipModel( int id = 0 ) const;
int GetNumClipModels( void ) const;
void SetMass( float mass, int id = -1 );
float GetMass( int id = -1 ) const;
void SetContents( int contents, int id = -1 );
int GetContents( int id = -1 ) const;
const idBounds & GetBounds( int id = -1 ) const;
const idBounds & GetAbsBounds( int id = -1 ) const;
bool IsPushable( void ) const;
const idVec3 & GetOrigin( int id = 0 ) const;
const idMat3 & GetAxis( int id = 0 ) const;
void SetGravity( const idVec3 &newGravity );
const idMat3 & GetGravityAxis( void ) const;
void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const;
void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const;
int ClipContents( const idClipModel *model ) const;
void DisableClip( void );
void EnableClip( void );
void UnlinkClip( void );
void LinkClip( void );
bool EvaluateContacts( void );
protected:
idClipModel * clipModel; // clip model used for collision detection
idMat3 clipModelAxis; // axis of clip model aligned with gravity direction
// derived properties
float mass;
float invMass;
// master
idEntity * masterEntity;
float masterYaw;
float masterDeltaYaw;
// results of last evaluate
idEntityPtr<idEntity> groundEntityPtr;
};
#endif /* !__PHYSICS_ACTOR_H__ */

View File

@@ -0,0 +1,837 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
CLASS_DECLARATION( idPhysics, idPhysics_Base )
END_CLASS
/*
================
idPhysics_Base::idPhysics_Base
================
*/
idPhysics_Base::idPhysics_Base( void ) {
self = NULL;
clipMask = 0;
SetGravity( gameLocal.GetGravity() );
ClearContacts();
}
/*
================
idPhysics_Base::~idPhysics_Base
================
*/
idPhysics_Base::~idPhysics_Base( void ) {
if ( self && self->GetPhysics() == this ) {
self->SetPhysics( NULL );
}
idForce::DeletePhysics( this );
ClearContacts();
}
/*
================
idPhysics_Base::Save
================
*/
void idPhysics_Base::Save( idSaveGame *savefile ) const {
int i;
savefile->WriteObject( self );
savefile->WriteInt( clipMask );
savefile->WriteVec3( gravityVector );
savefile->WriteVec3( gravityNormal );
savefile->WriteInt( contacts.Num() );
for ( i = 0; i < contacts.Num(); i++ ) {
savefile->WriteContactInfo( contacts[i] );
}
savefile->WriteInt( contactEntities.Num() );
for ( i = 0; i < contactEntities.Num(); i++ ) {
contactEntities[i].Save( savefile );
}
}
/*
================
idPhysics_Base::Restore
================
*/
void idPhysics_Base::Restore( idRestoreGame *savefile ) {
int i, num;
savefile->ReadObject( reinterpret_cast<idClass *&>( self ) );
savefile->ReadInt( clipMask );
savefile->ReadVec3( gravityVector );
savefile->ReadVec3( gravityNormal );
savefile->ReadInt( num );
contacts.SetNum( num );
for ( i = 0; i < contacts.Num(); i++ ) {
savefile->ReadContactInfo( contacts[i] );
}
savefile->ReadInt( num );
contactEntities.SetNum( num );
for ( i = 0; i < contactEntities.Num(); i++ ) {
contactEntities[i].Restore( savefile );
}
}
/*
================
idPhysics_Base::SetSelf
================
*/
void idPhysics_Base::SetSelf( idEntity *e ) {
assert( e );
self = e;
}
/*
================
idPhysics_Base::SetClipModel
================
*/
void idPhysics_Base::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) {
}
/*
================
idPhysics_Base::GetClipModel
================
*/
idClipModel *idPhysics_Base::GetClipModel( int id ) const {
return NULL;
}
/*
================
idPhysics_Base::GetNumClipModels
================
*/
int idPhysics_Base::GetNumClipModels( void ) const {
return 0;
}
/*
================
idPhysics_Base::SetMass
================
*/
void idPhysics_Base::SetMass( float mass, int id ) {
}
/*
================
idPhysics_Base::GetMass
================
*/
float idPhysics_Base::GetMass( int id ) const {
return 0.0f;
}
/*
================
idPhysics_Base::SetContents
================
*/
void idPhysics_Base::SetContents( int contents, int id ) {
}
/*
================
idPhysics_Base::SetClipMask
================
*/
int idPhysics_Base::GetContents( int id ) const {
return 0;
}
/*
================
idPhysics_Base::SetClipMask
================
*/
void idPhysics_Base::SetClipMask( int mask, int id ) {
clipMask = mask;
}
/*
================
idPhysics_Base::GetClipMask
================
*/
int idPhysics_Base::GetClipMask( int id ) const {
return clipMask;
}
/*
================
idPhysics_Base::GetBounds
================
*/
const idBounds &idPhysics_Base::GetBounds( int id ) const {
return bounds_zero;
}
/*
================
idPhysics_Base::GetAbsBounds
================
*/
const idBounds &idPhysics_Base::GetAbsBounds( int id ) const {
return bounds_zero;
}
/*
================
idPhysics_Base::Evaluate
================
*/
bool idPhysics_Base::Evaluate( int timeStepMSec, int endTimeMSec ) {
return false;
}
/*
================
idPhysics_Base::UpdateTime
================
*/
void idPhysics_Base::UpdateTime( int endTimeMSec ) {
}
/*
================
idPhysics_Base::GetTime
================
*/
int idPhysics_Base::GetTime( void ) const {
return 0;
}
/*
================
idPhysics_Base::GetImpactInfo
================
*/
void idPhysics_Base::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const {
memset( info, 0, sizeof( *info ) );
}
/*
================
idPhysics_Base::ApplyImpulse
================
*/
void idPhysics_Base::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) {
}
/*
================
idPhysics_Base::AddForce
================
*/
void idPhysics_Base::AddForce( const int id, const idVec3 &point, const idVec3 &force ) {
}
/*
================
idPhysics_Base::Activate
================
*/
void idPhysics_Base::Activate( void ) {
}
/*
================
idPhysics_Base::PutToRest
================
*/
void idPhysics_Base::PutToRest( void ) {
}
/*
================
idPhysics_Base::IsAtRest
================
*/
bool idPhysics_Base::IsAtRest( void ) const {
return true;
}
/*
================
idPhysics_Base::GetRestStartTime
================
*/
int idPhysics_Base::GetRestStartTime( void ) const {
return 0;
}
/*
================
idPhysics_Base::IsPushable
================
*/
bool idPhysics_Base::IsPushable( void ) const {
return true;
}
/*
================
idPhysics_Base::SaveState
================
*/
void idPhysics_Base::SaveState( void ) {
}
/*
================
idPhysics_Base::RestoreState
================
*/
void idPhysics_Base::RestoreState( void ) {
}
/*
================
idPhysics_Base::SetOrigin
================
*/
void idPhysics_Base::SetOrigin( const idVec3 &newOrigin, int id ) {
}
/*
================
idPhysics_Base::SetAxis
================
*/
void idPhysics_Base::SetAxis( const idMat3 &newAxis, int id ) {
}
/*
================
idPhysics_Base::Translate
================
*/
void idPhysics_Base::Translate( const idVec3 &translation, int id ) {
}
/*
================
idPhysics_Base::Rotate
================
*/
void idPhysics_Base::Rotate( const idRotation &rotation, int id ) {
}
/*
================
idPhysics_Base::GetOrigin
================
*/
const idVec3 &idPhysics_Base::GetOrigin( int id ) const {
return vec3_origin;
}
/*
================
idPhysics_Base::GetAxis
================
*/
const idMat3 &idPhysics_Base::GetAxis( int id ) const {
return mat3_identity;
}
/*
================
idPhysics_Base::SetLinearVelocity
================
*/
void idPhysics_Base::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) {
}
/*
================
idPhysics_Base::SetAngularVelocity
================
*/
void idPhysics_Base::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) {
}
/*
================
idPhysics_Base::GetLinearVelocity
================
*/
const idVec3 &idPhysics_Base::GetLinearVelocity( int id ) const {
return vec3_origin;
}
/*
================
idPhysics_Base::GetAngularVelocity
================
*/
const idVec3 &idPhysics_Base::GetAngularVelocity( int id ) const {
return vec3_origin;
}
/*
================
idPhysics_Base::SetGravity
================
*/
void idPhysics_Base::SetGravity( const idVec3 &newGravity ) {
gravityVector = newGravity;
gravityNormal = newGravity;
gravityNormal.Normalize();
}
/*
================
idPhysics_Base::GetGravity
================
*/
const idVec3 &idPhysics_Base::GetGravity( void ) const {
return gravityVector;
}
/*
================
idPhysics_Base::GetGravityNormal
================
*/
const idVec3 &idPhysics_Base::GetGravityNormal( void ) const {
return gravityNormal;
}
/*
================
idPhysics_Base::ClipTranslation
================
*/
void idPhysics_Base::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const {
memset( &results, 0, sizeof( trace_t ) );
}
/*
================
idPhysics_Base::ClipRotation
================
*/
void idPhysics_Base::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const {
memset( &results, 0, sizeof( trace_t ) );
}
/*
================
idPhysics_Base::ClipContents
================
*/
int idPhysics_Base::ClipContents( const idClipModel *model ) const {
return 0;
}
/*
================
idPhysics_Base::DisableClip
================
*/
void idPhysics_Base::DisableClip( void ) {
}
/*
================
idPhysics_Base::EnableClip
================
*/
void idPhysics_Base::EnableClip( void ) {
}
/*
================
idPhysics_Base::UnlinkClip
================
*/
void idPhysics_Base::UnlinkClip( void ) {
}
/*
================
idPhysics_Base::LinkClip
================
*/
void idPhysics_Base::LinkClip( void ) {
}
/*
================
idPhysics_Base::EvaluateContacts
================
*/
bool idPhysics_Base::EvaluateContacts( void ) {
return false;
}
/*
================
idPhysics_Base::GetNumContacts
================
*/
int idPhysics_Base::GetNumContacts( void ) const {
return contacts.Num();
}
/*
================
idPhysics_Base::GetContact
================
*/
const contactInfo_t &idPhysics_Base::GetContact( int num ) const {
return contacts[num];
}
/*
================
idPhysics_Base::ClearContacts
================
*/
void idPhysics_Base::ClearContacts( void ) {
int i;
idEntity *ent;
for ( i = 0; i < contacts.Num(); i++ ) {
ent = gameLocal.entities[ contacts[i].entityNum ];
if ( ent ) {
ent->RemoveContactEntity( self );
}
}
contacts.SetNum( 0, false );
}
/*
================
idPhysics_Base::AddContactEntity
================
*/
void idPhysics_Base::AddContactEntity( idEntity *e ) {
int i;
idEntity *ent;
bool found = false;
for ( i = 0; i < contactEntities.Num(); i++ ) {
ent = contactEntities[i].GetEntity();
if ( ent == NULL ) {
contactEntities.RemoveIndex( i-- );
}
if ( ent == e ) {
found = true;
}
}
if ( !found ) {
contactEntities.Alloc() = e;
}
}
/*
================
idPhysics_Base::RemoveContactEntity
================
*/
void idPhysics_Base::RemoveContactEntity( idEntity *e ) {
int i;
idEntity *ent;
for ( i = 0; i < contactEntities.Num(); i++ ) {
ent = contactEntities[i].GetEntity();
if ( !ent ) {
contactEntities.RemoveIndex( i-- );
continue;
}
if ( ent == e ) {
contactEntities.RemoveIndex( i-- );
return;
}
}
}
/*
================
idPhysics_Base::HasGroundContacts
================
*/
bool idPhysics_Base::HasGroundContacts( void ) const {
int i;
for ( i = 0; i < contacts.Num(); i++ ) {
if ( contacts[i].normal * -gravityNormal > 0.0f ) {
return true;
}
}
return false;
}
/*
================
idPhysics_Base::IsGroundEntity
================
*/
bool idPhysics_Base::IsGroundEntity( int entityNum ) const {
int i;
for ( i = 0; i < contacts.Num(); i++ ) {
if ( contacts[i].entityNum == entityNum && ( contacts[i].normal * -gravityNormal > 0.0f ) ) {
return true;
}
}
return false;
}
/*
================
idPhysics_Base::IsGroundClipModel
================
*/
bool idPhysics_Base::IsGroundClipModel( int entityNum, int id ) const {
int i;
for ( i = 0; i < contacts.Num(); i++ ) {
if ( contacts[i].entityNum == entityNum && contacts[i].id == id && ( contacts[i].normal * -gravityNormal > 0.0f ) ) {
return true;
}
}
return false;
}
/*
================
idPhysics_Base::SetPushed
================
*/
void idPhysics_Base::SetPushed( int deltaTime ) {
}
/*
================
idPhysics_Base::GetPushedLinearVelocity
================
*/
const idVec3 &idPhysics_Base::GetPushedLinearVelocity( const int id ) const {
return vec3_origin;
}
/*
================
idPhysics_Base::GetPushedAngularVelocity
================
*/
const idVec3 &idPhysics_Base::GetPushedAngularVelocity( const int id ) const {
return vec3_origin;
}
/*
================
idPhysics_Base::SetMaster
================
*/
void idPhysics_Base::SetMaster( idEntity *master, const bool orientated ) {
}
/*
================
idPhysics_Base::GetBlockingInfo
================
*/
const trace_t *idPhysics_Base::GetBlockingInfo( void ) const {
return NULL;
}
/*
================
idPhysics_Base::GetBlockingEntity
================
*/
idEntity *idPhysics_Base::GetBlockingEntity( void ) const {
return NULL;
}
/*
================
idPhysics_Base::GetLinearEndTime
================
*/
int idPhysics_Base::GetLinearEndTime( void ) const {
return 0;
}
/*
================
idPhysics_Base::GetAngularEndTime
================
*/
int idPhysics_Base::GetAngularEndTime( void ) const {
return 0;
}
/*
================
idPhysics_Base::AddGroundContacts
================
*/
void idPhysics_Base::AddGroundContacts( const idClipModel *clipModel ) {
idVec6 dir;
int index, num;
index = contacts.Num();
contacts.SetNum( index + 10, false );
dir.SubVec3(0) = gravityNormal;
dir.SubVec3(1) = vec3_origin;
num = gameLocal.clip.Contacts( &contacts[index], 10, clipModel->GetOrigin(),
dir, CONTACT_EPSILON, clipModel, clipModel->GetAxis(), clipMask, self );
contacts.SetNum( index + num, false );
}
/*
================
idPhysics_Base::AddContactEntitiesForContacts
================
*/
void idPhysics_Base::AddContactEntitiesForContacts( void ) {
int i;
idEntity *ent;
for ( i = 0; i < contacts.Num(); i++ ) {
ent = gameLocal.entities[ contacts[i].entityNum ];
if ( ent && ent != self ) {
ent->AddContactEntity( self );
}
}
}
/*
================
idPhysics_Base::ActivateContactEntities
================
*/
void idPhysics_Base::ActivateContactEntities( void ) {
int i;
idEntity *ent;
for ( i = 0; i < contactEntities.Num(); i++ ) {
ent = contactEntities[i].GetEntity();
if ( ent ) {
ent->ActivatePhysics( self );
} else {
contactEntities.RemoveIndex( i-- );
}
}
}
/*
================
idPhysics_Base::IsOutsideWorld
================
*/
bool idPhysics_Base::IsOutsideWorld( void ) const {
if ( !gameLocal.clip.GetWorldBounds().Expand( 128.0f ).IntersectsBounds( GetAbsBounds() ) ) {
return true;
}
return false;
}
/*
================
idPhysics_Base::DrawVelocity
================
*/
void idPhysics_Base::DrawVelocity( int id, float linearScale, float angularScale ) const {
idVec3 dir, org, vec, start, end;
idMat3 axis;
float length, a;
dir = GetLinearVelocity( id );
dir *= linearScale;
if ( dir.LengthSqr() > Square( 0.1f ) ) {
dir.Truncate( 10.0f );
org = GetOrigin( id );
gameRenderWorld->DebugArrow( colorRed, org, org + dir, 1 );
}
dir = GetAngularVelocity( id );
length = dir.Normalize();
length *= angularScale;
if ( length > 0.1f ) {
if ( length < 60.0f ) {
length = 60.0f;
}
else if ( length > 360.0f ) {
length = 360.0f;
}
axis = GetAxis( id );
vec = axis[2];
if ( idMath::Fabs( dir * vec ) > 0.99f ) {
vec = axis[0];
}
vec -= vec * dir * vec;
vec.Normalize();
vec *= 4.0f;
start = org + vec;
for ( a = 20.0f; a < length; a += 20.0f ) {
end = org + idRotation( vec3_origin, dir, -a ).ToMat3() * vec;
gameRenderWorld->DebugLine( colorBlue, start, end, 1 );
start = end;
}
end = org + idRotation( vec3_origin, dir, -length ).ToMat3() * vec;
gameRenderWorld->DebugArrow( colorBlue, start, end, 1 );
}
}
/*
================
idPhysics_Base::WriteToSnapshot
================
*/
void idPhysics_Base::WriteToSnapshot( idBitMsgDelta &msg ) const {
}
/*
================
idPhysics_Base::ReadFromSnapshot
================
*/
void idPhysics_Base::ReadFromSnapshot( const idBitMsgDelta &msg ) {
}

View File

@@ -0,0 +1,165 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __PHYSICS_BASE_H__
#define __PHYSICS_BASE_H__
/*
===============================================================================
Physics base for a moving object using one or more collision models.
===============================================================================
*/
#define contactEntity_t idEntityPtr<idEntity>
class idPhysics_Base : public idPhysics {
public:
CLASS_PROTOTYPE( idPhysics_Base );
idPhysics_Base( void );
~idPhysics_Base( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
public: // common physics interface
void SetSelf( idEntity *e );
void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true );
idClipModel * GetClipModel( int id = 0 ) const;
int GetNumClipModels( void ) const;
void SetMass( float mass, int id = -1 );
float GetMass( int id = -1 ) const;
void SetContents( int contents, int id = -1 );
int GetContents( int id = -1 ) const;
void SetClipMask( int mask, int id = -1 );
int GetClipMask( int id = -1 ) const;
const idBounds & GetBounds( int id = -1 ) const;
const idBounds & GetAbsBounds( int id = -1 ) const;
bool Evaluate( int timeStepMSec, int endTimeMSec );
void UpdateTime( int endTimeMSec );
int GetTime( void ) const;
void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const;
void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse );
void AddForce( const int id, const idVec3 &point, const idVec3 &force );
void Activate( void );
void PutToRest( void );
bool IsAtRest( void ) const;
int GetRestStartTime( void ) const;
bool IsPushable( void ) const;
void SaveState( void );
void RestoreState( void );
void SetOrigin( const idVec3 &newOrigin, int id = -1 );
void SetAxis( const idMat3 &newAxis, int id = -1 );
void Translate( const idVec3 &translation, int id = -1 );
void Rotate( const idRotation &rotation, int id = -1 );
const idVec3 & GetOrigin( int id = 0 ) const;
const idMat3 & GetAxis( int id = 0 ) const;
void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 );
void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 );
const idVec3 & GetLinearVelocity( int id = 0 ) const;
const idVec3 & GetAngularVelocity( int id = 0 ) const;
void SetGravity( const idVec3 &newGravity );
const idVec3 & GetGravity( void ) const;
const idVec3 & GetGravityNormal( void ) const;
void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const;
void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const;
int ClipContents( const idClipModel *model ) const;
void DisableClip( void );
void EnableClip( void );
void UnlinkClip( void );
void LinkClip( void );
bool EvaluateContacts( void );
int GetNumContacts( void ) const;
const contactInfo_t & GetContact( int num ) const;
void ClearContacts( void );
void AddContactEntity( idEntity *e );
void RemoveContactEntity( idEntity *e );
bool HasGroundContacts( void ) const;
bool IsGroundEntity( int entityNum ) const;
bool IsGroundClipModel( int entityNum, int id ) const;
void SetPushed( int deltaTime );
const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const;
const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const;
void SetMaster( idEntity *master, const bool orientated = true );
const trace_t * GetBlockingInfo( void ) const;
idEntity * GetBlockingEntity( void ) const;
int GetLinearEndTime( void ) const;
int GetAngularEndTime( void ) const;
void WriteToSnapshot( idBitMsgDelta &msg ) const;
void ReadFromSnapshot( const idBitMsgDelta &msg );
protected:
idEntity * self; // entity using this physics object
int clipMask; // contents the physics object collides with
idVec3 gravityVector; // direction and magnitude of gravity
idVec3 gravityNormal; // normalized direction of gravity
idList<contactInfo_t> contacts; // contacts with other physics objects
idList<contactEntity_t> contactEntities; // entities touching this physics object
protected:
// add ground contacts for the clip model
void AddGroundContacts( const idClipModel *clipModel );
// add contact entity links to contact entities
void AddContactEntitiesForContacts( void );
// active all contact entities
void ActivateContactEntities( void );
// returns true if the whole physics object is outside the world bounds
bool IsOutsideWorld( void ) const;
// draw linear and angular velocity
void DrawVelocity( int id, float linearScale, float angularScale ) const;
};
#endif /* !__PHYSICS_BASE_H__ */

View File

@@ -0,0 +1,806 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
CLASS_DECLARATION( idPhysics_Actor, idPhysics_Monster )
END_CLASS
const float OVERCLIP = 1.001f;
/*
=====================
idPhysics_Monster::CheckGround
=====================
*/
void idPhysics_Monster::CheckGround( monsterPState_t &state ) {
trace_t groundTrace;
idVec3 down;
if ( gravityNormal == vec3_zero ) {
state.onGround = false;
groundEntityPtr = NULL;
return;
}
down = state.origin + gravityNormal * CONTACT_EPSILON;
gameLocal.clip.Translation( groundTrace, state.origin, down, clipModel, clipModel->GetAxis(), clipMask, self );
if ( groundTrace.fraction == 1.0f ) {
state.onGround = false;
groundEntityPtr = NULL;
return;
}
groundEntityPtr = gameLocal.entities[ groundTrace.c.entityNum ];
if ( ( groundTrace.c.normal * -gravityNormal ) < minFloorCosine ) {
state.onGround = false;
return;
}
state.onGround = true;
// let the entity know about the collision
self->Collide( groundTrace, state.velocity );
// apply impact to a non world floor entity
if ( groundTrace.c.entityNum != ENTITYNUM_WORLD && groundEntityPtr.GetEntity() ) {
impactInfo_t info;
groundEntityPtr.GetEntity()->GetImpactInfo( self, groundTrace.c.id, groundTrace.c.point, &info );
if ( info.invMass != 0.0f ) {
groundEntityPtr.GetEntity()->ApplyImpulse( self, 0, groundTrace.c.point, state.velocity / ( info.invMass * 10.0f ) );
}
}
}
/*
=====================
idPhysics_Monster::SlideMove
=====================
*/
monsterMoveResult_t idPhysics_Monster::SlideMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ) {
int i;
trace_t tr;
idVec3 move;
blockingEntity = NULL;
move = delta;
for( i = 0; i < 3; i++ ) {
gameLocal.clip.Translation( tr, start, start + move, clipModel, clipModel->GetAxis(), clipMask, self );
start = tr.endpos;
if ( tr.fraction == 1.0f ) {
if ( i > 0 ) {
return MM_SLIDING;
}
return MM_OK;
}
if ( tr.c.entityNum != ENTITYNUM_NONE ) {
blockingEntity = gameLocal.entities[ tr.c.entityNum ];
}
// clip the movement delta and velocity
move.ProjectOntoPlane( tr.c.normal, OVERCLIP );
velocity.ProjectOntoPlane( tr.c.normal, OVERCLIP );
}
return MM_BLOCKED;
}
/*
=====================
idPhysics_Monster::StepMove
move start into the delta direction
the velocity is clipped conform any collisions
=====================
*/
monsterMoveResult_t idPhysics_Monster::StepMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ) {
trace_t tr;
idVec3 up, down, noStepPos, noStepVel, stepPos, stepVel;
monsterMoveResult_t result1, result2;
float stepdist;
float nostepdist;
if ( delta == vec3_origin ) {
return MM_OK;
}
// try to move without stepping up
noStepPos = start;
noStepVel = velocity;
result1 = SlideMove( noStepPos, noStepVel, delta );
if ( result1 == MM_OK ) {
velocity = noStepVel;
if ( gravityNormal == vec3_zero ) {
start = noStepPos;
return MM_OK;
}
// try to step down so that we walk down slopes and stairs at a normal rate
down = noStepPos + gravityNormal * maxStepHeight;
gameLocal.clip.Translation( tr, noStepPos, down, clipModel, clipModel->GetAxis(), clipMask, self );
if ( tr.fraction < 1.0f ) {
start = tr.endpos;
return MM_STEPPED;
} else {
start = noStepPos;
return MM_OK;
}
}
if ( blockingEntity && blockingEntity->IsType( idActor::Type ) ) {
// try to step down in case walking into an actor while going down steps
down = noStepPos + gravityNormal * maxStepHeight;
gameLocal.clip.Translation( tr, noStepPos, down, clipModel, clipModel->GetAxis(), clipMask, self );
start = tr.endpos;
velocity = noStepVel;
return MM_BLOCKED;
}
if ( gravityNormal == vec3_zero ) {
return result1;
}
// try to step up
up = start - gravityNormal * maxStepHeight;
gameLocal.clip.Translation( tr, start, up, clipModel, clipModel->GetAxis(), clipMask, self );
if ( tr.fraction == 0.0f ) {
start = noStepPos;
velocity = noStepVel;
return result1;
}
// try to move at the stepped up position
stepPos = tr.endpos;
stepVel = velocity;
result2 = SlideMove( stepPos, stepVel, delta );
if ( result2 == MM_BLOCKED ) {
start = noStepPos;
velocity = noStepVel;
return result1;
}
// step down again
down = stepPos + gravityNormal * maxStepHeight;
gameLocal.clip.Translation( tr, stepPos, down, clipModel, clipModel->GetAxis(), clipMask, self );
stepPos = tr.endpos;
// if the move is further without stepping up, or the slope is too steap, don't step up
nostepdist = ( noStepPos - start ).LengthSqr();
stepdist = ( stepPos - start ).LengthSqr();
if ( ( nostepdist >= stepdist ) || ( ( tr.c.normal * -gravityNormal ) < minFloorCosine ) ) {
start = noStepPos;
velocity = noStepVel;
return MM_SLIDING;
}
start = stepPos;
velocity = stepVel;
return MM_STEPPED;
}
/*
================
idPhysics_Monster::Activate
================
*/
void idPhysics_Monster::Activate( void ) {
current.atRest = -1;
self->BecomeActive( TH_PHYSICS );
}
/*
================
idPhysics_Monster::Rest
================
*/
void idPhysics_Monster::Rest( void ) {
current.atRest = gameLocal.time;
current.velocity.Zero();
self->BecomeInactive( TH_PHYSICS );
}
/*
================
idPhysics_Monster::PutToRest
================
*/
void idPhysics_Monster::PutToRest( void ) {
Rest();
}
/*
================
idPhysics_Monster::idPhysics_Monster
================
*/
idPhysics_Monster::idPhysics_Monster( void ) {
memset( &current, 0, sizeof( current ) );
current.atRest = -1;
saved = current;
delta.Zero();
maxStepHeight = 18.0f;
minFloorCosine = 0.7f;
moveResult = MM_OK;
forceDeltaMove = false;
fly = false;
useVelocityMove = false;
noImpact = false;
blockingEntity = NULL;
}
/*
================
idPhysics_Monster_SavePState
================
*/
void idPhysics_Monster_SavePState( idSaveGame *savefile, const monsterPState_t &state ) {
savefile->WriteVec3( state.origin );
savefile->WriteVec3( state.velocity );
savefile->WriteVec3( state.localOrigin );
savefile->WriteVec3( state.pushVelocity );
savefile->WriteBool( state.onGround );
savefile->WriteInt( state.atRest );
}
/*
================
idPhysics_Monster_RestorePState
================
*/
void idPhysics_Monster_RestorePState( idRestoreGame *savefile, monsterPState_t &state ) {
savefile->ReadVec3( state.origin );
savefile->ReadVec3( state.velocity );
savefile->ReadVec3( state.localOrigin );
savefile->ReadVec3( state.pushVelocity );
savefile->ReadBool( state.onGround );
savefile->ReadInt( state.atRest );
}
/*
================
idPhysics_Monster::Save
================
*/
void idPhysics_Monster::Save( idSaveGame *savefile ) const {
idPhysics_Monster_SavePState( savefile, current );
idPhysics_Monster_SavePState( savefile, saved );
savefile->WriteFloat( maxStepHeight );
savefile->WriteFloat( minFloorCosine );
savefile->WriteVec3( delta );
savefile->WriteBool( forceDeltaMove );
savefile->WriteBool( fly );
savefile->WriteBool( useVelocityMove );
savefile->WriteBool( noImpact );
savefile->WriteInt( (int)moveResult );
savefile->WriteObject( blockingEntity );
}
/*
================
idPhysics_Monster::Restore
================
*/
void idPhysics_Monster::Restore( idRestoreGame *savefile ) {
idPhysics_Monster_RestorePState( savefile, current );
idPhysics_Monster_RestorePState( savefile, saved );
savefile->ReadFloat( maxStepHeight );
savefile->ReadFloat( minFloorCosine );
savefile->ReadVec3( delta );
savefile->ReadBool( forceDeltaMove );
savefile->ReadBool( fly );
savefile->ReadBool( useVelocityMove );
savefile->ReadBool( noImpact );
savefile->ReadInt( (int &)moveResult );
savefile->ReadObject( reinterpret_cast<idClass *&>( blockingEntity ) );
}
/*
================
idPhysics_Monster::SetDelta
================
*/
void idPhysics_Monster::SetDelta( const idVec3 &d ) {
delta = d;
if ( delta != vec3_origin ) {
Activate();
}
}
/*
================
idPhysics_Monster::SetMaxStepHeight
================
*/
void idPhysics_Monster::SetMaxStepHeight( const float newMaxStepHeight ) {
maxStepHeight = newMaxStepHeight;
}
/*
================
idPhysics_Monster::GetMaxStepHeight
================
*/
float idPhysics_Monster::GetMaxStepHeight( void ) const {
return maxStepHeight;
}
/*
================
idPhysics_Monster::OnGround
================
*/
bool idPhysics_Monster::OnGround( void ) const {
return current.onGround;
}
/*
================
idPhysics_Monster::GetSlideMoveEntity
================
*/
idEntity *idPhysics_Monster::GetSlideMoveEntity( void ) const {
return blockingEntity;
}
/*
================
idPhysics_Monster::GetMoveResult
================
*/
monsterMoveResult_t idPhysics_Monster::GetMoveResult( void ) const {
return moveResult;
}
/*
================
idPhysics_Monster::ForceDeltaMove
================
*/
void idPhysics_Monster::ForceDeltaMove( bool force ) {
forceDeltaMove = force;
}
/*
================
idPhysics_Monster::UseFlyMove
================
*/
void idPhysics_Monster::UseFlyMove( bool force ) {
fly = force;
}
/*
================
idPhysics_Monster::UseVelocityMove
================
*/
void idPhysics_Monster::UseVelocityMove( bool force ) {
useVelocityMove = force;
}
/*
================
idPhysics_Monster::EnableImpact
================
*/
void idPhysics_Monster::EnableImpact( void ) {
noImpact = false;
}
/*
================
idPhysics_Monster::DisableImpact
================
*/
void idPhysics_Monster::DisableImpact( void ) {
noImpact = true;
}
/*
================
idPhysics_Monster::Evaluate
================
*/
bool idPhysics_Monster::Evaluate( int timeStepMSec, int endTimeMSec ) {
idVec3 masterOrigin, oldOrigin;
idMat3 masterAxis;
float timeStep;
timeStep = MS2SEC( timeStepMSec );
moveResult = MM_OK;
blockingEntity = NULL;
oldOrigin = current.origin;
// if bound to a master
if ( masterEntity ) {
self->GetMasterPosition( masterOrigin, masterAxis );
current.origin = masterOrigin + current.localOrigin * masterAxis;
clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() );
current.velocity = ( current.origin - oldOrigin ) / timeStep;
masterDeltaYaw = masterYaw;
masterYaw = masterAxis[0].ToYaw();
masterDeltaYaw = masterYaw - masterDeltaYaw;
return true;
}
// if the monster is at rest
if ( current.atRest >= 0 ) {
return false;
}
ActivateContactEntities();
// move the monster velocity into the frame of a pusher
current.velocity -= current.pushVelocity;
clipModel->Unlink();
// check if on the ground
idPhysics_Monster::CheckGround( current );
// if not on the ground or moving upwards
float upspeed;
if ( gravityNormal != vec3_zero ) {
upspeed = -( current.velocity * gravityNormal );
} else {
upspeed = current.velocity.z;
}
if ( fly || ( !forceDeltaMove && ( !current.onGround || upspeed > 1.0f ) ) ) {
if ( upspeed < 0.0f ) {
moveResult = MM_FALLING;
}
else {
current.onGround = false;
moveResult = MM_OK;
}
delta = current.velocity * timeStep;
if ( delta != vec3_origin ) {
moveResult = idPhysics_Monster::SlideMove( current.origin, current.velocity, delta );
delta.Zero();
}
if ( !fly ) {
current.velocity += gravityVector * timeStep;
}
} else {
if ( useVelocityMove ) {
delta = current.velocity * timeStep;
} else {
current.velocity = delta / timeStep;
}
current.velocity -= ( current.velocity * gravityNormal ) * gravityNormal;
if ( delta == vec3_origin ) {
Rest();
} else {
// try moving into the desired direction
moveResult = idPhysics_Monster::StepMove( current.origin, current.velocity, delta );
delta.Zero();
}
}
clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() );
// get all the ground contacts
EvaluateContacts();
// move the monster velocity back into the world frame
current.velocity += current.pushVelocity;
current.pushVelocity.Zero();
if ( IsOutsideWorld() ) {
gameLocal.Warning( "clip model outside world bounds for entity '%s' at (%s)", self->name.c_str(), current.origin.ToString(0) );
Rest();
}
return ( current.origin != oldOrigin );
}
/*
================
idPhysics_Monster::UpdateTime
================
*/
void idPhysics_Monster::UpdateTime( int endTimeMSec ) {
}
/*
================
idPhysics_Monster::GetTime
================
*/
int idPhysics_Monster::GetTime( void ) const {
return gameLocal.time;
}
/*
================
idPhysics_Monster::GetImpactInfo
================
*/
void idPhysics_Monster::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const {
info->invMass = invMass;
info->invInertiaTensor.Zero();
info->position.Zero();
info->velocity = current.velocity;
}
/*
================
idPhysics_Monster::ApplyImpulse
================
*/
void idPhysics_Monster::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) {
if ( noImpact ) {
return;
}
current.velocity += impulse * invMass;
Activate();
}
/*
================
idPhysics_Monster::IsAtRest
================
*/
bool idPhysics_Monster::IsAtRest( void ) const {
return current.atRest >= 0;
}
/*
================
idPhysics_Monster::GetRestStartTime
================
*/
int idPhysics_Monster::GetRestStartTime( void ) const {
return current.atRest;
}
/*
================
idPhysics_Monster::SaveState
================
*/
void idPhysics_Monster::SaveState( void ) {
saved = current;
}
/*
================
idPhysics_Monster::RestoreState
================
*/
void idPhysics_Monster::RestoreState( void ) {
current = saved;
clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() );
EvaluateContacts();
}
/*
================
idPhysics_Player::SetOrigin
================
*/
void idPhysics_Monster::SetOrigin( const idVec3 &newOrigin, int id ) {
idVec3 masterOrigin;
idMat3 masterAxis;
current.localOrigin = newOrigin;
if ( masterEntity ) {
self->GetMasterPosition( masterOrigin, masterAxis );
current.origin = masterOrigin + newOrigin * masterAxis;
}
else {
current.origin = newOrigin;
}
clipModel->Link( gameLocal.clip, self, 0, newOrigin, clipModel->GetAxis() );
Activate();
}
/*
================
idPhysics_Player::SetAxis
================
*/
void idPhysics_Monster::SetAxis( const idMat3 &newAxis, int id ) {
clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), newAxis );
Activate();
}
/*
================
idPhysics_Monster::Translate
================
*/
void idPhysics_Monster::Translate( const idVec3 &translation, int id ) {
current.localOrigin += translation;
current.origin += translation;
clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() );
Activate();
}
/*
================
idPhysics_Monster::Rotate
================
*/
void idPhysics_Monster::Rotate( const idRotation &rotation, int id ) {
idVec3 masterOrigin;
idMat3 masterAxis;
current.origin *= rotation;
if ( masterEntity ) {
self->GetMasterPosition( masterOrigin, masterAxis );
current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose();
}
else {
current.localOrigin = current.origin;
}
clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() * rotation.ToMat3() );
Activate();
}
/*
================
idPhysics_Monster::SetLinearVelocity
================
*/
void idPhysics_Monster::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) {
current.velocity = newLinearVelocity;
Activate();
}
/*
================
idPhysics_Monster::GetLinearVelocity
================
*/
const idVec3 &idPhysics_Monster::GetLinearVelocity( int id ) const {
return current.velocity;
}
/*
================
idPhysics_Monster::SetPushed
================
*/
void idPhysics_Monster::SetPushed( int deltaTime ) {
// velocity with which the monster is pushed
current.pushVelocity += ( current.origin - saved.origin ) / ( deltaTime * idMath::M_MS2SEC );
}
/*
================
idPhysics_Monster::GetPushedLinearVelocity
================
*/
const idVec3 &idPhysics_Monster::GetPushedLinearVelocity( const int id ) const {
return current.pushVelocity;
}
/*
================
idPhysics_Monster::SetMaster
the binding is never orientated
================
*/
void idPhysics_Monster::SetMaster( idEntity *master, const bool orientated ) {
idVec3 masterOrigin;
idMat3 masterAxis;
if ( master ) {
if ( !masterEntity ) {
// transform from world space to master space
self->GetMasterPosition( masterOrigin, masterAxis );
current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose();
masterEntity = master;
masterYaw = masterAxis[0].ToYaw();
}
ClearContacts();
}
else {
if ( masterEntity ) {
masterEntity = NULL;
Activate();
}
}
}
const float MONSTER_VELOCITY_MAX = 4000;
const int MONSTER_VELOCITY_TOTAL_BITS = 16;
const int MONSTER_VELOCITY_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( MONSTER_VELOCITY_MAX ) ) + 1;
const int MONSTER_VELOCITY_MANTISSA_BITS = MONSTER_VELOCITY_TOTAL_BITS - 1 - MONSTER_VELOCITY_EXPONENT_BITS;
/*
================
idPhysics_Monster::WriteToSnapshot
================
*/
void idPhysics_Monster::WriteToSnapshot( idBitMsgDelta &msg ) const {
msg.WriteFloat( current.origin[0] );
msg.WriteFloat( current.origin[1] );
msg.WriteFloat( current.origin[2] );
msg.WriteFloat( current.velocity[0], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
msg.WriteFloat( current.velocity[1], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
msg.WriteFloat( current.velocity[2], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] );
msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] );
msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] );
msg.WriteDeltaFloat( 0.0f, current.pushVelocity[0], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
msg.WriteDeltaFloat( 0.0f, current.pushVelocity[1], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
msg.WriteDeltaFloat( 0.0f, current.pushVelocity[2], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
msg.WriteLong( current.atRest );
msg.WriteBits( current.onGround, 1 );
}
/*
================
idPhysics_Monster::ReadFromSnapshot
================
*/
void idPhysics_Monster::ReadFromSnapshot( const idBitMsgDelta &msg ) {
current.origin[0] = msg.ReadFloat();
current.origin[1] = msg.ReadFloat();
current.origin[2] = msg.ReadFloat();
current.velocity[0] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
current.velocity[1] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
current.velocity[2] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] );
current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] );
current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] );
current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS );
current.atRest = msg.ReadLong();
current.onGround = msg.ReadBits( 1 ) != 0;
}

View File

@@ -0,0 +1,152 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __PHYSICS_MONSTER_H__
#define __PHYSICS_MONSTER_H__
/*
===================================================================================
Monster physics
Simulates the motion of a monster through the environment. The monster motion
is typically driven by animations.
===================================================================================
*/
typedef enum {
MM_OK,
MM_SLIDING,
MM_BLOCKED,
MM_STEPPED,
MM_FALLING
} monsterMoveResult_t;
typedef struct monsterPState_s {
int atRest;
bool onGround;
idVec3 origin;
idVec3 velocity;
idVec3 localOrigin;
idVec3 pushVelocity;
} monsterPState_t;
class idPhysics_Monster : public idPhysics_Actor {
public:
CLASS_PROTOTYPE( idPhysics_Monster );
idPhysics_Monster( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
// maximum step up the monster can take, default 18 units
void SetMaxStepHeight( const float newMaxStepHeight );
float GetMaxStepHeight( void ) const;
// minimum cosine of floor angle to be able to stand on the floor
void SetMinFloorCosine( const float newMinFloorCosine );
// set delta for next move
void SetDelta( const idVec3 &d );
// returns true if monster is standing on the ground
bool OnGround( void ) const;
// returns the movement result
monsterMoveResult_t GetMoveResult( void ) const;
// overrides any velocity for pure delta movement
void ForceDeltaMove( bool force );
// whether velocity should be affected by gravity
void UseFlyMove( bool force );
// don't use delta movement
void UseVelocityMove( bool force );
// get entity blocking the move
idEntity * GetSlideMoveEntity( void ) const;
// enable/disable activation by impact
void EnableImpact( void );
void DisableImpact( void );
public: // common physics interface
bool Evaluate( int timeStepMSec, int endTimeMSec );
void UpdateTime( int endTimeMSec );
int GetTime( void ) const;
void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const;
void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse );
void Activate( void );
void PutToRest( void );
bool IsAtRest( void ) const;
int GetRestStartTime( void ) const;
void SaveState( void );
void RestoreState( void );
void SetOrigin( const idVec3 &newOrigin, int id = -1 );
void SetAxis( const idMat3 &newAxis, int id = -1 );
void Translate( const idVec3 &translation, int id = -1 );
void Rotate( const idRotation &rotation, int id = -1 );
void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 );
const idVec3 & GetLinearVelocity( int id = 0 ) const;
void SetPushed( int deltaTime );
const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const;
void SetMaster( idEntity *master, const bool orientated = true );
void WriteToSnapshot( idBitMsgDelta &msg ) const;
void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
// monster physics state
monsterPState_t current;
monsterPState_t saved;
// properties
float maxStepHeight; // maximum step height
float minFloorCosine; // minimum cosine of floor angle
idVec3 delta; // delta for next move
bool forceDeltaMove;
bool fly;
bool useVelocityMove;
bool noImpact; // if true do not activate when another object collides
// results of last evaluate
monsterMoveResult_t moveResult;
idEntity * blockingEntity;
private:
void CheckGround( monsterPState_t &state );
monsterMoveResult_t SlideMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta );
monsterMoveResult_t StepMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta );
void Rest( void );
};
#endif /* !__PHYSICS_MONSTER_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,176 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __PHYSICS_PARAMETRIC_H__
#define __PHYSICS_PARAMETRIC_H__
/*
===================================================================================
Parametric physics
Used for predefined or scripted motion. The motion of an object is completely
parametrized. By adjusting the parameters an object is forced to follow a
predefined path. The parametric physics is typically used for doors, bridges,
rotating fans etc.
===================================================================================
*/
typedef struct parametricPState_s {
int time; // physics time
int atRest; // set when simulation is suspended
idVec3 origin; // world origin
idAngles angles; // world angles
idMat3 axis; // world axis
idVec3 localOrigin; // local origin
idAngles localAngles; // local angles
idExtrapolate<idVec3> linearExtrapolation; // extrapolation based description of the position over time
idExtrapolate<idAngles> angularExtrapolation; // extrapolation based description of the orientation over time
idInterpolateAccelDecelLinear<idVec3> linearInterpolation; // interpolation based description of the position over time
idInterpolateAccelDecelLinear<idAngles> angularInterpolation; // interpolation based description of the orientation over time
idCurve_Spline<idVec3> * spline; // spline based description of the position over time
idInterpolateAccelDecelLinear<float> splineInterpolate; // position along the spline over time
bool useSplineAngles; // set the orientation using the spline
} parametricPState_t;
class idPhysics_Parametric : public idPhysics_Base {
public:
CLASS_PROTOTYPE( idPhysics_Parametric );
idPhysics_Parametric( void );
~idPhysics_Parametric( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetPusher( int flags );
bool IsPusher( void ) const;
void SetLinearExtrapolation( extrapolation_t type, int time, int duration, const idVec3 &base, const idVec3 &speed, const idVec3 &baseSpeed );
void SetAngularExtrapolation( extrapolation_t type, int time, int duration, const idAngles &base, const idAngles &speed, const idAngles &baseSpeed );
extrapolation_t GetLinearExtrapolationType( void ) const;
extrapolation_t GetAngularExtrapolationType( void ) const;
void SetLinearInterpolation( int time, int accelTime, int decelTime, int duration, const idVec3 &startPos, const idVec3 &endPos );
void SetAngularInterpolation( int time, int accelTime, int decelTime, int duration, const idAngles &startAng, const idAngles &endAng );
void SetSpline( idCurve_Spline<idVec3> *spline, int accelTime, int decelTime, bool useSplineAngles );
idCurve_Spline<idVec3> *GetSpline( void ) const;
int GetSplineAcceleration( void ) const;
int GetSplineDeceleration( void ) const;
bool UsingSplineAngles( void ) const;
void GetLocalOrigin( idVec3 &curOrigin ) const;
void GetLocalAngles( idAngles &curAngles ) const;
void GetAngles( idAngles &curAngles ) const;
public: // common physics interface
void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true );
idClipModel * GetClipModel( int id = 0 ) const;
int GetNumClipModels( void ) const;
void SetMass( float mass, int id = -1 );
float GetMass( int id = -1 ) const;
void SetContents( int contents, int id = -1 );
int GetContents( int id = -1 ) const;
const idBounds & GetBounds( int id = -1 ) const;
const idBounds & GetAbsBounds( int id = -1 ) const;
bool Evaluate( int timeStepMSec, int endTimeMSec );
void UpdateTime( int endTimeMSec );
int GetTime( void ) const;
void Activate( void );
bool IsAtRest( void ) const;
int GetRestStartTime( void ) const;
bool IsPushable( void ) const;
void SaveState( void );
void RestoreState( void );
void SetOrigin( const idVec3 &newOrigin, int id = -1 );
void SetAxis( const idMat3 &newAxis, int id = -1 );
void Translate( const idVec3 &translation, int id = -1 );
void Rotate( const idRotation &rotation, int id = -1 );
const idVec3 & GetOrigin( int id = 0 ) const;
const idMat3 & GetAxis( int id = 0 ) const;
void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 );
void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 );
const idVec3 & GetLinearVelocity( int id = 0 ) const;
const idVec3 & GetAngularVelocity( int id = 0 ) const;
void DisableClip( void );
void EnableClip( void );
void UnlinkClip( void );
void LinkClip( void );
void SetMaster( idEntity *master, const bool orientated = true );
const trace_t * GetBlockingInfo( void ) const;
idEntity * GetBlockingEntity( void ) const;
int GetLinearEndTime( void ) const;
int GetAngularEndTime( void ) const;
void WriteToSnapshot( idBitMsgDelta &msg ) const;
void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
// parametric physics state
parametricPState_t current;
parametricPState_t saved;
// pusher
bool isPusher;
idClipModel * clipModel;
int pushFlags;
// results of last evaluate
trace_t pushResults;
bool isBlocked;
// master
bool hasMaster;
bool isOrientated;
private:
bool TestIfAtRest( void ) const;
void Rest( void );
};
#endif /* !__PHYSICS_PARAMETRIC_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,195 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __PHYSICS_PLAYER_H__
#define __PHYSICS_PLAYER_H__
/*
===================================================================================
Player physics
Simulates the motion of a player through the environment. Input from the
player is used to allow a certain degree of control over the motion.
===================================================================================
*/
// movementType
typedef enum {
PM_NORMAL, // normal physics
PM_DEAD, // no acceleration or turning, but free falling
PM_SPECTATOR, // flying without gravity but with collision detection
PM_FREEZE, // stuck in place without control
PM_NOCLIP // flying without collision detection nor gravity
} pmtype_t;
typedef enum {
WATERLEVEL_NONE,
WATERLEVEL_FEET,
WATERLEVEL_WAIST,
WATERLEVEL_HEAD
} waterLevel_t;
#define MAXTOUCH 32
typedef struct playerPState_s {
idVec3 origin;
idVec3 velocity;
idVec3 localOrigin;
idVec3 pushVelocity;
float stepUp;
int movementType;
int movementFlags;
int movementTime;
} playerPState_t;
class idPhysics_Player : public idPhysics_Actor {
public:
CLASS_PROTOTYPE( idPhysics_Player );
idPhysics_Player( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
// initialisation
void SetSpeed( const float newWalkSpeed, const float newCrouchSpeed );
void SetMaxStepHeight( const float newMaxStepHeight );
float GetMaxStepHeight( void ) const;
void SetMaxJumpHeight( const float newMaxJumpHeight );
void SetMovementType( const pmtype_t type );
void SetPlayerInput( const usercmd_t &cmd, const idAngles &newViewAngles );
void SetKnockBack( const int knockBackTime );
void SetDebugLevel( bool set );
// feed back from last physics frame
waterLevel_t GetWaterLevel( void ) const;
int GetWaterType( void ) const;
bool HasJumped( void ) const;
bool HasSteppedUp( void ) const;
float GetStepUp( void ) const;
bool IsCrouching( void ) const;
bool OnLadder( void ) const;
const idVec3 & PlayerGetOrigin( void ) const; // != GetOrigin
public: // common physics interface
bool Evaluate( int timeStepMSec, int endTimeMSec );
void UpdateTime( int endTimeMSec );
int GetTime( void ) const;
void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const;
void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse );
bool IsAtRest( void ) const;
int GetRestStartTime( void ) const;
void SaveState( void );
void RestoreState( void );
void SetOrigin( const idVec3 &newOrigin, int id = -1 );
void SetAxis( const idMat3 &newAxis, int id = -1 );
void Translate( const idVec3 &translation, int id = -1 );
void Rotate( const idRotation &rotation, int id = -1 );
void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 );
const idVec3 & GetLinearVelocity( int id = 0 ) const;
void SetPushed( int deltaTime );
const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const;
void ClearPushedVelocity( void );
void SetMaster( idEntity *master, const bool orientated = true );
void WriteToSnapshot( idBitMsgDelta &msg ) const;
void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
// player physics state
playerPState_t current;
playerPState_t saved;
// properties
float walkSpeed;
float crouchSpeed;
float maxStepHeight;
float maxJumpHeight;
int debugLevel; // if set, diagnostic output will be printed
// player input
usercmd_t command;
idAngles viewAngles;
// run-time variables
int framemsec;
float frametime;
float playerSpeed;
idVec3 viewForward;
idVec3 viewRight;
// walk movement
bool walking;
bool groundPlane;
trace_t groundTrace;
const idMaterial * groundMaterial;
// ladder movement
bool ladder;
idVec3 ladderNormal;
// results of last evaluate
waterLevel_t waterLevel;
int waterType;
private:
float CmdScale( const usercmd_t &cmd ) const;
void Accelerate( const idVec3 &wishdir, const float wishspeed, const float accel );
bool SlideMove( bool gravity, bool stepUp, bool stepDown, bool push );
void Friction( void );
void WaterJumpMove( void );
void WaterMove( void );
void FlyMove( void );
void AirMove( void );
void WalkMove( void );
void DeadMove( void );
void NoclipMove( void );
void SpectatorMove( void );
void LadderMove( void );
void CorrectAllSolid( trace_t &trace, int contents );
void CheckGround( void );
void CheckDuck( void );
void CheckLadder( void );
bool CheckJump( void );
bool CheckWaterJump( void );
void SetWaterLevel( void );
void DropTimers( void );
void MovePlayer( int msec );
};
#endif /* !__PHYSICS_PLAYER_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,196 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __PHYSICS_RIGIDBODY_H__
#define __PHYSICS_RIGIDBODY_H__
/*
===================================================================================
Rigid body physics
Employs an impulse based dynamic simulation which is not very accurate but
relatively fast and still reliable due to the continuous collision detection.
===================================================================================
*/
extern const float RB_VELOCITY_MAX;
extern const int RB_VELOCITY_TOTAL_BITS;
extern const int RB_VELOCITY_EXPONENT_BITS;
extern const int RB_VELOCITY_MANTISSA_BITS;
typedef struct rididBodyIState_s {
idVec3 position; // position of trace model
idMat3 orientation; // orientation of trace model
idVec3 linearMomentum; // translational momentum relative to center of mass
idVec3 angularMomentum; // rotational momentum relative to center of mass
} rigidBodyIState_t;
typedef struct rigidBodyPState_s {
int atRest; // set when simulation is suspended
float lastTimeStep; // length of last time step
idVec3 localOrigin; // origin relative to master
idMat3 localAxis; // axis relative to master
idVec6 pushVelocity; // push velocity
idVec3 externalForce; // external force relative to center of mass
idVec3 externalTorque; // external torque relative to center of mass
rigidBodyIState_t i; // state used for integration
} rigidBodyPState_t;
class idPhysics_RigidBody : public idPhysics_Base {
public:
CLASS_PROTOTYPE( idPhysics_RigidBody );
idPhysics_RigidBody( void );
~idPhysics_RigidBody( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
// initialisation
void SetFriction( const float linear, const float angular, const float contact );
void SetBouncyness( const float b );
// same as above but drop to the floor first
void DropToFloor( void );
// no contact determination and contact friction
void NoContact( void );
// enable/disable activation by impact
void EnableImpact( void );
void DisableImpact( void );
public: // common physics interface
void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true );
idClipModel * GetClipModel( int id = 0 ) const;
int GetNumClipModels( void ) const;
void SetMass( float mass, int id = -1 );
float GetMass( int id = -1 ) const;
void SetContents( int contents, int id = -1 );
int GetContents( int id = -1 ) const;
const idBounds & GetBounds( int id = -1 ) const;
const idBounds & GetAbsBounds( int id = -1 ) const;
bool Evaluate( int timeStepMSec, int endTimeMSec );
void UpdateTime( int endTimeMSec );
int GetTime( void ) const;
void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const;
void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse );
void AddForce( const int id, const idVec3 &point, const idVec3 &force );
void Activate( void );
void PutToRest( void );
bool IsAtRest( void ) const;
int GetRestStartTime( void ) const;
bool IsPushable( void ) const;
void SaveState( void );
void RestoreState( void );
void SetOrigin( const idVec3 &newOrigin, int id = -1 );
void SetAxis( const idMat3 &newAxis, int id = -1 );
void Translate( const idVec3 &translation, int id = -1 );
void Rotate( const idRotation &rotation, int id = -1 );
const idVec3 & GetOrigin( int id = 0 ) const;
const idMat3 & GetAxis( int id = 0 ) const;
void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 );
void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 );
const idVec3 & GetLinearVelocity( int id = 0 ) const;
const idVec3 & GetAngularVelocity( int id = 0 ) const;
void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const;
void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const;
int ClipContents( const idClipModel *model ) const;
void DisableClip( void );
void EnableClip( void );
void UnlinkClip( void );
void LinkClip( void );
bool EvaluateContacts( void );
void SetPushed( int deltaTime );
const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const;
const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const;
void SetMaster( idEntity *master, const bool orientated );
void WriteToSnapshot( idBitMsgDelta &msg ) const;
void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
// state of the rigid body
rigidBodyPState_t current;
rigidBodyPState_t saved;
// rigid body properties
float linearFriction; // translational friction
float angularFriction; // rotational friction
float contactFriction; // friction with contact surfaces
float bouncyness; // bouncyness
idClipModel * clipModel; // clip model used for collision detection
// derived properties
float mass; // mass of body
float inverseMass; // 1 / mass
idVec3 centerOfMass; // center of mass of trace model
idMat3 inertiaTensor; // mass distribution
idMat3 inverseInertiaTensor; // inverse inertia tensor
idODE * integrator; // integrator
bool dropToFloor; // true if dropping to the floor and putting to rest
bool testSolid; // true if testing for solid when dropping to the floor
bool noImpact; // if true do not activate when another object collides
bool noContact; // if true do not determine contacts and no contact friction
// master
bool hasMaster;
bool isOrientated;
private:
friend void RigidBodyDerivatives( const float t, const void *clientData, const float *state, float *derivatives );
void Integrate( const float deltaTime, rigidBodyPState_t &next );
bool CheckForCollisions( const float deltaTime, rigidBodyPState_t &next, trace_t &collision );
bool CollisionImpulse( const trace_t &collision, idVec3 &impulse );
void ContactFriction( float deltaTime );
void DropToFloorAndRest( void );
bool TestIfAtRest( void ) const;
void Rest( void );
void DebugDraw( void );
};
#endif /* !__PHYSICS_RIGIDBODY_H__ */

View File

@@ -0,0 +1,842 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
CLASS_DECLARATION( idPhysics, idPhysics_Static )
END_CLASS
/*
================
idPhysics_Static::idPhysics_Static
================
*/
idPhysics_Static::idPhysics_Static( void ) {
self = NULL;
clipModel = NULL;
current.origin.Zero();
current.axis.Identity();
current.localOrigin.Zero();
current.localAxis.Identity();
hasMaster = false;
isOrientated = false;
}
/*
================
idPhysics_Static::~idPhysics_Static
================
*/
idPhysics_Static::~idPhysics_Static( void ) {
if ( self && self->GetPhysics() == this ) {
self->SetPhysics( NULL );
}
idForce::DeletePhysics( this );
if ( clipModel ) {
delete clipModel;
}
}
/*
================
idPhysics_Static::Save
================
*/
void idPhysics_Static::Save( idSaveGame *savefile ) const {
savefile->WriteObject( self );
savefile->WriteVec3( current.origin );
savefile->WriteMat3( current.axis );
savefile->WriteVec3( current.localOrigin );
savefile->WriteMat3( current.localAxis );
savefile->WriteClipModel( clipModel );
savefile->WriteBool( hasMaster );
savefile->WriteBool( isOrientated );
}
/*
================
idPhysics_Static::Restore
================
*/
void idPhysics_Static::Restore( idRestoreGame *savefile ) {
savefile->ReadObject( reinterpret_cast<idClass *&>( self ) );
savefile->ReadVec3( current.origin );
savefile->ReadMat3( current.axis );
savefile->ReadVec3( current.localOrigin );
savefile->ReadMat3( current.localAxis );
savefile->ReadClipModel( clipModel );
savefile->ReadBool( hasMaster );
savefile->ReadBool( isOrientated );
}
/*
================
idPhysics_Static::SetSelf
================
*/
void idPhysics_Static::SetSelf( idEntity *e ) {
assert( e );
self = e;
}
/*
================
idPhysics_Static::SetClipModel
================
*/
void idPhysics_Static::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) {
assert( self );
if ( clipModel && clipModel != model && freeOld ) {
delete clipModel;
}
clipModel = model;
if ( clipModel ) {
clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
}
}
/*
================
idPhysics_Static::GetClipModel
================
*/
idClipModel *idPhysics_Static::GetClipModel( int id ) const {
if ( clipModel ) {
return clipModel;
}
return gameLocal.clip.DefaultClipModel();
}
/*
================
idPhysics_Static::GetNumClipModels
================
*/
int idPhysics_Static::GetNumClipModels( void ) const {
return ( clipModel != NULL );
}
/*
================
idPhysics_Static::SetMass
================
*/
void idPhysics_Static::SetMass( float mass, int id ) {
}
/*
================
idPhysics_Static::GetMass
================
*/
float idPhysics_Static::GetMass( int id ) const {
return 0.0f;
}
/*
================
idPhysics_Static::SetContents
================
*/
void idPhysics_Static::SetContents( int contents, int id ) {
if ( clipModel ) {
clipModel->SetContents( contents );
}
}
/*
================
idPhysics_Static::GetContents
================
*/
int idPhysics_Static::GetContents( int id ) const {
if ( clipModel ) {
return clipModel->GetContents();
}
return 0;
}
/*
================
idPhysics_Static::SetClipMask
================
*/
void idPhysics_Static::SetClipMask( int mask, int id ) {
}
/*
================
idPhysics_Static::GetClipMask
================
*/
int idPhysics_Static::GetClipMask( int id ) const {
return 0;
}
/*
================
idPhysics_Static::GetBounds
================
*/
const idBounds &idPhysics_Static::GetBounds( int id ) const {
if ( clipModel ) {
return clipModel->GetBounds();
}
return bounds_zero;
}
/*
================
idPhysics_Static::GetAbsBounds
================
*/
const idBounds &idPhysics_Static::GetAbsBounds( int id ) const {
static idBounds absBounds;
if ( clipModel ) {
return clipModel->GetAbsBounds();
}
absBounds[0] = absBounds[1] = current.origin;
return absBounds;
}
/*
================
idPhysics_Static::Evaluate
================
*/
bool idPhysics_Static::Evaluate( int timeStepMSec, int endTimeMSec ) {
idVec3 masterOrigin, oldOrigin;
idMat3 masterAxis, oldAxis;
if ( hasMaster ) {
oldOrigin = current.origin;
oldAxis = current.axis;
self->GetMasterPosition( masterOrigin, masterAxis );
current.origin = masterOrigin + current.localOrigin * masterAxis;
if ( isOrientated ) {
current.axis = current.localAxis * masterAxis;
} else {
current.axis = current.localAxis;
}
if ( clipModel ) {
clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
}
return ( current.origin != oldOrigin || current.axis != oldAxis );
}
return false;
}
/*
================
idPhysics_Static::UpdateTime
================
*/
void idPhysics_Static::UpdateTime( int endTimeMSec ) {
}
/*
================
idPhysics_Static::GetTime
================
*/
int idPhysics_Static::GetTime( void ) const {
return 0;
}
/*
================
idPhysics_Static::GetImpactInfo
================
*/
void idPhysics_Static::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const {
memset( info, 0, sizeof( *info ) );
}
/*
================
idPhysics_Static::ApplyImpulse
================
*/
void idPhysics_Static::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) {
}
/*
================
idPhysics_Static::AddForce
================
*/
void idPhysics_Static::AddForce( const int id, const idVec3 &point, const idVec3 &force ) {
}
/*
================
idPhysics_Static::Activate
================
*/
void idPhysics_Static::Activate( void ) {
}
/*
================
idPhysics_Static::PutToRest
================
*/
void idPhysics_Static::PutToRest( void ) {
}
/*
================
idPhysics_Static::IsAtRest
================
*/
bool idPhysics_Static::IsAtRest( void ) const {
return true;
}
/*
================
idPhysics_Static::GetRestStartTime
================
*/
int idPhysics_Static::GetRestStartTime( void ) const {
return 0;
}
/*
================
idPhysics_Static::IsPushable
================
*/
bool idPhysics_Static::IsPushable( void ) const {
return false;
}
/*
================
idPhysics_Static::SaveState
================
*/
void idPhysics_Static::SaveState( void ) {
}
/*
================
idPhysics_Static::RestoreState
================
*/
void idPhysics_Static::RestoreState( void ) {
}
/*
================
idPhysics_Static::SetOrigin
================
*/
void idPhysics_Static::SetOrigin( const idVec3 &newOrigin, int id ) {
idVec3 masterOrigin;
idMat3 masterAxis;
current.localOrigin = newOrigin;
if ( hasMaster ) {
self->GetMasterPosition( masterOrigin, masterAxis );
current.origin = masterOrigin + newOrigin * masterAxis;
} else {
current.origin = newOrigin;
}
if ( clipModel ) {
clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
}
}
/*
================
idPhysics_Static::SetAxis
================
*/
void idPhysics_Static::SetAxis( const idMat3 &newAxis, int id ) {
idVec3 masterOrigin;
idMat3 masterAxis;
current.localAxis = newAxis;
if ( hasMaster && isOrientated ) {
self->GetMasterPosition( masterOrigin, masterAxis );
current.axis = newAxis * masterAxis;
} else {
current.axis = newAxis;
}
if ( clipModel ) {
clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
}
}
/*
================
idPhysics_Static::Translate
================
*/
void idPhysics_Static::Translate( const idVec3 &translation, int id ) {
current.localOrigin += translation;
current.origin += translation;
if ( clipModel ) {
clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
}
}
/*
================
idPhysics_Static::Rotate
================
*/
void idPhysics_Static::Rotate( const idRotation &rotation, int id ) {
idVec3 masterOrigin;
idMat3 masterAxis;
current.origin *= rotation;
current.axis *= rotation.ToMat3();
if ( hasMaster ) {
self->GetMasterPosition( masterOrigin, masterAxis );
current.localAxis *= rotation.ToMat3();
current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose();
} else {
current.localAxis = current.axis;
current.localOrigin = current.origin;
}
if ( clipModel ) {
clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
}
}
/*
================
idPhysics_Static::GetOrigin
================
*/
const idVec3 &idPhysics_Static::GetOrigin( int id ) const {
return current.origin;
}
/*
================
idPhysics_Static::GetAxis
================
*/
const idMat3 &idPhysics_Static::GetAxis( int id ) const {
return current.axis;
}
/*
================
idPhysics_Static::SetLinearVelocity
================
*/
void idPhysics_Static::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) {
}
/*
================
idPhysics_Static::SetAngularVelocity
================
*/
void idPhysics_Static::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) {
}
/*
================
idPhysics_Static::GetLinearVelocity
================
*/
const idVec3 &idPhysics_Static::GetLinearVelocity( int id ) const {
return vec3_origin;
}
/*
================
idPhysics_Static::GetAngularVelocity
================
*/
const idVec3 &idPhysics_Static::GetAngularVelocity( int id ) const {
return vec3_origin;
}
/*
================
idPhysics_Static::SetGravity
================
*/
void idPhysics_Static::SetGravity( const idVec3 &newGravity ) {
}
/*
================
idPhysics_Static::GetGravity
================
*/
const idVec3 &idPhysics_Static::GetGravity( void ) const {
static idVec3 gravity( 0, 0, -g_gravity.GetFloat() );
return gravity;
}
/*
================
idPhysics_Static::GetGravityNormal
================
*/
const idVec3 &idPhysics_Static::GetGravityNormal( void ) const {
static idVec3 gravity( 0, 0, -1 );
return gravity;
}
/*
================
idPhysics_Static::ClipTranslation
================
*/
void idPhysics_Static::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const {
if ( model ) {
gameLocal.clip.TranslationModel( results, current.origin, current.origin + translation,
clipModel, current.axis, MASK_SOLID, model->Handle(), model->GetOrigin(), model->GetAxis() );
} else {
gameLocal.clip.Translation( results, current.origin, current.origin + translation,
clipModel, current.axis, MASK_SOLID, self );
}
}
/*
================
idPhysics_Static::ClipRotation
================
*/
void idPhysics_Static::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const {
if ( model ) {
gameLocal.clip.RotationModel( results, current.origin, rotation,
clipModel, current.axis, MASK_SOLID, model->Handle(), model->GetOrigin(), model->GetAxis() );
} else {
gameLocal.clip.Rotation( results, current.origin, rotation, clipModel, current.axis, MASK_SOLID, self );
}
}
/*
================
idPhysics_Static::ClipContents
================
*/
int idPhysics_Static::ClipContents( const idClipModel *model ) const {
if ( clipModel ) {
if ( model ) {
return gameLocal.clip.ContentsModel( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1,
model->Handle(), model->GetOrigin(), model->GetAxis() );
} else {
return gameLocal.clip.Contents( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, NULL );
}
}
return 0;
}
/*
================
idPhysics_Static::DisableClip
================
*/
void idPhysics_Static::DisableClip( void ) {
if ( clipModel ) {
clipModel->Disable();
}
}
/*
================
idPhysics_Static::EnableClip
================
*/
void idPhysics_Static::EnableClip( void ) {
if ( clipModel ) {
clipModel->Enable();
}
}
/*
================
idPhysics_Static::UnlinkClip
================
*/
void idPhysics_Static::UnlinkClip( void ) {
if ( clipModel ) {
clipModel->Unlink();
}
}
/*
================
idPhysics_Static::LinkClip
================
*/
void idPhysics_Static::LinkClip( void ) {
if ( clipModel ) {
clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
}
}
/*
================
idPhysics_Static::EvaluateContacts
================
*/
bool idPhysics_Static::EvaluateContacts( void ) {
return false;
}
/*
================
idPhysics_Static::GetNumContacts
================
*/
int idPhysics_Static::GetNumContacts( void ) const {
return 0;
}
/*
================
idPhysics_Static::GetContact
================
*/
const contactInfo_t &idPhysics_Static::GetContact( int num ) const {
static contactInfo_t info;
memset( &info, 0, sizeof( info ) );
return info;
}
/*
================
idPhysics_Static::ClearContacts
================
*/
void idPhysics_Static::ClearContacts( void ) {
}
/*
================
idPhysics_Static::AddContactEntity
================
*/
void idPhysics_Static::AddContactEntity( idEntity *e ) {
}
/*
================
idPhysics_Static::RemoveContactEntity
================
*/
void idPhysics_Static::RemoveContactEntity( idEntity *e ) {
}
/*
================
idPhysics_Static::HasGroundContacts
================
*/
bool idPhysics_Static::HasGroundContacts( void ) const {
return false;
}
/*
================
idPhysics_Static::IsGroundEntity
================
*/
bool idPhysics_Static::IsGroundEntity( int entityNum ) const {
return false;
}
/*
================
idPhysics_Static::IsGroundClipModel
================
*/
bool idPhysics_Static::IsGroundClipModel( int entityNum, int id ) const {
return false;
}
/*
================
idPhysics_Static::SetPushed
================
*/
void idPhysics_Static::SetPushed( int deltaTime ) {
}
/*
================
idPhysics_Static::GetPushedLinearVelocity
================
*/
const idVec3 &idPhysics_Static::GetPushedLinearVelocity( const int id ) const {
return vec3_origin;
}
/*
================
idPhysics_Static::GetPushedAngularVelocity
================
*/
const idVec3 &idPhysics_Static::GetPushedAngularVelocity( const int id ) const {
return vec3_origin;
}
/*
================
idPhysics_Static::SetMaster
================
*/
void idPhysics_Static::SetMaster( idEntity *master, const bool orientated ) {
idVec3 masterOrigin;
idMat3 masterAxis;
if ( master ) {
if ( !hasMaster ) {
// transform from world space to master space
self->GetMasterPosition( masterOrigin, masterAxis );
current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose();
if ( orientated ) {
current.localAxis = current.axis * masterAxis.Transpose();
} else {
current.localAxis = current.axis;
}
hasMaster = true;
isOrientated = orientated;
}
} else {
if ( hasMaster ) {
hasMaster = false;
}
}
}
/*
================
idPhysics_Static::GetBlockingInfo
================
*/
const trace_t *idPhysics_Static::GetBlockingInfo( void ) const {
return NULL;
}
/*
================
idPhysics_Static::GetBlockingEntity
================
*/
idEntity *idPhysics_Static::GetBlockingEntity( void ) const {
return NULL;
}
/*
================
idPhysics_Static::GetLinearEndTime
================
*/
int idPhysics_Static::GetLinearEndTime( void ) const {
return 0;
}
/*
================
idPhysics_Static::GetAngularEndTime
================
*/
int idPhysics_Static::GetAngularEndTime( void ) const {
return 0;
}
/*
================
idPhysics_Static::WriteToSnapshot
================
*/
void idPhysics_Static::WriteToSnapshot( idBitMsgDelta &msg ) const {
idCQuat quat, localQuat;
quat = current.axis.ToCQuat();
localQuat = current.localAxis.ToCQuat();
msg.WriteFloat( current.origin[0] );
msg.WriteFloat( current.origin[1] );
msg.WriteFloat( current.origin[2] );
msg.WriteFloat( quat.x );
msg.WriteFloat( quat.y );
msg.WriteFloat( quat.z );
msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] );
msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] );
msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] );
msg.WriteDeltaFloat( quat.x, localQuat.x );
msg.WriteDeltaFloat( quat.y, localQuat.y );
msg.WriteDeltaFloat( quat.z, localQuat.z );
}
/*
================
idPhysics_Base::ReadFromSnapshot
================
*/
void idPhysics_Static::ReadFromSnapshot( const idBitMsgDelta &msg ) {
idCQuat quat, localQuat;
current.origin[0] = msg.ReadFloat();
current.origin[1] = msg.ReadFloat();
current.origin[2] = msg.ReadFloat();
quat.x = msg.ReadFloat();
quat.y = msg.ReadFloat();
quat.z = msg.ReadFloat();
current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] );
current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] );
current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] );
localQuat.x = msg.ReadDeltaFloat( quat.x );
localQuat.y = msg.ReadDeltaFloat( quat.y );
localQuat.z = msg.ReadDeltaFloat( quat.z );
current.axis = quat.ToMat3();
current.localAxis = localQuat.ToMat3();
}

View File

@@ -0,0 +1,158 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __PHYSICS_STATIC_H__
#define __PHYSICS_STATIC_H__
/*
===============================================================================
Physics for a non moving object using at most one collision model.
===============================================================================
*/
typedef struct staticPState_s {
idVec3 origin;
idMat3 axis;
idVec3 localOrigin;
idMat3 localAxis;
} staticPState_t;
class idPhysics_Static : public idPhysics {
public:
CLASS_PROTOTYPE( idPhysics_Static );
idPhysics_Static( void );
~idPhysics_Static( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
public: // common physics interface
void SetSelf( idEntity *e );
void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true );
idClipModel * GetClipModel( int id = 0 ) const;
int GetNumClipModels( void ) const;
void SetMass( float mass, int id = -1 );
float GetMass( int id = -1 ) const;
void SetContents( int contents, int id = -1 );
int GetContents( int id = -1 ) const;
void SetClipMask( int mask, int id = -1 );
int GetClipMask( int id = -1 ) const;
const idBounds & GetBounds( int id = -1 ) const;
const idBounds & GetAbsBounds( int id = -1 ) const;
bool Evaluate( int timeStepMSec, int endTimeMSec );
void UpdateTime( int endTimeMSec );
int GetTime( void ) const;
void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const;
void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse );
void AddForce( const int id, const idVec3 &point, const idVec3 &force );
void Activate( void );
void PutToRest( void );
bool IsAtRest( void ) const;
int GetRestStartTime( void ) const;
bool IsPushable( void ) const;
void SaveState( void );
void RestoreState( void );
void SetOrigin( const idVec3 &newOrigin, int id = -1 );
void SetAxis( const idMat3 &newAxis, int id = -1 );
void Translate( const idVec3 &translation, int id = -1 );
void Rotate( const idRotation &rotation, int id = -1 );
const idVec3 & GetOrigin( int id = 0 ) const;
const idMat3 & GetAxis( int id = 0 ) const;
void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 );
void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 );
const idVec3 & GetLinearVelocity( int id = 0 ) const;
const idVec3 & GetAngularVelocity( int id = 0 ) const;
void SetGravity( const idVec3 &newGravity );
const idVec3 & GetGravity( void ) const;
const idVec3 & GetGravityNormal( void ) const;
void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const;
void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const;
int ClipContents( const idClipModel *model ) const;
void DisableClip( void );
void EnableClip( void );
void UnlinkClip( void );
void LinkClip( void );
bool EvaluateContacts( void );
int GetNumContacts( void ) const;
const contactInfo_t & GetContact( int num ) const;
void ClearContacts( void );
void AddContactEntity( idEntity *e );
void RemoveContactEntity( idEntity *e );
bool HasGroundContacts( void ) const;
bool IsGroundEntity( int entityNum ) const;
bool IsGroundClipModel( int entityNum, int id ) const;
void SetPushed( int deltaTime );
const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const;
const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const;
void SetMaster( idEntity *master, const bool orientated = true );
const trace_t * GetBlockingInfo( void ) const;
idEntity * GetBlockingEntity( void ) const;
int GetLinearEndTime( void ) const;
int GetAngularEndTime( void ) const;
void WriteToSnapshot( idBitMsgDelta &msg ) const;
void ReadFromSnapshot( const idBitMsgDelta &msg );
protected:
idEntity * self; // entity using this physics object
staticPState_t current; // physics state
idClipModel * clipModel; // collision model
// master
bool hasMaster;
bool isOrientated;
};
#endif /* !__PHYSICS_STATIC_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,154 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __PHYSICS_STATICMULTI_H__
#define __PHYSICS_STATICMULTI_H__
/*
===============================================================================
Physics for a non moving object using no or multiple collision models.
===============================================================================
*/
class idPhysics_StaticMulti : public idPhysics {
public:
CLASS_PROTOTYPE( idPhysics_StaticMulti );
idPhysics_StaticMulti( void );
~idPhysics_StaticMulti( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void RemoveIndex( int id = 0, bool freeClipModel = true );
public: // common physics interface
void SetSelf( idEntity *e );
void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true );
idClipModel * GetClipModel( int id = 0 ) const;
int GetNumClipModels( void ) const;
void SetMass( float mass, int id = -1 );
float GetMass( int id = -1 ) const;
void SetContents( int contents, int id = -1 );
int GetContents( int id = -1 ) const;
void SetClipMask( int mask, int id = -1 );
int GetClipMask( int id = -1 ) const;
const idBounds & GetBounds( int id = -1 ) const;
const idBounds & GetAbsBounds( int id = -1 ) const;
bool Evaluate( int timeStepMSec, int endTimeMSec );
void UpdateTime( int endTimeMSec );
int GetTime( void ) const;
void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const;
void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse );
void AddForce( const int id, const idVec3 &point, const idVec3 &force );
void Activate( void );
void PutToRest( void );
bool IsAtRest( void ) const;
int GetRestStartTime( void ) const;
bool IsPushable( void ) const;
void SaveState( void );
void RestoreState( void );
void SetOrigin( const idVec3 &newOrigin, int id = -1 );
void SetAxis( const idMat3 &newAxis, int id = -1 );
void Translate( const idVec3 &translation, int id = -1 );
void Rotate( const idRotation &rotation, int id = -1 );
const idVec3 & GetOrigin( int id = 0 ) const;
const idMat3 & GetAxis( int id = 0 ) const;
void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 );
void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 );
const idVec3 & GetLinearVelocity( int id = 0 ) const;
const idVec3 & GetAngularVelocity( int id = 0 ) const;
void SetGravity( const idVec3 &newGravity );
const idVec3 & GetGravity( void ) const;
const idVec3 & GetGravityNormal( void ) const;
void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const;
void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const;
int ClipContents( const idClipModel *model ) const;
void DisableClip( void );
void EnableClip( void );
void UnlinkClip( void );
void LinkClip( void );
bool EvaluateContacts( void );
int GetNumContacts( void ) const;
const contactInfo_t & GetContact( int num ) const;
void ClearContacts( void );
void AddContactEntity( idEntity *e );
void RemoveContactEntity( idEntity *e );
bool HasGroundContacts( void ) const;
bool IsGroundEntity( int entityNum ) const;
bool IsGroundClipModel( int entityNum, int id ) const;
void SetPushed( int deltaTime );
const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const;
const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const;
void SetMaster( idEntity *master, const bool orientated = true );
const trace_t * GetBlockingInfo( void ) const;
idEntity * GetBlockingEntity( void ) const;
int GetLinearEndTime( void ) const;
int GetAngularEndTime( void ) const;
void WriteToSnapshot( idBitMsgDelta &msg ) const;
void ReadFromSnapshot( const idBitMsgDelta &msg );
protected:
idEntity * self; // entity using this physics object
idList<staticPState_t> current; // physics state
idList<idClipModel *> clipModels; // collision model
// master
bool hasMaster;
bool isOrientated;
};
#endif /* !__PHYSICS_STATICMULTI_H__ */

1448
neo/game/physics/Push.cpp Normal file

File diff suppressed because it is too large Load Diff

113
neo/game/physics/Push.h Normal file
View File

@@ -0,0 +1,113 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __PUSH_H__
#define __PUSH_H__
/*
===============================================================================
Allows physics objects to be pushed geometrically.
===============================================================================
*/
#define PUSHFL_ONLYMOVEABLE 1 // only push moveable entities
#define PUSHFL_NOGROUNDENTITIES 2 // don't push entities the clip model rests upon
#define PUSHFL_CLIP 4 // also clip against all non-moveable entities
#define PUSHFL_CRUSH 8 // kill blocking entities
#define PUSHFL_APPLYIMPULSE 16 // apply impulse to pushed entities
//#define NEW_PUSH
class idPush {
public:
// Try to push other entities by moving the given entity.
// If results.fraction < 1.0 the move was blocked by results.c.entityNum
// Returns total mass of all pushed entities.
float ClipTranslationalPush( trace_t &results, idEntity *pusher, const int flags,
const idVec3 &newOrigin, const idVec3 &move );
float ClipRotationalPush( trace_t &results, idEntity *pusher, const int flags,
const idMat3 &newAxis, const idRotation &rotation );
float ClipPush( trace_t &results, idEntity *pusher, const int flags,
const idVec3 &oldOrigin, const idMat3 &oldAxis,
idVec3 &newOrigin, idMat3 &newAxis );
// initialize saving the positions of entities being pushed
void InitSavingPushedEntityPositions( void );
// move all pushed entities back to their previous position
void RestorePushedEntityPositions( void );
// returns the number of pushed entities
int GetNumPushedEntities( void ) const { return numPushed; }
// get the ith pushed entity
idEntity * GetPushedEntity( int i ) const { assert( i >= 0 && i < numPushed ); return pushed[i].ent; }
private:
struct pushed_s {
idEntity * ent; // pushed entity
idAngles deltaViewAngles; // actor delta view angles
} pushed[MAX_GENTITIES]; // pushed entities
int numPushed; // number of pushed entities
struct pushedGroup_s {
idEntity * ent;
float fraction;
bool groundContact;
bool test;
} pushedGroup[MAX_GENTITIES];
int pushedGroupSize;
private:
void SaveEntityPosition( idEntity *ent );
bool RotateEntityToAxial( idEntity *ent, idVec3 rotationPoint );
#ifdef NEW_PUSH
bool CanPushEntity( idEntity *ent, idEntity *pusher, idEntity *initialPusher, const int flags );
void AddEntityToPushedGroup( idEntity *ent, float fraction, bool groundContact );
bool IsFullyPushed( idEntity *ent );
bool ClipTranslationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idVec3 &translation );
int GetPushableEntitiesForTranslation( idEntity *pusher, idEntity *initialPusher, const int flags,
const idVec3 &translation, idEntity *entityList[], int maxEntities );
bool ClipRotationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idRotation &rotation );
int GetPushableEntitiesForRotation( idEntity *pusher, idEntity *initialPusher, const int flags,
const idRotation &rotation, idEntity *entityList[], int maxEntities );
#else
void ClipEntityRotation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel,
idClipModel *skip, const idRotation &rotation );
void ClipEntityTranslation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel,
idClipModel *skip, const idVec3 &translation );
int TryTranslatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags,
const idVec3 &newOrigin, const idVec3 &move );
int TryRotatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags,
const idMat3 &newAxis, const idRotation &rotation );
int DiscardEntities( idEntity *entityList[], int numEntities, int flags, idEntity *pusher );
#endif
};
#endif /* !__PUSH_H__ */