/* ================ BuildTree_r ================ */ node_t *BuildTree_r (node_t *node, bspbrush_t *brushes) { node_t *newnode; side_t *bestside; int i; bspbrush_t *children[2]; if (numthreads == 1) c_nodes++; if (drawflag) DrawBrushList (brushes, node); // find the best plane to use as a splitter bestside = SelectSplitSide (brushes, node); if (!bestside) { // leaf node node->side = NULL; node->planenum = -1; LeafNode (node, brushes); return node; } // this is a splitplane node node->side = bestside; node->planenum = bestside->planenum & ~1; // always use front facing SplitBrushList (brushes, node, &children[0], &children[1]); FreeBrushList (brushes); // allocate children before recursing for (i=0 ; i<2 ; i++) { newnode = AllocNode (); newnode->parent = node; node->children[i] = newnode; } SplitBrush (node->volume, node->planenum, &node->children[0]->volume, &node->children[1]->volume); // recursively process children for (i=0 ; i<2 ; i++) { node->children[i] = BuildTree_r (node->children[i], children[i]); } return node; }
static node_t *BuildTree_r (node_t *node, bspbrush_t *brushes) { node_t *newnode; side_t *bestside; int i; bspbrush_t *children[2]; if (threadstate.numthreads == 1) c_nodes++; /* find the best plane to use as a splitter */ bestside = SelectSplitSide(brushes, node->volume); if (!bestside) { /* leaf node */ LeafNode(node, brushes); Verb_Printf(VERB_DUMP, "BuildTree_r: Created a leaf node.\n"); return node; } /* make sure the selected plane hasn't been used before. */ CheckPlaneAgainstParents(bestside->planenum, node); Verb_Printf(VERB_DUMP, "BuildTree_r: splitting along plane %i\n", (int)bestside->planenum); /* this is a splitplane node */ node->side = bestside; node->planenum = bestside->planenum & ~1; /* always use front facing */ SplitBrushList(brushes, node->planenum, &children[0], &children[1]); FreeBrushList(brushes); /* allocate children before recursing */ for (i = 0; i < 2; i++) { newnode = AllocNode(); newnode->parent = node; node->children[i] = newnode; } SplitBrush(node->volume, node->planenum, &node->children[0]->volume, &node->children[1]->volume); /* recursively process children */ for (i = 0; i < 2; i++) { node->children[i] = BuildTree_r(node->children[i], children[i]); } return node; }
//thread function, gets nodes from the nodelist and processes them void BuildTreeThread( int threadid ) { node_t *newnode, *node; side_t *bestside; int i, totalmem; bspbrush_t *brushes; for ( node = NextNodeFromList(); node; ) { //if the nodelist isn't empty try to add another thread //if (NodeListSize() > 10) AddThread(BuildTreeThread); //display the number of nodes processed so far if ( numthreads == 1 ) { IncreaseNodeCounter(); } brushes = node->brushlist; if ( numthreads == 1 ) { totalmem = WindingMemory() + c_nodememory + c_brushmemory; if ( totalmem > c_peak_totalbspmemory ) { c_peak_totalbspmemory = totalmem; } //end if c_nodes++; } //endif if ( drawflag ) { DrawBrushList( brushes, node ); } //end if if ( cancelconversion ) { bestside = NULL; } //end if else { // find the best plane to use as a splitter bestside = SelectSplitSide( brushes, node ); } //end else //if there's no split side left if ( !bestside ) { //create a leaf out of the node LeafNode( node, brushes ); if ( node->contents & CONTENTS_SOLID ) { c_solidleafnodes++; } if ( create_aas ) { //free up memory!!! FreeBrushList( node->brushlist ); node->brushlist = NULL; } //end if //free the node volume brush (it is not used anymore) if ( node->volume ) { FreeBrush( node->volume ); node->volume = NULL; } //end if node = NextNodeFromList(); continue; } //end if // this is a splitplane node node->side = bestside; node->planenum = bestside->planenum & ~1; //always use front facing //allocate children for ( i = 0; i < 2; i++ ) { newnode = AllocNode(); newnode->parent = node; node->children[i] = newnode; } //end for //split the brush list in two for both children SplitBrushList( brushes, node, &node->children[0]->brushlist, &node->children[1]->brushlist ); CheckBrushLists( node->children[0]->brushlist, node->children[1]->brushlist ); //free the old brush list FreeBrushList( brushes ); node->brushlist = NULL; //split the volume brush of the node for the children SplitBrush( node->volume, node->planenum, &node->children[0]->volume, &node->children[1]->volume ); if ( !node->children[0]->volume || !node->children[1]->volume ) { Error( "child without volume brush" ); } //end if //free the volume brush if ( node->volume ) { FreeBrush( node->volume ); node->volume = NULL; } //end if //add both children to the node list //AddNodeToList(node->children[0]); AddNodeToList( node->children[1] ); node = node->children[0]; } //end while RemoveThread( threadid ); } //end of the function BuildTreeThread
node_t *BuildTree_r( node_t *node, bspbrush_t *brushes ) { node_t *newnode; side_t *bestside; int i, totalmem; bspbrush_t *children[2]; qprintf( "\r%6d", numrecurse ); numrecurse++; if ( numthreads == 1 ) { totalmem = WindingMemory() + c_nodememory + c_brushmemory; if ( totalmem > c_peak_totalbspmemory ) { c_peak_totalbspmemory = totalmem; } c_nodes++; } //endif if ( drawflag ) { DrawBrushList( brushes, node ); } // find the best plane to use as a splitter bestside = SelectSplitSide( brushes, node ); if ( !bestside ) { // leaf node node->side = NULL; node->planenum = -1; LeafNode( node, brushes ); if ( node->contents & CONTENTS_SOLID ) { c_solidleafnodes++; } if ( create_aas ) { //free up memory!!! FreeBrushList( node->brushlist ); node->brushlist = NULL; //free the node volume brush if ( node->volume ) { FreeBrush( node->volume ); node->volume = NULL; } //end if } //end if return node; } //end if // this is a splitplane node node->side = bestside; node->planenum = bestside->planenum & ~1; // always use front facing //split the brush list in two for both children SplitBrushList( brushes, node, &children[0], &children[1] ); //free the old brush list FreeBrushList( brushes ); // allocate children before recursing for ( i = 0; i < 2; i++ ) { newnode = AllocNode(); newnode->parent = node; node->children[i] = newnode; } //end for //split the volume brush of the node for the children SplitBrush( node->volume, node->planenum, &node->children[0]->volume, &node->children[1]->volume ); if ( create_aas ) { //free the volume brush if ( node->volume ) { FreeBrush( node->volume ); node->volume = NULL; } //end if } //end if // recursively process children for ( i = 0; i < 2; i++ ) { node->children[i] = BuildTree_r( node->children[i], children[i] ); } //end for return node; } //end of the function BuildTree_r