Hi,
I've noticed that my frustum culling is behaving strange when doing a boundingsphere check on entities of meshes. It looks like entities are being culled just before there out of the frustum/ screen.
Before I dig into my code calculation the radius of my entities, I'd like to know if someone sees any strange things my frustum calculation and check boundingsphere functions. Any help is really appreciated:
void CD3dcam::CalculateFrustum()
{
D3DXMatrixMultiply(&mFrustumMatrix, &mMatView, &mMatProjection);
// left plane
mFrustumPlane[0].a = mFrustumMatrix._14 + mFrustumMatrix._11;
mFrustumPlane[0].b = mFrustumMatrix._24 + mFrustumMatrix._21;
mFrustumPlane[0].c = mFrustumMatrix._34 + mFrustumMatrix._31;
mFrustumPlane[0].d = mFrustumMatrix._44 + mFrustumMatrix._41;
D3DXPlaneNormalize(&mFrustumPlane[0], &mFrustumPlane[0]);
// right plane
mFrustumPlane[1].a = mFrustumMatrix._14 - mFrustumMatrix._11;
mFrustumPlane[1].b = mFrustumMatrix._24 - mFrustumMatrix._21;
mFrustumPlane[1].c = mFrustumMatrix._34 - mFrustumMatrix._31;
mFrustumPlane[1].d = mFrustumMatrix._44 - mFrustumMatrix._41;
D3DXPlaneNormalize(&mFrustumPlane[1], &mFrustumPlane[1]);
// top plane
mFrustumPlane[2].a = mFrustumMatrix._14 - mFrustumMatrix._12;
mFrustumPlane[2].b = mFrustumMatrix._24 - mFrustumMatrix._22;
mFrustumPlane[2].c = mFrustumMatrix._34 - mFrustumMatrix._32;
mFrustumPlane[2].d = mFrustumMatrix._44 - mFrustumMatrix._42;
D3DXPlaneNormalize(&mFrustumPlane[2], &mFrustumPlane[2]);
// bottom plane
mFrustumPlane[3].a = mFrustumMatrix._14 + mFrustumMatrix._12;
mFrustumPlane[3].b = mFrustumMatrix._24 + mFrustumMatrix._22;
mFrustumPlane[3].c = mFrustumMatrix._34 + mFrustumMatrix._32;
mFrustumPlane[3].d = mFrustumMatrix._44 + mFrustumMatrix._42;
D3DXPlaneNormalize(&mFrustumPlane[3], &mFrustumPlane[3]);
// near plane
mFrustumPlane[4].a = mFrustumMatrix._13;
mFrustumPlane[4].b = mFrustumMatrix._23;
mFrustumPlane[4].c = mFrustumMatrix._33;
mFrustumPlane[4].d = mFrustumMatrix._43;
D3DXPlaneNormalize(&mFrustumPlane[4], &mFrustumPlane[4]);
// far plane
mFrustumPlane[5].a = mFrustumMatrix._14 - mFrustumMatrix._13;
mFrustumPlane[5].b = mFrustumMatrix._24 - mFrustumMatrix._23;
mFrustumPlane[5].c = mFrustumMatrix._34 - mFrustumMatrix._33;
mFrustumPlane[5].d = mFrustumMatrix._44 - mFrustumMatrix._43;
D3DXPlaneNormalize(&mFrustumPlane[5], &mFrustumPlane[5]);
}
bool CD3dcam::SphereInFrustum(D3DXVECTOR3 *pPosition, float pRadius)
{
float fDistance;
for(int i=0;i<6;++i)
{
fDistance = D3DXPlaneDotCoord(&mFrustumPlane[i], pPosition) + pRadius;
if(fDistance < -pRadius) return false; // outside the frustum
if((float)fabs(fDistance) < pRadius) return true; // intersects
}
return true; // inside the frustum completely or intersecting; see XLS
}
// calculating the entities/ meshes radius
bool CD3dmesh::CalcRadiusAndWorldPos()
{
mAttrWorldPos = new D3DXVECTOR3[mAttrSize];
mAttrBoundingRadius = new float[mAttrSize];
mAttrBoundingBox = new BOUNDINGBOX[mAttrSize];
TVERTEX *verticesPointer;
TVERTEX *vertices = new TVERTEX[mMesh->GetNumVertices()];
mVtxBuffer->Lock(0, 0, (void**)&verticesPointer, 0); //D3DLOCK_READONLY);
memcpy(vertices, verticesPointer, mMesh->GetNumVertices()*D3DXGetDeclVertexSize(dec, 0));
mVtxBuffer->Unlock();
// scale the vertices, before determining bounding radius, mesh (world)pos etc.
for(DWORD vc=0;vc<mMesh->GetNumVertices();++vc)
D3DXVec3Scale(&vertices[vc].position, &vertices[vc].position, mScale);
// calculatie bounding radius, using always absolute, 0.0.0 mMeshCenter
D3DXComputeBoundingSphere(&vertices[0].position, mMesh->GetNumVertices(), D3DXGetDeclVertexSize(dec, 0), &mMeshCenter, &mBoundingRadius);
// do the same for all subobjects in the attr table, mAttrWorldPos is DETERMINED based on subobject vertices
for(DWORD obj=0;obj<mAttrSize;++obj)
{
D3DXComputeBoundingSphere(&vertices[mAttrTable[obj].VertexStart].position, (DWORD)mAttrTable[obj].VertexCount, D3DXGetDeclVertexSize(dec, 0), &mAttrWorldPos[obj], &mAttrBoundingRadius[obj]);
mAttrBoundingRadius[obj] += 0.1f;
CalcBoundingBox(vertices, mAttrTable[obj].VertexStart, mAttrTable[obj].VertexCount, &mAttrBoundingBox[obj]);
}
SafeDelete(vertices);
// add WorldPos of object to all sub objects
for(DWORD obj=0;obj<mAttrSize;++obj)
{
D3DXVec3Add(&mAttrWorldPos[obj], &mAttrWorldPos[obj], &mWorldPos);
for(int vc=0;vc<8;++vc)
D3DXVec3Add(&mAttrBoundingBox[obj].boxArray[vc], &mAttrBoundingBox[obj].boxArray[vc], &mWorldPos);
}
UpdateWorldMatrix();
return true;
}
It doesn't seem to occur on full meshes though (first boundingsphere check in rendering a frame).