UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
levels.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 "levels.h"
26 #include "bsp.h"
27 
28 
30 
32 
33 void PushInfo (void)
34 {
46 }
47 
48 void PopInfo (void)
49 {
61 }
62 
67 static int32_t BuildNodeChildren (const int n[3])
68 {
69  int32_t node = LEAFNODE;
70 
71  for (int i = 0; i < 3; i++) {
73 
74  if (n[i] == LEAFNODE)
75  continue;
76 
77  if (node == LEAFNODE) {
78  /* store the valid node */
79  node = n[i];
80 
81  aabb.setNegativeVolume();
82  VectorCopy(curTile->nodes[node].mins, aabb.mins);
83  VectorCopy(curTile->nodes[node].maxs, aabb.maxs);
84  } else {
85  dBspNode_t* newnode;
86  vec3_t addvec;
87  /* add a new "special" dnode and store it */
88  newnode = &curTile->nodes[curTile->numnodes];
89  curTile->numnodes++;
90 
91  newnode->planenum = PLANENUM_LEAF;
92  newnode->children[0] = node;
93  newnode->children[1] = n[i];
94  newnode->firstface = 0;
95  newnode->numfaces = 0;
96 
97  aabb.setNegativeVolume();
98  VectorCopy(curTile->nodes[node].mins, aabb.mins);
99  VectorCopy(curTile->nodes[node].maxs, aabb.maxs);
100  VectorCopy(curTile->nodes[n[i]].mins, addvec);
101  aabb.add(addvec);
102  VectorCopy(curTile->nodes[n[i]].maxs, addvec);
103  aabb.add(addvec);
104  VectorCopy(aabb.mins, newnode->mins);
105  VectorCopy(aabb.maxs, newnode->maxs);
106 
107  node = curTile->numnodes - 1;
108  }
109 
110  Verb_Printf(VERB_DUMP, "BuildNodeChildren: node=%i (%i %i %i) (%i %i %i)\n", node,
111  curTile->nodes[node].mins[0], curTile->nodes[node].mins[1], curTile->nodes[node].mins[2], curTile->nodes[node].maxs[0], curTile->nodes[node].maxs[1], curTile->nodes[node].maxs[2]);
112  }
113 
114  /* return the last stored node */
115  return node;
116 }
117 
118 #define SPLIT_AT_POW2 6
119 #define SPLIT_COORDS 2
120 
125 static int32_t ConstructLevelNodes_r (const int levelnum, const AABB& partBox, int entityNum)
126 {
127  bspbrush_t* list;
128  tree_t* tree;
129  AABB bBox; /* bounding box for all brushes inside partBox */
130  int32_t tmins[SPLIT_COORDS], tmaxs[SPLIT_COORDS];
131  int32_t nn[3];
132  node_t* node;
133 
134  /* calculate bounds, stop if no brushes are available */
135  if (!MapBrushesBounds(brush_start, brush_end, levelnum, partBox, bBox))
136  return LEAFNODE;
137 
138  Verb_Printf(VERB_DUMP, "ConstructLevelNodes_r: lv=%i (%f %f %f) (%f %f %f)\n", levelnum,
139  partBox.mins[0], partBox.mins[1], partBox.mins[2], partBox.maxs[0], partBox.maxs[1], partBox.maxs[2]);
140 
141  for (int i = 0; i < SPLIT_COORDS; i++) {
142  tmins[i] = ((int)floor(bBox.mins[i])) >> SPLIT_AT_POW2;
143  tmaxs[i] = ((int)ceil(bBox.maxs[i])) >> SPLIT_AT_POW2;
144  }
145 
146  Verb_Printf(VERB_DUMP, "(%i): %i %i: (%i %i) (%i %i) -> (%i %i) (%i %i)\n", levelnum, tmaxs[0] - tmins[0], tmaxs[1] - tmins[1],
147  (int)partBox.mins[0], (int)partBox.mins[1], (int)partBox.maxs[0], (int)partBox.maxs[1],
148  (int)bBox.mins[0], (int)bBox.mins[1], (int)bBox.maxs[0], (int)bBox.maxs[1]);
149 
151  if (tmaxs[1] - tmins[1] >= 2 || tmaxs[0] - tmins[0] >= 2) {
152  /* continue subdivision */
153  /* split the remaining hull at pow2 pos about the middle of the longer axis */
154  int n;
155  int32_t splitAt;
156 
157  if (tmaxs[1] - tmins[1] > tmaxs[0] - tmins[0])
158  n = 1;
159  else
160  n = 0;
161 
162  AABB newPartBox(bBox); /* bounding box of the partition */
163 
164  splitAt = (tmins[n] + ((tmaxs[n] - tmins[n]) >> 1)) << SPLIT_AT_POW2;
165  newPartBox.maxs[n] = splitAt;
166 
167  Verb_Printf(VERB_DUMP, "Chlid 0: (%i %i) (%i %i)\n", (int)newPartBox.mins[0], (int)newPartBox.mins[1], (int)newPartBox.maxs[0], (int)newPartBox.maxs[1]);
168  nn[0] = ConstructLevelNodes_r(levelnum, newPartBox, entityNum);
169 
170  newPartBox.setMaxs(bBox.maxs);
171  newPartBox.mins[n] = splitAt;
172 
173  Verb_Printf(VERB_DUMP, "Child 1: (%i %i) (%i %i)\n", (int)newPartBox.mins[0], (int)newPartBox.mins[1], (int)newPartBox.maxs[0], (int)newPartBox.maxs[1]);
174  nn[1] = ConstructLevelNodes_r(levelnum, newPartBox, entityNum);
175  } else {
176  /* no children */
177  nn[0] = LEAFNODE;
178  nn[1] = LEAFNODE;
179  }
180 
181  /* add one unit to avoid clipping errors */
182  bBox.expand(1);
183 
184  /* Call BeginModel only to initialize brush pointers */
185  BeginModel(entityNum);
186 
187  list = MakeBspBrushList(brush_start, brush_end, levelnum, bBox);
188  if (!list) {
189  nn[2] = LEAFNODE;
190  return BuildNodeChildren(nn);
191  }
192 
193  if (!config.nocsg)
194  list = ChopBrushes(list);
195 
196  /* begin model creation now */
197  tree = BuildTree(list, bBox.mins, bBox.maxs);
198  MakeTreePortals(tree);
200  MakeFaces(tree->headnode);
201  FixTjuncs(tree->headnode);
202 
203  if (!config.noprune)
204  PruneNodes(tree->headnode);
205 
206  /* correct bounds */
207  node = tree->headnode;
208  bBox.expand(-1);
209  node->nBox.set(bBox);
210 
211  /* finish model */
212  nn[2] = WriteBSP(tree->headnode);
213  FreeTree(tree);
214 
215  /* Store created nodes */
216  return BuildNodeChildren(nn);
217 }
218 
220 static int entityNum;
221 
222 void ProcessLevelEntityNumber (int entityNumber)
223 {
224  entityNum = entityNumber;
225 }
226 
238 void ProcessLevel (unsigned int levelnum)
239 {
240  vec3_t mins, maxs;
241  dBspModel_t* dm;
242 
243  /* oversizing the blocks guarantees that all the boundaries will also get nodes. */
244  /* get maxs */
245  mins[0] = (config.block_xl) * 512.0 + 1.0;
246  mins[1] = (config.block_yl) * 512.0 + 1.0;
247  mins[2] = -MAX_WORLD_WIDTH + 1.0;
248 
249  maxs[0] = (config.block_xh + 1.0) * 512.0 - 1.0;
250  maxs[1] = (config.block_yh + 1.0) * 512.0 - 1.0f;
251  maxs[2] = MAX_WORLD_WIDTH - 1.0;
252  const AABB partBox(mins, maxs); /* bounding box of the level */
253 
254  Verb_Printf(VERB_EXTRA, "Process levelnum %i (curTile->nummodels: %i)\n", levelnum, curTile->nummodels);
255 
257  dm = &curTile->models[levelnum];
258  OBJZERO(*dm);
259 
261  /* back copy backup brush sides structure */
262  /* to reset all the changed values (especialy "finished") */
264 
265  /* Store face number for later use */
266  dm->firstface = curTile->numfaces;
267  dm->headnode = ConstructLevelNodes_r(levelnum, partBox, entityNum);
268  /* This here replaces the calls to EndModel */
269  dm->numfaces = curTile->numfaces - dm->firstface;
270 
271 /* if (!dm->numfaces)
272  Com_Printf("level: %i -> %i : f %i\n", levelnum, dm->headnode, dm->numfaces);
273 */
274 }
#define LEAFNODE
Definition: defines.h:44
static int entityNum
Definition: levels.cpp:220
int numleafs
Definition: typedefs.h:470
#define VectorCopy(src, dest)
Definition: vector.h:51
void setNegativeVolume()
Sets mins and maxs to their starting points before using addPoint.
Definition: aabb.h:98
short mins[3]
Definition: typedefs.h:381
int brush_start
Definition: levels.cpp:29
static int oldleafs
Definition: levels.cpp:31
#define SPLIT_COORDS
Definition: levels.cpp:119
dBspModel_t models[MAX_MAP_MODELS]
Definition: typedefs.h:468
Definition: aabb.h:42
Definition: bsp.h:61
#define SPLIT_AT_POW2
Definition: levels.cpp:118
const vec3_t vec3_origin
Definition: mathlib.cpp:35
int numplanes
Definition: typedefs.h:474
dBspNode_t nodes[MAX_MAP_NODES]
Definition: typedefs.h:484
void set(const AABB &other)
Copies the values from the given aabb.
Definition: aabb.h:60
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
int numleafbrushes
Definition: typedefs.h:495
int nummapbrushes
Definition: map.cpp:35
vec3_t maxs
Definition: aabb.h:258
void PushInfo(void)
Definition: levels.cpp:33
int nummodels
Definition: typedefs.h:467
void MarkVisibleSides(tree_t *tree, int start, int end)
Definition: portals.cpp:482
int numedges
Definition: typedefs.h:492
bspbrush_t * ChopBrushes(bspbrush_t *head)
Carves any intersecting solid brushes into the minimum number of non-intersecting brushes...
Definition: csg.cpp:376
int numtexinfo
Definition: typedefs.h:486
static int oldnodes
Definition: levels.cpp:31
unsigned short firstface
Definition: typedefs.h:383
static int oldmodels
Definition: levels.cpp:31
void FreeTree(tree_t *tree)
Definition: tree.cpp:102
mapbrush_t mapbrushes[MAX_MAP_BRUSHES]
Definition: map.cpp:34
void expand(const float byVal)
expand the box in all directions, but clip them to the maximum boundaries
Definition: aabb.h:240
static int oldedges
Definition: levels.cpp:31
tree_t * BuildTree(bspbrush_t *brushlist, const vec3_t mins, const vec3_t maxs)
The incoming list will be freed before exiting.
Definition: tree.cpp:182
void BeginModel(int entityNum)
Sets up a new brush model.
Definition: writebsp.cpp:353
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 oldfaces
Definition: levels.cpp:31
#define OBJZERO(obj)
Definition: shared.h:178
static int32_t BuildNodeChildren(const int n[3])
Definition: levels.cpp:67
void ProcessLevelEntityNumber(int entityNumber)
Definition: levels.cpp:222
void ProcessLevel(unsigned int levelnum)
process brushes with that level mask
Definition: levels.cpp:238
int32_t headnode
Definition: typedefs.h:357
static int oldleafbrushes
Definition: levels.cpp:31
void Verb_Printf(const verbosityLevel_t importance, const char *format,...) __attribute__((format(__printf__
int brush_end
Definition: levels.cpp:29
static config_t config
Definition: test_all.cpp:43
dMapTile_t * curTile
Definition: bsp.cpp:32
int numfaces
Definition: typedefs.h:358
static int oldvertexes
Definition: levels.cpp:31
struct node_s * headnode
Definition: bsp.h:62
#define PLANENUM_LEAF
Definition: defines.h:45
AABB nBox
Definition: bsp.h:46
QGL_EXTERN GLint i
Definition: r_gl.h:113
int numnormals
Definition: typedefs.h:477
int numnodes
Definition: typedefs.h:483
int32_t children[2]
Definition: typedefs.h:380
static int oldtexinfo
Definition: levels.cpp:31
int numvertexes
Definition: typedefs.h:480
void FixTjuncs(node_t *headnode)
Definition: faces.cpp:370
Definition: map.h:75
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
int numsurfedges
Definition: typedefs.h:505
void MakeFaces(node_t *headnode)
Definition: faces.cpp:764
void PopInfo(void)
Definition: levels.cpp:48
vec_t vec3_t[3]
Definition: ufotypes.h:39
static int oldsurfedges
Definition: levels.cpp:31
unsigned short numfaces
Definition: typedefs.h:384
#define MAX_WORLD_WIDTH
-MAX_WORLD_WIDTH up tp +MAX_WORLD_WIDTH
Definition: defines.h:288
void MakeTreePortals(tree_t *tree)
Definition: portals.cpp:391
static int32_t ConstructLevelNodes_r(const int levelnum, const AABB &partBox, int entityNum)
Definition: levels.cpp:125
vec3_t mins
Definition: aabb.h:257
static int oldnormals
Definition: levels.cpp:31
int32_t planenum
Definition: typedefs.h:379
Definition: bsp.h:42
int numfaces
Definition: typedefs.h:489
void setMaxs(const vec3_t maxi)
Definition: aabb.h:71
short maxs[3]
Definition: typedefs.h:382
bspbrush_t * MakeBspBrushList(int startbrush, int endbrush, int level, const AABB &clip)
Definition: csg.cpp:292
int MapBrushesBounds(const int startbrush, const int endbrush, const int level, const AABB &clipBox, AABB &bBox)
sets mins and maxs to the smallest sizes that can contain all brushes from startbrush to endbrush tha...
Definition: csg.cpp:264
void PruneNodes(node_t *node)
Definition: tree.cpp:261
int firstface
Definition: typedefs.h:358
static int oldplanes
Definition: levels.cpp:31