mirror of
https://github.com/dhewm/dhewm3.git
synced 2024-12-11 21:40:49 +00:00
736ec20d4d
Don't include the lazy precompiled.h everywhere, only what's required for the compilation unit. platform.h needs to be included instead to provide all essential defines and types. All includes use the relative path to the neo or the game specific root. Move all idlib related includes from idlib/Lib.h to precompiled.h. precompiled.h still exists for the MFC stuff in tools/. Add some missing header guards.
357 lines
14 KiB
C++
357 lines
14 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 GPL Source Code
|
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
|
|
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#ifndef __CLIP_H__
|
|
#define __CLIP_H__
|
|
|
|
#include "idlib/geometry/TraceModel.h"
|
|
#include "cm/CollisionModel.h"
|
|
|
|
class idSaveGame;
|
|
class idRestoreGame;
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
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 idEntity;
|
|
|
|
|
|
//===============================================================
|
|
//
|
|
// idClipModel
|
|
//
|
|
//===============================================================
|
|
|
|
class idClipModel {
|
|
|
|
friend class idClip;
|
|
|
|
public:
|
|
idClipModel( void );
|
|
explicit idClipModel( const char *name );
|
|
explicit idClipModel( const idTraceModel &trm );
|
|
explicit idClipModel( const int renderModelHandle );
|
|
explicit idClipModel( const idClipModel *model );
|
|
~idClipModel( void );
|
|
|
|
bool LoadModel( const char *name );
|
|
void LoadModel( const idTraceModel &trm );
|
|
void LoadModel( const int renderModelHandle );
|
|
|
|
void Save( idSaveGame *savefile ) const;
|
|
void Restore( idRestoreGame *savefile );
|
|
|
|
void Link( idClip &clp ); // must have been linked with an entity and id before
|
|
void Link( idClip &clp, idEntity *ent, int newId, const idVec3 &newOrigin, const idMat3 &newAxis, int renderModelHandle = -1 );
|
|
void Unlink( void ); // unlink from sectors
|
|
void SetPosition( const idVec3 &newOrigin, const idMat3 &newAxis ); // unlinks the clip model
|
|
void Translate( const idVec3 &translation ); // unlinks the clip model
|
|
void Rotate( const idRotation &rotation ); // unlinks the clip model
|
|
void Enable( void ); // enable for clipping
|
|
void Disable( void ); // keep linked but disable for clipping
|
|
void SetMaterial( const idMaterial *m );
|
|
const idMaterial * GetMaterial( void ) const;
|
|
void SetContents( int newContents ); // override contents
|
|
int GetContents( void ) const;
|
|
void SetEntity( idEntity *newEntity );
|
|
idEntity * GetEntity( void ) const;
|
|
void SetId( int newId );
|
|
int GetId( void ) const;
|
|
void SetOwner( idEntity *newOwner );
|
|
idEntity * GetOwner( void ) const;
|
|
const idBounds & GetBounds( void ) const;
|
|
const idBounds & GetAbsBounds( void ) const;
|
|
const idVec3 & GetOrigin( void ) const;
|
|
const idMat3 & GetAxis( void ) const;
|
|
bool IsTraceModel( void ) const; // returns true if this is a trace model
|
|
bool IsRenderModel( void ) const; // returns true if this is a render model
|
|
bool IsLinked( void ) const; // returns true if the clip model is linked
|
|
bool IsEnabled( void ) const; // returns true if enabled for collision detection
|
|
bool IsEqual( const idTraceModel &trm ) const;
|
|
cmHandle_t Handle( void ) const; // returns handle used to collide vs this model
|
|
const idTraceModel * GetTraceModel( void ) const;
|
|
void GetMassProperties( const float density, float &mass, idVec3 ¢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
|
|
idEntity * entity; // entity using this clip model
|
|
int id; // id for entities that use multiple clip models
|
|
idEntity * owner; // owner of the entity that owns this clip model
|
|
idVec3 origin; // origin of clip model
|
|
idMat3 axis; // orientation of clip model
|
|
idBounds bounds; // bounds
|
|
idBounds absBounds; // absolute bounds
|
|
const idMaterial * material; // material for trace models
|
|
int contents; // all contents ored together
|
|
cmHandle_t collisionModelHandle; // handle to collision model
|
|
int traceModelIndex; // trace model used for collision detection
|
|
int renderModelHandle; // render model def handle
|
|
|
|
struct clipLink_s * clipLinks; // links into sectors
|
|
int touchCount;
|
|
|
|
void Init( void ); // initialize
|
|
void Link_r( struct clipSector_s *node );
|
|
|
|
static int AllocTraceModel( const idTraceModel &trm );
|
|
static void FreeTraceModel( int traceModelIndex );
|
|
static idTraceModel * GetCachedTraceModel( int traceModelIndex );
|
|
static int GetTraceModelHashKey( const idTraceModel &trm );
|
|
};
|
|
|
|
|
|
ID_INLINE void idClipModel::Translate( const idVec3 &translation ) {
|
|
Unlink();
|
|
origin += translation;
|
|
}
|
|
|
|
ID_INLINE void idClipModel::Rotate( const idRotation &rotation ) {
|
|
Unlink();
|
|
origin *= rotation;
|
|
axis *= rotation.ToMat3();
|
|
}
|
|
|
|
ID_INLINE void idClipModel::Enable( void ) {
|
|
enabled = true;
|
|
}
|
|
|
|
ID_INLINE void idClipModel::Disable( void ) {
|
|
enabled = false;
|
|
}
|
|
|
|
ID_INLINE void idClipModel::SetMaterial( const idMaterial *m ) {
|
|
material = m;
|
|
}
|
|
|
|
ID_INLINE const idMaterial * idClipModel::GetMaterial( void ) const {
|
|
return material;
|
|
}
|
|
|
|
ID_INLINE void idClipModel::SetContents( int newContents ) {
|
|
contents = newContents;
|
|
}
|
|
|
|
ID_INLINE int idClipModel::GetContents( void ) const {
|
|
return contents;
|
|
}
|
|
|
|
ID_INLINE void idClipModel::SetEntity( idEntity *newEntity ) {
|
|
entity = newEntity;
|
|
}
|
|
|
|
ID_INLINE idEntity *idClipModel::GetEntity( void ) const {
|
|
return entity;
|
|
}
|
|
|
|
ID_INLINE void idClipModel::SetId( int newId ) {
|
|
id = newId;
|
|
}
|
|
|
|
ID_INLINE int idClipModel::GetId( void ) const {
|
|
return id;
|
|
}
|
|
|
|
ID_INLINE void idClipModel::SetOwner( idEntity *newOwner ) {
|
|
owner = newOwner;
|
|
}
|
|
|
|
ID_INLINE idEntity *idClipModel::GetOwner( void ) const {
|
|
return owner;
|
|
}
|
|
|
|
ID_INLINE const idBounds &idClipModel::GetBounds( void ) const {
|
|
return bounds;
|
|
}
|
|
|
|
ID_INLINE const idBounds &idClipModel::GetAbsBounds( void ) const {
|
|
return absBounds;
|
|
}
|
|
|
|
ID_INLINE const idVec3 &idClipModel::GetOrigin( void ) const {
|
|
return origin;
|
|
}
|
|
|
|
ID_INLINE const idMat3 &idClipModel::GetAxis( void ) const {
|
|
return axis;
|
|
}
|
|
|
|
ID_INLINE bool idClipModel::IsRenderModel( void ) const {
|
|
return ( renderModelHandle != -1 );
|
|
}
|
|
|
|
ID_INLINE bool idClipModel::IsTraceModel( void ) const {
|
|
return ( traceModelIndex != -1 );
|
|
}
|
|
|
|
ID_INLINE bool idClipModel::IsLinked( void ) const {
|
|
return ( clipLinks != NULL );
|
|
}
|
|
|
|
ID_INLINE bool idClipModel::IsEnabled( void ) const {
|
|
return enabled;
|
|
}
|
|
|
|
ID_INLINE bool idClipModel::IsEqual( const idTraceModel &trm ) const {
|
|
return ( traceModelIndex != -1 && *GetCachedTraceModel( traceModelIndex ) == trm );
|
|
}
|
|
|
|
ID_INLINE const idTraceModel *idClipModel::GetTraceModel( void ) const {
|
|
if ( !IsTraceModel() ) {
|
|
return NULL;
|
|
}
|
|
return idClipModel::GetCachedTraceModel( traceModelIndex );
|
|
}
|
|
|
|
|
|
//===============================================================
|
|
//
|
|
// idClip
|
|
//
|
|
//===============================================================
|
|
|
|
class idClip {
|
|
|
|
friend class idClipModel;
|
|
|
|
public:
|
|
idClip( void );
|
|
|
|
void Init( void );
|
|
void Shutdown( void );
|
|
|
|
// clip versus the rest of the world
|
|
bool Translation( trace_t &results, const idVec3 &start, const idVec3 &end,
|
|
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
|
|
bool Rotation( trace_t &results, const idVec3 &start, const idRotation &rotation,
|
|
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
|
|
bool Motion( trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation,
|
|
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
|
|
int Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
|
|
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
|
|
int Contents( const idVec3 &start,
|
|
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
|
|
|
|
// special case translations versus the rest of the world
|
|
bool TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end,
|
|
int contentMask, const idEntity *passEntity );
|
|
bool TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds,
|
|
int contentMask, const idEntity *passEntity );
|
|
|
|
// clip versus a specific model
|
|
void TranslationModel( trace_t &results, const idVec3 &start, const idVec3 &end,
|
|
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
|
|
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
|
|
void RotationModel( trace_t &results, const idVec3 &start, const idRotation &rotation,
|
|
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
|
|
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
|
|
int ContactsModel( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
|
|
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
|
|
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
|
|
int ContentsModel( const idVec3 &start,
|
|
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
|
|
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
|
|
|
|
// clip versus all entities but not the world
|
|
void TranslationEntities( trace_t &results, const idVec3 &start, const idVec3 &end,
|
|
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
|
|
|
|
// get a contact feature
|
|
bool GetModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding ) const;
|
|
|
|
// get entities/clip models within or touching the given bounds
|
|
int EntitiesTouchingBounds( const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount ) const;
|
|
int ClipModelsTouchingBounds( const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount ) const;
|
|
|
|
const idBounds & GetWorldBounds( void ) const;
|
|
idClipModel * DefaultClipModel( void );
|
|
|
|
// stats and debug drawing
|
|
void PrintStatistics( void );
|
|
void DrawClipModels( const idVec3 &eye, const float radius, const idEntity *passEntity );
|
|
bool DrawModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, int lifetime ) const;
|
|
|
|
private:
|
|
int numClipSectors;
|
|
struct clipSector_s * clipSectors;
|
|
idBounds worldBounds;
|
|
idClipModel temporaryClipModel;
|
|
idClipModel defaultClipModel;
|
|
mutable int touchCount;
|
|
// statistics
|
|
int numTranslations;
|
|
int numRotations;
|
|
int numMotions;
|
|
int numRenderModelTraces;
|
|
int numContents;
|
|
int numContacts;
|
|
|
|
private:
|
|
struct clipSector_s * CreateClipSectors_r( const int depth, const idBounds &bounds, idVec3 &maxSector );
|
|
void ClipModelsTouchingBounds_r( const struct clipSector_s *node, struct listParms_s &parms ) const;
|
|
const idTraceModel * TraceModelForClipModel( const idClipModel *mdl ) const;
|
|
int GetTraceClipModels( const idBounds &bounds, int contentMask, const idEntity *passEntity, idClipModel **clipModelList ) const;
|
|
void TraceRenderModel( trace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, const idMat3 &axis, idClipModel *touch ) const;
|
|
};
|
|
|
|
|
|
ID_INLINE bool idClip::TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end, int contentMask, const idEntity *passEntity ) {
|
|
Translation( results, start, end, NULL, mat3_identity, contentMask, passEntity );
|
|
return ( results.fraction < 1.0f );
|
|
}
|
|
|
|
ID_INLINE bool idClip::TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, int contentMask, const idEntity *passEntity ) {
|
|
temporaryClipModel.LoadModel( idTraceModel( bounds ) );
|
|
Translation( results, start, end, &temporaryClipModel, mat3_identity, contentMask, passEntity );
|
|
return ( results.fraction < 1.0f );
|
|
}
|
|
|
|
ID_INLINE const idBounds & idClip::GetWorldBounds( void ) const {
|
|
return worldBounds;
|
|
}
|
|
|
|
ID_INLINE idClipModel *idClip::DefaultClipModel( void ) {
|
|
return &defaultClipModel;
|
|
}
|
|
|
|
#endif /* !__CLIP_H__ */
|