UFO: Alien Invasion
Loading...
Searching...
No Matches
tree.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
29
35{
36 return Mem_AllocType(node_t);
37}
38
39static void FreeTreePortals_r (node_t* node)
40{
41 portal_t* p, *nextp;
42
43 /* free children */
44 if (node->planenum != PLANENUM_LEAF) {
47 }
48
49 /* free portals */
50 for (p = node->portals; p; p = nextp) {
51 const int s = (p->nodes[1] == node);
52 nextp = p->next[s];
53
54 RemovePortalFromNode(p, p->nodes[!s]);
55 FreePortal(p);
56 }
57 node->portals = nullptr;
58}
59
60static void FreeTree_r (node_t* node)
61{
62 face_t* f, *nextf;
63
64 /* free children */
65 if (node->planenum != PLANENUM_LEAF) {
66 FreeTree_r(node->children[0]);
67 FreeTree_r(node->children[1]);
68 }
69
70 /* free bspbrushes */
72
73 /* free faces */
74 for (f = node->faces; f; f = nextf) {
75 nextf = f->next;
76 FreeFace(f);
77 }
78
79 /* free the node */
80 if (node->volume)
81 FreeBrush(node->volume);
82
83 if (threadstate.numthreads == 1)
84 c_nodes--;
85 Mem_Free(node);
86}
87
88
93{
95
96 tree->aabb.setNegativeVolume();
97
98 return tree;
99}
100
101
102void FreeTree (tree_t* tree)
103{
105 FreeTree_r(tree->headnode);
106 Mem_Free(tree);
107}
108
109
110static void CheckPlaneAgainstParents (uint16_t pnum, const node_t* node)
111{
112 node_t* p;
113
114 for (p = node->parent; p; p = p->parent) {
115 if (p->planenum == pnum)
116 Sys_Error("Tried parent");
117 }
118}
119
120static void LeafNode (node_t* node, bspbrush_t* brushes)
121{
122 node->side = nullptr;
123 node->planenum = PLANENUM_LEAF;
124
125 Verb_Printf(VERB_DUMP, "LeafNode: scanning brushes.\n");
126
127 node->contentFlags = BrushListCalcContents(brushes);
128 node->brushlist = brushes;
129}
130
131static node_t* BuildTree_r (node_t* node, bspbrush_t* brushes)
132{
133 node_t* newnode;
134 side_t* bestside;
135 int i;
136 bspbrush_t* children[2];
137
138 if (threadstate.numthreads == 1)
139 c_nodes++;
140
141 /* find the best plane to use as a splitter */
142 bestside = SelectSplitSide(brushes, node->volume);
143 if (!bestside) {
144 /* leaf node */
145 LeafNode(node, brushes);
146 Verb_Printf(VERB_DUMP, "BuildTree_r: Created a leaf node.\n");
147 return node;
148 }
149 /* make sure the selected plane hasn't been used before. */
150 CheckPlaneAgainstParents(bestside->planenum, node);
151
152 Verb_Printf(VERB_DUMP, "BuildTree_r: splitting along plane %i\n", (int)bestside->planenum);
153
154 /* this is a splitplane node */
155 node->side = bestside;
156 node->planenum = bestside->planenum & ~1; /* always use front facing */
157
158 SplitBrushList(brushes, node->planenum, &children[0], &children[1]);
159 FreeBrushList(brushes);
160
161 /* allocate children before recursing */
162 for (i = 0; i < 2; i++) {
163 newnode = AllocNode();
164 newnode->parent = node;
165 node->children[i] = newnode;
166 }
167
168 SplitBrush(node->volume, node->planenum, &node->children[0]->volume,
169 &node->children[1]->volume);
170
171 /* recursively process children */
172 for (i = 0; i < 2; i++) {
173 node->children[i] = BuildTree_r(node->children[i], children[i]);
174 }
175
176 return node;
177}
178
182tree_t* BuildTree (bspbrush_t* brushlist, const vec3_t mins, const vec3_t maxs)
183{
184 node_t* node;
185 tree_t* tree;
186 AABB blBox;
187
188 Verb_Printf(VERB_EXTRA, "--- BrushBSP ---\n");
189
190 tree = AllocTree();
191
192 blBox.setNegativeVolume();
193 BrushlistCalcStats(brushlist, blBox);
194 tree->aabb.add(blBox);
195
196 c_nodes = 0;
197 c_nonvis = 0;
198 node = AllocNode();
199
200 node->volume = BrushFromBounds(mins, maxs);
201
202 tree->headnode = node;
203
204 node = BuildTree_r(node, brushlist);
205
206 Verb_Printf(VERB_EXTRA, "%5i visible nodes\n", c_nodes / 2 - c_nonvis);
207 Verb_Printf(VERB_EXTRA, "%5i nonvis nodes\n", c_nonvis);
208 Verb_Printf(VERB_EXTRA, "%5i leafs\n", (c_nodes + 1) / 2);
209 return tree;
210}
211
212/*=========================================================
213NODES THAT DON'T SEPERATE DIFFERENT CONTENTS CAN BE PRUNED
214=========================================================*/
215
216static int c_pruned;
217
222static void PruneNodes_r (node_t* node)
223{
224 bspbrush_t* b, *next;
225
226 if (node->planenum == PLANENUM_LEAF)
227 return;
228 PruneNodes_r(node->children[0]);
229 PruneNodes_r(node->children[1]);
230
231 if ((node->children[0]->contentFlags & CONTENTS_SOLID)
232 && (node->children[1]->contentFlags & CONTENTS_SOLID)) {
233 if (node->faces)
234 Sys_Error("node->faces seperating CONTENTS_SOLID");
235 if (node->children[0]->faces || node->children[1]->faces)
236 Sys_Error("!node->faces with children");
237
239 node->planenum = PLANENUM_LEAF;
241
242 if (node->brushlist)
243 Sys_Error("PruneNodes: node->brushlist");
244
245 /* combine brush lists */
246 node->brushlist = node->children[1]->brushlist;
247
248 for (b = node->children[0]->brushlist; b; b = next) {
249 next = b->next;
250 b->next = node->brushlist;
251 node->brushlist = b;
252 }
253
254 c_pruned++;
255 }
256}
257
261void PruneNodes (node_t* node)
262{
263 Verb_Printf(VERB_EXTRA, "--- PruneNodes ---\n");
264 c_pruned = 0;
265 PruneNodes_r(node);
266 Verb_Printf(VERB_EXTRA, "%5i pruned nodes\n", c_pruned);
267}
void FreePortal(portal_t *p)
Definition portals.cpp:52
void RemovePortalFromNode(portal_t *portal, node_t *l)
Removes references to the given portal from the given node.
Definition portals.cpp:102
void FreeFace(face_t *f)
Definition faces.cpp:133
bspbrush_t * BrushFromBounds(const vec3_t mins, const vec3_t maxs)
Creates a new axial brush.
Definition bspbrush.cpp:87
void FreeBrushList(bspbrush_t *brushes)
Definition bspbrush.cpp:193
void FreeBrush(bspbrush_t *brushes)
Definition bspbrush.cpp:179
side_t * SelectSplitSide(bspbrush_t *brushes, bspbrush_t *volume)
Using a heuristic, choses one of the sides out of the brushlist to partition the brushes with.
Definition bspbrush.cpp:416
int c_nodes
Definition tree.cpp:27
void SplitBrush(const bspbrush_t *brush, uint16_t planenum, bspbrush_t **front, bspbrush_t **back)
Generates two new brushes, leaving the original unchanged.
Definition bspbrush.cpp:544
uint32_t BrushListCalcContents(bspbrush_t *brushlist)
Collects the contentsflags of the brushes in the given list.
Definition bspbrush.cpp:300
void BrushlistCalcStats(bspbrush_t *brushlist, AABB &blBox)
Counts the faces and calculate the aabb.
Definition bspbrush.cpp:759
int c_nonvis
Definition tree.cpp:28
void SplitBrushList(bspbrush_t *brushes, uint16_t planenum, bspbrush_t **front, bspbrush_t **back)
Definition bspbrush.cpp:700
Definition aabb.h:42
void setNegativeVolume()
Sets mins and maxs to their starting points before using addPoint.
Definition aabb.h:98
void add(const vec3_t point)
If the point is outside the box, expand the box to accommodate it.
Definition aabb.cpp:57
#define CONTENTS_SOLID
Definition defines.h:223
#define PLANENUM_LEAF
Definition defines.h:45
void Sys_Error(const char *error,...)
Definition g_main.cpp:421
#define Mem_Free(ptr)
Definition mem.h:35
#define Mem_AllocType(type)
Definition mem.h:39
QGL_EXTERN GLfloat f
Definition r_gl.h:114
QGL_EXTERN GLint i
Definition r_gl.h:113
struct bspbrush_s * next
Definition bspbrush.h:36
Definition map.h:42
Definition bsp.h:42
int32_t planenum
Definition bsp.h:44
struct node_s * parent
Definition bsp.h:45
int32_t contentFlags
Definition bsp.h:56
bspbrush_t * brushlist
Definition bsp.h:55
side_t * side
Definition bsp.h:50
face_t * faces
Definition bsp.h:52
struct portal_s * portals
Definition bsp.h:58
bspbrush_t * volume
Definition bsp.h:47
struct node_s * children[2]
Definition bsp.h:51
struct node_s * nodes[2]
Definition map.h:113
struct portal_s * next[2]
Definition map.h:114
Definition map.h:60
uint16_t planenum
Definition map.h:61
Definition bsp.h:61
struct node_s * headnode
Definition bsp.h:62
AABB aabb
Definition bsp.h:64
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
threadstate_t threadstate
Definition threads.cpp:32
void FreeTree(tree_t *tree)
Definition tree.cpp:102
static node_t * BuildTree_r(node_t *node, bspbrush_t *brushes)
Definition tree.cpp:131
static int c_pruned
Definition tree.cpp:216
static void FreeTreePortals_r(node_t *node)
Definition tree.cpp:39
static void FreeTree_r(node_t *node)
Definition tree.cpp:60
static void LeafNode(node_t *node, bspbrush_t *brushes)
Definition tree.cpp:120
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 PruneNodes(node_t *node)
Definition tree.cpp:261
tree_t * AllocTree(void)
Allocates a tree and initializes it.
Definition tree.cpp:92
static void CheckPlaneAgainstParents(uint16_t pnum, const node_t *node)
Definition tree.cpp:110
node_t * AllocNode(void)
Definition tree.cpp:34
static void PruneNodes_r(node_t *node)
Will cut solid nodes by recursing down the bsp tree.
Definition tree.cpp:222
vec_t vec3_t[3]
Definition ufotypes.h:39