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