Archived

This topic is now archived and is closed to further replies.

DeepCover

Plane Extraction Problem

Recommended Posts

I followed this paper. http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf for plane extraction. Yet when I run my frustum culling routine, I get wierd results as if my camera is actually somewhere a little bit off of where it should be and facing the wrong direction. I've been at it for a few hours and I havent fixed it. Am I doing something wrong here? Here's my extraction code.
void Quadtree::extractPlanes()
{
	//4x4 float matrix

        //_11, _21, _31, _41;  

        //_12, _22, _32, _42;

        //_13, _23, _33, _43;

        //_14, _24, _34, _44;


        //stored in

        float combinedMatrix[16];

	// get the current projection view matrix

	glGetFloatv(GL_PROJECTION_MATRIX , combinedMatrix);

	//save the current modelview matrix

	glPushMatrix();

	//multiply the modelview matrix with the projection matrix

	//to get the combined matrix

	glMultMatrixf(combinedMatrix);

	// get the current modelview matrix (current modelview)

	glGetFloatv(GL_MODELVIEW_MATRIX , combinedMatrix);

	//restore the current modelview matrix

	glPopMatrix();

	// Left clipping plane

	frustumPlanes[0].surfaceNorm.x = combinedMatrix[12] + combinedMatrix[0];
	frustumPlanes[0].surfaceNorm.y = combinedMatrix[13] + combinedMatrix[1];
	frustumPlanes[0].surfaceNorm.z = combinedMatrix[14] + combinedMatrix[2];
	frustumPlanes[0].dist = combinedMatrix[15] + combinedMatrix[3];
	// Right clipping plane

	frustumPlanes[1].surfaceNorm.x = combinedMatrix[12] - combinedMatrix[0];
	frustumPlanes[1].surfaceNorm.y = combinedMatrix[13] - combinedMatrix[1];
	frustumPlanes[1].surfaceNorm.z = combinedMatrix[14] - combinedMatrix[2];
	frustumPlanes[1].dist = combinedMatrix[15] - combinedMatrix[3];
	// Top clipping plane

	frustumPlanes[2].surfaceNorm.x = combinedMatrix[12] - combinedMatrix[4];
	frustumPlanes[2].surfaceNorm.y = combinedMatrix[13] - combinedMatrix[5];
	frustumPlanes[2].surfaceNorm.z = combinedMatrix[14] - combinedMatrix[6];
	frustumPlanes[2].dist = combinedMatrix[15] - combinedMatrix[7];
	// Bottom clipping plane

	frustumPlanes[3].surfaceNorm.x = combinedMatrix[12] + combinedMatrix[4];
	frustumPlanes[3].surfaceNorm.y = combinedMatrix[13] + combinedMatrix[5];
	frustumPlanes[3].surfaceNorm.z = combinedMatrix[14] + combinedMatrix[6];
	frustumPlanes[3].dist = combinedMatrix[15] + combinedMatrix[7];
	// Near clipping plane

	frustumPlanes[4].surfaceNorm.x = combinedMatrix[12] + combinedMatrix[8];
	frustumPlanes[4].surfaceNorm.y = combinedMatrix[13] + combinedMatrix[9];
	frustumPlanes[4].surfaceNorm.z = combinedMatrix[14] + combinedMatrix[10];
	frustumPlanes[4].dist = combinedMatrix[15] + combinedMatrix[11];
	// Far clipping plane

	frustumPlanes[5].surfaceNorm.x = combinedMatrix[12] - combinedMatrix[8];
	frustumPlanes[5].surfaceNorm.y = combinedMatrix[13] - combinedMatrix[9];
	frustumPlanes[5].surfaceNorm.z = combinedMatrix[14] - combinedMatrix[10];
	frustumPlanes[5].dist = combinedMatrix[15] - combinedMatrix[11];

	normalizePlane(frustumPlanes[0]);
	normalizePlane(frustumPlanes[1]);
	normalizePlane(frustumPlanes[2]);
	normalizePlane(frustumPlanes[3]);
	normalizePlane(frustumPlanes[4]);
	normalizePlane(frustumPlanes[5]);

}


And here's the culling routine I'm running (taken from flipcode culling tutorial) http://www.flipcode.com/articles/article_frustumculling.shtml


   
Quadtree::HALFSPACE Quadtree::frustumTest()
{
	float distance;

	// calculate distance to each plane

	for(int i = 0; i < 6; ++i)
	{
		// find the distance to this plane

		distance = frustumPlanes[i].surfaceNorm.dot(quadCenter) + frustumPlanes[i].dist;

		// if this distance is < -sphere.radius, we are outside

		if(distance < -boundingSphereRadius)
		{
			return(NEGATIVE_PLANE);  //we are outside

		}

		// else if the distance is between +- radius, then we intersect

		if((float)fabs(distance) < boundingSphereRadius)
		{
			return(ON_PLANE);
		}
	}

	// otherwise we are fully in view

	return(POSITIVE_PLANE);
}


And one last bit of data, how the modelview matrix is modified:

   
void Engine::display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity(); 
    
    //all rotations take place

    glRotatef(-theHero->rotateX, 1.0f, 0.0f, 0.0f);
    glRotatef(-theHero->rotateY, 0.0f, 1.0f, 0.0f);

    glTranslatef(-theHero->eye.x, -theHero->eye.y, -theHero->eye.z);
....
Thanks in advance. [edited by - DeepCover on March 28, 2004 12:34:35 PM] [edited by - DeepCover on March 28, 2004 2:09:38 PM] [edited by - DeepCover on March 28, 2004 2:36:53 PM] [edited by - DeepCover on March 28, 2004 3:54:23 PM]

Share this post


Link to post
Share on other sites
This statement is wrong:
	return(ON_PLANE);  
You should not return right away because the sphere can intersect a plane but still be outside of the frustum (planes are infinite, as I'm sure you already know).

Check the culling tutorial again and I bet you'll find it looks more like this:

Quadtree::HALFSPACE Quadtree::frustumTest()
{
Quadtree::HALFSPACE result = POSITIVE_PLANE; // assume fully inside

float distance; // calculate distance to each plane

for(int i = 0; i < 6; ++i)
{
// find the distance to this plane

distance = frustumPlanes[i].surfaceNorm.dot(quadCenter) + frustumPlanes[i].dist;
// if this distance is < -sphere.radius, we are outside

if(distance < -boundingSphereRadius)
{
return(NEGATIVE_PLANE); //we are outside

}
// else if the distance is between +- radius, then we intersect a plane and aren't FULLY inside

if((float)fabs(distance) < boundingSphereRadius)
{
result = ON_PLANE;
}
}
return(result);
}



[edited by - JohnBolton on March 28, 2004 3:44:04 PM]

Share this post


Link to post
Share on other sites
I think I know what the problem is.

When I do transformations, I do it like this:
glTranslatef(- x, - y, - z);

This is because in openGL, you move the world, so if I want to go forward, I just move the world back.

I do the same with rotations. If I want to look to my left, I rotate the world to my right.

I think this is screwing up my rotations. So now before I do the frustum calculations, I save my modelview matrix and load the correct matrix to the modelview.

glLoadIdentity();
glRotatef(theHero->rotateX, 1.0f, 0.0f, 0.0f);
glRotatef(theHero->rotateY, 0.0f, 1.0f, 0.0f);
glTranslatef(theHero->eye.x, theHero->eye.y, theHero->eye.z);

It seems to work in one direction, but not in the oposite, which leads me to believe there is something wrong with my rotation.

Share this post


Link to post
Share on other sites
quote:
Original post by JohnBolton
This statement is wrong:
	return(ON_PLANE);   
You should not return right away because the sphere can intersect a plane but still be outside of the frustum (planes are infinite, as I''m sure you already know).



Hi Bolton, you are correct. However I failed to mention that I do a cone-intersection before this step, so only the quads within my conanicle (sp?) view are being tested here. So if the quad intersects the frusrum here, it''s within view (or at least some of it''s children quads).

Share this post


Link to post
Share on other sites
I think it was right the first time -- the model-view matrix is the inverse of the orientation/translation and you want to use the real model-view matrix, regardless of how it was generated.

Anyway, I don''t think this will fix anything, but the inverse of
    glLoadIdentity(); 
glRotatef(-theHero->rotateX, 1.0f, 0.0f, 0.0f);
glRotatef(-theHero->rotateY, 0.0f, 1.0f, 0.0f);
glTranslatef(-theHero->eye.x, -theHero->eye.y, -theHero->eye.z);
is
    glLoadIdentity(); 
glTranslatef(theHero->eye.x, theHero->eye.y, theHero->eye.z);
glRotatef(theHero->rotateY, 0.0f, 1.0f, 0.0f);
glRotatef(theHero->rotateX, 1.0f, 0.0f, 0.0f);
not
    glLoadIdentity(); 
glRotatef(theHero->rotateX, 1.0f, 0.0f, 0.0f);
glRotatef(theHero->rotateY, 0.0f, 1.0f, 0.0f);
glTranslatef(theHero->eye.x, theHero->eye.y, theHero->eye.z);

Share this post


Link to post
Share on other sites
Thanks Bolton. What you said makes sense. So I''m back at square one. On thing I noticed is that when I change the near-plane in my gluPerspective call from 1 to 0.3 or something similar, I get differences in what I see n the screen. I''. thinking that maybe the way I''m multiplying the perspective and modelview matrices isn''t right.

Share this post


Link to post
Share on other sites
I finally got it working.
First off was multiplying the matrices in the wrong order, then with that matrix I used the frustum calculations from this website, which used different rows than what I was using:

http://cslab.wheaton.edu/~dthulson/projects/Pirates/frustum.html

That worked. Thanks Bolton fot getting me started in the right direction.

[edited by - DeepCover on March 28, 2004 10:01:30 PM]

Share this post


Link to post
Share on other sites