Original Post
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:
"planes" is a matrix that equals: mat_view*mat_projection.
Anyone see a blatant problem in there? Thanks!!
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;