Esempio n. 1
0
/**
 * @brief Projects a decal onto a world surface
 * @param[in] dp
 * @param[in] surf
 * @param[in] bmodel
 */
void R_ProjectDecalOntoSurface(decalProjector_t *dp, msurface_t *surf, bmodel_t *bmodel)
{
	srfGeneric_t *gen;
	int          i;

	// early outs
	if (dp->shader == NULL)
	{
		return;
	}
	//if( surf->viewCount == tr.viewCount )
	//  return;
	if ((surf->shader->surfaceFlags & (SURF_NOIMPACT | SURF_NOMARKS)) || (surf->shader->contentFlags & CONTENTS_FOG))
	{
		return;
	}

	// get generic surface
	gen = (srfGeneric_t *) surf->data;

	// ignore certain surfacetypes
	if (gen->surfaceType != SF_FACE && gen->surfaceType != SF_TRIANGLES && gen->surfaceType != SF_GRID)
	{
		return;
	}

	// test bounding sphere
	if (!R_TestDecalBoundingSphere(dp, gen->origin, (gen->radius * gen->radius)))
	{
		return;
	}

	// planar surface
	if (gen->plane.normal[0] != 0.f || gen->plane.normal[1] != 0.f || gen->plane.normal[2] != 0.f)
	{
		float d;

		// backface check
		d = DotProduct(dp->planes[0], gen->plane.normal);
		if (d < -0.0001f)
		{
			return;
		}

		// plane-sphere check
		d = DotProduct(dp->center, gen->plane.normal) - gen->plane.dist;
		if (Q_fabs(d) >= dp->radius)
		{
			return;
		}
	}

	// add to counts
	tr.pc.c_decalClipSurfaces++;

	// check if this projector already has a decal on this surface
	{
		int     count  = (bmodel == tr.world->bmodels ? MAX_WORLD_DECALS : MAX_ENTITY_DECALS);
		decal_t *decal = bmodel->decals;

		for (i = 0; i < count; i++, decal++)
		{
			if (decal->parent == surf && decal->projectorNum == dp->projectorNum)
			{
				return;
			}
		}
		// add to counts
		tr.pc.c_decalTestSurfaces++;
	}

	// switch on type
	switch (gen->surfaceType)
	{
	case SF_FACE:
	case SF_TRIANGLES:
		ProjectDecalOntoTriangles(dp, surf, bmodel);
		break;
	case SF_GRID:
		ProjectDecalOntoGrid(dp, surf, bmodel);
		break;
	default:
		break;
	}
}
Esempio n. 2
0
void R_ProjectDecalOntoSurface( decalProjector_t *dp, bspSurface_t *surf, bspModel_t *bmodel )
{
	float        d;
	srfGeneric_t *gen;

	/* early outs */
	if ( dp->shader == NULL )
	{
		return;
	}

	//% if( surf->viewCount == tr.viewCount )
	//%     return;
	if ( ( surf->shader->surfaceFlags & ( SURF_NOIMPACT | SURF_NOMARKS ) ) || ( surf->shader->contentFlags & CONTENTS_FOG ) )
	{
		return;
	}

	/* add to counts */
	tr.pc.c_decalTestSurfaces++;

	/* get generic surface */
	gen = ( srfGeneric_t * ) surf->data;

	/* ignore certain surfacetypes */
	if ( gen->surfaceType != SF_FACE && gen->surfaceType != SF_TRIANGLES && gen->surfaceType != SF_GRID )
	{
		return;
	}

	/* test bounding sphere */
	if ( !R_TestDecalBoundingSphere( dp, gen->origin, ( gen->radius * gen->radius ) ) )
//	if(!R_TestDecalBoundingBox(dp, gen->bounds[0], gen->bounds[1]))
	{
		return;
	}

	/* planar surface */
	if ( gen->surfaceType == SF_FACE )
	{
		srfSurfaceFace_t *srf = ( srfSurfaceFace_t * )surf->data;

		if ( srf->plane.normal[ 0 ] || srf->plane.normal[ 1 ] || srf->plane.normal[ 2 ] )
		{
			/* backface check */
			d = DotProduct( dp->planes[ 0 ], srf->plane.normal );

			if ( d < -0.0001 )
			{
				return;
			}

			/* plane-sphere check */
			d = DotProduct( dp->center, srf->plane.normal ) - srf->plane.dist;

			if ( fabs( d ) >= dp->radius )
			{
				return;
			}
		}
	}

	/* add to counts */
	tr.pc.c_decalClipSurfaces++;

	/* switch on type */
	switch ( gen->surfaceType )
	{
		case SF_FACE:
		case SF_TRIANGLES:
			ProjectDecalOntoTriangles( dp, surf, bmodel );
			break;

		case SF_GRID:
			ProjectDecalOntoGrid( dp, surf, bmodel );
			break;

		default:
			break;
	}
}
Esempio n. 3
0
void MakeEntityDecals( entity_t *e )
{
	int		i, j, k, f, fOld;
	double		start;
	decalProjector_t	dp;
	mapDrawSurface_t	*ds;
	vec3_t		identityAxis[ 3 ] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
	
	
	/* note it */
	MsgDev( D_NOTE, "--- MakeEntityDecals ---\n" );
	
	/* set entity origin */
	VectorCopy( e->origin, entityOrigin );
	
	/* transform projector instead of geometry */
	VectorClear( entityOrigin );
	
	/* init pacifier */
	fOld = -1;
	start = Sys_DoubleTime();
	
	/* walk the list of decal projectors */
	for( i = 0; i < numProjectors; i++ )
	{
		/* print pacifier */
		f = 10 * i / numProjectors;
		if( f != fOld )
		{
			fOld = f;
			MsgDev( D_NOTE, "%d...", f );
		}
		
		/* get projector */
		TransformDecalProjector( &projectors[ i ], identityAxis, e->origin, &dp );
		
		/* walk the list of surfaces in the entity */
		for( j = e->firstDrawSurf; j < numMapDrawSurfs; j++ )
		{
			/* get surface */
			ds = &mapDrawSurfs[ j ];
			if( ds->numVerts <= 0 )
				continue;
			
			/* ignore autosprite or nomarks */
			if( ds->shaderInfo->autosprite || (ds->shaderInfo->compileFlags & C_NOMARKS) )
				continue;
			
			/* bounds check */
			for( k = 0; k < 3; k++ )
				if( ds->mins[ k ] >= (dp.center[ k ] + dp.radius) ||
					ds->maxs[ k ] <= (dp.center[ k ] - dp.radius) )
					break;
			if( k < 3 )
				continue;
			
			/* switch on type */
			switch( ds->type )
			{
				case SURFACE_FACE:
					ProjectDecalOntoFace( &dp, ds );
					break;
				
				case SURFACE_PATCH:
					ProjectDecalOntoPatch( &dp, ds );
					break;
				
				case SURFACE_TRIANGLES:
				case SURFACE_FORCED_META:
				case SURFACE_META:
					ProjectDecalOntoTriangles( &dp, ds );
					break;
				default:
					break;
			}
		}
	}
	
	MsgDev( D_NOTE, " (%g) second elapsed\n", (Sys_DoubleTime() - start ));
	MsgDev( D_NOTE, "%9d decal surfaces\n", numDecalSurfaces );
}