예제 #1
0
파일: fog.c 프로젝트: otty/cake3
/*
====================
ChopPatchByBrush
====================
*/
qboolean ChopPatchByBrush(drawSurface_t * ds, bspBrush_t * b)
{
	int             i, j;
	side_t         *s;
	plane_t        *plane;
	mesh_t         *outside[MAX_BRUSH_SIDES];
	int             numOutside;
	mesh_t         *m, *front, *back;
	drawSurface_t  *newds;

	m = DrawSurfToMesh(ds);
	numOutside = 0;

	// only split by the top and bottom planes to avoid
	// some messy patch clipping issues

	for(i = 4; i <= 5; i++)
	{
		s = &b->sides[i];
		plane = &mapPlanes[s->planenum];

		SplitMeshByPlane(m, plane->normal, plane->dist, &front, &back);

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

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

	// all of outside fragments become seperate drawsurfs
	c_fogPatchFragments += numOutside;
	for(i = 0; i < numOutside; i++)
	{
		newds = DrawSurfaceForMesh(outside[i]);
		newds->shaderInfo = ds->shaderInfo;
		FreeMesh(outside[i]);
	}

	// replace ds with m
	ds->patchWidth = m->width;
	ds->patchHeight = m->height;
	ds->numVerts = m->width * m->height;
	free(ds->verts);
	ds->verts = malloc(ds->numVerts * sizeof(*ds->verts));
	memcpy(ds->verts, m->verts, ds->numVerts * sizeof(*ds->verts));

	FreeMesh(m);

	return qtrue;
}
예제 #2
0
파일: fog.c 프로젝트: Elzair/q3map2
qboolean ChopPatchSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
	int i, j;
	side_t      *s;
	plane_t     *plane;
	mesh_t      *outside[MAX_BRUSH_SIDES];
	int numOutside;
	mesh_t      *m, *front, *back;
	mapDrawSurface_t    *newds;

	m = DrawSurfToMesh( ds );
	numOutside = 0;

	// only split by the top and bottom planes to avoid
	// some messy patch clipping issues

	for ( i = 4 ; i <= 5 ; i++ ) {
		s = &b->sides[ i ];
		plane = &mapplanes[ s->planenum ];

		SplitMeshByPlane( m, plane->normal, plane->dist, &front, &back );

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

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

	/* all of outside fragments become seperate drawsurfs */
	numFogPatchFragments += numOutside;
	for ( i = 0; i < numOutside; i++ )
	{
		/* transpose and invert the chopped patch (fixes potential crash. fixme: why?) */
		outside[ i ] = TransposeMesh( outside[ i ] );
		InvertMesh( outside[ i ] );

		/* ydnar: do this the hacky right way */
		newds = AllocDrawSurface( SURFACE_PATCH );
		memcpy( newds, ds, sizeof( *ds ) );
		newds->patchWidth = outside[ i ]->width;
		newds->patchHeight = outside[ i ]->height;
		newds->numVerts = outside[ i ]->width * outside[ i ]->height;
		newds->verts = safe_malloc( newds->numVerts * sizeof( *newds->verts ) );
		memcpy( newds->verts, outside[ i ]->verts, newds->numVerts * sizeof( *newds->verts ) );

		/* free the source mesh */
		FreeMesh( outside[ i ] );
	}

	/* only rejigger this patch if it was chopped */
	//%	Sys_Printf( "Inside: %d x %d\n", m->width, m->height );
	if ( numOutside > 0 ) {
		/* transpose and invert the chopped patch (fixes potential crash. fixme: why?) */
		m = TransposeMesh( m );
		InvertMesh( m );

		/* replace ds with m */
		ds->patchWidth = m->width;
		ds->patchHeight = m->height;
		ds->numVerts = m->width * m->height;
		free( ds->verts );
		ds->verts = safe_malloc( ds->numVerts * sizeof( *ds->verts ) );
		memcpy( ds->verts, m->verts, ds->numVerts * sizeof( *ds->verts ) );
	}

	/* free the source mesh and return */
	FreeMesh( m );
	return qtrue;
}