UFO: Alien Invasion
Loading...
Searching...
No Matches
writebsp.cpp
Go to the documentation of this file.
1
4
5/*
6Copyright (C) 1997-2001 Id Software, Inc.
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17See the GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23*/
24
25#include "bsp.h"
26
27static int c_nofaces;
28static int c_facenodes;
29
30/*
31=========================================================
32ONLY SAVE OUT PLANES THAT ARE ACTUALLY USED AS NODES
33=========================================================
34*/
35
41void EmitPlanes (void)
42{
43 const plane_t* mp = mapplanes;
44
45 for (int i = 0; i < nummapplanes; i++, mp++) {
46 dBspPlane_t* dp = &curTile->planes[curTile->numplanes];
47 VectorCopy(mp->normal, dp->normal);
48 dp->dist = mp->dist;
49 dp->type = mp->type;
50 curTile->numplanes++;
51 }
52}
53
57static 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 */
64 if (curTile->numleafs >= MAX_MAP_LEAFS)
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 */
78 leaf_p->firstleafbrush = curTile->numleafbrushes;
79 for (b = node->brushlist; b; b = b->next) {
80 if (curTile->numleafbrushes >= MAX_MAP_LEAFBRUSHES)
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);
89 curTile->leafbrushes[curTile->numleafbrushes] = brushnum;
90 curTile->numleafbrushes++;
91 }
92 }
93 leaf_p->numleafbrushes = curTile->numleafbrushes - leaf_p->firstleafbrush;
94}
95
96
101static 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
110 if (curTile->numfaces >= MAX_MAP_FACES)
111 Sys_Error("numfaces >= MAX_MAP_FACES (%i)", curTile->numfaces);
112 dBspSurface_t* df = &curTile->faces[curTile->numfaces];
113 curTile->numfaces++;
114
115 df->planenum = f->planenum & (~1);
116 df->side = f->planenum & 1;
117
118 df->firstedge = curTile->numsurfedges;
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);
124 if (curTile->numsurfedges >= MAX_MAP_SURFEDGES)
125 Sys_Error("numsurfedges >= MAX_MAP_SURFEDGES (%i)", curTile->numsurfedges);
126 curTile->surfedges[curTile->numsurfedges] = e;
127 curTile->numsurfedges++;
128 }
129 for (int i = 0; i < LIGHTMAP_MAX; i++)
130 df->lightofs[i] = -1;
131}
132
137static 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 */
148 if (curTile->numnodes >= MAX_MAP_NODES)
149 Sys_Error("MAX_MAP_NODES (%i)", curTile->numnodes);
150 dBspNode_t* n = &curTile->nodes[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
195int 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
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
236void EmitBrushes (void)
237{
238 curTile->numbrushsides = 0;
239 curTile->numbrushes = nummapbrushes;
240 /* Clear out curTile->brushes */
241 OBJZERO(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
249 db->firstbrushside = curTile->numbrushsides;
250 db->numsides = b->numsides;
252 cb->firstbrushside = curTile->numbrushsides;
253 cb->numsides = b->numsides;
254 cb->checkcount = 0;
255 for (int j = 0; j < b->numsides; j++) {
256 if (curTile->numbrushsides == MAX_MAP_BRUSHSIDES) {
257 Sys_Error("MAX_MAP_BRUSHSIDES (%i)", curTile->numbrushsides);
258 } else {
259 dBspBrushSide_t* cp = &curTile->brushsides[curTile->numbrushsides];
260 curTile->numbrushsides++;
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) {
286 if (curTile->numbrushsides >= MAX_MAP_BRUSHSIDES)
287 Sys_Error("MAX_MAP_BRUSHSIDES (%i)", curTile->numbrushsides);
288
289 curTile->brushsides[curTile->numbrushsides].planenum = planenum;
290 curTile->brushsides[curTile->numbrushsides].texinfo = curTile->brushsides[curTile->numbrushsides - 1].texinfo;
291 curTile->numbrushsides++;
292 db->numsides++;
293 cb->numsides++;
294 }
295 }
296 }
297}
298
303void 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;
328 curTile->leafs[0].contentFlags = CONTENTS_SOLID;
329}
330
331
336void EndBSPFile (const char* filename)
337{
338 EmitBrushes();
339 EmitPlanes();
341
342 /* write the map */
343 Verb_Printf(VERB_LESS, "Writing %s\n", filename);
345}
346
347extern int firstmodeledge;
348
354{
355 if (curTile->nummodels == MAX_MAP_MODELS)
356 Sys_Error("MAX_MAP_MODELS (%i)", curTile->nummodels);
357
358 dBspModel_t* mod = &curTile->models[curTile->nummodels];
359 mod->firstface = curTile->numfaces;
360
361 firstmodeledge = curTile->numedges;
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
387void 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}
int GetEdge(int v1, int v2, const face_t *f)
Definition faces.cpp:399
int nummapbrushes
Definition map.cpp:35
int nummapplanes
Definition map.cpp:44
plane_t mapplanes[MAX_MAP_PLANES]
Definition map.cpp:43
uint16_t FindOrCreateFloatPlane(vec3_t normal, vec_t dist)
Definition map.cpp:194
mapbrush_t mapbrushes[MAX_MAP_BRUSHES]
Definition map.cpp:34
const char * UnparseEntities(void)
Generates the curTile->entdata string from all the entities.
Definition bspfile.cpp:515
void SetKeyValue(entity_t *ent, const char *key, const char *value)
Definition bspfile.cpp:546
int num_entities
Definition bspfile.cpp:394
entity_t entities[MAX_MAP_ENTITIES]
Definition bspfile.cpp:395
long WriteBSPFile(const char *filename)
Swaps the bsp file in place, so it should not be referenced again.
Definition bspfile.cpp:316
Definition aabb.h:42
vec3_t maxs
Definition aabb.h:258
void setNegativeVolume()
Sets mins and maxs to their starting points before using addPoint.
Definition aabb.h:98
vec3_t mins
Definition aabb.h:257
void set(const AABB &other)
Copies the values from the given aabb.
Definition aabb.h:60
void add(const vec3_t point)
If the point is outside the box, expand the box to accommodate it.
Definition aabb.cpp:57
#define LIGHTMAP_MAX
Definition defines.h:365
#define MAX_MAP_SURFEDGES
Definition defines.h:147
#define MAX_MAP_BRUSHSIDES
Definition defines.h:141
#define MAX_MAP_LEAFS
Definition defines.h:142
#define MAX_MAP_MODELS
Definition defines.h:134
#define MAX_MAP_FACES
Definition defines.h:144
#define CONTENTS_SOLID
Definition defines.h:223
#define MAX_MAP_NODES
Definition defines.h:140
#define PLANENUM_LEAF
Definition defines.h:45
#define MAX_MAP_LEAFBRUSHES
Definition defines.h:145
int firstmodeledge
Definition faces.cpp:41
void Sys_Error(const char *error,...)
Definition g_main.cpp:421
const char * filename
Definition ioapi.h:41
static int entityNum
Definition levels.cpp:220
static int oldfaces
Definition levels.cpp:31
const vec3_t vec3_origin
Definition mathlib.cpp:35
QGL_EXTERN GLfloat f
Definition r_gl.h:114
QGL_EXTERN GLint i
Definition r_gl.h:113
#define OBJZERO(obj)
Definition shared.h:178
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
struct mapbrush_s * original
Definition bspbrush.h:40
struct bspbrush_s * next
Definition bspbrush.h:36
int checkcount
Definition typedefs.h:63
int firstbrushside
Definition typedefs.h:62
uint32_t brushContentFlags
Definition typedefs.h:60
int numsides
Definition typedefs.h:61
int firstbrushside
Definition typedefs.h:435
uint32_t brushContentFlags
Definition typedefs.h:437
uint16_t planenum
Definition typedefs.h:429
convex region of space in the BSP tree
Definition typedefs.h:416
short mins[3]
Definition typedefs.h:421
short area
Definition typedefs.h:419
uint16_t numleafbrushes
Definition typedefs.h:425
uint32_t contentFlags
Definition typedefs.h:417
uint16_t firstleafbrush
Definition typedefs.h:424
short maxs[3]
Definition typedefs.h:422
int firstface
Definition typedefs.h:358
AABB dbmBox
Definition typedefs.h:355
int32_t planenum
Definition typedefs.h:379
short maxs[3]
Definition typedefs.h:382
unsigned short numfaces
Definition typedefs.h:384
unsigned short firstface
Definition typedefs.h:383
short mins[3]
Definition typedefs.h:381
int32_t children[2]
Definition typedefs.h:380
vec3_t normal
Definition typedefs.h:373
float dist
Definition typedefs.h:374
int lightofs[LIGHTMAP_MAX]
Definition typedefs.h:412
short texinfo
Definition typedefs.h:409
short numedges
Definition typedefs.h:408
uint16_t planenum
Definition typedefs.h:404
int numbrushes
Definition bspfile.h:49
int firstbrush
Definition bspfile.h:48
Definition map.h:42
struct side_s * original_sides
Definition map.h:84
int numsides
Definition map.h:83
uint32_t contentFlags
Definition map.h:79
AABB mbBox
Definition map.h:81
Definition bsp.h:42
int32_t planenum
Definition bsp.h:44
AABB nBox
Definition bsp.h:46
int32_t contentFlags
Definition bsp.h:56
int area
Definition bsp.h:57
bspbrush_t * brushlist
Definition bsp.h:55
face_t * faces
Definition bsp.h:52
struct node_s * children[2]
Definition bsp.h:51
Definition map.h:98
int type
Definition map.h:105
vec_t dist
Definition map.h:100
vec3_t normal
Definition map.h:99
static mapTiles_t mapTiles
dMapTile_t * curTile
Definition bsp.cpp:32
void Verb_Printf(const verbosityLevel_t importance, const char *format,...) __attribute__((format(__printf__
@ VERB_EXTRA
Definition shared.h:46
@ VERB_LESS
Definition shared.h:44
@ VERB_DUMP
Definition shared.h:47
float vec_t
Definition ufotypes.h:37
vec_t vec3_t[3]
Definition ufotypes.h:39
#define UFO_SIZE_T
Definition ufotypes.h:89
#define VectorCopy(src, dest)
Definition vector.h:51
void EmitBrushes(void)
Writes the brush list to the bsp.
Definition writebsp.cpp:236
void EndBSPFile(const char *filename)
Finishes a new bsp and writes to disk.
Definition writebsp.cpp:336
void EndModel(void)
Finish a model's processing.
Definition writebsp.cpp:387
static int c_nofaces
Definition writebsp.cpp:27
void BeginBSPFile(void)
Starts a new bsp file.
Definition writebsp.cpp:303
static int EmitDrawNode_r(node_t *node)
Writes the draw nodes.
Definition writebsp.cpp:137
static void EmitFace(const face_t *f)
Definition writebsp.cpp:101
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
static void EmitLeaf(const node_t *node)
Emits a leafnode to the bsp file.
Definition writebsp.cpp:57
void EmitPlanes(void)
Emits planes to the bsp file.
Definition writebsp.cpp:41
static int c_facenodes
Definition writebsp.cpp:28
void BeginModel(int entityNum)
Sets up a new brush model.
Definition writebsp.cpp:353
void SetModelNumbers(void)
Set the model numbers for SOLID_BSP or SOLID_TRIGGER entities like func_door or func_breakable.
Definition writebsp.cpp:217