/* =========================================================================== Return to Castle Wolfenstein single player GPL Source Code Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company. This file is part of the Return to Castle Wolfenstein single player GPL Source Code (“RTCW SP Source Code”). RTCW SP Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. RTCW SP Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with RTCW SP Source Code. If not, see . In addition, the RTCW SP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW SP Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ //=========================================================================== // // Name: textures.c // Function: textures // Programmer: Mr Elusive (MrElusive@worldentity.com) // Last update: 1999-08-10 // Tab Size: 3 //=========================================================================== #include "qbsp.h" extern int c_nodes; int c_pruned; int freedtreemem = 0; void RemovePortalFromNode( portal_t *portal, node_t *l ); //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== node_t *NodeForPoint( node_t *node, vec3_t origin ) { plane_t *plane; vec_t d; while ( node->planenum != PLANENUM_LEAF ) { plane = &mapplanes[node->planenum]; d = DotProduct( origin, plane->normal ) - plane->dist; if ( d >= 0 ) { node = node->children[0]; } else { node = node->children[1]; } } return node; } //end of the function NodeForPoint //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void Tree_FreePortals_r( node_t *node ) { portal_t *p, *nextp; int s; // free children if ( node->planenum != PLANENUM_LEAF ) { Tree_FreePortals_r( node->children[0] ); Tree_FreePortals_r( node->children[1] ); } // free portals for ( p = node->portals; p; p = nextp ) { s = ( p->nodes[1] == node ); nextp = p->next[s]; RemovePortalFromNode( p, p->nodes[!s] ); #ifdef ME if ( p->winding ) { freedtreemem += MemorySize( p->winding ); } freedtreemem += MemorySize( p ); #endif //ME FreePortal( p ); } node->portals = NULL; } //end of the function Tree_FreePortals_r //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void Tree_Free_r( node_t *node ) { // face_t *f, *nextf; bspbrush_t *brush, *nextbrush; //free children if ( node->planenum != PLANENUM_LEAF ) { Tree_Free_r( node->children[0] ); Tree_Free_r( node->children[1] ); } //end if //free bspbrushes // FreeBrushList (node->brushlist); for ( brush = node->brushlist; brush; brush = nextbrush ) { nextbrush = brush->next; #ifdef ME freedtreemem += MemorySize( brush ); #endif //ME FreeBrush( brush ); } //end for node->brushlist = NULL; /* NOTE: only used when creating Q2 bsp // free faces for (f = node->faces; f; f = nextf) { nextf = f->next; #ifdef ME if (f->w) freedtreemem += MemorySize(f->w); freedtreemem += sizeof(face_t); #endif //ME FreeFace(f); } //end for */ // free the node if ( node->volume ) { #ifdef ME freedtreemem += MemorySize( node->volume ); #endif //ME FreeBrush( node->volume ); } //end if if ( numthreads == 1 ) { c_nodes--; } #ifdef ME freedtreemem += MemorySize( node ); #endif //ME FreeMemory( node ); } //end of the function Tree_Free_r //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void Tree_Free( tree_t *tree ) { //if no tree just return if ( !tree ) { return; } // freedtreemem = 0; // Tree_FreePortals_r( tree->headnode ); Tree_Free_r( tree->headnode ); #ifdef ME freedtreemem += MemorySize( tree ); #endif //ME FreeMemory( tree ); #ifdef ME Log_Print( "freed " ); PrintMemorySize( freedtreemem ); Log_Print( " of tree memory\n" ); #endif //ME } //end of the function Tree_Free //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== tree_t *Tree_Alloc( void ) { tree_t *tree; tree = GetMemory( sizeof( *tree ) ); memset( tree, 0, sizeof( *tree ) ); ClearBounds( tree->mins, tree->maxs ); return tree; } //end of the function Tree_Alloc //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void Tree_Print_r( node_t *node, int depth ) { int i; plane_t *plane; bspbrush_t *bb; for ( i = 0 ; i < depth ; i++ ) printf( " " ); if ( node->planenum == PLANENUM_LEAF ) { if ( !node->brushlist ) { printf( "NULL\n" ); } else { for ( bb = node->brushlist ; bb ; bb = bb->next ) printf( "%i ", bb->original->brushnum ); printf( "\n" ); } return; } plane = &mapplanes[node->planenum]; printf( "#%i (%5.2f %5.2f %5.2f):%5.2f\n", node->planenum, plane->normal[0], plane->normal[1], plane->normal[2], plane->dist ); Tree_Print_r( node->children[0], depth + 1 ); Tree_Print_r( node->children[1], depth + 1 ); } //end of the function Tree_Print_r //=========================================================================== // NODES THAT DON'T SEPERATE DIFFERENT CONTENTS CAN BE PRUNED // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void Tree_PruneNodes_r( node_t *node ) { bspbrush_t *b, *next; if ( node->planenum == PLANENUM_LEAF ) { return; } Tree_PruneNodes_r( node->children[0] ); Tree_PruneNodes_r( node->children[1] ); if ( create_aas ) { if ( ( node->children[0]->contents & CONTENTS_LADDER ) || ( node->children[1]->contents & CONTENTS_LADDER ) ) { return; } } if ( ( node->children[0]->contents & CONTENTS_SOLID ) && ( node->children[1]->contents & CONTENTS_SOLID ) ) { if ( node->faces ) { Error( "node->faces seperating CONTENTS_SOLID" ); } if ( node->children[0]->faces || node->children[1]->faces ) { Error( "!node->faces with children" ); } // FIXME: free stuff node->planenum = PLANENUM_LEAF; node->contents = CONTENTS_SOLID; node->detail_seperator = false; if ( node->brushlist ) { Error( "PruneNodes: node->brushlist" ); } // combine brush lists node->brushlist = node->children[1]->brushlist; for ( b = node->children[0]->brushlist; b; b = next ) { next = b->next; b->next = node->brushlist; node->brushlist = b; } //end for //free the child nodes FreeMemory( node->children[0] ); FreeMemory( node->children[1] ); //two nodes are cut away c_pruned += 2; } //end if } //end of the function Tree_PruneNodes_r //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void Tree_PruneNodes( node_t *node ) { Log_Print( "------- Prune Nodes --------\n" ); c_pruned = 0; Tree_PruneNodes_r( node ); Log_Print( "%5i pruned nodes\n", c_pruned ); } //end of the function Tree_PruneNodes