Example #1
0
File: csg4.c Project: dommul/super8
/*
==================
BuildSurfaces

Returns a chain of all the external surfaces with one or more visible
faces.
==================
*/
void BuildSurfaces( tree_t *tree )
{
	int			i;
	face_t		**f;
	face_t		*count;
	surface_t	*s;
	surface_t	*surfhead;

	surfhead = NULL;
	for( i = 0, f = tree->validfaces; i < nummapplanes; i++, f++ ) {
		if( !*f )
			continue;	// nothing left on this plane

		// create a new surface to hold the faces on this plane
		s = AllocSurface ();
		s->planenum = i;
		s->next = surfhead;
		surfhead = s;
		s->faces = *f;

		for( count = s->faces; count; count = count->next )
			numcsgmergefaces++;

		CalcSurfaceInfo( s );	// bounding box and flags
	}

	tree->surfaces = surfhead;
}
Example #2
0
/*
==================
DivideSurface
==================
*/
void DivideSurface (surface_t *in, dplane_t *split, surface_t **front, surface_t **back)
{
	face_t		*facet, *next;
	face_t		*frontlist, *backlist;
	face_t		*frontfrag, *backfrag;
	surface_t	*news;
	dplane_t	*inplane;	

	inplane = &dplanes[in->planenum];
	
	// parallel case is easy

	if (inplane->normal[0] == split->normal[0]
	&& inplane->normal[1] == split->normal[1]
	&& inplane->normal[2] == split->normal[2])
	{
		if (inplane->dist > split->dist)
		{
			*front = in;
			*back = NULL;
		}
		else if (inplane->dist < split->dist)
		{
			*front = NULL;
			*back = in;
		}
		else
		{	// split the surface into front and back
			frontlist = NULL;
			backlist = NULL;
			for (facet = in->faces ; facet ; facet = next)
			{
				next = facet->next;
				if (facet->planenum & 1)
				{
					facet->next = backlist;
					backlist = facet;
				}
				else
				{
					facet->next = frontlist;
					frontlist = facet;
				}
			}
			goto makesurfs;
		}
		return;
	}
	
// do a real split.  may still end up entirely on one side
// OPTIMIZE: use bounding box for fast test
	frontlist = NULL;
	backlist = NULL;
	
	for (facet = in->faces ; facet ; facet = next)
	{
		next = facet->next;
		SplitFace (facet, split, &frontfrag, &backfrag);
		if (frontfrag)
		{
			frontfrag->next = frontlist;
			frontlist = frontfrag;
		}
		if (backfrag)
		{
			backfrag->next = backlist;
			backlist = backfrag;
		}
	}

// if nothing actually got split, just move the in plane
makesurfs:
	if (frontlist == NULL)
	{
		*front = NULL;
		*back = in;
		in->faces = backlist;
		return;
	}

	if (backlist == NULL)
	{
		*front = in;
		*back = NULL;
		in->faces = frontlist;
		return;
	}
	

// stuff got split, so allocate one new surface and reuse in
	news = AllocSurface ();
	*news = *in;
	news->faces = backlist;
	*back = news;
	
	in->faces = frontlist;
	*front = in;
	
// recalc bboxes and flags
	CalcSurfaceInfo (news);
	CalcSurfaceInfo (in);	
}
Example #3
0
/*
==================
DividePlane
==================
*/
void DividePlane (surface_t *in, plane_t *split, surface_t **front, surface_t **back)
{
	face_t		*facet, *next;
	face_t		*frontlist, *backlist;
	face_t		*frontfrag, *backfrag;
	surface_t	*news;
	plane_t		*inplane;

	inplane = &planes[in->planenum];

	// parallel case is easy
	if (VectorCompare (inplane->normal, split->normal))
	{
		// check for exactly on node
		if (inplane->dist == split->dist)
		{	// divide the facets to the front and back sides
			news = AllocSurface ();
			*news = *in;

			facet=in->faces;
			in->faces = NULL;
			news->faces = NULL;
			in->onnode = news->onnode = true;

			for ( ; facet ; facet=next)
			{
				next = facet->next;
				if (facet->planeside == 1)
				{
					facet->next = news->faces;
					news->faces = facet;
				}
				else
				{
					facet->next = in->faces;
					in->faces = facet;
				}
			}

			if (in->faces)
				*front = in;
			else
				*front = NULL;
			if (news->faces)
				*back = news;
			else
				*back = NULL;
			return;
		}

		if (inplane->dist > split->dist)
		{
			*front = in;
			*back = NULL;
		}
		else
		{
			*front = NULL;
			*back = in;
		}
		return;
	}

	// do a real split.  may still end up entirely on one side
	// OPTIMIZE: use bounding box for fast test
	frontlist = NULL;
	backlist = NULL;

	for (facet = in->faces ; facet ; facet = next)
	{
		next = facet->next;
		SplitFace (facet, split, &frontfrag, &backfrag);
		if (frontfrag)
		{
			frontfrag->next = frontlist;
			frontlist = frontfrag;
		}
		if (backfrag)
		{
			backfrag->next = backlist;
			backlist = backfrag;
		}
	}

	// if nothing actually got split, just move the in plane

	if (frontlist == NULL)
	{
		*front = NULL;
		*back = in;
		in->faces = backlist;
		return;
	}

	if (backlist == NULL)
	{
		*front = in;
		*back = NULL;
		in->faces = frontlist;
		return;
	}


	// stuff got split, so allocate one new plane and reuse in
	news = AllocSurface ();
	*news = *in;
	news->faces = backlist;
	*back = news;

	in->faces = frontlist;
	*front = in;

	// recalc bboxes and flags
	CalcSurfaceInfo (news);
	CalcSurfaceInfo (in);
}