DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

Clip.h (13784B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition 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 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #ifndef __CLIP_H__
     30 #define __CLIP_H__
     31 
     32 /*
     33 ===============================================================================
     34 
     35   Handles collision detection with the world and between physics objects.
     36 
     37 ===============================================================================
     38 */
     39 
     40 #define CLIPMODEL_ID_TO_JOINT_HANDLE( id )	( ( id ) >= 0 ? INVALID_JOINT : ((jointHandle_t) ( -1 - id )) )
     41 #define JOINT_HANDLE_TO_CLIPMODEL_ID( id )	( -1 - id )
     42 
     43 class idClip;
     44 class idClipModel;
     45 class idEntity;
     46 
     47 //===============================================================
     48 //
     49 //	idClipModel
     50 //
     51 //===============================================================
     52 
     53 class idClipModel {
     54 
     55 	friend class idClip;
     56 
     57 public:
     58 							idClipModel();
     59 							explicit idClipModel( const char *name );
     60 							explicit idClipModel( const idTraceModel &trm );
     61 							explicit idClipModel( const idTraceModel &trm, bool persistantThroughSave );
     62 							explicit idClipModel( const int renderModelHandle );
     63 							explicit idClipModel( const idClipModel *model );
     64 							~idClipModel();
     65 
     66 	bool					LoadModel( const char *name );
     67 	void					LoadModel( const idTraceModel &trm, bool persistantThroughSave = true );
     68 	void					LoadModel( const int renderModelHandle );
     69 
     70 	void					Save( idSaveGame *savefile ) const;
     71 	void					Restore( idRestoreGame *savefile );
     72 
     73 	void					Link( idClip &clp );				// must have been linked with an entity and id before
     74 	void					Link( idClip &clp, idEntity *ent, int newId, const idVec3 &newOrigin, const idMat3 &newAxis, int renderModelHandle = -1 );
     75 	void					Unlink();						// unlink from sectors
     76 	void					SetPosition( const idVec3 &newOrigin, const idMat3 &newAxis );	// unlinks the clip model
     77 	void					Translate( const idVec3 &translation );							// unlinks the clip model
     78 	void					Rotate( const idRotation &rotation );							// unlinks the clip model
     79 	void					Enable();						// enable for clipping
     80 	void					Disable();					// keep linked but disable for clipping
     81 	void					SetMaterial( const idMaterial *m );
     82 	const idMaterial *		GetMaterial() const;
     83 	void					SetContents( int newContents );		// override contents
     84 	int						GetContents() const;
     85 	void					SetEntity( idEntity *newEntity );
     86 	idEntity *				GetEntity() const;
     87 	void					SetId( int newId );
     88 	int						GetId() const;
     89 	void					SetOwner( idEntity *newOwner );
     90 	idEntity *				GetOwner() const;
     91 	const idBounds &		GetBounds() const;
     92 	const idBounds &		GetAbsBounds() const;
     93 	const idVec3 &			GetOrigin() const;
     94 	const idMat3 &			GetAxis() const;
     95 	bool					IsTraceModel() const;			// returns true if this is a trace model
     96 	bool					IsRenderModel() const;		// returns true if this is a render model
     97 	bool					IsLinked() const;				// returns true if the clip model is linked
     98 	bool					IsEnabled() const;			// returns true if enabled for collision detection
     99 	bool					IsEqual( const idTraceModel &trm ) const;
    100 	cmHandle_t				Handle() const;				// returns handle used to collide vs this model
    101 	const idTraceModel *	GetTraceModel() const;
    102 	void					GetMassProperties( const float density, float &mass, idVec3 &centerOfMass, idMat3 &inertiaTensor ) const;
    103 
    104 	static cmHandle_t		CheckModel( const char *name );
    105 	static void				ClearTraceModelCache();
    106 	static int				TraceModelCacheSize();
    107 
    108 	static void				SaveTraceModels( idSaveGame *savefile );
    109 	static void				RestoreTraceModels( idRestoreGame *savefile );
    110 
    111 private:
    112 	bool					enabled;				// true if this clip model is used for clipping
    113 	idEntity *				entity;					// entity using this clip model
    114 	int						id;						// id for entities that use multiple clip models
    115 	idEntity *				owner;					// owner of the entity that owns this clip model
    116 	idVec3					origin;					// origin of clip model
    117 	idMat3					axis;					// orientation of clip model
    118 	idBounds				bounds;					// bounds
    119 	idBounds				absBounds;				// absolute bounds
    120 	const idMaterial *		material;				// material for trace models
    121 	int						contents;				// all contents ored together
    122 	cmHandle_t				collisionModelHandle;	// handle to collision model
    123 	int						traceModelIndex;		// trace model used for collision detection
    124 	int						renderModelHandle;		// render model def handle
    125 
    126 	struct clipLink_s *		clipLinks;				// links into sectors
    127 	int						touchCount;
    128 
    129 	void					Init();			// initialize
    130 	void					Link_r( struct clipSector_s *node );
    131 
    132 	static int				AllocTraceModel( const idTraceModel &trm, bool persistantThroughSaves = true );
    133 	static void				FreeTraceModel( int traceModelIndex );
    134 	static idTraceModel *	GetCachedTraceModel( int traceModelIndex );
    135 	static int				GetTraceModelHashKey( const idTraceModel &trm );
    136 	static struct trmCache_s *		GetTraceModelEntry( int traceModelIndex );
    137 };
    138 
    139 
    140 ID_INLINE void idClipModel::Translate( const idVec3 &translation ) {
    141 	Unlink();
    142 	origin += translation;
    143 }
    144 
    145 ID_INLINE void idClipModel::Rotate( const idRotation &rotation ) {
    146 	Unlink();
    147 	origin *= rotation;
    148 	axis *= rotation.ToMat3();
    149 }
    150 
    151 ID_INLINE void idClipModel::Enable() {
    152 	enabled = true;
    153 }
    154 
    155 ID_INLINE void idClipModel::Disable() {
    156 	enabled = false;
    157 }
    158 
    159 ID_INLINE void idClipModel::SetMaterial( const idMaterial *m ) {
    160 	material = m;
    161 }
    162 
    163 ID_INLINE const idMaterial * idClipModel::GetMaterial() const {
    164 	return material;
    165 }
    166 
    167 ID_INLINE void idClipModel::SetContents( int newContents ) {
    168 	contents = newContents;
    169 }
    170 
    171 ID_INLINE int idClipModel::GetContents() const {
    172 	return contents;
    173 }
    174 
    175 ID_INLINE void idClipModel::SetEntity( idEntity *newEntity ) {
    176 	entity = newEntity;
    177 }
    178 
    179 ID_INLINE idEntity *idClipModel::GetEntity() const {
    180 	return entity;
    181 }
    182 
    183 ID_INLINE void idClipModel::SetId( int newId ) {
    184 	id = newId;
    185 }
    186 
    187 ID_INLINE int idClipModel::GetId() const {
    188 	return id;
    189 }
    190 
    191 ID_INLINE void idClipModel::SetOwner( idEntity *newOwner ) {
    192 	owner = newOwner;
    193 }
    194 
    195 ID_INLINE idEntity *idClipModel::GetOwner() const {
    196 	return owner;
    197 }
    198 
    199 ID_INLINE const idBounds &idClipModel::GetBounds() const {
    200 	return bounds;
    201 }
    202 
    203 ID_INLINE const idBounds &idClipModel::GetAbsBounds() const {
    204 	return absBounds;
    205 }
    206 
    207 ID_INLINE const idVec3 &idClipModel::GetOrigin() const {
    208 	return origin;
    209 }
    210 
    211 ID_INLINE const idMat3 &idClipModel::GetAxis() const {
    212 	return axis;
    213 }
    214 
    215 ID_INLINE bool idClipModel::IsRenderModel() const {
    216 	return ( renderModelHandle != -1 );
    217 }
    218 
    219 ID_INLINE bool idClipModel::IsTraceModel() const {
    220 	return ( traceModelIndex != -1 );
    221 }
    222 
    223 ID_INLINE bool idClipModel::IsLinked() const {
    224 	return ( clipLinks != NULL );
    225 }
    226 
    227 ID_INLINE bool idClipModel::IsEnabled() const {
    228 	return enabled;
    229 }
    230 
    231 ID_INLINE bool idClipModel::IsEqual( const idTraceModel &trm ) const {
    232 	return ( traceModelIndex != -1 && *GetCachedTraceModel( traceModelIndex ) == trm );
    233 }
    234 
    235 ID_INLINE const idTraceModel *idClipModel::GetTraceModel() const {
    236 	if ( !IsTraceModel() ) {
    237 		return NULL;
    238 	}
    239 	return idClipModel::GetCachedTraceModel( traceModelIndex );
    240 }
    241 
    242 
    243 //===============================================================
    244 //
    245 //	idClip
    246 //
    247 //===============================================================
    248 
    249 class idClip {
    250 
    251 	friend class idClipModel;
    252 
    253 public:
    254 							idClip();
    255 
    256 	void					Init();
    257 	void					Shutdown();
    258 
    259 	// clip versus the rest of the world
    260 	bool					Translation( trace_t &results, const idVec3 &start, const idVec3 &end,
    261 								const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
    262 	bool					Rotation( trace_t &results, const idVec3 &start, const idRotation &rotation,
    263 								const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
    264 	bool					Motion( trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation,
    265 								const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
    266 	int						Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
    267 								const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
    268 	int						Contents( const idVec3 &start,
    269 								const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
    270 
    271 	// special case translations versus the rest of the world
    272 	bool					TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end,
    273 								int contentMask, const idEntity *passEntity );
    274 	bool					TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds,
    275 								int contentMask, const idEntity *passEntity );
    276 
    277 	// clip versus a specific model
    278 	void					TranslationModel( trace_t &results, const idVec3 &start, const idVec3 &end,
    279 								const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
    280 								cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
    281 	void					RotationModel( trace_t &results, const idVec3 &start, const idRotation &rotation,
    282 								const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
    283 								cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
    284 	int						ContactsModel( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
    285 								const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
    286 								cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
    287 	int						ContentsModel( const idVec3 &start,
    288 								const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
    289 								cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
    290 
    291 	// clip versus all entities but not the world
    292 	void					TranslationEntities( trace_t &results, const idVec3 &start, const idVec3 &end,
    293 								const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
    294 
    295 	// get a contact feature
    296 	bool					GetModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding ) const;
    297 
    298 	// get entities/clip models within or touching the given bounds
    299 	int						EntitiesTouchingBounds( const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount ) const;
    300 	int						ClipModelsTouchingBounds( const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount ) const;
    301 
    302 	const idBounds &		GetWorldBounds() const;
    303 	idClipModel *			DefaultClipModel();
    304 
    305 							// stats and debug drawing
    306 	void					PrintStatistics();
    307 	void					DrawClipModels( const idVec3 &eye, const float radius, const idEntity *passEntity );
    308 	bool					DrawModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, int lifetime ) const;
    309 
    310 private:
    311 	int						numClipSectors;
    312 	struct clipSector_s *	clipSectors;
    313 	idBounds				worldBounds;
    314 	idClipModel				temporaryClipModel;
    315 	idClipModel				defaultClipModel;
    316 	mutable int				touchCount;
    317 							// statistics
    318 	int						numTranslations;
    319 	int						numRotations;
    320 	int						numMotions;
    321 	int						numRenderModelTraces;
    322 	int						numContents;
    323 	int						numContacts;
    324 
    325 private:
    326 	struct clipSector_s *	CreateClipSectors_r( const int depth, const idBounds &bounds, idVec3 &maxSector );
    327 	void					ClipModelsTouchingBounds_r( const struct clipSector_s *node, struct listParms_s &parms ) const;
    328 	const idTraceModel *	TraceModelForClipModel( const idClipModel *mdl ) const;
    329 	int						GetTraceClipModels( const idBounds &bounds, int contentMask, const idEntity *passEntity, idClipModel **clipModelList ) const;
    330 	void					TraceRenderModel( trace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, const idMat3 &axis, idClipModel *touch ) const;
    331 };
    332 
    333 
    334 ID_INLINE bool idClip::TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end, int contentMask, const idEntity *passEntity ) {
    335 	Translation( results, start, end, NULL, mat3_identity, contentMask, passEntity );
    336 	return ( results.fraction < 1.0f );
    337 }
    338 
    339 ID_INLINE bool idClip::TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, int contentMask, const idEntity *passEntity ) {
    340 	temporaryClipModel.LoadModel( idTraceModel( bounds ) );
    341 	Translation( results, start, end, &temporaryClipModel, mat3_identity, contentMask, passEntity );
    342 	return ( results.fraction < 1.0f );
    343 }
    344 
    345 ID_INLINE const idBounds & idClip::GetWorldBounds() const {
    346 	return worldBounds;
    347 }
    348 
    349 ID_INLINE idClipModel *idClip::DefaultClipModel() {
    350 	return &defaultClipModel;
    351 }
    352 
    353 #endif /* !__CLIP_H__ */