Пример #1
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;
	}
}
Пример #2
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;
	}
}