mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 19:23:51 +02:00
Initial Prey Game integration support.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,397 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#ifndef __CLIP_H__
|
||||
#define __CLIP_H__
|
||||
|
||||
#if _HH_CLIP_FASTSECTORS //HUMANHEAD rww
|
||||
const int CLIPSECTOR_DEPTH = 6;
|
||||
const int CLIPSECTOR_WIDTH = 1 << CLIPSECTOR_DEPTH;
|
||||
#endif //HUMANHEAD END
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
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 );
|
||||
|
||||
#if _HH_CLIP_FASTSECTORS //HUMANHEAD rww
|
||||
void UpdateDynamicContents( void );
|
||||
#endif //HUMANHEAD END
|
||||
|
||||
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 ¢erOfMass, 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
|
||||
#if _HH_CLIP_FASTSECTORS //HUMANHEAD rww
|
||||
bool checked; // Splash's clip model code
|
||||
#endif //HUMANHEAD END
|
||||
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
|
||||
#if !_HH_CLIP_FASTSECTORS //HUMANHEAD rww
|
||||
void Link_r( struct clipSector_s *node );
|
||||
#endif //HUMANHEAD END
|
||||
|
||||
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;
|
||||
#if _HH_CLIP_FASTSECTORS //HUMANHEAD rww
|
||||
UpdateDynamicContents();
|
||||
#endif //HUMANHEAD END
|
||||
}
|
||||
|
||||
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 );
|
||||
//HUMANEHAD rww - translation with overhead of checking game logic for collision allowance
|
||||
bool TranslationWithExceptions( trace_t &results, const idVec3 &start, const idVec3 &end, idEntity *ent,
|
||||
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;
|
||||
|
||||
#if _HH_CLIP_FASTSECTORS //HUMANHEAD rww
|
||||
void CoordsForBounds( int* coords, idBounds& bounds ) const;
|
||||
static void UpdateDynamicContents( struct clipSector_s* sector );
|
||||
static void UpdateDynamicContents( idClipModel* clipModel );
|
||||
#endif //HUMANHEAD END
|
||||
|
||||
// HUMANHEAD pdm
|
||||
void DrawClipModelsInTree_r( const struct clipSector_s *node, const idVec3 &eye );
|
||||
// HUMANHEAD END
|
||||
|
||||
#if !GOLD //HUMANHEAD rww
|
||||
bool CheckClipEntMatch( const struct clipSector_s *node, const idClipModel *currentClip, const idEntity *ent ) const;
|
||||
#endif //HUMANHEAD END
|
||||
|
||||
private:
|
||||
#if _HH_CLIP_FASTSECTORS //HUMANHEAD rww
|
||||
idVec3 nodeScale;
|
||||
idVec3 nodeOffset;
|
||||
idVec3 nodeOffsetVisual;
|
||||
#endif //HUMANHEAD END
|
||||
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 );
|
||||
#if !_HH_CLIP_FASTSECTORS //HUMANHEAD rww
|
||||
void ClipModelsTouchingBounds_r( const struct clipSector_s *node, struct listParms_s &parms ) const;
|
||||
#endif //HUMANHEAD END
|
||||
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;
|
||||
#if _HH_CLIP_FASTSECTORS //HUMANHEAD rww
|
||||
void GetClipSectorsStaticContents( void );
|
||||
#endif //HUMANHEAD END
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#if _HH_CLIP_FASTSECTORS //HUMANHEAD rww
|
||||
ID_INLINE void idClip::CoordsForBounds( int* coords, idBounds& bounds ) const {
|
||||
float fCoords[ 4 ];
|
||||
|
||||
fCoords[ 0 ] = ( bounds[ 0 ].x - nodeOffset.x ) * nodeScale.x;
|
||||
fCoords[ 1 ] = ( bounds[ 0 ].y - nodeOffset.y ) * nodeScale.y;
|
||||
fCoords[ 2 ] = ( bounds[ 1 ].x - nodeOffset.x ) * nodeScale.x;
|
||||
fCoords[ 3 ] = ( bounds[ 1 ].y - nodeOffset.y ) * nodeScale.y;
|
||||
|
||||
int i;
|
||||
for( i = 0; i < 4; i++ ) {
|
||||
|
||||
coords[ i ] = idMath::FtoiFast( fCoords[ i ] );
|
||||
|
||||
if( coords[ i ] < 0 ) {
|
||||
coords[ i ] = 0;
|
||||
} else if( coords[ i ] > CLIPSECTOR_WIDTH - 1 ) {
|
||||
coords[ i ] = CLIPSECTOR_WIDTH - 1;
|
||||
}
|
||||
}
|
||||
coords[ 2 ]++; coords[ 3 ]++;
|
||||
}
|
||||
#endif //HUMANHEAD END
|
||||
|
||||
#endif /* !__CLIP_H__ */
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#include "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 ) {
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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__ */
|
||||
@@ -0,0 +1,110 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#include "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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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__ */
|
||||
@@ -0,0 +1,130 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#include "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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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__ */
|
||||
@@ -0,0 +1,243 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#include "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 ];
|
||||
//HUMANHEAD: aob
|
||||
idVec3 linearVelocity;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//HUMANHEAD: aob - should ignore players that noclip
|
||||
if ( !monsterOnly ) {
|
||||
idEntity* entity = cm->GetEntity();
|
||||
if ( entity->IsType( idPlayer::Type ) && static_cast<idPlayer *>(entity)->noclip ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//HUMANHEAD END
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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__ */
|
||||
@@ -0,0 +1,183 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#include "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( idEntity *physics1, int id1, const idVec3 &p1, idEntity *physics2, int id2, const idVec3 &p2 ) { // HUMANHEAD mdl: Changed physics1 and physics2 to idEntity instead of the entity's physics object
|
||||
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.IsValid() ) { // HUMANHEAD mdl: Added IsValid()
|
||||
axis = physics1->GetPhysics()->GetAxis( id1 ); // HUMANHEAD: Added GetPhysics()
|
||||
pos1 = physics1->GetPhysics()->GetOrigin( id1 ); // HUMANHEAD: Added GetPhysics()
|
||||
pos1 += p1 * axis;
|
||||
if ( damping > 0.0f ) {
|
||||
physics1->GetPhysics()->GetImpactInfo( id1, pos1, &info ); // HUMANHEAD: Added GetPhysics()
|
||||
velocity1 = info.velocity;
|
||||
}
|
||||
}
|
||||
|
||||
if ( physics2.IsValid() ) { // HUMANHEAD mdl: Added IsValid()
|
||||
axis = physics2->GetPhysics()->GetAxis( id2 ); // HUMANHEAD: Added GetPhysics()
|
||||
pos2 = physics2->GetPhysics()->GetOrigin( id2 ); // HUMANHEAD: Added GetPhysics()
|
||||
pos2 += p2 * axis;
|
||||
if ( damping > 0.0f ) {
|
||||
physics2->GetPhysics()->GetImpactInfo( id2, pos2, &info ); // HUMANHEAD: Added GetPhysics()
|
||||
velocity2 = info.velocity;
|
||||
}
|
||||
}
|
||||
|
||||
force = pos2 - pos1;
|
||||
|
||||
#ifdef _HH_FLOAT_PROTECTION //HUMANHEAD rww
|
||||
if (FLOAT_IS_NAN(velocity1.x) || FLOAT_IS_NAN(velocity1.y) || FLOAT_IS_NAN(velocity1.z) ||
|
||||
FLOAT_IS_NAN(velocity2.x) || FLOAT_IS_NAN(velocity2.y) || FLOAT_IS_NAN(velocity2.z)) {
|
||||
gameLocal.DWarning( "idForce_Spring::Evaluate: NaN velocity." );
|
||||
return;
|
||||
}
|
||||
#endif //HUMANHEAD END
|
||||
if (force == vec3_origin) { //HUMANHEAD rww
|
||||
//gameLocal.Warning( "idForce_Spring::Evaluate: force equal to zero." );
|
||||
dampingForce = vec3_origin;
|
||||
}
|
||||
else { //HUMANHEAD END
|
||||
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.IsValid() ) { // HUMANHEAD mdl: Added IsValid()
|
||||
physics1->GetPhysics()->AddForce( id1, pos1, force ); // HUMANHEAD: Added GetPhysics()
|
||||
}
|
||||
if ( physics2.IsValid() ) { // HUMANHEAD mdl: Added IsValid()
|
||||
physics2->GetPhysics()->AddForce( id2, pos2, -force ); // HUMANHEAD: Added GetPhysics()
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( Kcompress > 0.0f ) {
|
||||
force = ( Square( length - restLength ) * Kcompress ) * force - dampingForce;
|
||||
if ( physics1.IsValid() ) { // HUMANHEAD mdl: Added IsValid()
|
||||
physics1->GetPhysics()->AddForce( id1, pos1, -force ); // HUMANHEAD: Added GetPhysics()
|
||||
}
|
||||
if ( physics2.IsValid() ) { // HUMANHEAD mdl: Added IsValid()
|
||||
physics2->GetPhysics()->AddForce( id2, pos2, force ); // HUMANHEAD: Added GetPhysics()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idForce_Spring::RemovePhysics
|
||||
================
|
||||
*/
|
||||
void idForce_Spring::RemovePhysics( const idEntity *phys ) { // HUMANHEAD mdl: Changed to take entity instead of its physics object
|
||||
if ( physics1.GetEntity() == phys ) { // HUMANHEAD mdl: Added GetEntity()
|
||||
physics1 = NULL;
|
||||
}
|
||||
if ( physics2.GetEntity() == phys ) { // HUMANHEAD mdl: Added GetEntity()
|
||||
physics2 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// HUMANHEAD mdl
|
||||
void idForce_Spring::Save( idSaveGame *savefile ) const {
|
||||
savefile->WriteFloat( Kstretch );
|
||||
savefile->WriteFloat( Kcompress );
|
||||
savefile->WriteFloat( damping );
|
||||
savefile->WriteFloat( restLength );
|
||||
physics1.Save( savefile );
|
||||
savefile->WriteInt( id1 );
|
||||
savefile->WriteVec3( p1 );
|
||||
physics2.Save( savefile );
|
||||
savefile->WriteInt( id2 );
|
||||
savefile->WriteVec3( p2 );
|
||||
}
|
||||
|
||||
void idForce_Spring::Restore( idRestoreGame *savefile ) {
|
||||
savefile->ReadFloat( Kstretch );
|
||||
savefile->ReadFloat( Kcompress );
|
||||
savefile->ReadFloat( damping );
|
||||
savefile->ReadFloat( restLength );
|
||||
physics1.Restore( savefile );
|
||||
savefile->ReadInt( id1 );
|
||||
savefile->ReadVec3( p1 );
|
||||
physics2.Restore( savefile );
|
||||
savefile->ReadInt( id2 );
|
||||
savefile->ReadVec3( p2 );
|
||||
}
|
||||
// HUMANHEAD END
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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( idEntity *physics1, int id1, const idVec3 &p1,
|
||||
idEntity *physics2, int id2, const idVec3 &p2 ); // HUMANHEAD mdl: Changed to taking entities instead of their physics objects
|
||||
|
||||
// HUMANHEAD mdl: Added Save/Restore
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
// HUMANHEAD END
|
||||
|
||||
public: // common force interface
|
||||
virtual void Evaluate( int time );
|
||||
virtual void RemovePhysics( const idEntity *phys ); // HUMANHEAD mdl: Changed to take entity instead of its physics object
|
||||
|
||||
private:
|
||||
|
||||
// spring properties
|
||||
float Kstretch;
|
||||
float Kcompress;
|
||||
float damping;
|
||||
float restLength;
|
||||
|
||||
// positioning
|
||||
idEntityPtr< idEntity > physics1; // first physics object // HUMANHEAD mdl: Changed to entity
|
||||
int id1; // clip model id of first physics object
|
||||
idVec3 p1; // position on clip model
|
||||
idEntityPtr< idEntity > physics2; // second physics object // HUMANHEAD mdl: Changed to entity
|
||||
int id2; // clip model id of second physics object
|
||||
idVec3 p2; // position on clip model
|
||||
|
||||
};
|
||||
|
||||
#endif /* !__FORCE_SPRING_H__ */
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#include "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 );
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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;
|
||||
|
||||
//HUMANHEAD: aob - need declarations so we can call these with GetPhysics()
|
||||
virtual void ActivateContactEntities( void ) {}
|
||||
//HUMANHEAD END
|
||||
};
|
||||
|
||||
#endif /* !__PHYSICS_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,671 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
|
||||
CLASS_DECLARATION( idPhysics_Base, idPhysics_Actor )
|
||||
END_CLASS
|
||||
|
||||
//HUMANHEAD PCF mdl 04/30/06 - Added this in case last minute change below causes chaos
|
||||
#define LAST_MINUTE_HACK
|
||||
|
||||
/*
|
||||
================
|
||||
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;
|
||||
|
||||
// HUMANHEAD nla
|
||||
numTouch = 0;
|
||||
memset( &groundTrace, 0, sizeof(trace_t) );
|
||||
hadGroundContacts = false;
|
||||
// HUMANHEAD END
|
||||
|
||||
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 );
|
||||
|
||||
// HUMANHEAD mdl
|
||||
int i;
|
||||
savefile->WriteTrace( groundTrace );
|
||||
savefile->WriteInt( numTouch );
|
||||
for( i = 0; i < MAXTOUCH; i++ ) {
|
||||
savefile->WriteInt( touchEnts[i] );
|
||||
}
|
||||
savefile->WriteBool( hadGroundContacts );
|
||||
for( i = 0; i < c_iNumRotationTraces; i++ ) {
|
||||
savefile->WriteVec3( rotationTraceDirectionTable[i] );
|
||||
}
|
||||
// HUMANHEAD END
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
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 );
|
||||
|
||||
// HUMANHEAD mdl
|
||||
int i;
|
||||
savefile->ReadTrace( groundTrace );
|
||||
savefile->ReadInt( numTouch );
|
||||
for( i = 0; i < MAXTOUCH; i++ ) {
|
||||
savefile->ReadInt( touchEnts[i] );
|
||||
}
|
||||
savefile->ReadBool( hadGroundContacts );
|
||||
for( i = 0; i < c_iNumRotationTraces; i++ ) {
|
||||
savefile->ReadVec3( rotationTraceDirectionTable[i] );
|
||||
}
|
||||
// HUMANHEAD END
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idPhysics_Actor::SetClipModelAxis
|
||||
================
|
||||
*/
|
||||
void idPhysics_Actor::SetClipModelAxis( void ) {
|
||||
|
||||
idMat3 prevClipModelAxis = clipModelAxis; // HUMANHEAD JRM
|
||||
|
||||
// align clip model to gravity direction
|
||||
if ( ( gravityNormal[2] == -1.0f ) || ( gravityNormal == vec3_zero ) ) {
|
||||
clipModelAxis.Identity();
|
||||
}
|
||||
else {
|
||||
|
||||
// HUMANHEAD JRM/PDM/NLA - To get the right clipmodel axis in gravity zones
|
||||
idVec3 newx;
|
||||
newx = prevClipModelAxis[0] - (prevClipModelAxis[0] * -gravityNormal)*-gravityNormal;
|
||||
if(newx.LengthSqr() < VECTOR_EPSILON) {
|
||||
gameLocal.Warning("idPhysics_Actor::SetClipModelAxis invalid newx");
|
||||
if(prevClipModelAxis[0] * -gravityNormal > 0.0f) {
|
||||
newx = -prevClipModelAxis[2];
|
||||
}
|
||||
else {
|
||||
newx = prevClipModelAxis[2];
|
||||
}
|
||||
}
|
||||
newx.Normalize();
|
||||
clipModelAxis[0] = newx;
|
||||
clipModelAxis[2] = -gravityNormal;
|
||||
clipModelAxis[1] = clipModelAxis[2].Cross(clipModelAxis[0]);
|
||||
// HUMANHEAD END
|
||||
}
|
||||
|
||||
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 );
|
||||
/* HUMANHEAD: aob - removed because InterativeRotateMove updates bbox
|
||||
SetClipModelAxis();
|
||||
HUMANHEAD END*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
// HUMANHEAD functions
|
||||
|
||||
/*
|
||||
===============
|
||||
idPhysics_Actor::AddTouchEnt
|
||||
HUMANHEAD nla
|
||||
===============
|
||||
*/
|
||||
void idPhysics_Actor::AddTouchEnt( int entityNum ) {
|
||||
int i;
|
||||
|
||||
if ( entityNum == ENTITYNUM_WORLD ) {
|
||||
return;
|
||||
}
|
||||
if ( numTouch == MAXTOUCH ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// see if it is already added
|
||||
for ( i = 0; i < numTouch; i++ ) {
|
||||
if ( touchEnts[ i ] == entityNum ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// add it
|
||||
touchEnts[numTouch] = entityNum;
|
||||
numTouch++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
idPhysics_Actor::AddTouchEntList
|
||||
HUMANHEAD nla
|
||||
===============
|
||||
*/
|
||||
void idPhysics_Actor::AddTouchEntList( idList<int> &list ) {
|
||||
int i;
|
||||
|
||||
|
||||
for ( i = 0; i < list.Num(); i++ ) {
|
||||
AddTouchEnt(list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
idPhysics_Actor::GetNumTouchEnts
|
||||
HUMANHEAD nla
|
||||
================
|
||||
*/
|
||||
int idPhysics_Actor::GetNumTouchEnts( void ) const {
|
||||
return numTouch;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idPhysics_Actor::GetTouchEnt
|
||||
HUMANHEAD nla
|
||||
================
|
||||
*/
|
||||
int idPhysics_Actor::GetTouchEnt( int i ) const {
|
||||
if ( i < 0 || i >= numTouch ) {
|
||||
return ENTITYNUM_NONE;
|
||||
}
|
||||
return touchEnts[i];
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPhysics_Actor::ResetNumTouchEnt
|
||||
HUMANHEAD nla
|
||||
===============
|
||||
*/
|
||||
void idPhysics_Actor::ResetNumTouchEnt( int i ) {
|
||||
|
||||
numTouch = i;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
hhPhysics_Player::HadGroundContacts
|
||||
|
||||
HUMANHEAD: aob
|
||||
================
|
||||
*/
|
||||
bool idPhysics_Actor::HadGroundContacts() const {
|
||||
return hadGroundContacts;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idPhysics_Actor::HadGroundContacts
|
||||
|
||||
HUMANHEAD: aob
|
||||
================
|
||||
*/
|
||||
void idPhysics_Actor::HadGroundContacts( const bool hadGroundContacts ) {
|
||||
this->hadGroundContacts = hadGroundContacts;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idPhysics_Actor::InterativeRotateMove
|
||||
|
||||
HUMANHEAD: aob
|
||||
================
|
||||
*/
|
||||
bool idPhysics_Actor::IterativeRotateMove( const idVec3& upVector, const idVec3& idealUpVector, const idVec3& rotationOrigin, const idVec3& rotationCheckOrigin, int numIterations) {
|
||||
trace_t rotationTraceInfo;
|
||||
trace_t translationTraceInfo;
|
||||
idRotation rotator;
|
||||
idVec3 rotationVector;
|
||||
const idVec3 origPos( rotationOrigin );
|
||||
idVec3 currentOrigin( rotationOrigin );
|
||||
idMat3 currentAxis( GetAxis() );
|
||||
idVec3 averageTranslationVector( vec3_origin );
|
||||
float numTranslationVectors = 0.0f;
|
||||
|
||||
if( idealUpVector.Compare(vec3_origin, VECTOR_EPSILON) ) {// For Zero G
|
||||
return false;
|
||||
}
|
||||
|
||||
if( upVector.Compare(idealUpVector, VECTOR_EPSILON) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rotator.SetVec( DetermineRotationVector(upVector, idealUpVector, rotationCheckOrigin) );
|
||||
rotator.SetAngle( RAD2DEG(idMath::ACos(upVector * idealUpVector)) );
|
||||
rotator.ToMat3();
|
||||
|
||||
do {
|
||||
rotator.SetOrigin( currentOrigin );
|
||||
gameLocal.clip.Rotation( rotationTraceInfo, currentOrigin, rotator, clipModel, currentAxis, clipMask, self );
|
||||
currentAxis = rotationTraceInfo.endAxis;
|
||||
|
||||
if( rotationTraceInfo.fraction < 1.0f ) {
|
||||
gameLocal.clip.Translation( translationTraceInfo, currentOrigin, currentOrigin + rotationTraceInfo.c.normal * p_iterRotMoveTransDist.GetFloat(), clipModel, currentAxis, clipMask, self );
|
||||
currentOrigin = translationTraceInfo.endpos;
|
||||
averageTranslationVector += rotationTraceInfo.c.normal;
|
||||
numTranslationVectors += 1.0f;
|
||||
}
|
||||
} while( --numIterations && rotationTraceInfo.fraction < 1.0f );
|
||||
|
||||
if( numTranslationVectors > 0.0f ) {
|
||||
averageTranslationVector /= numTranslationVectors;
|
||||
averageTranslationVector.Normalize();
|
||||
gameLocal.clip.Translation( translationTraceInfo, currentOrigin, currentOrigin + -averageTranslationVector * p_iterRotMoveTransDist.GetFloat(), clipModel, currentAxis, clipMask, self );
|
||||
currentOrigin = translationTraceInfo.endpos;
|
||||
}
|
||||
|
||||
//HUMANHEAD rww - do a translation test before using this origin/axis
|
||||
if (!gameLocal.clip.Translation( translationTraceInfo, currentOrigin, currentOrigin, clipModel, currentAxis, clipMask, self )) {
|
||||
SetOrigin( currentOrigin );
|
||||
SetAxis( currentAxis );
|
||||
}
|
||||
else { //HUMANHEAD rww - if we fail, try instantly rotating to the desired orientation
|
||||
//HUMANHEAD PCF mdl 04/30/06 - Added LAST_MINUTE_HACK in case we want to revert this
|
||||
#ifndef LAST_MINUTE_HACK
|
||||
if (groundTrace.fraction < 1.0f && fabsf(DotProduct(idealUpVector, groundTrace.c.normal)) > 0.8f) { //hitting ground
|
||||
const float fudge = 1.0f;
|
||||
currentOrigin = rotationCheckOrigin + (groundTrace.c.normal*(fabsf(GetBounds()[0].z)+fudge));
|
||||
|
||||
idMat3 m = idealUpVector.ToMat3();
|
||||
currentAxis[0] = m[2];
|
||||
currentAxis[2] = m[0];
|
||||
currentAxis[1] = m[0].Cross(m[2]);
|
||||
if (!gameLocal.clip.Translation( translationTraceInfo, currentOrigin, currentOrigin, clipModel, currentAxis, clipMask, self )) {
|
||||
SetOrigin( currentOrigin );
|
||||
SetAxis( currentAxis );
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (groundTrace.fraction < 1.0f && fabsf(DotProduct(idealUpVector, groundTrace.c.normal)) > 0.8f) { //hitting ground
|
||||
const float fudge = 1.0f;
|
||||
float safeD = (fabsf(GetBounds()[0].z)+fudge);
|
||||
currentOrigin = rotationCheckOrigin + (groundTrace.c.normal*safeD);
|
||||
idMat3 m = idealUpVector.ToMat3();
|
||||
currentAxis[0] = m[2];
|
||||
currentAxis[2] = m[0];
|
||||
currentAxis[1] = m[0].Cross(m[2]);
|
||||
if (!gameLocal.clip.Translation( translationTraceInfo, currentOrigin, currentOrigin, clipModel, currentAxis, clipMask, self )) {
|
||||
//HUMANHEAD PCF rww 04/30/06 - trace back down on the normal once we have made sure we have a safe spot.
|
||||
const float downFudge = 16.0f;
|
||||
safeD = (fabsf(GetBounds()[1].z)+downFudge);
|
||||
idVec3 backDown = currentOrigin - (groundTrace.c.normal*safeD);
|
||||
gameLocal.clip.Translation( translationTraceInfo, currentOrigin, backDown, clipModel, currentAxis, clipMask, self );
|
||||
|
||||
SetOrigin( translationTraceInfo.endpos );
|
||||
SetAxis( translationTraceInfo.endAxis );
|
||||
}
|
||||
}
|
||||
#endif // LAST_MINUTE_HACK
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
idPhysics_Actor::DetermineRotationVector
|
||||
|
||||
HUMANHEAD: aob
|
||||
=============
|
||||
*/
|
||||
idVec3 idPhysics_Actor::DetermineRotationVector( const idVec3& upVector, const idVec3& idealUpVector, const idVec3& checkOrigin ) {
|
||||
idVec3 rotationVector = idealUpVector.Cross( upVector );
|
||||
if( rotationVector.LengthSqr() <= VECTOR_EPSILON ) {
|
||||
BuildRotationTraceDirectionTable( self->GetAxis() );//Actors return viewAxis and plain entities return physics axis
|
||||
|
||||
for( int iIndex = 0; iIndex < c_iNumRotationTraces; ++iIndex ) {
|
||||
if( DirectionIsClear(checkOrigin, rotationTraceDirectionTable[iIndex]) ) {
|
||||
rotationVector = rotationTraceDirectionTable[iIndex];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rotationVector.Normalize();
|
||||
|
||||
return rotationVector;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
idPhysics_Actor::DirectionIsClear
|
||||
|
||||
HUMANHEAD: aob
|
||||
=============
|
||||
*/
|
||||
#define ROTATION_TRACE_DISTANCE ((pm_bboxwidth.GetFloat() * 0.5f) + 10.0f)
|
||||
bool idPhysics_Actor::DirectionIsClear( const idVec3& checkOrigin, const idVec3& direction ) {
|
||||
trace_t traceInfo;
|
||||
|
||||
gameLocal.clip.TracePoint( traceInfo, checkOrigin, checkOrigin + direction * ROTATION_TRACE_DISTANCE, clipMask, self );
|
||||
|
||||
return (traceInfo.fraction == 1.0f);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
idPhysics_Actor::BuildRotationTraceDirectionTable
|
||||
|
||||
HUMANHEAD: aob
|
||||
=============
|
||||
*/
|
||||
void idPhysics_Actor::BuildRotationTraceDirectionTable( const idMat3& Axis ) {
|
||||
rotationTraceDirectionTable[0] = Axis[0];
|
||||
rotationTraceDirectionTable[1] = -Axis[0];
|
||||
rotationTraceDirectionTable[2] = Axis[1];
|
||||
rotationTraceDirectionTable[3] = -Axis[1];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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.
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
//HUMANHEAD
|
||||
#define MAXTOUCH 32
|
||||
const int c_iNumRotationTraces = 4;
|
||||
//HUMANHEAD END
|
||||
|
||||
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 );
|
||||
|
||||
//HUMANHEAD nla
|
||||
int GetNumTouchEnts( void ) const;
|
||||
int GetTouchEnt( int i ) const;
|
||||
void ResetNumTouchEnt( int i );
|
||||
// HUMANHEAD END
|
||||
|
||||
//HUMANHEAD: aob - added
|
||||
const trace_t& GetGroundTrace() const { return groundTrace; }
|
||||
virtual const idMaterial* GetGroundMaterial() const { if(!HasGroundContacts()) return NULL; return groundTrace.c.material; } // JRM - return NULL if no gc's
|
||||
surfTypes_t GetGroundMatterType() const { return gameLocal.GetMatterType(groundTrace); }
|
||||
const int GetGroundSurfaceFlags() const { const idMaterial* mat = GetGroundMaterial(); if( mat ) { return mat->GetSurfaceFlags(); } else { return 0; } }
|
||||
bool HadGroundContacts() const;
|
||||
virtual void HadGroundContacts( const bool hadGroundContacts );
|
||||
//HUMANHEAD END
|
||||
|
||||
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;
|
||||
|
||||
virtual // HUMANHEAD jsh made virtual
|
||||
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;
|
||||
|
||||
//HUMANHEAD: aob
|
||||
trace_t groundTrace;
|
||||
//HUMANHEAD END
|
||||
|
||||
//HUMANHEAD nla
|
||||
// entities touched during last evaluate
|
||||
int numTouch;
|
||||
int touchEnts[MAXTOUCH];
|
||||
void AddTouchEnt( int entityNum );
|
||||
void AddTouchEntList( idList<int> &list );
|
||||
|
||||
bool hadGroundContacts;
|
||||
|
||||
idVec3 rotationTraceDirectionTable[ c_iNumRotationTraces ];
|
||||
// HUMANHEAD END
|
||||
|
||||
// results of last evaluate
|
||||
idEntityPtr<idEntity> groundEntityPtr;
|
||||
|
||||
//HUMANHEAD: aob
|
||||
protected:
|
||||
virtual bool IterativeRotateMove( const idVec3& upVector, const idVec3& idealUpVector, const idVec3& rotationOrigin, const idVec3& rotationCheckOrigin, int numIterations );
|
||||
idVec3 DetermineRotationVector( const idVec3& upVector, const idVec3& idealUpVector, const idVec3& rotationOrigin );
|
||||
bool DirectionIsClear( const idVec3& checkOrigin, const idVec3& direction );
|
||||
void BuildRotationTraceDirectionTable( const idMat3& Axis );
|
||||
//HUMANHEAD END
|
||||
};
|
||||
|
||||
#endif /* !__PHYSICS_ACTOR_H__ */
|
||||
@@ -0,0 +1,844 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#include "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::HasContacts
|
||||
|
||||
HUMANHEAD: aob
|
||||
================
|
||||
*/
|
||||
bool idPhysics_Base::HasContacts( void ) const {
|
||||
return contacts.Num() > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idPhysics_Base::GetGroundContactNormal
|
||||
|
||||
HUMANHEAD: aob
|
||||
================
|
||||
*/
|
||||
idVec3 idPhysics_Base::GetGroundContactNormal() const {
|
||||
idVec3 contactNormal;
|
||||
|
||||
// HUMANHEAD PCF pdm 05-10-06: Bugfix from Venom, Initialize before use
|
||||
contactNormal.Zero();
|
||||
|
||||
for( int ix = contacts.Num() - 1; ix >= 0; --ix ) {
|
||||
contactNormal += contacts[ix].normal;
|
||||
}
|
||||
contactNormal.Normalize();
|
||||
|
||||
return contactNormal;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
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 ) {
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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;
|
||||
|
||||
//HUMANHEAD: aob
|
||||
bool HasContacts( void ) const;
|
||||
idVec3 GetGroundContactNormal() const;
|
||||
//HUMANHEAD END
|
||||
|
||||
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__ */
|
||||
@@ -0,0 +1,809 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
|
||||
CLASS_DECLARATION( idPhysics_Actor, idPhysics_Monster )
|
||||
END_CLASS
|
||||
|
||||
// HUMANHEAD PDM: This now declared in physics_player.h, so not needed here
|
||||
//const float OVERCLIP = 1.001f;
|
||||
|
||||
/*
|
||||
=====================
|
||||
idPhysics_Monster::CheckGround
|
||||
=====================
|
||||
*/
|
||||
void idPhysics_Monster::CheckGround( monsterPState_t &state ) {
|
||||
// HUMANHEAD aob: groundTrace is now stored on object
|
||||
// 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, idList<int> *touched ) {
|
||||
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;
|
||||
idList<int> noStepEntities, stepEntities; // HUMANHEAD nla
|
||||
|
||||
if ( delta == vec3_origin ) {
|
||||
return MM_OK;
|
||||
}
|
||||
|
||||
// try to move without stepping up
|
||||
noStepPos = start;
|
||||
noStepVel = velocity;
|
||||
result1 = SlideMove( noStepPos, noStepVel, delta, &noStepEntities );
|
||||
if ( result1 == MM_OK ) {
|
||||
AddTouchEntList( noStepEntities ); // HUMANHEAD nla
|
||||
velocity = noStepVel;
|
||||
if ( gravityNormal == vec3_zero ) {
|
||||
start = noStepPos;
|
||||
return MM_OK;
|
||||
}
|
||||
|
||||
//! Check block below for requirment of any touch entities
|
||||
// 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 ) {
|
||||
AddTouchEntList( noStepEntities ); // HUMANHEAD nla
|
||||
start = noStepPos;
|
||||
velocity = noStepVel;
|
||||
return result1;
|
||||
}
|
||||
|
||||
//HUMANHEAD nla - Add the entity touched
|
||||
if (tr.fraction < 1.0f) {
|
||||
stepEntities.Append( tr.c.entityNum );
|
||||
}
|
||||
|
||||
// try to move at the stepped up position
|
||||
stepPos = tr.endpos;
|
||||
stepVel = velocity;
|
||||
result2 = SlideMove( stepPos, stepVel, delta );
|
||||
if ( result2 == MM_BLOCKED ) {
|
||||
AddTouchEntList( noStepEntities ); // HUMANHEAD nla
|
||||
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;
|
||||
|
||||
//HUMANHEAD nla - Add the entity touched
|
||||
if (tr.fraction < 1.0f) {
|
||||
stepEntities.Append( tr.c.entityNum );
|
||||
}
|
||||
|
||||
// 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 ) ) {
|
||||
AddTouchEntList( noStepEntities ); // HUMANHEAD nla
|
||||
start = noStepPos;
|
||||
velocity = noStepVel;
|
||||
return MM_SLIDING;
|
||||
}
|
||||
|
||||
AddTouchEntList( stepEntities ); // HUMANHEAD nla
|
||||
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( ¤t, 0, sizeof( current ) );
|
||||
current.atRest = -1;
|
||||
saved = current;
|
||||
|
||||
delta.Zero();
|
||||
maxStepHeight = 22.0f; // JRM CHANGED FROM 18
|
||||
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
|
||||
================
|
||||
*/
|
||||
// HUMANHEAD AOB: PERSISTANT NOTIFY
|
||||
bool idPhysics_Monster::Evaluate( int timeStepMSec, int endTimeMSec ) {
|
||||
PROFILE_SCOPE("Monster", PROFMASK_PHYSICS);
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HUMANHEAD pdm: weren't implemented before, just stubbed out
|
||||
void idPhysics_Monster::SetMinFloorCosine( const float newMinFloorCosine ) {
|
||||
minFloorCosine = newMinFloorCosine;
|
||||
}
|
||||
// HUMANHEAD END
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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 );
|
||||
idVec3 GetDelta(void) const {return delta;} // HUMANHEAD JRM
|
||||
// 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 );
|
||||
|
||||
protected://HUMANHEAD: aob
|
||||
// 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;
|
||||
|
||||
protected://HUMANHEAD: aob
|
||||
void CheckGround( monsterPState_t &state );
|
||||
virtual//HUMANHEAD: aob
|
||||
monsterMoveResult_t SlideMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta, idList<int> *touched = NULL );
|
||||
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
@@ -0,0 +1,160 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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
|
||||
// HUMANHEAD mdl: Added these for accumulating spline angle changes. They are NULL when splines are inactive.
|
||||
idAngles * lastSplineAngles; // If not NULL, The spline angles from the last Evaluate() call
|
||||
idMat3 * deltaSplineAngles; // If not NULL, the difference between current.angle and the initial spline angles when SetSpline is called.
|
||||
idMat3 * deltaSplineAnglesInverse; // If not NULL, deltaSplineAngles.Inverse()
|
||||
// HUMANHEAD END
|
||||
} 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;
|
||||
|
||||
//HUMANHEAD: aob
|
||||
const idAngles &GetCurrentAngularSpeed( int id = 0 ) const;
|
||||
//HUMANHEAD END
|
||||
|
||||
void WriteToSnapshot( idBitMsgDelta &msg ) const;
|
||||
void ReadFromSnapshot( const idBitMsgDelta &msg );
|
||||
|
||||
protected: // HUMANHEAD nla
|
||||
// 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
@@ -0,0 +1,220 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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.
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
//HUMANHEAD START: All these moved here from physics_player.cpp
|
||||
// movement parameters
|
||||
const float PM_STOPSPEED = 100.0f;
|
||||
const float PM_SWIMSCALE = 0.5f;
|
||||
const float PM_LADDERSPEED = 100.0f;
|
||||
const float PM_STEPSCALE = 1.0f;
|
||||
|
||||
const float PM_ACCELERATE = 10.0f;
|
||||
const float PM_AIRACCELERATE = 1.0f;
|
||||
const float PM_WATERACCELERATE = 4.0f;
|
||||
const float PM_FLYACCELERATE = 8.0f;
|
||||
|
||||
const float PM_FRICTION = 6.0f;
|
||||
const float PM_AIRFRICTION = 0.0f;
|
||||
const float PM_WATERFRICTION = 1.0f;
|
||||
const float PM_FLYFRICTION = 3.0f;
|
||||
const float PM_NOCLIPFRICTION = 12.0f;
|
||||
|
||||
const float MIN_WALK_NORMAL = 0.7f; // can't walk on very steep slopes
|
||||
const float OVERCLIP = 1.001f;
|
||||
|
||||
// movementFlags
|
||||
const int PMF_DUCKED = 1; // set when ducking
|
||||
const int PMF_JUMPED = 2; // set when the player jumped this frame
|
||||
const int PMF_STEPPED_UP = 4; // set when the player stepped up this frame
|
||||
const int PMF_STEPPED_DOWN = 8; // set when the player stepped down this frame
|
||||
const int PMF_JUMP_HELD = 16; // set when jump button is held down
|
||||
const int PMF_TIME_LAND = 32; // movementTime is time before rejump
|
||||
const int PMF_TIME_KNOCKBACK = 64; // movementTime is an air-accelerate only time
|
||||
const int PMF_TIME_WATERJUMP = 128; // movementTime is waterjump
|
||||
const int PMF_ALL_TIMES = (PMF_TIME_WATERJUMP|PMF_TIME_LAND|PMF_TIME_KNOCKBACK);
|
||||
//HUMANHEAD END
|
||||
|
||||
// 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;
|
||||
|
||||
typedef struct playerPState_s {
|
||||
idVec3 origin;
|
||||
|
||||
//HUMANHEAD: aob - needed for saving state and vehicles
|
||||
idMat3 axis;
|
||||
idMat3 localAxis;
|
||||
//HUMANHEAD END
|
||||
|
||||
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 );
|
||||
virtual //HUMANHEAD: Made virtual
|
||||
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;
|
||||
|
||||
virtual //HUMANHEAD: Made virtual
|
||||
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 );
|
||||
|
||||
protected: //HUMANHEAD
|
||||
// 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;
|
||||
//HUMANHEAD: aob - moved to idPhysics_Actor
|
||||
// trace_t groundTrace;
|
||||
//HUMANHEAD END
|
||||
const idMaterial * groundMaterial;
|
||||
|
||||
// ladder movement
|
||||
bool ladder;
|
||||
idVec3 ladderNormal;
|
||||
|
||||
// results of last evaluate
|
||||
waterLevel_t waterLevel;
|
||||
int waterType;
|
||||
|
||||
idVec3 wishdir; //HUMANHEAD
|
||||
|
||||
protected://HUMANHEAD
|
||||
// HUMANHEAD
|
||||
virtual idVec3 DetermineJumpVelocity();
|
||||
// HUMANHEAD END
|
||||
|
||||
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 );
|
||||
virtual //HUMANHEAD: Made virtual
|
||||
void AirMove( void );
|
||||
virtual //HUMANHEAD: Made virtual
|
||||
void WalkMove( void );
|
||||
void DeadMove( void );
|
||||
void NoclipMove( void );
|
||||
void SpectatorMove( void );
|
||||
void LadderMove( void );
|
||||
void CorrectAllSolid( trace_t &trace, int contents );
|
||||
virtual //HUMANHEAD: Made virtual
|
||||
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
@@ -0,0 +1,122 @@
|
||||
#ifndef __HH_PHYSICS_PLAYER_H
|
||||
#define __HH_PHYSICS_PLAYER_H
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
hhPhysics_Player
|
||||
|
||||
**********************************************************************/
|
||||
const int c_iNumWallwalkTraces = 5;
|
||||
|
||||
class hhPhysics_Player: public idPhysics_Player
|
||||
{
|
||||
CLASS_PROTOTYPE( hhPhysics_Player );
|
||||
|
||||
public:
|
||||
hhPhysics_Player( void );
|
||||
|
||||
virtual bool Evaluate( int timeStepMSec, int endTimeMSec );
|
||||
|
||||
virtual void SetSelf( idEntity *e );
|
||||
|
||||
virtual void SaveState( void );
|
||||
virtual void RestoreState( void );
|
||||
|
||||
void WriteToSnapshot( idBitMsgDelta &msg, bool inVehicle ) const;
|
||||
void ReadFromSnapshot( const idBitMsgDelta &msg, bool inVehicle );
|
||||
|
||||
bool IsWallWalking() const { return isWallWalking; }
|
||||
bool WasWallWalking() const { return wasWallWalking; }
|
||||
void IsWallWalking( bool wallwalking ) { isWallWalking = wallwalking; }
|
||||
void WasWallWalking( bool wallwalking ) { wasWallWalking = wallwalking; }
|
||||
bool AlignedWithGravity() const;
|
||||
bool ShouldSlopeCheck() const { return bDoSlopeCheck && !isWallWalking; }
|
||||
void SetSlopeCheck( bool on ) { bDoSlopeCheck = on; }
|
||||
void SetInwardGravity(int inwardGravity); //rww
|
||||
bool IsInwardGravity() const { return iInwardGravity > 0; } //rww
|
||||
|
||||
virtual void ShouldRemainAlignedToAxial( const bool remainAligned );
|
||||
virtual bool ShouldRemainAlignedToAxial() const;
|
||||
virtual void OrientToGravity( bool orientToGravity );
|
||||
virtual bool OrientToGravity() const;
|
||||
|
||||
|
||||
virtual void Translate( const idVec3 &translation, int id = 0 );
|
||||
virtual void Rotate( const idRotation& rotation, int id = 0 );
|
||||
virtual const idVec3& GetOrigin( int id = 0 ) const;
|
||||
virtual const idMat3& GetAxis( int id = 0 ) const;
|
||||
virtual void SetOrigin( const idVec3 &newOrigin, int id = 0 );
|
||||
virtual void SetAxis( const idMat3 &newAxis, int id = 0 );
|
||||
virtual void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const;
|
||||
virtual void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const;
|
||||
virtual bool IsGroundEntity( int entityNum ) const;
|
||||
virtual bool IsGroundClipModel( int entityNum, int id = 0 ) const;
|
||||
virtual bool HasGroundContacts( void ) const;
|
||||
virtual bool ExtraGroundCheck(idClipModel *customClipModel = NULL); //HUMANHEAD rww
|
||||
virtual void AddGroundContacts( const idClipModel *clipModel );
|
||||
virtual bool EvaluateContacts( void );
|
||||
virtual void SetKnockBack( const int knockBackTime );
|
||||
|
||||
virtual void SetPushed( int deltaTime );
|
||||
|
||||
virtual void ForceMovedFrame(bool forceMoved) { bMoveNextFrame = forceMoved; } //HUMANHEAD rww
|
||||
|
||||
virtual void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse );
|
||||
|
||||
virtual bool WallWalkIsAllowed() const;
|
||||
void CheckWallWalk( bool bForce = false );
|
||||
virtual void CheckGround();
|
||||
|
||||
virtual const idMaterial* GetGroundMaterial() const { return groundMaterial; }
|
||||
|
||||
playerPState_t& GetPlayerState() { return current; }
|
||||
|
||||
virtual void ForceCrouching();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
protected:
|
||||
idVec3 ClipModelRotationOrigin;
|
||||
bool shouldRemainAlignedToAxial;
|
||||
bool orientToGravity;
|
||||
bool isWallWalking;
|
||||
bool wasWallWalking;
|
||||
idVec3 oldOrigin;
|
||||
idMat3 oldAxis;
|
||||
bool bDoSlopeCheck;
|
||||
int iInwardGravity; //rww - number of inward gravity zones player is in
|
||||
|
||||
//HUMANHEAD PCF rww 05/11/06 - hack fix for stuck bugs
|
||||
int stuckCount;
|
||||
idVec3 stuckOrigin;
|
||||
//HUMANHEAD END
|
||||
|
||||
hhCameraInterpolator* camera;
|
||||
hhPlayer* castSelf;
|
||||
idEntity* castSelfGeneric; //rww
|
||||
|
||||
idVec3 wallwalkTraceOriginTable[ c_iNumWallwalkTraces ];
|
||||
bool bMoveNextFrame; //HUMANHEAD rww
|
||||
|
||||
protected:
|
||||
void EvaluateOwnerCamera( const int timeStep );
|
||||
void SetOwnerCameraTarget( const idVec3& Origin, const idMat3& Axis, int iInterpFlags );
|
||||
void LinkClip( const idVec3& Origin, const idMat3& Axis );
|
||||
virtual idVec3 DetermineJumpVelocity();
|
||||
void BuildWallwalkTraceOriginTable( const idMat3& Axis );
|
||||
void PerformGroundTrace( trace_t& TraceInfo, const idVec3& Start );
|
||||
|
||||
bool EvaluateGroundTrace( const trace_t& TraceInfo );
|
||||
|
||||
virtual bool IterativeRotateMove( const idVec3& UpVector, const idVec3& IdealUpVector, const idVec3& RotationOrigin, const idVec3& RotationCheckOrigin, int iNumIterations );
|
||||
bool RotateMove( const idVec3& UpVector, const idVec3& IdealUpVector, const idVec3& RotationOrigin, const idVec3& RotationCheckOrigin );
|
||||
void TranslateMove( const idVec3& TranslationVector, const float fDist );
|
||||
|
||||
virtual void WalkMove();
|
||||
virtual void AirMove();
|
||||
|
||||
float GetContactEpsilon(void) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,179 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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 );
|
||||
|
||||
//HUMANHEAD: aob
|
||||
const idVec3& GetCenterOfMass() const { return centerOfMass; }
|
||||
|
||||
protected: // HUMANHEAD
|
||||
// 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;
|
||||
|
||||
protected: // HUMANHEAD
|
||||
friend void RigidBodyDerivatives( const float t, const void *clientData, const float *state, float *derivatives );
|
||||
virtual // HUMANHEAD: made virtual
|
||||
void Integrate( const float deltaTime, rigidBodyPState_t &next );
|
||||
virtual // HUMANHEAD: made virtual
|
||||
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 );
|
||||
// HUMANHEAD pdm: testing
|
||||
void TestForRotation(const char *text);
|
||||
// HUMANHEAD pdm: testing
|
||||
};
|
||||
|
||||
#endif /* !__PHYSICS_RIGIDBODY_H__ */
|
||||
@@ -0,0 +1,836 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#include "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 ) {
|
||||
PROFILE_SCOPE("Static", PROFMASK_PHYSICS);
|
||||
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 );
|
||||
}
|
||||
|
||||
// HUMANHEAD pdm: Statics occasionally get physics activated by things binding to them.
|
||||
// Allow this, but immediately become inactive again since we can't move unless bound to something else.
|
||||
if (self->IsActive(TH_PHYSICS)) {
|
||||
self->BecomeInactive( TH_PHYSICS );
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
//HUMANHEAD rww
|
||||
/*
|
||||
================
|
||||
idPhysics_Static::GetPState
|
||||
================
|
||||
*/
|
||||
staticPState_t *idPhysics_Static::GetPState(void) {
|
||||
return ¤t;
|
||||
}
|
||||
//HUMANHEAD END
|
||||
@@ -0,0 +1,136 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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 );
|
||||
|
||||
//HUMANHEAD rww - sorry, need access for snapshot code (better than making multiple snapshot functions)
|
||||
virtual staticPState_t *GetPState(void);
|
||||
//HUMANHEAD END
|
||||
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
@@ -0,0 +1,129 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,91 @@
|
||||
// Copyright (C) 2004 Id Software, Inc.
|
||||
//
|
||||
|
||||
#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
|
||||
// HUMANHEAD nla - Used to fix ragdolls colliding with movers when on them.
|
||||
#define PUSHFL_UNBLOCKABLE 128 // can not be blocked
|
||||
// HUMANHEAD END
|
||||
|
||||
//#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__ */
|
||||
Reference in New Issue
Block a user