UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
writebsp.cpp
Go to the documentation of this file.
1 
5 /*
6 Copyright (C) 1997-2001 Id Software, Inc.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 
23 */
24 
25 #include "bsp.h"
26 
27 static int c_nofaces;
28 static int c_facenodes;
29 
30 /*
31 =========================================================
32 ONLY SAVE OUT PLANES THAT ARE ACTUALLY USED AS NODES
33 =========================================================
34 */
35 
41 void EmitPlanes (void)
42 {
43  const plane_t* mp = mapplanes;
44 
45  for (int i = 0; i < nummapplanes; i++, mp++) {
47  VectorCopy(mp->normal, dp->normal);
48  dp->dist = mp->dist;
49  dp->type = mp->type;
50  curTile->numplanes++;
51  }
52 }
53 
57 static void EmitLeaf (const node_t* node)
58 {
59  dBspLeaf_t* leaf_p;
60  int i;
61  const bspbrush_t* b;
62 
63  /* emit a leaf */
65  Sys_Error("MAX_MAP_LEAFS (%i)", curTile->numleafs);
66 
67  leaf_p = &curTile->leafs[curTile->numleafs];
68  curTile->numleafs++;
69 
70  leaf_p->contentFlags = node->contentFlags;
71  leaf_p->area = node->area;
72 
73  /* write bounding box info */
74  VectorCopy(node->nBox.mins, leaf_p->mins);
75  VectorCopy(node->nBox.maxs, leaf_p->maxs);
76 
77  /* write the leafbrushes */
79  for (b = node->brushlist; b; b = b->next) {
81  Sys_Error("MAX_MAP_LEAFBRUSHES (%i)", curTile->numleafbrushes);
82 
83  int brushnum = b->original - mapbrushes;
84  for (i = leaf_p->firstleafbrush; i < curTile->numleafbrushes; i++)
85  if (curTile->leafbrushes[i] == brushnum)
86  break;
87  if (i == curTile->numleafbrushes) {
88  Verb_Printf(VERB_DUMP, "EmitLeaf: adding brush %i to leaf %i\n", brushnum, curTile->numleafs - 1);
91  }
92  }
94 }
95 
96 
101 static void EmitFace (const face_t* f)
102 {
103  if (f->numpoints < 3) {
104  return; /* degenerated */
105  }
106  if (f->merged || f->split[0] || f->split[1]) {
107  return; /* not a final face */
108  }
109 
111  Sys_Error("numfaces >= MAX_MAP_FACES (%i)", curTile->numfaces);
113  curTile->numfaces++;
114 
115  df->planenum = f->planenum & (~1);
116  df->side = f->planenum & 1;
117 
119  df->numedges = f->numpoints;
120  df->texinfo = f->texinfo;
121  int i;
122  for (i = 0; i < f->numpoints; i++) {
123  const int e = GetEdge(f->vertexnums[i], f->vertexnums[(i + 1) % f->numpoints], f);
125  Sys_Error("numsurfedges >= MAX_MAP_SURFEDGES (%i)", curTile->numsurfedges);
128  }
129  for (int i = 0; i < LIGHTMAP_MAX; i++)
130  df->lightofs[i] = -1;
131 }
132 
137 static int EmitDrawNode_r (node_t* node)
138 {
139  const char* side[2] = {"front", "back"};
140 
141  if (node->planenum == PLANENUM_LEAF) {
142  Verb_Printf(VERB_DUMP, "EmitDrawNode_r: creating singleton leaf.\n");
143  EmitLeaf(node);
144  return -curTile->numleafs;
145  }
146 
147  /* emit a node */
149  Sys_Error("MAX_MAP_NODES (%i)", curTile->numnodes);
151  Verb_Printf(VERB_DUMP, "EmitDrawNode_r: creating bsp node %i\n", curTile->numnodes);
152  curTile->numnodes++;
153 
154  VectorCopy(node->nBox.mins, n->mins);
155  VectorCopy(node->nBox.maxs, n->maxs);
156 
157  if (node->planenum & 1)
158  Sys_Error("EmitDrawNode_r: odd planenum: %i", node->planenum);
159  n->planenum = node->planenum;
160  n->firstface = curTile->numfaces;
161 
162  if (!node->faces)
163  c_nofaces++;
164  else
165  c_facenodes++;
166 
167  const face_t* f;
168  for (f = node->faces; f; f = f->next)
169  EmitFace(f);
170 
171  n->numfaces = curTile->numfaces - n->firstface;
172 
173  /* recursively output the other nodes */
174  for (int i = 0; i < 2; i++) {
175  if (node->children[i]->planenum == PLANENUM_LEAF) {
176  Verb_Printf(VERB_DUMP, "EmitDrawNode_r: creating child leaf for %s of bsp node " UFO_SIZE_T ".\n", side[i], n - curTile->nodes);
177  n->children[i] = -(curTile->numleafs + 1);
178  EmitLeaf(node->children[i]);
179  } else {
180  Verb_Printf(VERB_DUMP, "EmitDrawNode_r: adding child node for bsp node " UFO_SIZE_T ".\n", n - curTile->nodes);
181  n->children[i] = curTile->numnodes;
182  EmitDrawNode_r(node->children[i]);
183  }
184  }
185 
186  return n - curTile->nodes;
187 }
188 
189 
195 int WriteBSP (node_t* headnode)
196 {
197  int oldfaces, emittedHeadnode;
198 
199  c_nofaces = 0;
200  c_facenodes = 0;
201 
202  Verb_Printf(VERB_EXTRA, "--- WriteBSP ---\n");
203 
204  oldfaces = curTile->numfaces;
205  emittedHeadnode = EmitDrawNode_r(headnode);
206 
207  Verb_Printf(VERB_EXTRA, "%5i nodes with faces\n", c_facenodes);
208  Verb_Printf(VERB_EXTRA, "%5i nodes without faces\n", c_nofaces);
209  Verb_Printf(VERB_EXTRA, "%5i faces\n", curTile->numfaces - oldfaces);
210 
211  return emittedHeadnode;
212 }
213 
217 void SetModelNumbers (void)
218 {
219  int i;
220  char value[10];
221 
222  /* 0 is the world - start at 1 */
223  int models = 1;
224  for (i = 1; i < num_entities; i++) {
225  if (entities[i].numbrushes) {
226  Com_sprintf(value, sizeof(value), "*%i", models);
227  models++;
228  SetKeyValue(&entities[i], "model", value);
229  }
230  }
231 }
232 
236 void EmitBrushes (void)
237 {
238  curTile->numbrushsides = 0;
240  /* Clear out curTile->brushes */
242 
243  for (int bnum = 0; bnum < nummapbrushes; bnum++) {
244  const mapbrush_t* b = &mapbrushes[bnum];
245  dBspBrush_t* db = &curTile->dbrushes[bnum];
246  cBspBrush_t* cb = &curTile->brushes[bnum];
247 
250  db->numsides = b->numsides;
253  cb->numsides = b->numsides;
254  cb->checkcount = 0;
255  for (int j = 0; j < b->numsides; j++) {
257  Sys_Error("MAX_MAP_BRUSHSIDES (%i)", curTile->numbrushsides);
258  } else {
261  cp->planenum = b->original_sides[j].planenum;
262  cp->texinfo = b->original_sides[j].texinfo;
263  }
264  }
265 
266  /* add any axis planes not contained in the brush to bevel off corners */
267  for (int x = 0; x < 3; x++)
268  for (int s = -1; s <= 1; s += 2) {
269  /* add the plane */
270  vec3_t normal;
271  VectorCopy(vec3_origin, normal);
272  normal[x] = (float)s;
273 
274  vec_t dist;
275  if (s == -1)
276  dist = -b->mbBox.mins[x];
277  else
278  dist = b->mbBox.maxs[x];
279  int planenum = FindOrCreateFloatPlane(normal, dist);
280 
281  int i;
282  for (i = 0; i < b->numsides; i++)
283  if (b->original_sides[i].planenum == planenum)
284  break;
285  if (i == b->numsides) {
287  Sys_Error("MAX_MAP_BRUSHSIDES (%i)", curTile->numbrushsides);
288 
292  db->numsides++;
293  cb->numsides++;
294  }
295  }
296  }
297 }
298 
303 void BeginBSPFile (void)
304 {
305  /* Create this shortcut to mapTiles[0] */
306  curTile = &mapTiles.mapTiles[0];
307  /* Set the number of tiles to 1. */
308  mapTiles.numTiles = 1;
309 
310  /* these values may actually be initialized
311  * if the file existed when loaded, so clear them explicitly */
312  curTile->nummodels = 0;
313  curTile->numfaces = 0;
314  curTile->numbrushsides = 0;
315  curTile->numleafbrushes = 0;
316  curTile->numsurfedges = 0;
317  curTile->numnodes = 0;
318 
319  /* edge 0 is not used, because 0 can't be negated */
320  curTile->numedges = 1;
321 
322  /* leave vertex 0 as an error */
323  curTile->numvertexes = 1;
324  curTile->numnormals = 1;
325 
326  /* leave leaf 0 as an error */
327  curTile->numleafs = 1;
329 }
330 
331 
336 void EndBSPFile (const char* filename)
337 {
338  EmitBrushes();
339  EmitPlanes();
340  UnparseEntities();
341 
342  /* write the map */
343  Verb_Printf(VERB_LESS, "Writing %s\n", filename);
344  WriteBSPFile(filename);
345 }
346 
347 extern int firstmodeledge;
348 
354 {
356  Sys_Error("MAX_MAP_MODELS (%i)", curTile->nummodels);
357 
359  mod->firstface = curTile->numfaces;
360 
362 
363  /* bound the brushes */
364  const entity_t* e = &entities[entityNum];
365 
366  int start = e->firstbrush;
367  int end = start + e->numbrushes;
368  AABB modBox;
369  modBox.setNegativeVolume();
370 
371  for (int j = start; j < end; j++) {
372  const mapbrush_t* b = &mapbrushes[j];
373  /* not a real brush (origin brush) - e.g. func_door */
374  if (!b->numsides)
375  continue;
376  modBox.add(b->mbBox);
377  }
378 
379  mod->dbmBox.set(modBox);
380 }
381 
382 
387 void EndModel (void)
388 {
389  dBspModel_t* mod;
390 
391  /* set surfaces and brushes */
392  mod = &curTile->models[curTile->nummodels];
393  mod->numfaces = curTile->numfaces - mod->firstface;
394 
395  /* increment model count */
396  curTile->nummodels++;
397 }
static int entityNum
Definition: levels.cpp:220
int32_t contentFlags
Definition: bsp.h:56
int numleafs
Definition: typedefs.h:470
int vertexnums[MAXEDGES]
Definition: map.h:57
vec3_t normal
Definition: map.h:99
#define VectorCopy(src, dest)
Definition: vector.h:51
int firstbrushside
Definition: typedefs.h:62
void setNegativeVolume()
Sets mins and maxs to their starting points before using addPoint.
Definition: aabb.h:98
void Sys_Error(const char *error,...)
Definition: g_main.cpp:421
int texinfo
Definition: map.h:62
short mins[3]
Definition: typedefs.h:381
#define MAX_MAP_FACES
Definition: defines.h:144
void SetModelNumbers(void)
Set the model numbers for SOLID_BSP or SOLID_TRIGGER entities like func_door or func_breakable.
Definition: writebsp.cpp:217
int firstbrushside
Definition: typedefs.h:435
Definition: map.h:42
static void EmitFace(const face_t *f)
Definition: writebsp.cpp:101
uint32_t contentFlags
Definition: typedefs.h:417
struct face_s * next
Definition: map.h:43
uint16_t FindOrCreateFloatPlane(vec3_t normal, vec_t dist)
Definition: map.cpp:194
int firstbrush
Definition: bspfile.h:48
#define CONTENTS_SOLID
Definition: defines.h:223
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
int type
Definition: map.h:105
dBspModel_t models[MAX_MAP_MODELS]
Definition: typedefs.h:468
Definition: aabb.h:42
const char * filename
Definition: ioapi.h:41
const vec3_t vec3_origin
Definition: mathlib.cpp:35
int numsides
Definition: typedefs.h:436
#define MAX_MAP_LEAFS
Definition: defines.h:142
float vec_t
Definition: ufotypes.h:37
int numplanes
Definition: typedefs.h:474
uint16_t numleafbrushes
Definition: typedefs.h:425
dBspNode_t nodes[MAX_MAP_NODES]
Definition: typedefs.h:484
void BeginModel(int entityNum)
Sets up a new brush model.
Definition: writebsp.cpp:353
void BeginBSPFile(void)
Starts a new bsp file.
Definition: writebsp.cpp:303
int numsides
Definition: map.h:83
void set(const AABB &other)
Copies the values from the given aabb.
Definition: aabb.h:60
int numleafbrushes
Definition: typedefs.h:495
int nummapbrushes
Definition: map.cpp:35
float dist
Definition: typedefs.h:374
vec3_t maxs
Definition: aabb.h:258
entity_t entities[MAX_MAP_ENTITIES]
Definition: bspfile.cpp:395
int nummodels
Definition: typedefs.h:467
convex region of space in the BSP tree
Definition: typedefs.h:416
AABB mbBox
Definition: map.h:81
int numedges
Definition: typedefs.h:492
int32_t planenum
Definition: bsp.h:44
unsigned short firstface
Definition: typedefs.h:383
mapbrush_t mapbrushes[MAX_MAP_BRUSHES]
Definition: map.cpp:34
struct face_s * split[2]
Definition: map.h:49
int nummapplanes
Definition: map.cpp:44
static int EmitDrawNode_r(node_t *node)
Writes the draw nodes.
Definition: writebsp.cpp:137
dBspBrushSide_t brushsides[MAX_MAP_BRUSHSIDES]
Definition: typedefs.h:513
cBspBrush_t brushes[MAX_MAP_BRUSHES]
Definition: typedefs.h:510
#define MAX_MAP_BRUSHSIDES
Definition: defines.h:141
void SetKeyValue(entity_t *ent, const char *key, const char *value)
Definition: bspfile.cpp:546
Definition: map.h:98
AABB dbmBox
Definition: typedefs.h:355
void add(const vec3_t point)
If the point is outside the box, expand the box to accommodate it.
Definition: aabb.cpp:57
static int c_nofaces
Definition: writebsp.cpp:27
static int oldfaces
Definition: levels.cpp:31
dBspSurface_t faces[MAX_MAP_FACES]
Definition: typedefs.h:490
#define OBJZERO(obj)
Definition: shared.h:178
struct node_s * children[2]
Definition: bsp.h:51
uint16_t planenum
Definition: map.h:61
dBspPlane_t planes[MAX_MAP_PLANES]
Definition: typedefs.h:475
struct side_s * original_sides
Definition: map.h:84
short maxs[3]
Definition: typedefs.h:422
uint16_t planenum
Definition: typedefs.h:429
plane_t mapplanes[MAX_MAP_PLANES]
Definition: map.cpp:43
short numedges
Definition: typedefs.h:408
void Verb_Printf(const verbosityLevel_t importance, const char *format,...) __attribute__((format(__printf__
uint32_t brushContentFlags
Definition: typedefs.h:60
dBspLeaf_t leafs[MAX_MAP_LEAFS]
Definition: typedefs.h:471
int WriteBSP(node_t *headnode)
copies working data for a bsp tree into the structures used to create the bsp file.
Definition: writebsp.cpp:195
void EndBSPFile(const char *filename)
Finishes a new bsp and writes to disk.
Definition: writebsp.cpp:336
dMapTile_t * curTile
Definition: bsp.cpp:32
#define MAX_MAP_MODELS
Definition: defines.h:134
int numfaces
Definition: typedefs.h:358
int texinfo
Definition: map.h:52
uint16_t planenum
Definition: map.h:53
void EndModel(void)
Finish a model's processing.
Definition: writebsp.cpp:387
struct bspbrush_s * next
Definition: bspbrush.h:36
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
const char * UnparseEntities(void)
Generates the curTile->entdata string from all the entities.
Definition: bspfile.cpp:515
int checkcount
Definition: typedefs.h:63
int numbrushes
Definition: bspfile.h:49
int numbrushsides
Definition: typedefs.h:512
unsigned short leafbrushes[MAX_MAP_LEAFBRUSHES]
Definition: typedefs.h:496
int numTiles
Definition: tracing.h:82
#define PLANENUM_LEAF
Definition: defines.h:45
TR_TILE_TYPE mapTiles[MAX_MAPTILES]
Definition: tracing.h:79
AABB nBox
Definition: bsp.h:46
QGL_EXTERN GLint i
Definition: r_gl.h:113
int numpoints
Definition: map.h:56
struct mapbrush_s * original
Definition: bspbrush.h:40
int numnormals
Definition: typedefs.h:477
int numnodes
Definition: typedefs.h:483
bspbrush_t * brushlist
Definition: bsp.h:55
int32_t children[2]
Definition: typedefs.h:380
#define MAX_MAP_SURFEDGES
Definition: defines.h:147
vec_t dist
Definition: map.h:100
int numsides
Definition: typedefs.h:61
int numvertexes
Definition: typedefs.h:480
Definition: map.h:75
int firstmodeledge
Definition: faces.cpp:41
int surfedges[MAX_MAP_SURFEDGES]
Definition: typedefs.h:506
int numsurfedges
Definition: typedefs.h:505
static void EmitLeaf(const node_t *node)
Emits a leafnode to the bsp file.
Definition: writebsp.cpp:57
long WriteBSPFile(const char *filename)
Swaps the bsp file in place, so it should not be referenced again.
Definition: bspfile.cpp:316
int lightofs[LIGHTMAP_MAX]
Definition: typedefs.h:412
short side
Definition: typedefs.h:405
#define UFO_SIZE_T
Definition: ufotypes.h:89
vec_t vec3_t[3]
Definition: ufotypes.h:39
uint16_t firstleafbrush
Definition: typedefs.h:424
short texinfo
Definition: typedefs.h:409
int GetEdge(int v1, int v2, const face_t *f)
Definition: faces.cpp:399
unsigned short numfaces
Definition: typedefs.h:384
struct face_s * merged
Definition: map.h:48
vec3_t mins
Definition: aabb.h:257
face_t * faces
Definition: bsp.h:52
uint32_t brushContentFlags
Definition: typedefs.h:437
#define MAX_MAP_LEAFBRUSHES
Definition: defines.h:145
int32_t planenum
Definition: typedefs.h:379
short mins[3]
Definition: typedefs.h:421
Definition: bsp.h:42
#define LIGHTMAP_MAX
Definition: defines.h:365
static int c_facenodes
Definition: writebsp.cpp:28
int numfaces
Definition: typedefs.h:489
uint16_t planenum
Definition: typedefs.h:404
vec3_t normal
Definition: typedefs.h:373
int area
Definition: bsp.h:57
short area
Definition: typedefs.h:419
short maxs[3]
Definition: typedefs.h:382
void EmitBrushes(void)
Writes the brush list to the bsp.
Definition: writebsp.cpp:236
int num_entities
Definition: bspfile.cpp:394
int firstface
Definition: typedefs.h:358
dBspBrush_t dbrushes[MAX_MAP_BRUSHES]
Definition: typedefs.h:509
uint32_t contentFlags
Definition: map.h:79
static mapTiles_t mapTiles
int numbrushes
Definition: typedefs.h:508
void EmitPlanes(void)
Emits planes to the bsp file.
Definition: writebsp.cpp:41
#define MAX_MAP_NODES
Definition: defines.h:140