• Advertisement
Sign in to follow this  

Frustum Culling Frustration

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys, I have spent the last (long time), trying to debug this code, and i finally had to swallow my pride and ask for help =\. The problem is that it my frustum culling sort of work...but i am getting some wacky results, it almost looks like my frustum isn't moving with me...or something if that effect. I have got the non-identity model view matrix, extracted the planes and check my spheres against them, and it works, but not how i want it to, the further i get away from the starting point the worse it looks... ummm yeah, got some code, if anyone could help that would be great. *Note i have to use C in this project*
quatBuildCamera();

MultSingleMatrix44f(nimvMatrix);
	
//Extracts Planes and Normalizes them
ExtractPlanes(plane, nimvMatrix);

float *MultSingleMatrix44f(float *nimvMatrix)
{
	float pMatrix[16];
	float mvMatrix[16];
	//Model View Matrix * Projection Matris = Non-Identity Model View Matrix
	glGetFloatv(GL_MODELVIEW_MATRIX, mvMatrix);
	glGetFloatv(GL_PROJECTION_MATRIX, pMatrix);

	//Column 1
	nimvMatrix[0] = ((mvMatrix[0] * pMatrix[0]) + (mvMatrix[1] * pMatrix[4])     + (mvMatrix[2] * pMatrix[8]) + (mvMatrix[3] * pMatrix[12]));
	nimvMatrix[4] = ((mvMatrix[0] * pMatrix[1]) + (mvMatrix[1] * pMatrix[5]) + (mvMatrix[2] * pMatrix[9]) + (mvMatrix[3] * pMatrix[13]));
	nimvMatrix[8] = ((mvMatrix[0] * pMatrix[2]) + (mvMatrix[1] * pMatrix[6]) + (mvMatrix[2] * pMatrix[10]) + (mvMatrix[3] * pMatrix[14]));
	nimvMatrix[12] = ((mvMatrix[0] * pMatrix[3]) + (mvMatrix[1] * pMatrix[7]) + (mvMatrix[2] * pMatrix[11]) + (mvMatrix[3] * pMatrix[15]));

	//Column 2
	nimvMatrix[1] = ((mvMatrix[4] * pMatrix[0]) + (mvMatrix[5] * pMatrix[4]) + (mvMatrix[6] * pMatrix[8]) + (mvMatrix[7] * pMatrix[12]));
	nimvMatrix[5] = ((mvMatrix[4] * pMatrix[1]) + (mvMatrix[5] * pMatrix[5]) + (mvMatrix[6] * pMatrix[9]) + (mvMatrix[7] * pMatrix[13]));
	nimvMatrix[9] = ((mvMatrix[4] * pMatrix[2]) + (mvMatrix[5] * pMatrix[6]) + (mvMatrix[6] * pMatrix[10]) + (mvMatrix[7] * pMatrix[14]));
	nimvMatrix[13] = ((mvMatrix[4] * pMatrix[3]) + (mvMatrix[5] * pMatrix[7]) + (mvMatrix[6] * pMatrix[11]) + (mvMatrix[7] * pMatrix[15]));
	
	//Column 3
	nimvMatrix[2] = ((mvMatrix[8] * pMatrix[0]) + (mvMatrix[9] * pMatrix[4]) + (mvMatrix[10] * pMatrix[8]) + (mvMatrix[11] * pMatrix[12]));
	nimvMatrix[6] = ((mvMatrix[8] * pMatrix[1]) + (mvMatrix[9] * pMatrix[5]) + (mvMatrix[10] * pMatrix[9]) + (mvMatrix[11] * pMatrix[13]));
	nimvMatrix[10] = ((mvMatrix[8] * pMatrix[2]) + (mvMatrix[9] * pMatrix[6]) + (mvMatrix[10] * pMatrix[10]) + (mvMatrix[11] * pMatrix[14]));
	nimvMatrix[14] = ((mvMatrix[8] * pMatrix[3]) + (mvMatrix[9] * pMatrix[7]) + (mvMatrix[10] * pMatrix[11]) + (mvMatrix[11] * pMatrix[15]));

	//Column 4
	nimvMatrix[3] = ((mvMatrix[12] * pMatrix[0]) + (mvMatrix[13] * pMatrix[4]) + (mvMatrix[14] * pMatrix[8]) + (mvMatrix[15] * pMatrix[12]));
	nimvMatrix[7] = ((mvMatrix[12] * pMatrix[1]) + (mvMatrix[13] * pMatrix[5]) + (mvMatrix[14] * pMatrix[9]) + (mvMatrix[15] * pMatrix[13]));
	nimvMatrix[11] = ((mvMatrix[12] * pMatrix[2]) + (mvMatrix[13] * pMatrix[6]) + (mvMatrix[14] * pMatrix[10]) + (mvMatrix[15] * pMatrix[14]));
	nimvMatrix[15] = ((mvMatrix[12] * pMatrix[3]) + (mvMatrix[13] * pMatrix[7]) + (mvMatrix[14] * pMatrix[11]) + (mvMatrix[15] * pMatrix[15]));

	return (nimvMatrix);
}

Plane *ExtractPlanes(Plane *plane, SingleMatrix44f nimvMatrix)
{
	//Left Plane
	plane[0].a = nimvMatrix[3] + nimvMatrix[1];
	plane[0].b = nimvMatrix[7] + nimvMatrix[4];
	plane[0].c = nimvMatrix[11] + nimvMatrix[8];
	plane[0].d = nimvMatrix[15] + nimvMatrix[12];

	//Right Plane
	plane[1].a = nimvMatrix[3] - nimvMatrix[0];
	plane[1].b = nimvMatrix[7] - nimvMatrix[4];
	plane[1].c = nimvMatrix[11] - nimvMatrix[8];
	plane[1].d = nimvMatrix[15] - nimvMatrix[12];

	//Top Plane
	plane[2].a = nimvMatrix[3] - nimvMatrix[1];
	plane[2].b = nimvMatrix[7] - nimvMatrix[5];
	plane[2].c = nimvMatrix[11] - nimvMatrix[9];
	plane[2].d = nimvMatrix[15] - nimvMatrix[13];

	//Bottom Plane
	plane[3].a = nimvMatrix[3] + nimvMatrix[1];
	plane[3].b = nimvMatrix[7] + nimvMatrix[5];
	plane[3].c = nimvMatrix[11] + nimvMatrix[9];
	plane[3].d = nimvMatrix[15] + nimvMatrix[13];

	//Near Plane
	plane[4].a = nimvMatrix[3] + nimvMatrix[2];
	plane[4].b = nimvMatrix[7] + nimvMatrix[6];
	plane[4].c = nimvMatrix[11] + nimvMatrix[10];
	plane[4].d = nimvMatrix[15] + nimvMatrix[14];

	//Far Plane
	plane[5].a = nimvMatrix[3] - nimvMatrix[2];
	plane[5].b = nimvMatrix[7] - nimvMatrix[6];
	plane[5].c = nimvMatrix[11] - nimvMatrix[10];
	plane[5].d = nimvMatrix[15] - nimvMatrix[14];

	//Normalizing Planes
	plane[0] = NormalizePlane(plane[0]);
	plane[1] = NormalizePlane(plane[1]);
	plane[2] = NormalizePlane(plane[2]);
	plane[3] = NormalizePlane(plane[3]);
	plane[4] = NormalizePlane(plane[4]);
	plane[5] = NormalizePlane(plane[5]);


	return plane;
}


Plane NormalizePlane(Plane plane)
{
	float pointMag;

	pointMag = sqrt((plane.a * plane.a) + (plane.b * plane.b) + (plane.c * plane.c) + plane.d);

	plane.a /= pointMag;
	plane.b /= pointMag;
	plane.c /= pointMag;
	plane.d /= pointMag;

	return plane;
}

int SphereInFrustum(BaseObject *model, Plane *plane)
{
	int planeCount;
	float dist;
	int inFrust = 0;

	for( planeCount = 0; planeCount < 6; planeCount++ )
	{
		dist = ((plane[planeCount].a * model->m_position[0]) + 
				(plane[planeCount].b * model->m_position[1]) + 
				(plane[planeCount].c * model->m_position[2]) +
				plane[planeCount].d);
		
		if(dist >= (model->m_model->bounding_radius))
		{
			inFrust = 1;
			//planeCount =6;
		}
	}
	
	return inFrust;
}

thanks for any help.

Share this post


Link to post
Share on other sites
Advertisement
I am using this code (however, I am not sure whether it has been tested yet so be careful):


EPHClassification U3D_STD_CALL CPHViewFrustum::ClassifySphere(
const CPHBoundingSphere* p_piSphere) const
{
EPHClassification eResult = EPHClassification_Inside;
for (register uIntT i = 0; i < 6; i++)
{
const Maths::CPlane3* pcPlane = &this->m_apPlanes;

// check center point of the plane
const CVector3& vN = p_piSphere->m_vCenter;
const sFloat32 fTemp = pcPlane->n.x *
vN.x plus pcPlane->n.y * vN.y plus pcPlane->n.z * vN.z;

if (fTemp plus p_piSphere->m_fRadius > -pcPlane->d)
return EPHClassification_Outside;

if (fTemp minus p_piSphere->m_fRadius > -pcPlane->d)
eResult = EPHClassification_Intersecting;
}
return eResult;
}


Hope it helps you. I have replaced *the plus sign* with plus, what do I have to do to keep GD.net from removing *the plus sign* characters?

And I'm sorry for you that you must use C ;-)

Best regards,
Porthos

Share this post


Link to post
Share on other sites
Quote:
Original post by Porthos
I have replaced *the plus sign* with plus, what do I have to do to keep GD.net from removing *the plus sign* characters?

It's just a quirk with the preview. They're there in the actual post: +++
</offtopichelp>

Share this post


Link to post
Share on other sites
I think your SphereInFrustrum is wrong. It seems to be saying 'is the sphere inside ANY of the faces', whereas I would say it should be 'is the sphere inside ALL the faces', i.e. (pseudo)
for(each face){
float dist = (big long calculation I didn't check but which is probably right);
if(dist > radius) return false; // or (-dist) depending on your sign convention
}
return true;

Share this post


Link to post
Share on other sites
I didn't make it through everything, but your plane normalize function is off: it should be:


Plane NormalizePlane(Plane plane)
{
float normalLen;

normalLen = sqrt((plane.a * plane.a) + (plane.b * plane.b) + (plane.c * plane.c));

plane.a /= normalLen;
plane.b /= normalLen;
plane.c /= normalLen;
plane.d /= normalLen;

return plane;
}

Share this post


Link to post
Share on other sites
Well thansk for the help guys, still have the problem that it is culling stuff when it is still in the frustum, i think it must be a problem of me mixing column major and row major stuff, but i don't know

Share this post


Link to post
Share on other sites
ok got it working now guys :)
Thanks for all your help, when the project is ready i will post it up

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement