00001 00005 /* 00006 Copyright (C) 1997-2001 Id Software, Inc. 00007 00008 This program is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU General Public License 00010 as published by the Free Software Foundation; either version 2 00011 of the License, or (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 00017 See the GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00022 00023 */ 00024 00025 #include "bsp.h" 00026 00027 extern int c_nodes; 00028 00029 static void FreeTreePortals_r (node_t *node) 00030 { 00031 portal_t *p, *nextp; 00032 00033 /* free children */ 00034 if (node->planenum != PLANENUM_LEAF) { 00035 FreeTreePortals_r(node->children[0]); 00036 FreeTreePortals_r(node->children[1]); 00037 } 00038 00039 /* free portals */ 00040 for (p = node->portals; p; p = nextp) { 00041 const int s = (p->nodes[1] == node); 00042 nextp = p->next[s]; 00043 00044 RemovePortalFromNode(p, p->nodes[!s]); 00045 FreePortal(p); 00046 } 00047 node->portals = NULL; 00048 } 00049 00050 static void FreeTree_r (node_t *node) 00051 { 00052 face_t *f, *nextf; 00053 00054 /* free children */ 00055 if (node->planenum != PLANENUM_LEAF) { 00056 FreeTree_r(node->children[0]); 00057 FreeTree_r(node->children[1]); 00058 } 00059 00060 /* free bspbrushes */ 00061 FreeBrushList(node->brushlist); 00062 00063 /* free faces */ 00064 for (f = node->faces; f; f = nextf) { 00065 nextf = f->next; 00066 FreeFace(f); 00067 } 00068 00069 /* free the node */ 00070 if (node->volume) 00071 FreeBrush(node->volume); 00072 00073 if (threadstate.numthreads == 1) 00074 c_nodes--; 00075 Mem_Free(node); 00076 } 00077 00078 00079 void FreeTree (tree_t *tree) 00080 { 00081 FreeTreePortals_r(tree->headnode); 00082 FreeTree_r(tree->headnode); 00083 Mem_Free(tree); 00084 } 00085 00086 /*========================================================= 00087 NODES THAT DON'T SEPERATE DIFFERENT CONTENTS CAN BE PRUNED 00088 =========================================================*/ 00089 00090 static int c_pruned; 00091 00096 static void PruneNodes_r (node_t *node) 00097 { 00098 bspbrush_t *b, *next; 00099 00100 if (node->planenum == PLANENUM_LEAF) 00101 return; 00102 PruneNodes_r(node->children[0]); 00103 PruneNodes_r(node->children[1]); 00104 00105 if ((node->children[0]->contentFlags & CONTENTS_SOLID) 00106 && (node->children[1]->contentFlags & CONTENTS_SOLID)) { 00107 if (node->faces) 00108 Sys_Error("node->faces seperating CONTENTS_SOLID"); 00109 if (node->children[0]->faces || node->children[1]->faces) 00110 Sys_Error("!node->faces with children"); 00111 00113 node->planenum = PLANENUM_LEAF; 00114 node->contentFlags = CONTENTS_SOLID; 00115 00116 if (node->brushlist) 00117 Sys_Error("PruneNodes: node->brushlist"); 00118 00119 /* combine brush lists */ 00120 node->brushlist = node->children[1]->brushlist; 00121 00122 for (b = node->children[0]->brushlist; b; b = next) { 00123 next = b->next; 00124 b->next = node->brushlist; 00125 node->brushlist = b; 00126 } 00127 00128 c_pruned++; 00129 } 00130 } 00131 00135 void PruneNodes (node_t *node) 00136 { 00137 Verb_Printf(VERB_EXTRA, "--- PruneNodes ---\n"); 00138 c_pruned = 0; 00139 PruneNodes_r(node); 00140 Verb_Printf(VERB_EXTRA, "%5i pruned nodes\n", c_pruned); 00141 }