//=========================================================================== // build the bsp tree using a node list // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void BuildTree( tree_t *tree ) { int i; firstnode = NULL; lastnode = NULL; //use a node queue or node stack if ( use_nodequeue ) { AddNodeToList = AddNodeToQueue; } else { AddNodeToList = AddNodeToStack;} //setup thread locking ThreadSetupLock(); ThreadSetupSemaphore(); numwaiting = 0; // Log_Print( "%6d threads max\n", numthreads ); if ( use_nodequeue ) { Log_Print( "breadth first bsp building\n" ); } else { Log_Print( "depth first bsp building\n" );} qprintf( "%6d splits", 0 ); //add the first node to the list AddNodeToList( tree->headnode ); //start the threads for ( i = 0; i < numthreads; i++ ) AddThread( BuildTreeThread ); //wait for all added threads to be finished WaitForAllThreadsFinished(); //shutdown the thread locking ThreadShutdownLock(); ThreadShutdownSemaphore(); } //end of the function BuildTree
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PBook::Insert(): Insert a position. Returns OK if a new position // was inserted, or updates the comment and returns ERROR_Exists if // the position was already in the PBook. errorT PBook::Insert (Position * pos, const char * comment) { ASSERT (pos && comment); bookNodeT * node; errorT err; uint material = pos->GetCount(WHITE) + pos->GetCount(BLACK); compactBoardStr cboard; pos->PrintCompactStr (cboard); err = Tree[material]->Insert (cboard, &node); if (err != OK) { // Already exists; we overwrite the old data. delete[] node->data.comment; } else { SetHashFlag (pos); AddNodeToList (node); } node->data.comment = strDuplicate (comment); node->data.enpassant = pos->GetEPTarget(); Altered = true; if (material < LeastMaterial) { LeastMaterial = material; } Stats_Inserts[material]++; Stats_TotalInserts++; return err; }
//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