Beispiel #1
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;
    }

}
Beispiel #2
0
/*
====================
ClipTriIntoTree_r

This is used for adding curve triangles
The winding will be freed before it returns
====================
*/
void ClipTriIntoTree_r( idWinding* w, mapTri_t* originalTri, uEntity_t* e, node_t* node )
{
	idWinding*		front, *back;
	
	if( !w )
	{
		return;
	}
	
	if( node->planenum != PLANENUM_LEAF )
	{
		//common->Printf( "ClipTriIntoTree_r: splitting triangle with splitplane %i\n", node->nodeNumber );
		
		w->Split( dmapGlobals.mapPlanes[ node->planenum ], ON_EPSILON, &front, &back );
		delete w;
		
		ClipTriIntoTree_r( front, originalTri, e, node->children[0] );
		ClipTriIntoTree_r( back, originalTri, e, node->children[1] );
		
		return;
	}
	
	//common->Printf( "ClipTriIntoTree_r: leaf area = %i, opaque = %i, occupied = %i\n", node->area, node->occupied );
	
	// if opaque leaf, don't add
	if( !node->opaque && node->area >= 0 )
	{
		mapTri_t*	list;
		int			planeNum;
		idPlane		plane;
		textureVectors_t	texVec;
		
		list = WindingToTriList( w, originalTri );
		
		PlaneForTri( originalTri, plane );
		planeNum = FindFloatPlane( plane );
		
		TexVecForTri( &texVec, originalTri );
		
		AddTriListToArea( e, list, planeNum, node->area, &texVec );
	}
	
	delete w;
	return;
}
/*
=================
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 );
		}
	}
}