Esempio n. 1
0
/*
==================
CSGFaces

Returns a list of surfaces containing aall of the faces
==================
*/
surface_t *CSGFaces (brushset_t *bs)
{
	brush_t		*b1, *b2;
	int			i;
	qboolean		overwrite;
	face_t		*f;
	surface_t	*surfhead;

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

	memset (validfaces, 0, sizeof(validfaces));

	csgfaces = brushfaces = csgmergefaces = 0;

	Draw_ClearWindow ();

//
// do the solid faces
//
	for (b1 = bs->brushes ; b1 ; b1 = b1->next)
	{
	// set outside to a copy of the brush's faces
		CopyFacesToOutside (b1);

		overwrite = false;

		for (b2 = bs->brushes ; b2 ; b2 = b2->next)
		{
		// see if b2 needs to clip a chunk out of b1

			if (b1 == b2)
			{
				overwrite = true;	// later brushes now overwrite
				continue;
			}

		// check bounding box first
			for (i = 0 ; i < 3 ; i++)
				if (b1->mins[i] > b2->maxs[i] || b1->maxs[i] < b2->mins[i])
					break;
			if (i < 3)
				continue;

		// divide faces by the planes of the new brush

			inside = outside;
			outside = NULL;

			for (f = b2->faces ; f ; f = f->next)
				ClipInside (f->planenum, f->planeside, overwrite);

		// these faces are continued in another brush, so get rid of them
			if (b1->contents == CONTENTS_SOLID && b2->contents <= CONTENTS_WATER)
				FreeInside (b2->contents);
			else
				FreeInside (CONTENTS_SOLID);
		}

	// all of the faces left in outside are real surface faces
		if (b1->contents != CONTENTS_SOLID)
			SaveOutside (true);	// mirror faces for inside view
		else
			SaveOutside (false);
	}

#if 0
	if (!csgfaces)
		Error ("No faces");
#endif

	surfhead = BuildSurfaces ();

	qprintf ("%5i brushfaces\n", brushfaces);
	qprintf ("%5i csgfaces\n", csgfaces);
	qprintf ("%5i mergedfaces\n", csgmergefaces);

	return surfhead;
}
Esempio n. 2
0
/*	Builds a list of surfaces containing all of the faces
*/
void CSGFaces( tree_t *tree )
{
	int			i;
	bool		overwrite;
	brush_t		*b1, *b2;
	face_t		*f;

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

	memset( tree->validfaces, 0, sizeof( tree->validfaces ) );

	numcsgfaces = numcsgbrushfaces = numcsgmergefaces = 0;

	// do the solid faces
	for( b1 = tree->brushes; b1; b1 = b1->next ) 
	{
		// set outside to a copy of the brush's faces
		CopyFacesToOutside( b1 );

		overwrite = false;
		for( b2 = tree->brushes; b2; b2 = b2->next )
		{
			// see if b2 needs to clip a chunk out of b1
			if( b1 == b2 ) 	
			{
				overwrite = true;	// later brushes now overwrite
				continue;
			}

			// check bounding box first
			for( i = 0; i < 3; i++ )
				if( b1->mins[i] > b2->maxs[i] || b1->maxs[i] < b2->mins[i] )
					break;

			if( i < 3 )
				continue;

			// divide faces by the planes of the new brush
			inside = outside;
			outside = NULL;

			for( f = b2->faces; f; f = f->next )
				ClipInside( f->planenum, f->planeside, overwrite );

			// these faces are continued in another brush, so get rid of them
			if( b1->contents == BSP_CONTENTS_SOLID && b2->contents <= BSP_CONTENTS_WATER )
				FreeInside( b2->contents );
			else
				FreeInside( BSP_CONTENTS_SOLID );
		}

		// all of the faces left in outside are real surface faces
		if( b1->contents != BSP_CONTENTS_SOLID )
			SaveOutside( tree, true );	// mirror faces for inside view
		else
			SaveOutside( tree, false );
	}

	BuildSurfaces( tree );

	qprintf( "%5i brushfaces\n", numcsgbrushfaces );
	qprintf( "%5i csgfaces\n", numcsgfaces );
	qprintf( "%5i mergedfaces\n", numcsgmergefaces );
}
Esempio n. 3
0
/*
==================
CSGFaces

Returns a list of surfaces containing all of the faces
==================
*/
surface_t *
CSGFaces(void)
{
    brush_t *b1, *b2;
    int i;
    bool overwrite;
    face_t *f;
    surface_t *surfhead;
    int iBrushes = 0;

    Message(msgProgress, "CSGFaces");

    if (validfaces == NULL)
	validfaces = AllocMem(OTHER, sizeof(face_t *) * cPlanes, true);
    else
	memset(validfaces, 0, sizeof(face_t *) * cPlanes);
    csgfaces = brushfaces = csgmergefaces = 0;

    // do the solid faces
    for (b1 = pCurEnt->pBrushes; b1; b1 = b1->next) {
	// set outside to a copy of the brush's faces
	CopyFacesToOutside(b1);

	// Why is this necessary?
	overwrite = false;

	for (b2 = pCurEnt->pBrushes; b2; b2 = b2->next) {
	    // check bounding box first
	    for (i = 0; i < 3; i++)
		if (b1->mins[i] > b2->maxs[i] || b1->maxs[i] < b2->mins[i])
		    break;
	    if (i < 3)
		continue;

	    // see if b2 needs to clip a chunk out of b1
	    if (b1 == b2) {
		overwrite = true;
		continue;
	    }
	    // divide faces by the planes of the new brush
	    inside = outside;
	    outside = NULL;

	    CheckInside(b2);
	    for (f = b2->faces; f; f = f->next)
		ClipInside(f->planenum, f->planeside, overwrite);

	    // these faces are continued in another brush, so get rid of them
	    if (b1->contents == CONTENTS_SOLID
		&& b2->contents <= CONTENTS_WATER)
		FreeInside(b2->contents);
	    else
		FreeInside(CONTENTS_SOLID);
	}

	// all of the faces left in outside are real surface faces
	if (b1->contents != CONTENTS_SOLID)
	    SaveOutside(true);	// mirror faces for inside view
	else
	    SaveOutside(false);

	iBrushes++;
	Message(msgPercent, iBrushes, pCurEnt->cBrushes);
    }

    surfhead = BuildSurfaces();

    Message(msgStat, "%5i brushfaces", brushfaces);
    Message(msgStat, "%5i csgfaces", csgfaces);
    Message(msgStat, "%5i mergedfaces", csgmergefaces);

    return surfhead;
}
Esempio n. 4
0
/*
===========
CSGBrush
===========
*/
void CSGBrush (int brushnum)
{
	int			hull;
	brush_t		*b1, *b2;
	brushhull_t	*bh1, *bh2;
	int			bn;
	qboolean	overwrite;
	int			i;
	bface_t		*f, *f2, *next, *fcopy;
	bface_t		*outside, *oldoutside;
	entity_t	*e;
	vec_t		area;

	SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);

	b1 = &mapbrushes[brushnum];

	e = &entities[b1->entitynum];

	for (hull = 0 ; hull<NUM_HULLS ; hull++)
	{
		bh1 = &b1->hulls[hull];

		// set outside to a copy of the brush's faces
		outside = CopyFacesToOutside (bh1);
		overwrite = false;

		for (bn=0 ; bn<e->numbrushes ; bn++)
		{
			// see if b2 needs to clip a chunk out of b1

			if (bn==brushnum)
			{
				overwrite = true;	// later brushes now overwrite
				continue;
			}

			b2 = &mapbrushes[e->firstbrush + bn];
			bh2 = &b2->hulls[hull];

			if (!bh2->faces)
				continue;		// brush isn't in this hull

			// check brush bounding box first
			for (i=0 ; i<3 ; i++)
				if (bh1->mins[i] > bh2->maxs[i] 
				|| bh1->maxs[i] < bh2->mins[i])
					break;
			if (i<3)
				continue;

			// divide faces by the planes of the b2 to find which
			// fragments are inside
		
			f = outside;
			outside = NULL;
			for ( ; f ; f=next)
			{
				next = f->next;

				// check face bounding box first
				for (i=0 ; i<3 ; i++)
					if (bh2->mins[i] > f->maxs[i] 
					|| bh2->maxs[i] < f->mins[i])
						break;
				if (i<3)
				{	// this face doesn't intersect brush2's bbox
					f->next = outside;
					outside = f;
					continue;
				}

				oldoutside = outside;
				fcopy = CopyFace (f);	// save to avoid fake splits

				// throw pieces on the front sides of the planes
				// into the outside list, return the remains on the inside
				for (f2=bh2->faces ; f2 && f ; f2=f2->next)
					f = ClipFace (b1, f, &outside, f2->planenum, overwrite);

				area = f ? WindingArea (f->w) : 0;
				if (f && area < 1.0)
				{
					qprintf ("Entity %i, Brush %i: tiny penetration\n"
						, b1->entitynum, b1->brushnum);
					c_tiny_clip++;
					FreeFace (f);
					f = NULL;
				}
				if (f)
				{
					// there is one convex fragment of the original
					// face left inside brush2
					FreeFace (fcopy);

					if (b1->contents > b2->contents)
					{	// inside a water brush
						f->contents = b2->contents;
						f->next = outside;
						outside = f;
					}
					else	// inside a solid brush
						FreeFace (f);	// throw it away
				}
				else
				{	// the entire thing was on the outside, even
					// though the bounding boxes intersected,
					// which will never happen with axial planes

					// free the fragments chopped to the outside
					while (outside != oldoutside)
					{
						f2 = outside->next;
						FreeFace (outside);
						outside = f2;
					}

					// revert to the original face to avoid
					// unneeded false cuts
					fcopy->next = outside;
					outside = fcopy;
				}
			}

		}

		// all of the faces left in outside are real surface faces
		SaveOutside (b1, hull, outside, b1->contents);
	}
}