コード例 #1
0
ファイル: decals.c プロジェクト: a1batross/Xash3D_ancient
static void ProjectDecalOntoFace( decalProjector_t *dp, mapDrawSurface_t *ds )
{
	vec4_t		plane;
	float		d;
	winding_t	*w;
	
	
	/* dummy check */
	if( ds->sideRef == NULL || ds->sideRef->side == NULL )
		return;
	
	/* backface check */
	if( ds->planar )
	{
		VectorCopy( mapplanes[ ds->planeNum ].normal, plane );
		plane[ 3 ] = mapplanes[ ds->planeNum ].dist + DotProduct( plane, entityOrigin );
		d = DotProduct( dp->planes[ 0 ], plane );
		if( d < -0.0001f )
			return;
	}
	
	/* generate decal */
	w = WindingFromDrawSurf( ds );
	ProjectDecalOntoWinding( dp, ds, w );
}
コード例 #2
0
ファイル: fog.c プロジェクト: otty/cake3
/*
====================
ChopFaceByBrush

There may be a fragment contained in the brush
====================
*/
qboolean ChopFaceByBrush(drawSurface_t * ds, bspBrush_t * b)
{
	int             i, j;
	side_t         *s;
	plane_t        *plane;
	winding_t      *w;
	winding_t      *front, *back;
	winding_t      *outside[MAX_BRUSH_SIDES];
	int             numOutside;
	drawSurface_t  *newds;
	drawVert_t     *dv;
	shaderInfo_t   *si;
	float           mins[2];

	// brush primitive :
	// axis base
	vec3_t          texX, texY;
	vec_t           x, y;

	w = WindingFromDrawSurf(ds);
	numOutside = 0;

	for(i = 0; i < b->numsides; i++)
	{
		s = &b->sides[i];
		if(s->backSide)
		{
			continue;
		}
		plane = &mapPlanes[s->planenum];

		// handle coplanar outfacing (don't fog)
		if(ds->side->planenum == s->planenum)
		{
			return qfalse;
		}

		// handle coplanar infacing (keep inside)
		if((ds->side->planenum ^ 1) == s->planenum)
		{
			continue;
		}

		// general case
		ClipWindingEpsilon(w, plane->normal, plane->dist, ON_EPSILON, &front, &back);
		FreeWinding(w);
		if(!back)
		{
			// nothing actually contained inside
			for(j = 0; j < numOutside; j++)
			{
				FreeWinding(outside[j]);
			}
			return qfalse;
		}
		if(front)
		{
			if(numOutside == MAX_BRUSH_SIDES)
			{
				Error("MAX_BRUSH_SIDES");
			}
			outside[numOutside] = front;
			numOutside++;
		}
		w = back;
	}

	// all of outside fragments become seperate drawsurfs
	// linked to the same side
	c_fogFragment += numOutside;
	s = ds->side;

	for(i = 0; i < numOutside; i++)
	{
		newds = DrawSurfaceForSide(ds->mapBrush, s, outside[i]);
		FreeWinding(outside[i]);
	}


	// replace ds->verts with the verts for w
	ds->numVerts = w->numpoints;
	free(ds->verts);

	ds->verts = malloc(ds->numVerts * sizeof(*ds->verts));
	memset(ds->verts, 0, ds->numVerts * sizeof(*ds->verts));

	si = s->shaderInfo;

	mins[0] = 9999;
	mins[1] = 9999;

	// compute s/t coordinates from brush primitive texture matrix
	// compute axis base
	ComputeAxisBase(mapPlanes[s->planenum].normal, texX, texY);

	for(j = 0; j < w->numpoints; j++)
	{
		dv = ds->verts + j;
		VectorCopy(w->p[j], dv->xyz);

		if(g_bBrushPrimit == BPRIMIT_OLDBRUSHES)
		{
			// calculate texture s/t
			dv->st[0] = s->vecs[0][3] + DotProduct(s->vecs[0], dv->xyz);
			dv->st[1] = s->vecs[1][3] + DotProduct(s->vecs[1], dv->xyz);
			dv->st[0] /= si->width;
			dv->st[1] /= si->height;
		}
		else
		{
			// calculate texture s/t from brush primitive texture matrix
			x = DotProduct(dv->xyz, texX);
			y = DotProduct(dv->xyz, texY);
			dv->st[0] = s->texMat[0][0] * x + s->texMat[0][1] * y + s->texMat[0][2];
			dv->st[1] = s->texMat[1][0] * x + s->texMat[1][1] * y + s->texMat[1][2];
		}

		if(dv->st[0] < mins[0])
		{
			mins[0] = dv->st[0];
		}
		if(dv->st[1] < mins[1])
		{
			mins[1] = dv->st[1];
		}

		// copy normal
		VectorCopy(mapPlanes[s->planenum].normal, dv->normal);
	}

	// adjust the texture coordinates to be as close to 0 as possible
	if(!si->globalTexture)
	{
		mins[0] = floor(mins[0]);
		mins[1] = floor(mins[1]);
		for(i = 0; i < w->numpoints; i++)
		{
			dv = ds->verts + i;
			dv->st[0] -= mins[0];
			dv->st[1] -= mins[1];
		}
	}

	return qtrue;
}
コード例 #3
0
ファイル: fog.c プロジェクト: Elzair/q3map2
qboolean ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
	int i, j;
	side_t              *s;
	plane_t             *plane;
	winding_t           *w;
	winding_t           *front, *back;
	winding_t           *outside[ MAX_BRUSH_SIDES ];
	int numOutside;
	mapDrawSurface_t    *newds;


	/* dummy check */
	if ( ds->sideRef == NULL || ds->sideRef->side == NULL ) {
		return qfalse;
	}

	/* initial setup */
	w = WindingFromDrawSurf( ds );
	numOutside = 0;

	/* chop by each brush side */
	for ( i = 0; i < b->numsides; i++ )
	{
		/* get brush side and plane */
		s = &b->sides[ i ];
		plane = &mapplanes[ s->planenum ];

		/* handle coplanar outfacing (don't fog) */
		if ( ds->sideRef->side->planenum == s->planenum ) {
			return qfalse;
		}

		/* handle coplanar infacing (keep inside) */
		if ( ( ds->sideRef->side->planenum ^ 1 ) == s->planenum ) {
			continue;
		}

		/* general case */
		ClipWindingEpsilonStrict( w, plane->normal, plane->dist, ON_EPSILON, &front, &back ); /* strict; if plane is "almost identical" to face, both ways to continue can be wrong, so we better not fog it */
		FreeWinding( w );

		if ( back == NULL ) {
			/* nothing actually contained inside */
			for ( j = 0; j < numOutside; j++ )
				FreeWinding( outside[ j ] );
			return qfalse;
		}

		if ( front != NULL ) {
			if ( numOutside == MAX_BRUSH_SIDES ) {
				Error( "MAX_BRUSH_SIDES" );
			}
			outside[ numOutside ] = front;
			numOutside++;
		}

		w = back;
	}

	/* fixme: celshaded surface fragment errata */

	/* all of outside fragments become seperate drawsurfs */
	numFogFragments += numOutside;
	s = ds->sideRef->side;
	for ( i = 0; i < numOutside; i++ )
	{
		newds = DrawSurfaceForSide( e, ds->mapBrush, s, outside[ i ] );
		newds->fogNum = ds->fogNum;
		FreeWinding( outside[ i ] );
	}

	/* ydnar: the old code neglected to snap to 0.125 for the fragment
	          inside the fog brush, leading to sparklies. this new code does
	          the right thing and uses the original surface's brush side */

	/* build a drawsurf for it */
	newds = DrawSurfaceForSide( e, ds->mapBrush, s, w );
	if ( newds == NULL ) {
		return qfalse;
	}

	/* copy new to original */
	ClearSurface( ds );
	memcpy( ds, newds, sizeof( mapDrawSurface_t ) );

	/* didn't really add a new drawsurface... :) */
	numMapDrawSurfs--;

	/* return ok */
	return qtrue;
}