00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "qbsp.h"
00024
00025 extern int c_nodes;
00026 int c_pruned;
00027 int freedtreemem = 0;
00028
00029 void RemovePortalFromNode (portal_t *portal, node_t *l);
00030
00031
00032
00033
00034
00035
00036
00037 node_t *NodeForPoint (node_t *node, vec3_t origin)
00038 {
00039 plane_t *plane;
00040 vec_t d;
00041
00042 while (node->planenum != PLANENUM_LEAF)
00043 {
00044 plane = &mapplanes[node->planenum];
00045 d = DotProduct (origin, plane->normal) - plane->dist;
00046 if (d >= 0)
00047 node = node->children[0];
00048 else
00049 node = node->children[1];
00050 }
00051 return node;
00052 }
00053
00054
00055
00056
00057
00058
00059 void Tree_FreePortals_r (node_t *node)
00060 {
00061 portal_t *p, *nextp;
00062 int s;
00063
00064
00065 if (node->planenum != PLANENUM_LEAF)
00066 {
00067 Tree_FreePortals_r(node->children[0]);
00068 Tree_FreePortals_r(node->children[1]);
00069 }
00070
00071
00072 for (p = node->portals; p; p = nextp)
00073 {
00074 s = (p->nodes[1] == node);
00075 nextp = p->next[s];
00076
00077 RemovePortalFromNode (p, p->nodes[!s]);
00078 #ifdef ME
00079 if (p->winding) freedtreemem += MemorySize(p->winding);
00080 freedtreemem += MemorySize(p);
00081 #endif //ME
00082 FreePortal(p);
00083 }
00084 node->portals = NULL;
00085 }
00086
00087
00088
00089
00090
00091
00092 void Tree_Free_r (node_t *node)
00093 {
00094
00095 bspbrush_t *brush, *nextbrush;
00096
00097
00098 if (node->planenum != PLANENUM_LEAF)
00099 {
00100 Tree_Free_r (node->children[0]);
00101 Tree_Free_r (node->children[1]);
00102 }
00103
00104
00105 for (brush = node->brushlist; brush; brush = nextbrush)
00106 {
00107 nextbrush = brush->next;
00108 #ifdef ME
00109 freedtreemem += MemorySize(brush);
00110 #endif //ME
00111 FreeBrush(brush);
00112 }
00113 node->brushlist = NULL;
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 if (node->volume)
00131 {
00132 #ifdef ME
00133 freedtreemem += MemorySize(node->volume);
00134 #endif //ME
00135 FreeBrush (node->volume);
00136 }
00137
00138 if (numthreads == 1) c_nodes--;
00139 #ifdef ME
00140 freedtreemem += MemorySize(node);
00141 #endif //ME
00142 FreeMemory(node);
00143 }
00144
00145
00146
00147
00148
00149
00150 void Tree_Free(tree_t *tree)
00151 {
00152
00153 if (!tree) return;
00154
00155 freedtreemem = 0;
00156
00157 Tree_FreePortals_r(tree->headnode);
00158 Tree_Free_r(tree->headnode);
00159 #ifdef ME
00160 freedtreemem += MemorySize(tree);
00161 #endif //ME
00162 FreeMemory(tree);
00163 #ifdef ME
00164 Log_Print("freed ");
00165 PrintMemorySize(freedtreemem);
00166 Log_Print(" of tree memory\n");
00167 #endif //ME
00168 }
00169
00170
00171
00172
00173
00174
00175 tree_t *Tree_Alloc(void)
00176 {
00177 tree_t *tree;
00178
00179 tree = GetMemory(sizeof(*tree));
00180 memset (tree, 0, sizeof(*tree));
00181 ClearBounds (tree->mins, tree->maxs);
00182
00183 return tree;
00184 }
00185
00186
00187
00188
00189
00190
00191 void Tree_Print_r (node_t *node, int depth)
00192 {
00193 int i;
00194 plane_t *plane;
00195 bspbrush_t *bb;
00196
00197 for (i=0 ; i<depth ; i++)
00198 printf (" ");
00199 if (node->planenum == PLANENUM_LEAF)
00200 {
00201 if (!node->brushlist)
00202 printf ("NULL\n");
00203 else
00204 {
00205 for (bb=node->brushlist ; bb ; bb=bb->next)
00206 printf ("%i ", bb->original->brushnum);
00207 printf ("\n");
00208 }
00209 return;
00210 }
00211
00212 plane = &mapplanes[node->planenum];
00213 printf ("#%i (%5.2f %5.2f %5.2f):%5.2f\n", node->planenum,
00214 plane->normal[0], plane->normal[1], plane->normal[2],
00215 plane->dist);
00216 Tree_Print_r (node->children[0], depth+1);
00217 Tree_Print_r (node->children[1], depth+1);
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 void Tree_PruneNodes_r (node_t *node)
00227 {
00228 bspbrush_t *b, *next;
00229
00230 if (node->planenum == PLANENUM_LEAF) return;
00231
00232 Tree_PruneNodes_r (node->children[0]);
00233 Tree_PruneNodes_r (node->children[1]);
00234
00235 if (create_aas)
00236 {
00237 if ((node->children[0]->contents & CONTENTS_LADDER) ||
00238 (node->children[1]->contents & CONTENTS_LADDER)) return;
00239 }
00240
00241 if ((node->children[0]->contents & CONTENTS_SOLID)
00242 && (node->children[1]->contents & CONTENTS_SOLID))
00243 {
00244 if (node->faces)
00245 Error ("node->faces seperating CONTENTS_SOLID");
00246 if (node->children[0]->faces || node->children[1]->faces)
00247 Error ("!node->faces with children");
00248
00249 node->planenum = PLANENUM_LEAF;
00250 node->contents = CONTENTS_SOLID;
00251 node->detail_seperator = false;
00252
00253 if (node->brushlist)
00254 Error ("PruneNodes: node->brushlist");
00255
00256 node->brushlist = node->children[1]->brushlist;
00257
00258 for (b = node->children[0]->brushlist; b; b = next)
00259 {
00260 next = b->next;
00261 b->next = node->brushlist;
00262 node->brushlist = b;
00263 }
00264
00265 FreeMemory(node->children[0]);
00266 FreeMemory(node->children[1]);
00267
00268 c_pruned += 2;
00269 }
00270 }
00271
00272
00273
00274
00275
00276
00277 void Tree_PruneNodes(node_t *node)
00278 {
00279 Log_Print("------- Prune Nodes --------\n");
00280 c_pruned = 0;
00281 Tree_PruneNodes_r(node);
00282 Log_Print("%5i pruned nodes\n", c_pruned);
00283 }