level/vis_flow.c
/*
==================
ClipVisWinding

Clips the winding to the plane, returning the new winding on the positive side
Frees the input winding.
If keepon is true, an exactly on-plane winding will be saved, otherwise
it will be clipped away.
==================
*/
ClipVisWinding
Clips the winding to the plane, returning the new winding on the positive side
Frees the input winding.
If keepon is true, an exactly on-plane winding will be saved, otherwise
it will be clipped away.
ClipVisWinding Clips the winding to the plane returning the new winding on the positive side Frees the input winding . If keepon is true an exactly on - plane winding will be saved otherwise it will be clipped away .
viswinding_t *ClipVisWinding (viswinding_t *in, plane_t *split, bool keepon)
{
	int				i, j;
	vec_t			dists[MAX_POINTS_ON_VISWINDING + 1];
	int				sides[MAX_POINTS_ON_VISWINDING + 1];
	int				counts[3];
	vec_t			dot;
	vec_t			*p1, *p2;
	vec3_t			mid;
	viswinding_t	*neww;
	int				maxpts;
	counts[0] = counts[1] = counts[2] = 0;
	for (i=0 ; i<in->numpoints ; i++)
	{
		dists[i] = dot = DotProduct (in->points[i], split->normal) - split->dist;
		if (dot > ON_EPSILON) sides[i] = SIDE_FRONT;
		else if (dot < -ON_EPSILON) sides[i] = SIDE_BACK;
		else sides[i] = SIDE_ON;
		counts[sides[i]]++;
	}
	sides[i] = sides[0];
	dists[i] = dists[0];
	if (keepon && !counts[0] && !counts[1])
		return in;
	if (!counts[0])
	{
		FreeVisWinding (in);
		return NULL;
	}
	if (!counts[1])
		return in;
	maxpts = in->numpoints+4;	
	neww = NewVisWinding (maxpts);
	for (i=0 ; i<in->numpoints ; i++)
	{
		p1 = in->points[i];
		if (sides[i] == SIDE_ON)
		{
			VectorCopy (p1, neww->points[neww->numpoints]);
			neww->numpoints++;
			continue;
		}
		if (sides[i] == SIDE_FRONT)
		{
			VectorCopy (p1, neww->points[neww->numpoints]);
			neww->numpoints++;
		}
		if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
			continue;
		p2 = in->points[(i+1)%in->numpoints];
		dot = dists[i] / (dists[i]-dists[i+1]);
		for (j=0 ; j<3 ; j++)
		{	
			if (split->normal[j] == 1)
				mid[j] = split->dist;
			else if (split->normal[j] == -1)
				mid[j] = -split->dist;
			else
				mid[j] = p1[j] + dot*(p2[j]-p1[j]);
		}
		VectorCopy (mid, neww->points[neww->numpoints]);
		neww->numpoints++;
	}
	if (neww->numpoints > maxpts)
		Error ("ClipVisWinding: points exceeded estimate");
	FreeVisWinding (in);
	return neww;
}
viswinding_t * ClipVisWinding ( viswinding_t * in , plane_t * split , bool keepon ) { int i , j ; vec_t dists [ MAX_POINTS_ON_VISWINDING + 1 ] ; int sides [ MAX_POINTS_ON_VISWINDING + 1 ] ; int counts [ 3 ] ; vec_t dot ; vec_t * p1 , * p2 ; vec3_t mid ; viswinding_t * neww ; int maxpts ; counts [ 0 ] = counts [ 1 ] = counts [ 2 ] = 0 ; for ( i = 0 ; i < in -> numpoints ; i ++ ) { dists [ i ] = dot = DotProduct ( in -> points [ i ] , split -> normal ) - split -> dist ; if ( dot > ON_EPSILON ) sides [ i ] = SIDE_FRONT ; else if ( dot < - ON_EPSILON ) sides [ i ] = SIDE_BACK ; else sides [ i ] = SIDE_ON ; counts [ sides [ i ] ] ++ ; } sides [ i ] = sides [ 0 ] ; dists [ i ] = dists [ 0 ] ; if ( keepon && ! counts [ 0 ] && ! counts [ 1 ] ) return in ; if ( ! counts [ 0 ] ) { FreeVisWinding ( in ) ; return NULL ; } if ( ! counts [ 1 ] ) return in ; maxpts = in -> numpoints + 4 ; neww = NewVisWinding ( maxpts ) ; for ( i = 0 ; i < in -> numpoints ; i ++ ) { p1 = in -> points [ i ] ; if ( sides [ i ] == SIDE_ON ) { VectorCopy ( p1 , neww -> points [ neww -> numpoints ] ) ; neww -> numpoints ++ ; continue ; } if ( sides [ i ] == SIDE_FRONT ) { VectorCopy ( p1 , neww -> points [ neww -> numpoints ] ) ; neww -> numpoints ++ ; } if ( sides [ i + 1 ] == SIDE_ON || sides [ i + 1 ] == sides [ i ] ) continue ; p2 = in -> points [ ( i + 1 ) % in -> numpoints ] ; dot = dists [ i ] / ( dists [ i ] - dists [ i + 1 ] ) ; for ( j = 0 ; j < 3 ; j ++ ) { if ( split -> normal [ j ] == 1 ) mid [ j ] = split -> dist ; else if ( split -> normal [ j ] == -1 ) mid [ j ] = - split -> dist ; else mid [ j ] = p1 [ j ] + dot * ( p2 [ j ] - p1 [ j ] ) ; } VectorCopy ( mid , neww -> points [ neww -> numpoints ] ) ; neww -> numpoints ++ ; } if ( neww -> numpoints > maxpts ) Error ( " " ) ; FreeVisWinding ( in ) ; return neww ; }
ClipVisWinding
Clips the winding to the plane, returning the new winding on the positive side
Frees the input winding.
ClipVisWinding Clips the winding to the plane returning the new winding on the positive side Frees the input winding .
// determine sides for each point // can't use counts[0]+2 because // of fp grouping errors // generate a split point // avoid round off error when possible // free the original winding