Пример #1
0
/*
================
FaceBSP

List will be freed before returning
================
*/
tree_t         *FaceBSP(bspFace_t * list)
{
	tree_t         *tree;
	bspFace_t      *face;
	int             i;
	int             count;

	Sys_FPrintf(SYS_VRB, "--- FaceBSP ---\n");

	tree = AllocTree();

	count = 0;
	for(face = list; face; face = face->next)
	{
		count++;
		for(i = 0; i < face->w->numpoints; i++)
		{
			AddPointToBounds(face->w->p[i], tree->mins, tree->maxs);
		}
	}
	Sys_FPrintf(SYS_VRB, "%5i faces\n", count);

	tree->headnode = AllocNode();
	VectorCopy(tree->mins, tree->headnode->mins);
	VectorCopy(tree->maxs, tree->headnode->maxs);
	c_faceLeafs = 0;

	BuildFaceTree_r(tree->headnode, list);

	Sys_FPrintf(SYS_VRB, "%5i leafs\n", c_faceLeafs);

	return tree;
}
Пример #2
0
/*
================
FaceBSP

List will be freed before returning
================
*/
tree_t         *FaceBSP(face_t * list, qboolean drawDebug)
{
	tree_t         *tree;
	face_t         *face;
	int             i;
	int             count;

	Sys_FPrintf(SYS_VRB, "--- FaceBSP ---\n");

	tree = AllocTree();

	count = 0;
	for(face = list; face != NULL; face = face->next)
	{
		count++;
		for(i = 0; i < face->w->numpoints; i++)
		{
			AddPointToBounds(face->w->p[i], tree->mins, tree->maxs);
		}
	}
	Sys_FPrintf(SYS_VRB, "%9d faces\n", count);

	for(i = 0; i < nummapplanes; i++)
	{
		mapplanes[i].counter = 0;
	}

	tree->headnode = AllocNode();
	VectorCopy(tree->mins, tree->headnode->mins);
	VectorCopy(tree->maxs, tree->headnode->maxs);
	c_faceLeafs = 0;
	c_faceNodes = 1;

#if 1
	if(drawBSP && drawDebug)
	{
		drawTree = tree;
	}
#endif

	BuildFaceTree_r(tree->headnode, list);

	Sys_FPrintf(SYS_VRB, "%9d nodes\n", c_faceNodes);
	Sys_FPrintf(SYS_VRB, "%9d leafs\n", c_faceLeafs);
	Sys_FPrintf(SYS_VRB, "%9d depth\n", (int)(logf(c_faceNodes) / logf(2)));

	return tree;
}
Пример #3
0
/*
================
FaceBSP

List will be freed before returning
================
*/
tree_t *FaceBSP( bspface_t *list )
{
    tree_t		*tree;
    bspface_t	*face;
    int			i;
    int			count;
    int			start, end;

    start = Sys_Milliseconds();

    common->Printf( "--- FaceBSP ---\n" );

    tree = AllocTree ();

    count = 0;
    tree->bounds.Clear();
    for ( face = list ; face ; face = face->next )
    {
        count++;
        for ( i = 0 ; i < face->w->GetNumPoints() ; i++ )
        {
            tree->bounds.AddPoint( (*face->w)[i].ToVec3() );
        }
    }
    common->Printf( "%5i faces\n", count );

    tree->headnode = AllocNode();
    tree->headnode->bounds = tree->bounds;
    c_faceLeafs = 0;

    BuildFaceTree_r ( tree->headnode, list );

    common->Printf( "%5i leafs\n", c_faceLeafs );

    end = Sys_Milliseconds();

    common->Printf( "%5.1f seconds faceBsp\n", ( end - start ) / 1000.0 );

    return tree;
}
Пример #4
0
/*
================
BuildFaceTree_r
================
*/
void	BuildFaceTree_r( node_t *node, bspface_t *list ) {
	bspface_t	*split;
	bspface_t	*next;
	int			side;
	bspface_t	*newFace;
	bspface_t	*childLists[2];
	idWinding	*frontWinding, *backWinding;
	int			i;
	int			splitPlaneNum;

	splitPlaneNum = SelectSplitPlaneNum( node, list );
	// if we don't have any more faces, this is a node
	if ( splitPlaneNum == -1 ) {
		node->planenum = PLANENUM_LEAF;
		c_faceLeafs++;
		return;
	}

	// partition the list
	node->planenum = splitPlaneNum;
	idPlane &plane = dmapGlobals.mapPlanes[ splitPlaneNum ];
	childLists[0] = NULL;
	childLists[1] = NULL;
	for ( split = list ; split ; split = next ) {
		next = split->next;

		if ( split->planenum == node->planenum ) {
			FreeBspFace( split );
			continue;
		}

		side = split->w->PlaneSide( plane );

		if ( side == SIDE_CROSS ) {
			split->w->Split( plane, CLIP_EPSILON * 2, &frontWinding, &backWinding );
			if ( frontWinding ) {
				newFace = AllocBspFace();
				newFace->w = frontWinding;
				newFace->next = childLists[0];
				newFace->planenum = split->planenum;
				childLists[0] = newFace;
			}
			if ( backWinding ) {
				newFace = AllocBspFace();
				newFace->w = backWinding;
				newFace->next = childLists[1];
				newFace->planenum = split->planenum;
				childLists[1] = newFace;
			}
			FreeBspFace( split );
		} else if ( side == SIDE_FRONT ) {
			split->next = childLists[0];
			childLists[0] = split;
		} else if ( side == SIDE_BACK ) {
			split->next = childLists[1];
			childLists[1] = split;
		}
	}


	// recursively process children
	for ( i = 0 ; i < 2 ; i++ ) {
		node->children[i] = AllocNode();
		node->children[i]->parent = node;
		node->children[i]->bounds = node->bounds;
	}

	// split the bounds if we have a nice axial plane
	for ( i = 0 ; i < 3 ; i++ ) {
		if ( idMath::Fabs( plane[i] - 1.0 ) < 0.001 ) {
			node->children[0]->bounds[0][i] = plane.Dist();
			node->children[1]->bounds[1][i] = plane.Dist();
			break;
		}
	}

	for ( i = 0 ; i < 2 ; i++ ) {
		BuildFaceTree_r ( node->children[i], childLists[i]);
	}
}
Пример #5
0
void BuildFaceTree_r( node_t *node, face_t *list ){
	face_t      *split;
	face_t      *next;
	int side;
	plane_t     *plane;
	face_t      *newFace;
	face_t      *childLists[2];
	winding_t   *frontWinding, *backWinding;
	int i;
	int splitPlaneNum, compileFlags;


	/* count faces left */
	i = CountFaceList( list );

	/* select the best split plane */
	SelectSplitPlaneNum( node, list, &splitPlaneNum, &compileFlags );

	/* if we don't have any more faces, this is a node */
	if ( splitPlaneNum == -1 ) {
		node->planenum = PLANENUM_LEAF;
		c_faceLeafs++;
		return;
	}

	/* partition the list */
	node->planenum = splitPlaneNum;
	node->compileFlags = compileFlags;
	plane = &mapplanes[ splitPlaneNum ];
	childLists[0] = NULL;
	childLists[1] = NULL;
	for ( split = list; split; split = next )
	{
		/* set next */
		next = split->next;

		/* don't split by identical plane */
		if ( split->planenum == node->planenum ) {
			FreeBspFace( split );
			continue;
		}

		/* determine which side the face falls on */
		side = WindingOnPlaneSide( split->w, plane->normal, plane->dist );

		/* switch on side */
		if ( side == SIDE_CROSS ) {
			ClipWindingEpsilon( split->w, plane->normal, plane->dist, CLIP_EPSILON * 2,
								&frontWinding, &backWinding );
			if ( frontWinding ) {
				newFace = AllocBspFace();
				newFace->w = frontWinding;
				newFace->next = childLists[0];
				newFace->planenum = split->planenum;
				newFace->priority = split->priority;
				newFace->compileFlags = split->compileFlags;
				childLists[0] = newFace;
			}
			if ( backWinding ) {
				newFace = AllocBspFace();
				newFace->w = backWinding;
				newFace->next = childLists[1];
				newFace->planenum = split->planenum;
				newFace->priority = split->priority;
				newFace->compileFlags = split->compileFlags;
				childLists[1] = newFace;
			}
			FreeBspFace( split );
		}
		else if ( side == SIDE_FRONT ) {
			split->next = childLists[0];
			childLists[0] = split;
		}
		else if ( side == SIDE_BACK ) {
			split->next = childLists[1];
			childLists[1] = split;
		}
	}


	// recursively process children
	for ( i = 0 ; i < 2 ; i++ ) {
		node->children[i] = AllocNode();
		node->children[i]->parent = node;
		VectorCopy( node->mins, node->children[i]->mins );
		VectorCopy( node->maxs, node->children[i]->maxs );
	}

	for ( i = 0 ; i < 3 ; i++ ) {
		if ( plane->normal[i] == 1 ) {
			node->children[0]->mins[i] = plane->dist;
			node->children[1]->maxs[i] = plane->dist;
			break;
		}
	}

	for ( i = 0 ; i < 2 ; i++ ) {
		BuildFaceTree_r( node->children[i], childLists[i] );
	}
}
Пример #6
0
/*
================
BuildFaceTree_r
================
*/
void BuildFaceTree_r(node_t * node, bspFace_t * list)
{
	bspFace_t      *split;
	bspFace_t      *next;
	int             side;
	plane_t        *plane;
	bspFace_t      *newFace;
	bspFace_t      *childLists[2];
	winding_t      *frontWinding, *backWinding;
	int             i;
	int             splitPlaneNum;
	int             hintSplit;

	i = CountFaceList(list);

	SelectSplitPlaneNum(node, list, &splitPlaneNum, &hintSplit);

	// if we don't have any more faces, this is a node
	if(splitPlaneNum == -1)
	{
		node->planenum = PLANENUM_LEAF;
		c_faceLeafs++;
		return;
	}

	// partition the list
	node->planenum = splitPlaneNum;
	node->hint = hintSplit;
	plane = &mapPlanes[splitPlaneNum];
	childLists[0] = NULL;
	childLists[1] = NULL;
	for(split = list; split; split = next)
	{
		next = split->next;

		if(split->planenum == node->planenum)
		{
			FreeBspFace(split);
			continue;
		}

		side = WindingOnPlaneSide(split->w, plane->normal, plane->dist);

		if(side == SIDE_CROSS)
		{
			ClipWindingEpsilon(split->w, plane->normal, plane->dist, CLIP_EPSILON * 2, &frontWinding, &backWinding);
			if(frontWinding)
			{
				newFace = AllocBspFace();
				newFace->w = frontWinding;
				newFace->next = childLists[0];
				newFace->planenum = split->planenum;
				newFace->priority = split->priority;
				newFace->hint = split->hint;
				childLists[0] = newFace;
			}
			if(backWinding)
			{
				newFace = AllocBspFace();
				newFace->w = backWinding;
				newFace->next = childLists[1];
				newFace->planenum = split->planenum;
				newFace->priority = split->priority;
				newFace->hint = split->hint;
				childLists[1] = newFace;
			}
			FreeBspFace(split);
		}
		else if(side == SIDE_FRONT)
		{
			split->next = childLists[0];
			childLists[0] = split;
		}
		else if(side == SIDE_BACK)
		{
			split->next = childLists[1];
			childLists[1] = split;
		}
	}


	// recursively process children
	for(i = 0; i < 2; i++)
	{
		node->children[i] = AllocNode();
		node->children[i]->parent = node;
		VectorCopy(node->mins, node->children[i]->mins);
		VectorCopy(node->maxs, node->children[i]->maxs);
	}

	for(i = 0; i < 3; i++)
	{
		if(plane->normal[i] == 1)
		{
			node->children[0]->mins[i] = plane->dist;
			node->children[1]->maxs[i] = plane->dist;
			break;
		}
	}

	for(i = 0; i < 2; i++)
	{
		BuildFaceTree_r(node->children[i], childLists[i]);
	}
}
Пример #7
0
void BuildFaceTree_r(node_t * node, face_t * list)
{
	face_t         *split;
	face_t         *next;
	int             side;
	plane_t        *plane;
	face_t         *newFace;
	face_t         *childLists[2];
	winding_t      *frontWinding, *backWinding;
	int             i;
	int             splitPlaneNum, compileFlags;
	qboolean        isstruct = qfalse;
	int             splits, front, back;


	/* count faces left */
	i = CountFaceList(list);

#if defined(DEBUG_SPLITS)
	Sys_FPrintf(SYS_VRB, "faces left = %d\n", i);
#endif

	/* select the best split plane */
	SelectSplitPlaneNum(node, list, &splitPlaneNum, &compileFlags);

	/* if we don't have any more faces, this is a leaf */
	if(splitPlaneNum == -1)
	{
		node->planenum = PLANENUM_LEAF;
		node->has_structural_children = qfalse;
		c_faceLeafs++;
		return;
	}

	/* partition the list */
	node->planenum = splitPlaneNum;
	node->compileFlags = compileFlags;
	node->has_structural_children = !(compileFlags & C_DETAIL) && !node->opaque;
	plane = &mapplanes[splitPlaneNum];
	childLists[0] = NULL;
	childLists[1] = NULL;

	splits = front = back = 0;

	for(split = list; split; split = next)
	{
		/* set next */
		next = split->next;

		/* don't split by identical plane */
		if(split->planenum == node->planenum)
		{
			FreeBspFace(split);
			continue;
		}

		if(!(split->compileFlags & C_DETAIL))
			isstruct = 1;

		/* determine which side the face falls on */
		side = WindingOnPlaneSide(split->w, plane->normal, plane->dist);

		/* switch on side */
		if(side == SIDE_CROSS)
		{
			splits++;

			ClipWindingEpsilon(split->w, plane->normal, plane->dist, CLIP_EPSILON * 2, &frontWinding, &backWinding);
			if(frontWinding)
			{
				newFace = AllocBspFace();
				newFace->w = frontWinding;
				newFace->next = childLists[0];
				newFace->planenum = split->planenum;
				newFace->priority = split->priority;
				newFace->compileFlags = split->compileFlags;
				childLists[0] = newFace;

				front++;
			}
			if(backWinding)
			{
				newFace = AllocBspFace();
				newFace->w = backWinding;
				newFace->next = childLists[1];
				newFace->planenum = split->planenum;
				newFace->priority = split->priority;
				newFace->compileFlags = split->compileFlags;
				childLists[1] = newFace;

				back++;
			}
			FreeBspFace(split);
		}
		else if(side == SIDE_FRONT)
		{
			split->next = childLists[0];
			childLists[0] = split;

			front++;
		}
		else if(side == SIDE_BACK)
		{
			split->next = childLists[1];
			childLists[1] = split;

			back++;
		}
	}


	// recursively process children
	for(i = 0; i < 2; i++)
	{
		node->children[i] = AllocNode();
		node->children[i]->parent = node;
		VectorCopy(node->mins, node->children[i]->mins);
		VectorCopy(node->maxs, node->children[i]->maxs);

		c_faceNodes++;
	}

	for(i = 0; i < 3; i++)
	{
		if(plane->normal[i] == 1)
		{
			node->children[0]->mins[i] = plane->dist;
			node->children[1]->maxs[i] = plane->dist;
			break;
		}
	}

#if 1
	if(drawBSP && drawTree)
	{
		drawChildLists[0] = childLists[0];
		drawChildLists[1] = childLists[1];
		drawSplitNode = node;
		Draw_Scene(DrawAll);
	}
#endif

#if defined(DEBUG_SPLITS)
	if((node->compileFlags & C_DETAIL) && isstruct)
		Sys_FPrintf(SYS_ERR, "I am detail, my child is structural, this is a wtf1\n", node->has_structural_children);
#endif

	for(i = 0; i < 2; i++)
	{
		BuildFaceTree_r(node->children[i], childLists[i]);
		node->has_structural_children |= node->children[i]->has_structural_children;
	}

#if defined(DEBUG_SPLITS)
	if((node->compileFlags & C_DETAIL) && !(node->children[0]->compileFlags & C_DETAIL) &&
	   node->children[0]->planenum != PLANENUM_LEAF)
		Sys_FPrintf(SYS_ERR, "I am detail, my child is structural\n", node->has_structural_children);
	if((node->compileFlags & C_DETAIL) && isstruct)
		Sys_FPrintf(SYS_ERR, "I am detail, my child is structural, this is a wtf2\n", node->has_structural_children);
#endif
}