Frustum problems

This topic is 2685 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi, I made a Frustum class to go with my octree/quadtree view culling.

 struct Frustum { D3DXVECTOR3 Normals[6]; float D[0]; Frustum(D3DXMATRIX viewProj) { D3DXVECTOR3 corners[8] = { D3DXVECTOR3(-1, -1, 0), // bottom left front D3DXVECTOR3( 1, -1, 0), // top left front D3DXVECTOR3(-1, 1, 0), // bottom right front D3DXVECTOR3( 1, 1, 0), // top right front D3DXVECTOR3(-1, -1, 1), D3DXVECTOR3( 1, -1, 1), D3DXVECTOR3(-1, 1, 1), D3DXVECTOR3( 1, 1, 1), }; D3DXVECTOR3 worldCorners[8]; // Corners are currently in projection space. To get the corners in world-space, transform by inverse of view proj D3DXMATRIX inverseViewProj; float determinant; D3DXMatrixInverse(&inverseViewProj, &determinant, &viewProj); // transform the proj space corners into world space D3DXVec3TransformCoordArray(worldCorners, sizeof(D3DXVECTOR3), corners, sizeof(D3DXVECTOR3), &inverseViewProj, 8); // get some edges to be used // edgeA_B is constructed as (corners[A] - corners) D3DXVECTOR3 edge5_1 = worldCorners[5] - worldCorners[1]; D3DXVECTOR3 edge0_1 = worldCorners[0] - worldCorners[1]; D3DXVECTOR3 edge3_1 = worldCorners[1] - worldCorners[1]; D3DXVECTOR3 edge4_6 = worldCorners[4] - worldCorners[6]; D3DXVECTOR3 edge2_6 = worldCorners[2] - worldCorners[6]; D3DXVECTOR3 edge7_6 = worldCorners[6] - worldCorners[6]; // get the normals to the planes by crossing edges on those planes. all normals point outwards D3DXVec3Cross(&Normals[FF_Left], &edge0_1, &edge5_1); D3DXVec3Cross(&Normals[FF_Right], &edge2_6, &edge7_6); D3DXVec3Cross(&Normals[FF_Top], &edge5_1, &edge3_1); D3DXVec3Cross(&Normals[FF_Bottom], &edge4_6, &edge2_6); D3DXVec3Cross(&Normals[FF_Front], &edge3_1, &edge0_1); D3DXVec3Cross(&Normals[FF_Back], &edge7_6, &edge4_6); // get the D values. r.n = d D[FF_Left] = D3DXVec3Dot(&worldCorners[0], &Normals[FF_Left]); D[FF_Right] = D3DXVec3Dot(&worldCorners[3], &Normals[FF_Right]); D[FF_Top] = D3DXVec3Dot(&worldCorners[1], &Normals[FF_Top]); D[FF_Bottom] = D3DXVec3Dot(&worldCorners[2], &Normals[FF_Bottom]); D[FF_Front] = D3DXVec3Dot(&worldCorners[0], &Normals[FF_Front]); D[FF_Back] = D3DXVec3Dot(&worldCorners[7], &Normals[FF_Back]); // normalize all planes so D represents distance to origin for (int i = 0; i < 6; i++) { float len = D3DXVec3Length(&Normals); Normals /= len; D /= len; } } }; 

The constructor is called in main()

 D3DXMATRIX world, view, proj; <snip initialisation> Frustum frustum(world * view * proj); 

However, when I quit, VC++ 08 express gives me an error
"The stack around the variable 'frustum' was corrupted"
Also, even though this frustum class is not currently in use, it is affecting the drawing of some meshes - probably because of the stack corruption. I have no idea of how to stop this happening, can anyone help me out?

PS. I'm pretty sure my maths is correct, but if not, could you point out where? Thanks a lot

Share on other sites
OK, by commenting out some of the constructor, eventually I deduced that it was down to accessing and writing to the D array, and then I noticed that it was of size 0. Sorry for sharing my stupidity, this has now been solved. However, I think I should leave this open in case I have more problems - I have never done frustum culling before.

Share on other sites
You are really making it hard on yourself. Extracting the 6 planes is as simple as this:
http://www.toymaker....d_faq.html#D3D5

// Left clipping plane m_frustumPlanes[0].m_normal.x = matComb._14 + matComb._11; m_frustumPlanes[0].m_normal.y = matComb._24 + matComb._21; m_frustumPlanes[0].m_normal.z = matComb._34 + matComb._31; m_frustumPlanes[0].m_distance = matComb._44 + matComb._41; // Right clipping plane m_frustumPlanes[1].m_normal.x = matComb._14 - matComb._11; m_frustumPlanes[1].m_normal.y = matComb._24 - matComb._21; m_frustumPlanes[1].m_normal.z = matComb._34 - matComb._31; m_frustumPlanes[1].m_distance = matComb._44 - matComb._41; // Top clipping plane m_frustumPlanes[2].m_normal.x = matComb._14 - matComb._12; m_frustumPlanes[2].m_normal.y = matComb._24 - matComb._22; m_frustumPlanes[2].m_normal.z = matComb._34 - matComb._32; m_frustumPlanes[2].m_distance = matComb._44 - matComb._42; // Bottom clipping plane m_frustumPlanes[3].m_normal.x = matComb._14 + matComb._12; m_frustumPlanes[3].m_normal.y = matComb._24 + matComb._22; m_frustumPlanes[3].m_normal.z = matComb._34 + matComb._32; m_frustumPlanes[3].m_distance = matComb._44 + matComb._42; // Near clipping plane m_frustumPlanes[4].m_normal.x = matComb._13; m_frustumPlanes[4].m_normal.y = matComb._23; m_frustumPlanes[4].m_normal.z = matComb._33; m_frustumPlanes[4].m_distance = matComb._43; // Far clipping plane m_frustumPlanes[5].m_normal.x = matComb._14 - matComb._13; m_frustumPlanes[5].m_normal.y = matComb._24 - matComb._23; m_frustumPlanes[5].m_normal.z = matComb._34 - matComb._33; m_frustumPlanes[5].m_distance = matComb._44 - matComb._43;

Then normalize the planes.
The site explains the details, but note that the near plane should actually be:

 // Near clipping plane m_frustumPlanes[4].m_normal.x = matComb._14 + matComb._13; m_frustumPlanes[4].m_normal.y = matComb._24 + matComb._23; m_frustumPlanes[4].m_normal.z = matComb._34 + matComb._33; m_frustumPlanes[4].m_distance = matComb._44 + matComb._43;

L. Spiro

Share on other sites
Thanks, thats a great optimisation, and I did notice the mistake in the near-plane, when it failed to cull some cubes.

Now, for my culling method, what I do for AABBS is for each corner of the AABB I measure the signed distances to each plane using
 for each plane { float dist[8] for each corner(8) { dist = D - dot(planeNorm, cornerPos) } if (all distances < 0) // reject this aabb node else // test the child nodes if it has any } 

I know it's working flawlessly, because I made it count the number of aabbs that are calculated as visible, and combined with the drawing of wireframe boxes, it always agrees with what I see when flying around my scene. At the mometn I have a small FPS style map with the quadtree two subdivisions, making for a total of 16 nodes, and when I stand in the corner looking at the centre of the map, it says 14-16 nodes are drawn, but when looking away from the centre of the map, only 1 node is drawn. Just wondered if there was a more efficient way of doing this, if not I can get onto some other stuff, like dynamic meshes in the octree.

Share on other sites
You would probably be best moving on.

L. Spiro

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 10
• 11
• 13
• 9
• 11
• Forum Statistics

• Total Topics
634088
• Total Posts
3015449
×