Beispiel #1
0
void R_CullDecalProjectors( void )
{
	int              i, numDecalProjectors, decalBits;
	decalProjector_t *dp;

	/* limit */
	if ( tr.refdef.numDecalProjectors > MAX_DECAL_PROJECTORS )
	{
		tr.refdef.numDecalProjectors = MAX_DECAL_PROJECTORS;
	}

	/* walk decal projector list */
	numDecalProjectors = 0;
	decalBits = 0;

	for ( i = 0, dp = tr.refdef.decalProjectors; i < tr.refdef.numDecalProjectors; i++, dp++ )
	{
		if ( R_CullPointAndRadius( dp->center, dp->radius ) == CULL_OUT )
		{
			dp->shader = NULL;
		}
		else
		{
			numDecalProjectors = i + 1;
			decalBits |= ( 1 << i );
		}
	}

	/* reset count */
	tr.refdef.numDecalProjectors = numDecalProjectors;
	tr.pc.c_decalProjectors = numDecalProjectors;

	/* set bits */
	tr.refdef.decalBits = decalBits;
}
Beispiel #2
0
void R_CullDlights( void )
{
	int      i, numDlights, dlightBits;
	dlight_t *dl;

	/* limit */
	if ( tr.refdef.num_dlights > MAX_DLIGHTS )
	{
		tr.refdef.num_dlights = MAX_DLIGHTS;
	}

	/* walk dlight list */
	numDlights = 0;
	dlightBits = 0;

	for ( i = 0, dl = tr.refdef.dlights; i < tr.refdef.num_dlights; i++, dl++ )
	{
		if ( ( dl->flags & REF_DIRECTED_DLIGHT ) || R_CullPointAndRadius( dl->origin, dl->radius ) != CULL_OUT )
		{
			numDlights = i + 1;
			dlightBits |= ( 1 << i );
		}
	}

	/* reset count */
	tr.refdef.num_dlights = numDlights;

	/* set bits */
	tr.refdef.dlightBits = dlightBits;
}
Beispiel #3
0
//	frustum culls decal projector list
void R_CullDecalProjectors() {
	//	limit
	if ( tr.refdef.numDecalProjectors > MAX_DECAL_PROJECTORS ) {
		tr.refdef.numDecalProjectors = MAX_DECAL_PROJECTORS;
	}

	//	walk decal projector list
	int numDecalProjectors = 0;
	int decalBits = 0;
	decalProjector_t* dp = tr.refdef.decalProjectors;
	for ( int i = 0; i < tr.refdef.numDecalProjectors; i++, dp++ ) {
		if ( R_CullPointAndRadius( dp->center, dp->radius ) == CULL_OUT ) {
			dp->shader = NULL;
		} else {
			numDecalProjectors = i + 1;
			decalBits |= ( 1 << i );
		}
	}

	//	reset count
	tr.refdef.numDecalProjectors = numDecalProjectors;
	tr.pc.c_decalProjectors = numDecalProjectors;

	//	set bits
	tr.refdef.decalBits = decalBits;
}
Beispiel #4
0
/*
** R_CullLocalPointAndRadius
*/
int R_CullLocalPointAndRadius( vec3_t pt, float radius ) {
	vec3_t transformed;

	R_LocalPointToWorld( pt, transformed );

	return R_CullPointAndRadius( transformed, radius );
}
Beispiel #5
0
int R_CullLocalPointAndRadius( vector3 *pt, float radius )
{
	vector3 transformed;

	R_LocalPointToWorld( pt, &transformed );

	return R_CullPointAndRadius( &transformed, radius );
}
Beispiel #6
0
/*
=================
R_CullGrid

Returns true if the grid is completely culled away.
Also sets the clipped hint bit in tess
=================
*/
static qboolean R_CullGrid( srfGridMesh_t *cv )
{
	int boxCull;
	int sphereCull;

	if ( r_nocurves->integer )
	{
		return qtrue;
	}

	if ( tr.currentEntityNum != ENTITYNUM_WORLD )
	{
		sphereCull = R_CullLocalPointAndRadius( cv->localOrigin, cv->meshRadius );
	}
	else
	{
		sphereCull = R_CullPointAndRadius( cv->localOrigin, cv->meshRadius );
	}

	boxCull = CULL_OUT;

	// check for trivial reject
	if ( sphereCull == CULL_OUT )
	{
		tr.pc.c_sphere_cull_patch_out++;
		return qtrue;
	}
	// check bounding box if necessary
	else if ( sphereCull == CULL_CLIP )
	{
		tr.pc.c_sphere_cull_patch_clip++;

		boxCull = R_CullLocalBox( cv->meshBounds );

		if ( boxCull == CULL_OUT )
		{
			tr.pc.c_box_cull_patch_out++;
			return qtrue;
		}
		else if ( boxCull == CULL_IN )
		{
			tr.pc.c_box_cull_patch_in++;
		}
		else
		{
			tr.pc.c_box_cull_patch_clip++;
		}
	}
	else
	{
		tr.pc.c_sphere_cull_patch_in++;
	}

	return qfalse;
}
Beispiel #7
0
/*
=============
R_CullMD5
=============
*/
static void R_CullMD5( trRefEntity_t *ent )
{
	int        i;
	float      boundsRadius;

	if ( ent->e.skeleton.type == SK_INVALID )
	{
		// no properly set skeleton so use the bounding box by the model instead by the animations
		md5Model_t *model = tr.currentModel->md5;;

		VectorCopy( model->bounds[ 0 ], ent->localBounds[ 0 ] );
		VectorCopy( model->bounds[ 1 ], ent->localBounds[ 1 ] );
	}
	else
	{
		// copy a bounding box in the current coordinate system provided by skeleton
		for ( i = 0; i < 3; i++ )
		{
			ent->localBounds[ 0 ][ i ] = ent->e.skeleton.bounds[ 0 ][ i ];
			ent->localBounds[ 1 ][ i ] = ent->e.skeleton.bounds[ 1 ][ i ];
		}
	}

	boundsRadius = RadiusFromBounds( ent->localBounds[ 0 ], ent->localBounds[ 1 ] );

	switch ( R_CullPointAndRadius( ent->e.origin, boundsRadius ) )
	{
		case CULL_IN:
			tr.pc.c_box_cull_md5_in++;
			ent->cull = CULL_IN;
			return;

		case CULL_CLIP:
			tr.pc.c_box_cull_md5_clip++;
			ent->cull = CULL_CLIP;
			return;

		case CULL_OUT:
		default:
			tr.pc.c_box_cull_md5_out++;
			ent->cull = CULL_OUT;
			return;
	}
}
Beispiel #8
0
/**
 * @brief Frustum culls decal projector list
 */
void R_CullDecalProjectors(void)
{
	int              i, numDecalProjectors, decalBits;
	decalProjector_t *dp, temp;

	// walk decal projector list
	numDecalProjectors = 0;
	decalBits          = 0;
	for (i = 0, dp = tr.refdef.decalProjectors; i < tr.refdef.numDecalProjectors; i++, dp++)
	{
		if (R_CullPointAndRadius(dp->center, dp->radius) == CULL_OUT)
		{
			continue;
		}

		// put all active projectors at the beginning
		if (tr.refdef.numDecalProjectors > MAX_USED_DECAL_PROJECTORS && dp != &tr.refdef.decalProjectors[numDecalProjectors])
		{
			// swap them
			temp                                          = tr.refdef.decalProjectors[numDecalProjectors];
			tr.refdef.decalProjectors[numDecalProjectors] = *dp;
			*dp                                           = temp;
		}

		decalBits |= (1 << numDecalProjectors);
		numDecalProjectors++;

		// bitmask limit
		if (numDecalProjectors == MAX_USED_DECAL_PROJECTORS)
		{
			break;
		}
	}

	// reset count
	tr.refdef.numDecalProjectors = numDecalProjectors;
	tr.pc.c_decalProjectors      = numDecalProjectors;

	// set bits
	tr.refdef.decalBits = decalBits;
}
Beispiel #9
0
/*
R_CullDecalProjectors()
    frustum culls decal projector list
*/
void R_CullDecalProjectors(void)
{
	int              i, numDecalProjectors, decalBits;
	decalProjector_t *dp, temp;

	/* walk decal projector list */
	numDecalProjectors = 0;
	decalBits          = 0;
	for (i = 0, dp = tr.refdef.decalProjectors; i < tr.refdef.numDecalProjectors; i++, dp++)
	{
		if (R_CullPointAndRadius(dp->center, dp->radius) == CULL_OUT)
		{
			continue;
		}

		/* put all active projectors at the beginning */
		if (tr.refdef.numDecalProjectors > 32 && dp != &tr.refdef.decalProjectors[numDecalProjectors])
		{
			/* swap them */
			temp                                          = tr.refdef.decalProjectors[numDecalProjectors];
			tr.refdef.decalProjectors[numDecalProjectors] = *dp;
			*dp                                           = temp;
		}

		decalBits |= (1 << numDecalProjectors);
		numDecalProjectors++;

		/* bitmask limit */
		if (numDecalProjectors == 32)
		{
			break;
		}
	}

	/* reset count */
	tr.refdef.numDecalProjectors = numDecalProjectors;
	tr.pc.c_decalProjectors      = numDecalProjectors;

	/* set bits */
	tr.refdef.decalBits = decalBits;
}
Beispiel #10
0
/*
** R_CullLocalPointAndRadius
*/
int R_CullLocalPointAndRadius( vec3_t pt, float radius )
{
	vec3_t transformed;
/*
Ghoul2 Insert Start
*/
   	vec3_t	zero = {0.0f,0.0f,0.0f};

	// if we didn't get a local origin, make it all 0's
	if (!pt)
	{
		pt = zero;
	}

/*
Ghoul2 Insert End
*/

	R_LocalPointToWorld( pt, transformed );

	return R_CullPointAndRadius( transformed, radius );
}
Beispiel #11
0
void RE_ProjectDecal( qhandle_t hShader, int numPoints, vec3_t *points, vec4_t projection, vec4_t color, int lifeTime,
                      int fadeTime )
{
	int              i;
	float            radius, iDist;
	vec3_t           xyz;
	vec4_t           omniProjection;
	decalVert_t      dv[ 4 ];
	decalProjector_t *dp, temp;

	/* first frame rendered does not have a valid decals list */
	if ( tr.refdef.decalProjectors == NULL )
	{
		return;
	}

	/* dummy check */
	if ( numPoints != 1 && numPoints != 3 && numPoints != 4 )
	{
		ri.Printf( PRINT_WARNING, "WARNING: Invalid number of decal points (%d)\n", numPoints );
		return;
	}

	/* early outs */
	if ( lifeTime == 0 )
	{
		return;
	}

	if ( projection[ 3 ] <= 0.0f )
	{
		return;
	}

	/* set times properly */
	if ( lifeTime < 0 || fadeTime < 0 )
	{
		lifeTime = 0;
		fadeTime = 0;
	}

	/* basic setup */
	temp.shader = R_GetShaderByHandle( hShader );  /* debug code */
	temp.numPlanes = temp.shader->entityMergable;
	temp.color[ 0 ] = color[ 0 ] * 255;
	temp.color[ 1 ] = color[ 1 ] * 255;
	temp.color[ 2 ] = color[ 2 ] * 255;
	temp.color[ 3 ] = color[ 3 ] * 255;
	temp.numPlanes = numPoints + 2;
	temp.fadeStartTime = tr.refdef.time + lifeTime - fadeTime;
	temp.fadeEndTime = temp.fadeStartTime + fadeTime;

	/* set up decal texcoords (fixme: support arbitrary projector st coordinates in trapcall) */
	dv[ 0 ].st[ 0 ] = 0.0f;
	dv[ 0 ].st[ 1 ] = 0.0f;
	dv[ 1 ].st[ 0 ] = 0.0f;
	dv[ 1 ].st[ 1 ] = 1.0f;
	dv[ 2 ].st[ 0 ] = 1.0f;
	dv[ 2 ].st[ 1 ] = 1.0f;
	dv[ 3 ].st[ 0 ] = 1.0f;
	dv[ 3 ].st[ 1 ] = 0.0f;

	/* omnidirectional? */
	if ( numPoints == 1 )
	{
		/* set up omnidirectional */
		numPoints = 4;
		temp.numPlanes = 6;
		temp.omnidirectional = qtrue;
		radius = projection[ 3 ];
		Vector4Set( omniProjection, 0.0f, 0.0f, -1.0f, radius * 2.0f );
		projection = omniProjection;
		iDist = 1.0f / ( radius * 2.0f );

		/* set corner */
		VectorSet( xyz, points[ 0 ][ 0 ] - radius, points[ 0 ][ 1 ] - radius, points[ 0 ][ 2 ] + radius );

		/* make x axis texture matrix (yz) */
		VectorSet( temp.texMat[ 0 ][ 0 ], 0.0f, iDist, 0.0f );
		temp.texMat[ 0 ][ 0 ][ 3 ] = -DotProduct( temp.texMat[ 0 ][ 0 ], xyz );
		VectorSet( temp.texMat[ 0 ][ 1 ], 0.0f, 0.0f, iDist );
		temp.texMat[ 0 ][ 1 ][ 3 ] = -DotProduct( temp.texMat[ 0 ][ 1 ], xyz );

		/* make y axis texture matrix (xz) */
		VectorSet( temp.texMat[ 1 ][ 0 ], iDist, 0.0f, 0.0f );
		temp.texMat[ 1 ][ 0 ][ 3 ] = -DotProduct( temp.texMat[ 1 ][ 0 ], xyz );
		VectorSet( temp.texMat[ 1 ][ 1 ], 0.0f, 0.0f, iDist );
		temp.texMat[ 1 ][ 1 ][ 3 ] = -DotProduct( temp.texMat[ 1 ][ 1 ], xyz );

		/* make z axis texture matrix (xy) */
		VectorSet( temp.texMat[ 2 ][ 0 ], iDist, 0.0f, 0.0f );
		temp.texMat[ 2 ][ 0 ][ 3 ] = -DotProduct( temp.texMat[ 2 ][ 0 ], xyz );
		VectorSet( temp.texMat[ 2 ][ 1 ], 0.0f, iDist, 0.0f );
		temp.texMat[ 2 ][ 1 ][ 3 ] = -DotProduct( temp.texMat[ 2 ][ 1 ], xyz );

		/* setup decal points */
		VectorSet( dv[ 0 ].xyz, points[ 0 ][ 0 ] - radius, points[ 0 ][ 1 ] - radius, points[ 0 ][ 2 ] + radius );
		VectorSet( dv[ 1 ].xyz, points[ 0 ][ 0 ] - radius, points[ 0 ][ 1 ] + radius, points[ 0 ][ 2 ] + radius );
		VectorSet( dv[ 2 ].xyz, points[ 0 ][ 0 ] + radius, points[ 0 ][ 1 ] + radius, points[ 0 ][ 2 ] + radius );
		VectorSet( dv[ 3 ].xyz, points[ 0 ][ 0 ] + radius, points[ 0 ][ 1 ] - radius, points[ 0 ][ 2 ] + radius );
	}
	else
	{
		/* set up unidirectional */
		temp.omnidirectional = qfalse;

		/* set up decal points */
		VectorCopy( points[ 0 ], dv[ 0 ].xyz );
		VectorCopy( points[ 1 ], dv[ 1 ].xyz );
		VectorCopy( points[ 2 ], dv[ 2 ].xyz );
		VectorCopy( points[ 3 ], dv[ 3 ].xyz );

		/* make texture matrix */
		if ( !MakeTextureMatrix( temp.texMat[ 0 ], projection, &dv[ 0 ], &dv[ 1 ], &dv[ 2 ] ) )
		{
			return;
		}
	}

	/* bound the projector */
	ClearBounds( temp.mins, temp.maxs );

	for ( i = 0; i < numPoints; i++ )
	{
		AddPointToBounds( dv[ i ].xyz, temp.mins, temp.maxs );
		VectorMA( dv[ i ].xyz, projection[ 3 ], projection, xyz );
		AddPointToBounds( xyz, temp.mins, temp.maxs );
	}

	/* make bounding sphere */
	VectorAdd( temp.mins, temp.maxs, temp.center );
	VectorScale( temp.center, 0.5f, temp.center );
	VectorSubtract( temp.maxs, temp.center, xyz );
	temp.radius = VectorLength( xyz );
	temp.radius2 = temp.radius * temp.radius;

	/* frustum cull the projector (fixme: this uses a stale frustum!) */
	if ( R_CullPointAndRadius( temp.center, temp.radius ) == CULL_OUT )
	{
		return;
	}

	/* make the front plane */
	if ( !PlaneFromPoints( temp.planes[ 0 ], dv[ 0 ].xyz, dv[ 1 ].xyz, dv[ 2 ].xyz ) )
	{
		return;
	}

	/* make the back plane */
	VectorSubtract( vec3_origin, temp.planes[ 0 ], temp.planes[ 1 ] );
	VectorMA( dv[ 0 ].xyz, projection[ 3 ], projection, xyz );
	temp.planes[ 1 ][ 3 ] = DotProduct( xyz, temp.planes[ 1 ] );

	/* make the side planes */
	for ( i = 0; i < numPoints; i++ )
	{
		VectorMA( dv[ i ].xyz, projection[ 3 ], projection, xyz );

		if ( !PlaneFromPoints( temp.planes[ i + 2 ], dv[( i + 1 ) % numPoints ].xyz, dv[ i ].xyz, xyz ) )
		{
			return;
		}
	}

	/* create a new projector */
	dp = &tr.refdef.decalProjectors[ r_numDecalProjectors & DECAL_PROJECTOR_MASK ];
	Com_Memcpy( dp, &temp, sizeof( *dp ) );

	/* we have a winner */
	r_numDecalProjectors++;
}
Beispiel #12
0
/*
================
R_CullSurface

Tries to back face cull surfaces before they are lighted or
added to the sorting list.

This will also allow mirrors on both sides of a model without recursion.
================
*/
static qboolean R_CullSurface( surfaceType_t *surface, shader_t *shader, int *frontFace )
{
	srfGeneric_t *gen;
	int          cull;
	float        d;

	// force to non-front facing
	*frontFace = 0;

	// allow culling to be disabled
	if ( r_nocull->integer )
	{
		return qfalse;
	}

	// ydnar: made surface culling generic, inline with q3map2 surface classification
	switch ( *surface )
	{
		case SF_FACE:
		case SF_TRIANGLES:
			break;

		case SF_GRID:
			if ( r_nocurves->integer )
			{
				return qtrue;
			}

			break;

		case SF_FOLIAGE:
			if ( !r_drawfoliage->value )
			{
				return qtrue;
			}

			break;

		default:
			return qtrue;
	}

	// get generic surface
	gen = ( srfGeneric_t * ) surface;

	// plane cull
	if ( gen->plane.type != PLANE_NON_PLANAR && r_facePlaneCull->integer )
	{
		d = DotProduct( tr.orientation.viewOrigin, gen->plane.normal ) - gen->plane.dist;

		if ( d > 0.0f )
		{
			*frontFace = 1;
		}

		// don't cull exactly on the plane, because there are levels of rounding
		// through the BSP, ICD, and hardware that may cause pixel gaps if an
		// epsilon isn't allowed here
		if ( shader->cullType == CT_FRONT_SIDED )
		{
			if ( d < -8.0f )
			{
				tr.pc.c_plane_cull_out++;
				return qtrue;
			}
		}
		else if ( shader->cullType == CT_BACK_SIDED )
		{
			if ( d > 8.0f )
			{
				tr.pc.c_plane_cull_out++;
				return qtrue;
			}
		}

		tr.pc.c_plane_cull_in++;
	}

	{
		// try sphere cull
		if ( tr.currentEntityNum != ENTITYNUM_WORLD )
		{
			cull = R_CullLocalPointAndRadius( gen->origin, gen->radius );
		}
		else
		{
			cull = R_CullPointAndRadius( gen->origin, gen->radius );
		}

		if ( cull == CULL_OUT )
		{
			tr.pc.c_sphere_cull_out++;
			return qtrue;
		}

		tr.pc.c_sphere_cull_in++;
	}

	// must be visible
	return qfalse;
}