Exemple #1
0
/**
 * @brief The incoming list will be freed before exiting
 */
tree_t *BuildTree (bspbrush_t *brushlist, const vec3_t mins, const vec3_t maxs)
{
	node_t *node;
	tree_t *tree;
	vec3_t blmins, blmaxs;

	Verb_Printf(VERB_EXTRA, "--- BrushBSP ---\n");

	tree = AllocTree();

	ClearBounds(blmins, blmaxs);
	BrushlistCalcStats(brushlist, blmins, blmaxs);
	tree->aabb.add(blmins);
	tree->aabb.add(blmaxs);

	c_nodes = 0;
	c_nonvis = 0;
	node = AllocNode();

	node->volume = BrushFromBounds(mins, maxs);

	tree->headnode = node;

	node = BuildTree_r(node, brushlist);

	Verb_Printf(VERB_EXTRA, "%5i visible nodes\n", c_nodes / 2 - c_nonvis);
	Verb_Printf(VERB_EXTRA, "%5i nonvis nodes\n", c_nonvis);
	Verb_Printf(VERB_EXTRA, "%5i leafs\n", (c_nodes + 1) / 2);
	return tree;
}
Exemple #2
0
/*
================
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;
}
Exemple #3
0
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;
}
/*
=================
BrushBSP

The incoming list will be freed before exiting
=================
*/
tree_t *BrushBSP (bspbrush_t *brushlist, Vector& mins, Vector& maxs)
{
	node_t		*node;
	bspbrush_t	*b;
	int			c_faces, c_nonvisfaces;
	int			c_brushes;
	tree_t		*tree;
	int			i;
	vec_t		volume;

	qprintf ("--- BrushBSP ---\n");

	tree = AllocTree ();

	c_faces = 0;
	c_nonvisfaces = 0;
	c_brushes = 0;
	for (b=brushlist ; b ; b=b->next)
	{
		c_brushes++;

		volume = BrushVolume (b);
		if (volume < microvolume)
		{
			Warning("Brush %i: WARNING, microbrush\n", b->original->id);
		}

		for (i=0 ; i<b->numsides ; i++)
		{
			if (b->sides[i].bevel)
				continue;
			if (!b->sides[i].winding)
				continue;
			if (b->sides[i].texinfo == TEXINFO_NODE)
				continue;
			if (b->sides[i].visible)
				c_faces++;
			else
				c_nonvisfaces++;
		}

		AddPointToBounds (b->mins, tree->mins, tree->maxs);
		AddPointToBounds (b->maxs, tree->mins, tree->maxs);
	}

	qprintf ("%5i brushes\n", c_brushes);
	qprintf ("%5i visible faces\n", c_faces);
	qprintf ("%5i nonvisible faces\n", c_nonvisfaces);

	c_nodes = 0;
	c_nonvis = 0;
	node = AllocNode ();

	node->volume = BrushFromBounds (mins, maxs);

	tree->headnode = node;

	node = BuildTree_r (node, brushlist);
	qprintf ("%5i visible nodes\n", c_nodes/2 - c_nonvis);
	qprintf ("%5i nonvis nodes\n", c_nonvis);
	qprintf ("%5i leafs\n", (c_nodes+1)/2);
#if 0
{	// debug code
static node_t	*tnode;
Vector	p;

p[0] = -1469;
p[1] = -118;
p[2] = 119;
tnode = PointInLeaf (tree->headnode, p);
Msg("contents: %i\n", tnode->contents);
p[0] = 0;
}
#endif
	return tree;
}
Exemple #5
0
/*
 * =================
 * BrushBSP
 *
 * The incoming list will be freed before exiting
 * =================
 */
tree_t *BrushBSP(brush_t *brushlist, vec3_t mins, vec3_t maxs) {
	node_t *node;
	brush_t *b;
	int32_t c_faces, c_nonvisfaces;
	int32_t c_brushes;
	tree_t *tree;
	int32_t i;
	vec_t volume;

	Com_Debug(DEBUG_ALL, "--- BrushBSP ---\n");

	tree = AllocTree();

	c_faces = 0;
	c_nonvisfaces = 0;
	c_brushes = 0;
	for (b = brushlist; b; b = b->next) {
		c_brushes++;

		volume = BrushVolume(b);
		if (volume < microvolume) {
			Mon_SendSelect(ERROR_WARN, b->original->entity_num, b->original->brush_num, "Microbrush");
		}

		for (i = 0; i < b->num_sides; i++) {
			if (b->sides[i].bevel) {
				continue;
			}
			if (!b->sides[i].winding) {
				continue;
			}
			if (b->sides[i].texinfo == TEXINFO_NODE) {
				continue;
			}
			if (b->sides[i].visible) {
				c_faces++;
			} else {
				c_nonvisfaces++;
			}
		}

		AddPointToBounds(b->mins, tree->mins, tree->maxs);
		AddPointToBounds(b->maxs, tree->mins, tree->maxs);
	}

	Com_Debug(DEBUG_ALL, "%5i brushes\n", c_brushes);
	Com_Debug(DEBUG_ALL, "%5i visible faces\n", c_faces);
	Com_Debug(DEBUG_ALL, "%5i nonvisible faces\n", c_nonvisfaces);

	SDL_DestroySemaphore(semaphores.vis_nodes);
	semaphores.vis_nodes = SDL_CreateSemaphore(0);

	SDL_DestroySemaphore(semaphores.nonvis_nodes);
	semaphores.nonvis_nodes = SDL_CreateSemaphore(0);

	node = AllocNode();

	node->volume = BrushFromBounds(mins, maxs);

	tree->head_node = node;

	node = BuildTree_r(node, brushlist);

	const uint32_t vis_nodes = SDL_SemValue(semaphores.vis_nodes);
	const uint32_t nonvis_nodes = SDL_SemValue(semaphores.nonvis_nodes);

	Com_Debug(DEBUG_ALL, "%5i visible nodes\n", vis_nodes / 2 - nonvis_nodes);
	Com_Debug(DEBUG_ALL, "%5i nonvis nodes\n", nonvis_nodes);
	Com_Debug(DEBUG_ALL, "%5i leafs\n", (vis_nodes + 1) / 2);

	return tree;
}
Exemple #6
0
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