Original Post
I'm having an issue that could require some fresh eyes to look at while attempting frustum culling. Everything ends up outside the frustum regardless of where the camera is positioned.
Here are the steps i'm taking with my camera and cull check.
First I Set the projection matrix..
The camera updates its position and rebuilds its view matrix as follows..
Next the frustum planes are extracted with
last, bounding coordinates are checked with
Note, all the aabbs to be checked are technically 2D as y is constant. If anyone notices something that is wrong with this calculation please reply.
Here are the steps i'm taking with my camera and cull check.
First I Set the projection matrix..
void CD3DCamera::SetLens(float fov, float aspect, float nearZ, float farZ)
{
D3DXMatrixPerspectiveFovLH(&projMat, //projection matrix
D3DXToRadian(fov), //field of view
aspect,
nearZ,
farZ);
}
The camera updates its position and rebuilds its view matrix as follows..
void CD3DCamera::BuildView()
{
//keep axes orthoganal
D3DXVec3Normalize(&look, &look);
//up
D3DXVec3Cross(&up, &look, &right);
D3DXVec3Normalize(&up, &up);
//right
D3DXVec3Cross(&right, &up, &look);
D3DXVec3Normalize(&right, &right);
//fill view matrix
float x = -D3DXVec3Dot(&position, &right);
float y = -D3DXVec3Dot(&position, &up);
float z = -D3DXVec3Dot(&position, &look);
viewMat(0,0) = right.x;
viewMat(1,0) = right.y;
viewMat(2,0) = right.z;
viewMat(3,0) = x;
viewMat(0,1) = up.x;
viewMat(1,1) = up.y;
viewMat(2,1) = up.z;
viewMat(3,1) = y;
viewMat(0,2) = look.x;
viewMat(1,2) = look.y;
viewMat(2,2) = look.z;
viewMat(3,2) = z;
viewMat(0,3) = 0.0f;
viewMat(1,3) = 0.0f;
viewMat(2,3) = 0.0f;
viewMat(3,3) = 1.0f;
}
Next the frustum planes are extracted with
void CD3DCamera::BuildFrustum()
{
D3DXMatrixMultiply( &viewProj, &viewMat, &projMat );
//D3DXMatrixMultiply( &viewProjection, &m_mView, &m_mProjection );
// Left plane
frustum[0].a = viewProj._14 + viewProj._11;
frustum[0].b = viewProj._24 + viewProj._21;
frustum[0].c = viewProj._34 + viewProj._31;
frustum[0].d = viewProj._44 + viewProj._41;
// Right plane
frustum[1].a = viewProj._14 - viewProj._11;
frustum[1].b = viewProj._24 - viewProj._21;
frustum[1].c = viewProj._34 - viewProj._31;
frustum[1].d = viewProj._44 - viewProj._41;
// Top plane
frustum[2].a = viewProj._14 - viewProj._12;
frustum[2].b = viewProj._24 - viewProj._22;
frustum[2].c = viewProj._34 - viewProj._32;
frustum[2].d = viewProj._44 - viewProj._42;
// Bottom plane
frustum[3].a = viewProj._14 + viewProj._12;
frustum[3].b = viewProj._24 + viewProj._22;
frustum[3].c = viewProj._34 + viewProj._32;
frustum[3].d = viewProj._44 + viewProj._42;
// Near plane
frustum[4].a = viewProj._13;
frustum[4].b = viewProj._23;
frustum[4].c = viewProj._33;
frustum[4].d = viewProj._43;
// Far plane
frustum[5].a = viewProj._14 - viewProj._13;
frustum[5].b = viewProj._24 - viewProj._23;
frustum[5].c = viewProj._34 - viewProj._33;
frustum[5].d = viewProj._44 - viewProj._43;
// Normalize planes
for ( int i = 0; i < 6; i++ )
{
D3DXPlaneNormalize( &frustum, &frustum );
}
}
last, bounding coordinates are checked with
bool FrustumCheck(D3DXVECTOR3 max, D3DXVECTOR3 min, const D3DXPLANE* frustum)
{
D3DXVECTOR3 P;
D3DXVECTOR3 Q;
bool ret = false;
for(int i = 0; i < 6; ++i)
{
for(int j = 0; j < 3; ++j)
{
if( frustum[j] > 0.0f )
{
P[j] = min[j];
Q[j] = max[j];
}
else
{
P[j] = max[j];
Q[j] = min[j];
}
}
if(D3DXPlaneDotCoord(&frustum, &Q) < 0.0f ) // outside
ret = false;
}
return ret;
}
Note, all the aabbs to be checked are technically 2D as y is constant. If anyone notices something that is wrong with this calculation please reply.