tree.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "qbsp.h"
  19. extern int c_nodes;
  20. int c_pruned;
  21. int freedtreemem = 0;
  22. void RemovePortalFromNode (portal_t *portal, node_t *l);
  23. //===========================================================================
  24. //
  25. // Parameter: -
  26. // Returns: -
  27. // Changes Globals: -
  28. //===========================================================================
  29. node_t *NodeForPoint (node_t *node, vec3_t origin)
  30. {
  31. plane_t *plane;
  32. vec_t d;
  33. while (node->planenum != PLANENUM_LEAF)
  34. {
  35. plane = &mapplanes[node->planenum];
  36. d = DotProduct (origin, plane->normal) - plane->dist;
  37. if (d >= 0)
  38. node = node->children[0];
  39. else
  40. node = node->children[1];
  41. }
  42. return node;
  43. } //end of the function NodeForPoint
  44. //===========================================================================
  45. //
  46. // Parameter: -
  47. // Returns: -
  48. // Changes Globals: -
  49. //===========================================================================
  50. void Tree_FreePortals_r (node_t *node)
  51. {
  52. portal_t *p, *nextp;
  53. int s;
  54. // free children
  55. if (node->planenum != PLANENUM_LEAF)
  56. {
  57. Tree_FreePortals_r(node->children[0]);
  58. Tree_FreePortals_r(node->children[1]);
  59. }
  60. // free portals
  61. for (p = node->portals; p; p = nextp)
  62. {
  63. s = (p->nodes[1] == node);
  64. nextp = p->next[s];
  65. RemovePortalFromNode (p, p->nodes[!s]);
  66. #ifdef ME
  67. if (p->winding) freedtreemem += MemorySize(p->winding);
  68. freedtreemem += MemorySize(p);
  69. #endif //ME
  70. FreePortal(p);
  71. }
  72. node->portals = NULL;
  73. } //end of the function Tree_FreePortals_r
  74. //===========================================================================
  75. //
  76. // Parameter: -
  77. // Returns: -
  78. // Changes Globals: -
  79. //===========================================================================
  80. void Tree_Free_r (node_t *node)
  81. {
  82. // face_t *f, *nextf;
  83. bspbrush_t *brush, *nextbrush;
  84. //free children
  85. if (node->planenum != PLANENUM_LEAF)
  86. {
  87. Tree_Free_r (node->children[0]);
  88. Tree_Free_r (node->children[1]);
  89. } //end if
  90. //free bspbrushes
  91. // FreeBrushList (node->brushlist);
  92. for (brush = node->brushlist; brush; brush = nextbrush)
  93. {
  94. nextbrush = brush->next;
  95. #ifdef ME
  96. freedtreemem += MemorySize(brush);
  97. #endif //ME
  98. FreeBrush(brush);
  99. } //end for
  100. node->brushlist = NULL;
  101. /*
  102. NOTE: only used when creating Q2 bsp
  103. // free faces
  104. for (f = node->faces; f; f = nextf)
  105. {
  106. nextf = f->next;
  107. #ifdef ME
  108. if (f->w) freedtreemem += MemorySize(f->w);
  109. freedtreemem += sizeof(face_t);
  110. #endif //ME
  111. FreeFace(f);
  112. } //end for
  113. */
  114. // free the node
  115. if (node->volume)
  116. {
  117. #ifdef ME
  118. freedtreemem += MemorySize(node->volume);
  119. #endif //ME
  120. FreeBrush (node->volume);
  121. } //end if
  122. if (numthreads == 1) c_nodes--;
  123. #ifdef ME
  124. freedtreemem += MemorySize(node);
  125. #endif //ME
  126. FreeMemory(node);
  127. } //end of the function Tree_Free_r
  128. //===========================================================================
  129. //
  130. // Parameter: -
  131. // Returns: -
  132. // Changes Globals: -
  133. //===========================================================================
  134. void Tree_Free(tree_t *tree)
  135. {
  136. //if no tree just return
  137. if (!tree) return;
  138. //
  139. freedtreemem = 0;
  140. //
  141. Tree_FreePortals_r(tree->headnode);
  142. Tree_Free_r(tree->headnode);
  143. #ifdef ME
  144. freedtreemem += MemorySize(tree);
  145. #endif //ME
  146. FreeMemory(tree);
  147. #ifdef ME
  148. Log_Print("freed ");
  149. PrintMemorySize(freedtreemem);
  150. Log_Print(" of tree memory\n");
  151. #endif //ME
  152. } //end of the function Tree_Free
  153. //===========================================================================
  154. //
  155. // Parameter: -
  156. // Returns: -
  157. // Changes Globals: -
  158. //===========================================================================
  159. tree_t *Tree_Alloc(void)
  160. {
  161. tree_t *tree;
  162. tree = GetMemory(sizeof(*tree));
  163. memset (tree, 0, sizeof(*tree));
  164. ClearBounds (tree->mins, tree->maxs);
  165. return tree;
  166. } //end of the function Tree_Alloc
  167. //===========================================================================
  168. //
  169. // Parameter: -
  170. // Returns: -
  171. // Changes Globals: -
  172. //===========================================================================
  173. void Tree_Print_r (node_t *node, int depth)
  174. {
  175. int i;
  176. plane_t *plane;
  177. bspbrush_t *bb;
  178. for (i=0 ; i<depth ; i++)
  179. printf (" ");
  180. if (node->planenum == PLANENUM_LEAF)
  181. {
  182. if (!node->brushlist)
  183. printf ("NULL\n");
  184. else
  185. {
  186. for (bb=node->brushlist ; bb ; bb=bb->next)
  187. printf ("%i ", bb->original->brushnum);
  188. printf ("\n");
  189. }
  190. return;
  191. }
  192. plane = &mapplanes[node->planenum];
  193. printf ("#%i (%5.2f %5.2f %5.2f):%5.2f\n", node->planenum,
  194. plane->normal[0], plane->normal[1], plane->normal[2],
  195. plane->dist);
  196. Tree_Print_r (node->children[0], depth+1);
  197. Tree_Print_r (node->children[1], depth+1);
  198. } //end of the function Tree_Print_r
  199. //===========================================================================
  200. // NODES THAT DON'T SEPERATE DIFFERENT CONTENTS CAN BE PRUNED
  201. //
  202. // Parameter: -
  203. // Returns: -
  204. // Changes Globals: -
  205. //===========================================================================
  206. void Tree_PruneNodes_r (node_t *node)
  207. {
  208. bspbrush_t *b, *next;
  209. if (node->planenum == PLANENUM_LEAF) return;
  210. Tree_PruneNodes_r (node->children[0]);
  211. Tree_PruneNodes_r (node->children[1]);
  212. if (create_aas)
  213. {
  214. if ((node->children[0]->contents & CONTENTS_LADDER) ||
  215. (node->children[1]->contents & CONTENTS_LADDER)) return;
  216. }
  217. if ((node->children[0]->contents & CONTENTS_SOLID)
  218. && (node->children[1]->contents & CONTENTS_SOLID))
  219. {
  220. if (node->faces)
  221. Error ("node->faces seperating CONTENTS_SOLID");
  222. if (node->children[0]->faces || node->children[1]->faces)
  223. Error ("!node->faces with children");
  224. // FIXME: free stuff
  225. node->planenum = PLANENUM_LEAF;
  226. node->contents = CONTENTS_SOLID;
  227. node->detail_seperator = false;
  228. if (node->brushlist)
  229. Error ("PruneNodes: node->brushlist");
  230. // combine brush lists
  231. node->brushlist = node->children[1]->brushlist;
  232. for (b = node->children[0]->brushlist; b; b = next)
  233. {
  234. next = b->next;
  235. b->next = node->brushlist;
  236. node->brushlist = b;
  237. } //end for
  238. //free the child nodes
  239. FreeMemory(node->children[0]);
  240. FreeMemory(node->children[1]);
  241. //two nodes are cut away
  242. c_pruned += 2;
  243. } //end if
  244. } //end of the function Tree_PruneNodes_r
  245. //===========================================================================
  246. //
  247. // Parameter: -
  248. // Returns: -
  249. // Changes Globals: -
  250. //===========================================================================
  251. void Tree_PruneNodes(node_t *node)
  252. {
  253. Log_Print("------- Prune Nodes --------\n");
  254. c_pruned = 0;
  255. Tree_PruneNodes_r(node);
  256. Log_Print("%5i pruned nodes\n", c_pruned);
  257. } //end of the function Tree_PruneNodes