UFO: Alien Invasion
Loading...
Searching...
No Matches
levels.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 "levels.h"
26#include "bsp.h"
27
28
30
32
33void PushInfo (void)
34{
35 oldmodels = curTile->nummodels;
36 oldleafs = curTile->numleafs;
37 oldleafbrushes = curTile->numleafbrushes;
38 oldplanes = curTile->numplanes;
39 oldvertexes = curTile->numvertexes;
40 oldnormals = curTile->numnormals;
41 oldnodes = curTile->numnodes;
42 oldtexinfo = curTile->numtexinfo;
43 oldfaces = curTile->numfaces;
44 oldedges = curTile->numedges;
45 oldsurfedges = curTile->numsurfedges;
46}
47
48void PopInfo (void)
49{
50 curTile->nummodels = oldmodels;
51 curTile->numleafs = oldleafs;
52 curTile->numleafbrushes = oldleafbrushes;
53 curTile->numplanes = oldplanes;
54 curTile->numvertexes = oldvertexes;
55 curTile->numnormals = oldnormals;
56 curTile->numnodes = oldnodes;
57 curTile->numtexinfo = oldtexinfo;
58 curTile->numfaces = oldfaces;
59 curTile->numedges = oldedges;
60 curTile->numsurfedges = oldsurfedges;
61}
62
67static 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
125static 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 */
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
220static int entityNum;
221
222void ProcessLevelEntityNumber (int entityNumber)
223{
224 entityNum = entityNumber;
225}
226
238void 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}
int brush_start
Definition levels.cpp:29
void FreeTree(tree_t *tree)
Definition tree.cpp:102
int brush_end
Definition bsp.h:77
void MarkVisibleSides(tree_t *tree, int start, int end)
Definition portals.cpp:482
void MakeFaces(node_t *headnode)
Definition faces.cpp:764
bspbrush_t * ChopBrushes(bspbrush_t *head)
Carves any intersecting solid brushes into the minimum number of non-intersecting brushes.
Definition csg.cpp:376
bspbrush_t * MakeBspBrushList(int startbrush, int endbrush, int level, const AABB &clip)
Definition csg.cpp:292
void MakeTreePortals(tree_t *tree)
Definition portals.cpp:391
void FixTjuncs(node_t *headnode)
Definition faces.cpp:370
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
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
int nummapbrushes
Definition map.cpp:35
void PruneNodes(node_t *node)
Definition tree.cpp:261
mapbrush_t mapbrushes[MAX_MAP_BRUSHES]
Definition map.cpp:34
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 BeginModel(int entityNum)
Sets up a new brush model.
Definition writebsp.cpp:353
Definition aabb.h:42
vec3_t maxs
Definition aabb.h:258
void setMaxs(const vec3_t maxi)
Definition aabb.h:71
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
void expand(const float byVal)
expand the box in all directions, but clip them to the maximum boundaries
Definition aabb.h:240
#define LEAFNODE
Definition defines.h:44
#define PLANENUM_LEAF
Definition defines.h:45
#define MAX_WORLD_WIDTH
-MAX_WORLD_WIDTH up tp +MAX_WORLD_WIDTH
Definition defines.h:288
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
void ProcessLevel(unsigned int levelnum)
process brushes with that level mask
Definition levels.cpp:238
static int oldplanes
Definition levels.cpp:31
static int oldtexinfo
Definition levels.cpp:31
static int32_t BuildNodeChildren(const int n[3])
Definition levels.cpp:67
static int oldnormals
Definition levels.cpp:31
static int oldleafs
Definition levels.cpp:31
static int entityNum
Definition levels.cpp:220
static int oldedges
Definition levels.cpp:31
static int oldfaces
Definition levels.cpp:31
void PopInfo(void)
Definition levels.cpp:48
#define SPLIT_AT_POW2
Definition levels.cpp:118
static int oldleafbrushes
Definition levels.cpp:31
static int oldmodels
Definition levels.cpp:31
static int oldsurfedges
Definition levels.cpp:31
void ProcessLevelEntityNumber(int entityNumber)
Definition levels.cpp:222
void PushInfo(void)
Definition levels.cpp:33
static int oldnodes
Definition levels.cpp:31
static int oldvertexes
Definition levels.cpp:31
#define SPLIT_COORDS
Definition levels.cpp:119
static int32_t ConstructLevelNodes_r(const int levelnum, const AABB &partBox, int entityNum)
Definition levels.cpp:125
const vec3_t vec3_origin
Definition mathlib.cpp:35
QGL_EXTERN GLint i
Definition r_gl.h:113
#define OBJZERO(obj)
Definition shared.h:178
int32_t headnode
Definition typedefs.h:357
int firstface
Definition typedefs.h:358
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
Definition bsp.h:42
AABB nBox
Definition bsp.h:46
Definition bsp.h:61
struct node_s * headnode
Definition bsp.h:62
static config_t config
Definition test_all.cpp:43
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_DUMP
Definition shared.h:47
vec_t vec3_t[3]
Definition ufotypes.h:39
#define VectorCopy(src, dest)
Definition vector.h:51