Jump to content

  • Log In with Google      Sign In   
  • Create Account

strange frustum culling behaviour


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 cozzie   Members   -  Reputation: 1759

Like
0Likes
Like

Posted 11 January 2013 - 05:14 PM

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).

 



Sponsor:

#2 cozzie   Members   -  Reputation: 1759

Like
0Likes
Like

Posted 11 January 2013 - 05:17 PM

addition; I also tried to switch true and false in the boundingsphere check function, to see if nothing's culled, but strangely a lot of entities are still not culled (depending on the frustum at that moment)..



#3 cozzie   Members   -  Reputation: 1759

Like
0Likes
Like

Posted 11 January 2013 - 05:52 PM

Found the cause already, when I don't rotate my meshes (and thus entities), everything works fine.

I scale all vertices before calculating the boundingradius, but I don't do any rotation... probably have to do that to first



#4 0r0d   Members   -  Reputation: 819

Like
0Likes
Like

Posted 11 January 2013 - 06:32 PM

Found the cause already, when I don't rotate my meshes (and thus entities), everything works fine.

I scale all vertices before calculating the boundingradius, but I don't do any rotation... probably have to do that to first

 

You mean you werent rotating your bounding sphere to be in the same place as your rendering mesh?

 

Did you try rendering out the bounding sphere on top of the mesh to make sure they look correct?

 

It doesnt sound like you're sure what the problem is.  You should know what the problem is before moving on, not just put in a fix and hope that it's the right fix for the real problem.



#5 cozzie   Members   -  Reputation: 1759

Like
0Likes
Like

Posted 12 January 2013 - 06:16 AM

Hi.
What i do after loading the beshes, during initialization, is calculation the bounding radius of the meshes and entities. So i can use them for boundinghere checks in culling.

What i did was:
- lock vertexbuffer in local space (not scaled or rotated)
- scale the vertices
- then calculate the boundingradius (using d3dxcreateboundingsphere)
- then do the same for all entities

I was nearly there but forgot to rotate where i scale the vertices.
Found that out by setting rotation xyz for all meshes to 0 and then the problem wasn't there.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS