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

Used for curves and inlined models
==================
*/
void AddMapTriToAreas( mapTri_t* tri, uEntity_t* e )
{
	int				area;
	idWinding*		w;
	
	// skip degenerate triangles from pinched curves
	if( MapTriArea( tri ) <= 0 )
	{
		return;
	}
	
	if( dmapGlobals.fullCarve )
	{
		// always fragment into areas
		w = WindingForTri( tri );
		ClipTriIntoTree_r( w, tri, e, e->tree->headnode );
		return;
	}
	
	w = WindingForTri( tri );
	area = CheckWindingInAreas_r( w, e->tree->headnode );
	delete w;
	if( area == -1 )
	{
		return;
	}
	if( area >= 0 )
	{
		mapTri_t*	newTri;
		idPlane		plane;
		int			planeNum;
		textureVectors_t	texVec;
		
		// put in single area
		newTri = CopyMapTri( tri );
		newTri->next = NULL;
		
		PlaneForTri( tri, plane );
		planeNum = FindFloatPlane( plane );
		
		TexVecForTri( &texVec, newTri );
		
		AddTriListToArea( e, newTri, planeNum, area, &texVec );
	}
	else
	{
		// fragment into areas
		w = WindingForTri( tri );
		ClipTriIntoTree_r( w, tri, e, e->tree->headnode );
	}
}
Пример #2
0
/*
=====================
FilterMeshesIntoTree

Mark the leafs as opaque and areaportals and put mesh
fragments in each leaf so portal surfaces can be matched
to materials
=====================
*/
void FilterMeshesIntoTree( uEntity_t* e )
{
	uBrush_t*		b;
	primitive_t*	prim;
	mapTri_t*		tri;
	int				r;
	int				c_unique, c_clusters;
	
	common->Printf( "----- FilterMeshesIntoTree -----\n" );
	
	c_unique = 0;
	c_clusters = 0;
	for( prim = e->primitives ; prim ; prim = prim->next )
	{
		b = prim->brush;
		
		if( !b )
		{
			// add BSP triangles
			for( tri = prim->bsptris ; tri ; tri = tri->next )
			{
				idWinding* w = WindingForTri( tri );
				
				c_unique++;
				r = FilterMeshesIntoTree_r( w, tri, e->tree->headnode );
				c_clusters += r;
			}
			continue;
		}
	}
	
	common->Printf( "%5i total BSP triangles\n", c_unique );
	common->Printf( "%5i cluster references\n", c_clusters );
}
Пример #3
0
/*
==================
ClipTriList
==================
*/
void	ClipTriList( const mapTri_t *list, const idPlane &plane, float epsilon,
                     mapTri_t **front, mapTri_t **back ) {
    const mapTri_t *tri;
    mapTri_t		*newList;
    idWinding		*w, *frontW, *backW;

    *front = NULL;
    *back = NULL;

    for ( tri = list ; tri ; tri = tri->next ) {
        w = WindingForTri( tri );
        w->Split( plane, epsilon, &frontW, &backW );

        newList = WindingToTriList( frontW, tri );
        *front = MergeTriLists( *front, newList );

        newList = WindingToTriList( backW, tri );
        *back = MergeTriLists( *back, newList );

        delete w;
    }

}
/*
=================
ClipTriByLight

Carves a triangle by the frustom planes of a light, producing
a (possibly empty) list of triangles on the inside and outside.

The original triangle is not modified.

If no clipping is required, the result will be a copy of the original.

If clipping was required, the outside fragments will be planar clips, which
will benefit from re-optimization.
=================
*/
static void ClipTriByLight( const mapLight_t *light, const mapTri_t *tri,
						   mapTri_t **in, mapTri_t **out ) {
	idWinding	*inside, *oldInside;
	idWinding	*outside[6];
	bool	hasOutside;
	int			i;

	*in = NULL;
	*out = NULL;

	// clip this winding to the light
	inside = WindingForTri( tri );
	hasOutside = false;
	for ( i = 0 ; i < 6 ; i++ ) {
		oldInside = inside;
		if ( oldInside ) {
			oldInside->Split( light->def.frustum[i], 0, &outside[i], &inside );
			delete oldInside;
		}
		else {
			outside[i] = NULL;
		}
		if ( outside[i] ) {
			hasOutside = true;
		}
	}

	if ( !inside ) {
		// the entire winding is outside this light

		// free the clipped fragments
		for ( i = 0 ; i < 6 ; i++ ) {
			if ( outside[i] ) {
				delete outside[i];
			}
		}

		*out = CopyMapTri( tri );
		(*out)->next = NULL;

		return;
	}

	if ( !hasOutside ) {
		// the entire winding is inside this light

		// free the inside copy
		delete inside;

		*in = CopyMapTri( tri );
		(*in)->next = NULL;

		return;
	}

	// the winding is split
	*in = WindingToTriList( inside, tri );
	delete inside;

	// combine all the outside fragments
	for ( i = 0 ; i < 6 ; i++ ) {
		if ( outside[i] ) {
			mapTri_t	*list;

			list = WindingToTriList( outside[i], tri );
			delete outside[i];
			*out = MergeTriLists( *out, list );
		}
	}
}