# Frustum Culling Frustration

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

## 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);

{
inFrust = 1;
//planeCount =6;
}
}

return inFrust;
}


thanks for any help.

##### Share on other sites
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 on other sites
Quote:
 Original post by PorthosI 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 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 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 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 on other sites
ok got it working now guys :)
Thanks for all your help, when the project is ready i will post it up

1. 1
Rutin
22
2. 2
3. 3
4. 4
5. 5

• 9
• 9
• 9
• 14
• 12
• ### Forum Statistics

• Total Topics
633308
• Total Posts
3011293
• ### Who's Online (See full list)

There are no registered users currently online

×