1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #ifndef __COLLISIONMODELMANAGER_H__
30 #define __COLLISIONMODELMANAGER_H__
31 
32 #include "idlib/geometry/TraceModel.h"
33 #include "idlib/math/Vector.h"
34 #include "idlib/math/Matrix.h"
35 #include "idlib/bv/Bounds.h"
36 #include "idlib/MapFile.h"
37 
38 class idMaterial;
39 
40 /*
41 ===============================================================================
42 
43 	Trace model vs. polygonal model collision detection.
44 
45 	Short translations are the least expensive. Retrieving contact points is
46 	about as cheap as a short translation. Position tests are more expensive
47 	and rotations are most expensive.
48 
49 	There is no position test at the start of a translation or rotation. In other
50 	words if a translation with start != end or a rotation with angle != 0 starts
51 	in solid, this goes unnoticed and the collision result is undefined.
52 
53 	A translation with start == end or a rotation with angle == 0 performs
54 	a position test and fills in the trace_t structure accordingly.
55 
56 ===============================================================================
57 */
58 
59 // contact type
60 typedef enum {
61 	CONTACT_NONE,							// no contact
62 	CONTACT_EDGE,							// trace model edge hits model edge
63 	CONTACT_MODELVERTEX,					// model vertex hits trace model polygon
64 	CONTACT_TRMVERTEX						// trace model vertex hits model polygon
65 } contactType_t;
66 
67 // contact info
68 typedef struct {
69 	contactType_t			type;			// contact type
70 	idVec3					point;			// point of contact
71 	idVec3					normal;			// contact plane normal
72 	float					dist;			// contact plane distance
73 	int						contents;		// contents at other side of surface
74 	const idMaterial *		material;		// surface material
75 	int						modelFeature;	// contact feature on model
76 	int						trmFeature;		// contact feature on trace model
77 	int						entityNum;		// entity the contact surface is a part of
78 	int						id;				// id of clip model the contact surface is part of
79 } contactInfo_t;
80 
81 // trace result
82 typedef struct trace_s {
83 	float					fraction;		// fraction of movement completed, 1.0 = didn't hit anything
84 	idVec3					endpos;			// final position of trace model
85 	idMat3					endAxis;		// final axis of trace model
86 	contactInfo_t			c;				// contact information, only valid if fraction < 1.0
87 } trace_t;
88 
89 typedef int cmHandle_t;
90 
91 #define CM_CLIP_EPSILON		0.25f			// always stay this distance away from any model
92 #define CM_BOX_EPSILON		1.0f			// should always be larger than clip epsilon
93 #define CM_MAX_TRACE_DIST	4096.0f			// maximum distance a trace model may be traced, point traces are unlimited
94 
95 class idCollisionModelManager {
96 public:
~idCollisionModelManager(void)97 	virtual					~idCollisionModelManager( void ) {}
98 
99 	// Loads collision models from a map file.
100 	virtual void			LoadMap( const idMapFile *mapFile ) = 0;
101 	// Frees all the collision models.
102 	virtual void			FreeMap( void ) = 0;
103 
104 	// Gets the clip handle for a model.
105 	virtual cmHandle_t		LoadModel( const char *modelName, const bool precache ) = 0;
106 	// Sets up a trace model for collision with other trace models.
107 	virtual cmHandle_t		SetupTrmModel( const idTraceModel &trm, const idMaterial *material ) = 0;
108 	// Creates a trace model from a collision model, returns true if succesfull.
109 	virtual bool			TrmFromModel( const char *modelName, idTraceModel &trm ) = 0;
110 
111 	// Gets the name of a model.
112 	virtual const char *	GetModelName( cmHandle_t model ) const = 0;
113 	// Gets the bounds of a model.
114 	virtual bool			GetModelBounds( cmHandle_t model, idBounds &bounds ) const = 0;
115 	// Gets all contents flags of brushes and polygons of a model ored together.
116 	virtual bool			GetModelContents( cmHandle_t model, int &contents ) const = 0;
117 	// Gets a vertex of a model.
118 	virtual bool			GetModelVertex( cmHandle_t model, int vertexNum, idVec3 &vertex ) const = 0;
119 	// Gets an edge of a model.
120 	virtual bool			GetModelEdge( cmHandle_t model, int edgeNum, idVec3 &start, idVec3 &end ) const = 0;
121 	// Gets a polygon of a model.
122 	virtual bool			GetModelPolygon( cmHandle_t model, int polygonNum, idFixedWinding &winding ) const = 0;
123 
124 	// Translates a trace model and reports the first collision if any.
125 	virtual void			Translation( trace_t *results, const idVec3 &start, const idVec3 &end,
126 								const idTraceModel *trm, const idMat3 &trmAxis, int contentMask,
127 								cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0;
128 	// Rotates a trace model and reports the first collision if any.
129 	virtual void			Rotation( trace_t *results, const idVec3 &start, const idRotation &rotation,
130 								const idTraceModel *trm, const idMat3 &trmAxis, int contentMask,
131 								cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0;
132 	// Returns the contents touched by the trace model or 0 if the trace model is in free space.
133 	virtual int				Contents( const idVec3 &start,
134 								const idTraceModel *trm, const idMat3 &trmAxis, int contentMask,
135 								cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0;
136 	// Stores all contact points of the trace model with the model, returns the number of contacts.
137 	virtual int				Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
138 								const idTraceModel *trm, const idMat3 &trmAxis, int contentMask,
139 								cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0;
140 
141 	// Tests collision detection.
142 	virtual void			DebugOutput( const idVec3 &origin ) = 0;
143 	// Draws a model.
144 	virtual void			DrawModel( cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis,
145 												const idVec3 &viewOrigin, const float radius ) = 0;
146 	// Prints model information, use -1 handle for accumulated model info.
147 	virtual void			ModelInfo( cmHandle_t model ) = 0;
148 	// Lists all loaded models.
149 	virtual void			ListModels( void ) = 0;
150 	// Writes a collision model file for the given map entity.
151 	virtual bool			WriteCollisionModelForMapEntity( const idMapEntity *mapEnt, const char *filename, const bool testTraceModel = true ) = 0;
152 };
153 
154 extern idCollisionModelManager *		collisionModelManager;
155 
156 #endif /* !__COLLISIONMODELMANAGER_H__ */
157