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 __MAPFILE_H__
30 #define __MAPFILE_H__
31 
32 #include "idlib/geometry/Surface_Patch.h"
33 #include "idlib/math/Plane.h"
34 #include "idlib/Dict.h"
35 
36 /*
37 ===============================================================================
38 
39 	Reads or writes the contents of .map files into a standard internal
40 	format, which can then be moved into private formats for collision
41 	detection, map processing, or editor use.
42 
43 	No validation (duplicate planes, null area brushes, etc) is performed.
44 	There are no limits to the number of any of the elements in maps.
45 	The order of entities, brushes, and sides is maintained.
46 
47 ===============================================================================
48 */
49 
50 const int OLD_MAP_VERSION					= 1;
51 const int CURRENT_MAP_VERSION				= 2;
52 const int DEFAULT_CURVE_SUBDIVISION			= 4;
53 const float DEFAULT_CURVE_MAX_ERROR			= 4.0f;
54 const float DEFAULT_CURVE_MAX_ERROR_CD		= 24.0f;
55 const float DEFAULT_CURVE_MAX_LENGTH		= -1.0f;
56 const float DEFAULT_CURVE_MAX_LENGTH_CD		= -1.0f;
57 
58 
59 class idMapPrimitive {
60 public:
61 	enum { TYPE_INVALID = -1, TYPE_BRUSH, TYPE_PATCH };
62 
63 	idDict					epairs;
64 
idMapPrimitive(void)65 							idMapPrimitive( void ) { type = TYPE_INVALID; }
~idMapPrimitive(void)66 	virtual					~idMapPrimitive( void ) { }
GetType(void)67 	int						GetType( void ) const { return type; }
68 
69 protected:
70 	int						type;
71 };
72 
73 
74 class idMapBrushSide {
75 	friend class idMapBrush;
76 
77 public:
78 							idMapBrushSide( void );
~idMapBrushSide(void)79 							~idMapBrushSide( void ) { }
GetMaterial(void)80 	const char *			GetMaterial( void ) const { return material; }
SetMaterial(const char * p)81 	void					SetMaterial( const char *p ) { material = p; }
GetPlane(void)82 	const idPlane &			GetPlane( void ) const { return plane; }
SetPlane(const idPlane & p)83 	void					SetPlane( const idPlane &p ) { plane = p; }
SetTextureMatrix(const idVec3 mat[2])84 	void					SetTextureMatrix( const idVec3 mat[2] ) { texMat[0] = mat[0]; texMat[1] = mat[1]; }
GetTextureMatrix(idVec3 & mat1,idVec3 & mat2)85 	void					GetTextureMatrix( idVec3 &mat1, idVec3 &mat2 ) { mat1 = texMat[0]; mat2 = texMat[1]; }
86 	void					GetTextureVectors( idVec4 v[2] ) const;
87 
88 protected:
89 	idStr					material;
90 	idPlane					plane;
91 	idVec3					texMat[2];
92 	idVec3					origin;
93 };
94 
idMapBrushSide(void)95 ID_INLINE idMapBrushSide::idMapBrushSide( void ) {
96 	plane.Zero();
97 	texMat[0].Zero();
98 	texMat[1].Zero();
99 	origin.Zero();
100 }
101 
102 
103 class idMapBrush : public idMapPrimitive {
104 public:
idMapBrush(void)105 							idMapBrush( void ) { type = TYPE_BRUSH; sides.Resize( 8, 4 ); }
~idMapBrush(void)106 							~idMapBrush( void ) { sides.DeleteContents( true ); }
107 	static idMapBrush *		Parse( idLexer &src, const idVec3 &origin, bool newFormat = true, float version = CURRENT_MAP_VERSION );
108 	static idMapBrush *		ParseQ3( idLexer &src, const idVec3 &origin );
109 	bool					Write( idFile *fp, int primitiveNum, const idVec3 &origin ) const;
GetNumSides(void)110 	int						GetNumSides( void ) const { return sides.Num(); }
AddSide(idMapBrushSide * side)111 	int						AddSide( idMapBrushSide *side ) { return sides.Append( side ); }
GetSide(int i)112 	idMapBrushSide *		GetSide( int i ) const { return sides[i]; }
113 	unsigned int			GetGeometryCRC( void ) const;
114 
115 protected:
116 	int						numSides;
117 	idList<idMapBrushSide*> sides;
118 };
119 
120 
121 class idMapPatch : public idMapPrimitive, public idSurface_Patch {
122 public:
123 							idMapPatch( void );
124 							idMapPatch( int maxPatchWidth, int maxPatchHeight );
~idMapPatch(void)125 							~idMapPatch( void ) { }
126 	static idMapPatch *		Parse( idLexer &src, const idVec3 &origin, bool patchDef3 = true, float version = CURRENT_MAP_VERSION );
127 	bool					Write( idFile *fp, int primitiveNum, const idVec3 &origin ) const;
GetMaterial(void)128 	const char *			GetMaterial( void ) const { return material; }
SetMaterial(const char * p)129 	void					SetMaterial( const char *p ) { material = p; }
GetHorzSubdivisions(void)130 	int						GetHorzSubdivisions( void ) const { return horzSubdivisions; }
GetVertSubdivisions(void)131 	int						GetVertSubdivisions( void ) const { return vertSubdivisions; }
GetExplicitlySubdivided(void)132 	bool					GetExplicitlySubdivided( void ) const { return explicitSubdivisions; }
SetHorzSubdivisions(int n)133 	void					SetHorzSubdivisions( int n ) { horzSubdivisions = n; }
SetVertSubdivisions(int n)134 	void					SetVertSubdivisions( int n ) { vertSubdivisions = n; }
SetExplicitlySubdivided(bool b)135 	void					SetExplicitlySubdivided( bool b ) { explicitSubdivisions = b; }
136 	unsigned int			GetGeometryCRC( void ) const;
137 
138 protected:
139 	idStr					material;
140 	int						horzSubdivisions;
141 	int						vertSubdivisions;
142 	bool					explicitSubdivisions;
143 };
144 
idMapPatch(void)145 ID_INLINE idMapPatch::idMapPatch( void ) {
146 	type = TYPE_PATCH;
147 	horzSubdivisions = vertSubdivisions = 0;
148 	explicitSubdivisions = false;
149 	width = height = 0;
150 	maxWidth = maxHeight = 0;
151 	expanded = false;
152 }
153 
idMapPatch(int maxPatchWidth,int maxPatchHeight)154 ID_INLINE idMapPatch::idMapPatch( int maxPatchWidth, int maxPatchHeight ) {
155 	type = TYPE_PATCH;
156 	horzSubdivisions = vertSubdivisions = 0;
157 	explicitSubdivisions = false;
158 	width = height = 0;
159 	maxWidth = maxPatchWidth;
160 	maxHeight = maxPatchHeight;
161 	verts.SetNum( maxWidth * maxHeight );
162 	expanded = false;
163 }
164 
165 
166 class idMapEntity {
167 	friend class			idMapFile;
168 
169 public:
170 	idDict					epairs;
171 
172 public:
idMapEntity(void)173 							idMapEntity( void ) { epairs.SetHashSize( 64 ); }
~idMapEntity(void)174 							~idMapEntity( void ) { primitives.DeleteContents( true ); }
175 	static idMapEntity *	Parse( idLexer &src, bool worldSpawn = false, float version = CURRENT_MAP_VERSION );
176 	bool					Write( idFile *fp, int entityNum ) const;
GetNumPrimitives(void)177 	int						GetNumPrimitives( void ) const { return primitives.Num(); }
GetPrimitive(int i)178 	idMapPrimitive *		GetPrimitive( int i ) const { return primitives[i]; }
AddPrimitive(idMapPrimitive * p)179 	void					AddPrimitive( idMapPrimitive *p ) { primitives.Append( p ); }
180 	unsigned int			GetGeometryCRC( void ) const;
181 	void					RemovePrimitiveData();
182 
183 protected:
184 	idList<idMapPrimitive*>	primitives;
185 };
186 
187 
188 class idMapFile {
189 public:
190 							idMapFile( void );
~idMapFile(void)191 							~idMapFile( void ) { entities.DeleteContents( true ); }
192 
193 							// filename does not require an extension
194 							// normally this will use a .reg file instead of a .map file if it exists,
195 							// which is what the game and dmap want, but the editor will want to always
196 							// load a .map file
197 	bool					Parse( const char *filename, bool ignoreRegion = false, bool osPath = false );
198 	bool					Write( const char *fileName, const char *ext, bool fromBasePath = true );
199 							// get the number of entities in the map
GetNumEntities(void)200 	int						GetNumEntities( void ) const { return entities.Num(); }
201 							// get the specified entity
GetEntity(int i)202 	idMapEntity *			GetEntity( int i ) const { return entities[i]; }
203 							// get the name without file extension
GetName(void)204 	const char *			GetName( void ) const { return name; }
205 							// get the file time
GetFileTime(void)206 	ID_TIME_T					GetFileTime( void ) const { return fileTime; }
207 							// get CRC for the map geometry
208 							// texture coordinates and entity key/value pairs are not taken into account
GetGeometryCRC(void)209 	unsigned int			GetGeometryCRC( void ) const { return geometryCRC; }
210 							// returns true if the file on disk changed
211 	bool					NeedsReload();
212 
213 	int						AddEntity( idMapEntity *mapentity );
214 	idMapEntity *			FindEntity( const char *name );
215 	void					RemoveEntity( idMapEntity *mapEnt );
216 	void					RemoveEntities( const char *classname );
217 	void					RemoveAllEntities();
218 	void					RemovePrimitiveData();
HasPrimitiveData()219 	bool					HasPrimitiveData() { return hasPrimitiveData; }
220 
221 protected:
222 	float					version;
223 	ID_TIME_T					fileTime;
224 	unsigned int			geometryCRC;
225 	idList<idMapEntity *>	entities;
226 	idStr					name;
227 	bool					hasPrimitiveData;
228 
229 private:
230 	void					SetGeometryCRC( void );
231 };
232 
idMapFile(void)233 ID_INLINE idMapFile::idMapFile( void ) {
234 	version = CURRENT_MAP_VERSION;
235 	fileTime = 0;
236 	geometryCRC = 0;
237 	entities.Resize( 1024, 256 );
238 	hasPrimitiveData = false;
239 }
240 
241 #endif /* !__MAPFILE_H__ */
242