Rendering Q3 BSP curved surfaces?

Started by
4 comments, last by Promit 20 years, 1 month ago
I''m trying to find some resources on rendering curved surfaces in Quake 3 BSPs. I can''t seem to find anything except vague references to their existence, and the file header doesn''t even lend any clues to where the data is, or how I''m supposed to go about eating it. Even the Aftershock source had nothing useful. So what''s up with these curved surfaces things, and where can I get some info on loading/rendering them?
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Advertisement
It''s been a while since I used them, but IIRC they''re all 3x3 bezier patches. You get a set of 9 vertices, 3 rows of 3, which are your control points (with the patch anchored at the corner points); all you need to do then is tesselate it.

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

If I remember, there might also be times when you get your patches served to you in 9x9 form, I just cut mine up into 3x3 patches but each to their own..
yea, when i did them it took friggn ages, i cant remember how
exactly it was i did them, but i'll provide code from my q3
engine here.

sorry i cant be of more use, but its been so long.
ps. your really delayed

i guess you can contact me and i can try answer a few questions
silvermace007#hotmail

-------------------------------------------------------------------------
data stuctures you'll need:
/// internal structure, stores information needed to generate/// the quadratic bezier surfacestruct bspPatch{				 // 3x3 grid of anchor points	 // bspVertexData stores Texture/LM control points as well bspVertexData	cp[9]; int startv, endv; int index; int tessfactor; int step; int faceid;};[source]Patch compile code:[source]//////////////////////////////////////////////////// main bezier thingo function!//////////////////////////////////////////////////float quadbasis(float s, int index){	switch(index)	{		case 0: return (1 - s) * ( 1 - s );		case 1: return  2 * s  * ( 1 - s );		case 2: return  s * s;	}	return 0.f;}//////////////////////////////////////////////////// prepares data for compilation//////////////////////////////////////////////////void CBSPMap::internBuildFaces(){	int npatchs = 0;	int nmeshes = 0;	bspPatch patch;	memset(&patch, 0, sizeof(bspPatch));	patch.tessfactor = 8;	vector<bspFaceData>::iterator face = vFaces.begin();	for(; face != vFaces.end(); face++ )	{		if( face->type == PATCH )		{			int x, y, x_axis = 0, y_axis = 0;			// set the faces vertex indicies			int temp = vVerts.size();			//face->begin_index_verts = vVerts.size();//patch.startv;			for(int size_y = 0; size_y < (face->patch_size[1] - 1)/2; size_y++)			{				for(int size_x = 0; size_x < (face->patch_size[0] - 1)/2; size_x++)				{					int cpindex = 0;					for(y = 0; y < 3; y++)					for(x = 0; x < 3; x++)					{						bspVertexData& cp = patch.cp[cpindex];						int index = face->begin_index_verts + (x + x_axis) + ((y + y_axis) * face->patch_size[0]);						cp.point[0] = vVerts[index].point[0];						cp.point[1] = vVerts[index].point[1];						cp.point[2] = vVerts[index].point[2];						cp.tc[0]	= vVerts[index].tc[0];						cp.tc[1]	= vVerts[index].tc[1];						cp.lmtc[0]  = vVerts[index].lmtc[0];						cp.lmtc[1]  = vVerts[index].lmtc[1];						//memcpy( &, &cp, sizeof(bspVertexData) );						cpindex++;					}								x_axis +=2;					// compile the patch and add it to the vertex array					internCompilepatch( patch );					//face->n_verts += patch.endv - patch.startv;				}				x_axis = 0;				y_axis +=2;			}			face->begin_index_verts = temp;			face->n_verts = vVerts.size() - face->begin_index_verts;			npatchs++;		}		else 		if( face->type == MESH )		{                // REMOVED THIS AS IT IS IRRELIVANT TO PATCHES		}	}}///////////////////////////////////////////////////Patch Compile Function:////////////////////////////////////////////////   void CBSPMap::internCompilepatch(CBSPMap::bspPatch &info){	int factor = info.tessfactor - 2;	int x,y;	int i,j;	float step;	float s,t;	float bias;	if( factor < 3 ) 		factor = 3;	step = (float)( 1.0f / (float)(factor - 1) );	vector<bspVertexData> pts( factor * factor );	memset( &pts[0], 0, sizeof(bspVertexData) * pts.size() );	for( x = 0, s = 0; x < factor; x++, s+=step)	for( y = 0, t = 0; y < factor; y++, t+=step)	{		int index = 0, cpindex = 0;		index = x + (y * factor);		for( i = 0; i<3; i++)		for( j = 0; j<3; j++)		{			cpindex = i + j * 3;			bias = quadbasis(s,i) * quadbasis(t,j);			pts[index].point[0]		+= bias * info.cp[cpindex].point[0];			pts[index].point[1]		+= bias * info.cp[cpindex].point[1];			pts[index].point[2]		+= bias * info.cp[cpindex].point[2];			// interpolate texture & lightmap coords			pts[index].tc[0]		+= bias * info.cp[cpindex].tc[0];			pts[index].tc[1]		+= bias * info.cp[cpindex].tc[1];			pts[index].lmtc[0]		+= bias * info.cp[cpindex].lmtc[0];			pts[index].lmtc[1]		+= bias * info.cp[cpindex].lmtc[1];		}		}	info.startv = vVerts.size();#ifdef _DEBUG	vector< bspVertexData >::iterator test = pts.begin();#endif	bspVertexData *pt = NULL;	int numfaces = 0, numverts = 0;	for( y = 0, t = 0; y < factor-1; y++, t += step)	{		for(x = 0, s = 0; x < factor; x++, s += step)		{			pt = &pts[x+(y*factor)];			vVerts.push_back( *pt );					numverts++;			pt = &pts[x+((y+1)*factor)];			vVerts.push_back( *pt );			numverts++;		}	}	info.endv = vVerts.size();}


EDIT: source juggling
I hate these source boxes.

[edited by - silvermace on March 6, 2004 5:49:02 AM]
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
Ok, one thing...where is the bloody patch data in the file? I can''t find it, lol
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
it should be just a bspFace, it will be singnaled by the fact
that the type variable of the structure will be "patch".

patches are kept in the BSP''s as faces with 9+ verts, so they
are like all the other faces, its just that the 9+ verts are
control points rather than physical verticies.

its all in the code i supplied, take a good look
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website

This topic is closed to new replies.

Advertisement