Skip to main content
GameDev.net gamedev.net
🔒 Locked

Really simple quadtree culling implementation

Started by okonomiyaki May 16, 2003 at 6:45 PM 0 replies 500+ views
Original Post
okonomiyaki
okonomiyaki
With this being my first engine, I decided not to worry about going in too deep with spatial partitioning techniques, culling algorithms, and LOD algorithms for terrain. So I decided just to go with one simple thing and that''s it: a simple quadtree structure with out-of-the-frustrum culling. The quadtree implementation went very smoothly, although a bit hacked. I assumed a lot of things, and it''s not really a quadtree. It''s just several aligned blocks of 17x17 vertices. I can assume the vertices are spaced out evenly because I don''t use LOD yet. I''m saving that for next program Especially because I don''t understand how a quadtree is supposed to help when you are using LOD: The vertices change all the time because they are viewer-dependant, and if the "rule" you set for each quadtree node of to have n number of triangles, then the quadtree would have to be dynamic. Calculate a new quadtree every frame?? I don''t think that''s right! But besides that, the frustum culling is the problem I''m having right now. I even simplified this a lot, thinking it would go smoothly. My terrain block is made up of 513x513 vertices. That is 32x32 quadtree nodes (17x17 vertices each). Therefore I know that the first quadtree''s coordinates are (0,0), (0,16), (16,0), and (16,16). We can just forget the height because I just want to check against the left and right planes of the view frustum. So we know the coordinates of each node, and we know how to extract the planes, and we know how to test it! Well, I thought it would work, and it does.. partially. What happens is it renders the full terrain if I''m looking up a little bit, but as I start tilting downward, the terrain starts dissapearing! The thing is it disappears in a way that resembles the "V" of the view frustrum, meaning like the virtual frustum is shifting forward or something. Eventually the whole thing dissapears. I think code is applicable in this situation. Here is my plane-extraction and node-checking code:
  
	float **frustum = new float*[2];
	float t;
	for(int i=0; i<2; i++)
		frustum[i] = new float[4];

	//The RIGHT plane

	frustum[0][0] = planes->_14 - planes->_11;
	frustum[0][1] = planes->_24 - planes->_21;
	frustum[0][2] = planes->_34 - planes->_31;
	frustum[0][3] = planes->_44 - planes->_41;
	t = sqrt( frustum[0][0] * frustum[0][0] + frustum[0][1] * frustum[0][1] + frustum[0][2] * frustum[0][2] );
	frustum[0][0] /= t;
	frustum[0][1] /= t;
	frustum[0][2] /= t;
	frustum[0][3] /= t;


	//The LEFT plane

	frustum[1][0] = planes->_14 + planes->_11;
	frustum[1][1] = planes->_24 + planes->_21;
	frustum[1][2] = planes->_34 + planes->_31;
	frustum[1][3] = planes->_44 + planes->_41;
	t = sqrt( frustum[1][0] * frustum[1][0] + frustum[1][1] * frustum[1][1] + frustum[1][2] * frustum[1][2] );
	frustum[1][0] /= t;
	frustum[1][1] /= t;
	frustum[1][2] /= t;
	frustum[1][3] /= t;

	for(i=0; i<YTerrain/16; i++) {
		for(int k=0; k<XTerrain/16; k++) {


			BOOL draw = TRUE;


			for(int p=0; p<2; p++) {
				if( frustum[p][0] * (k*16) + frustum[p][1] * 0.0f + frustum[p][2] * (i*16) + frustum[p][3] > 0)
					continue;
				if( frustum[p][0] * (k*16+16) + frustum[p][1] * 0.0f + frustum[p][2] * (i*16) + frustum[p][3] > 0)
					continue;
				if( frustum[p][0] * (k*16) + frustum[p][1] * 0.0f + frustum[p][2] * (i*16+16) + frustum[p][3] > 0)
					continue;
				if( frustum[p][0] * (k*16+16) + frustum[p][1] * 0.0f + frustum[p][2] * (i*16+16) + frustum[p][3] > 0)
					continue;

				draw = FALSE;
				break;
			}

			if(draw)
				Octree[i*(YTerrain/16) + k]->Draw();



		}

	}

	delete[] frustum[0];
	delete[] frustum[1];
	delete[] frustum;
  
"planes" is a matrix that equals: mat_view*mat_projection. Anyone see a blatant problem in there? Thanks!!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.