# OpenGL Calculating frustum planes from arbitrary position/rotation [FIXED]

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

## Recommended Posts

Hi all, I have a Viewer class, which represents some entity capable of seeing things within my program's world. I'm trying to add some functions to calculate and perform tests on a viewer's frustum. Each viewer has its own information like fov, near/far plane distance, and aspect ratio. I've almost got everything working the way I want it, however some weird things happen: * I've checked all the values, but the frustum appears pointing out of the viewer's back, rather than in front. * The shape of the frustum appears to change as the viewer rotates about the Y (up) axis. I'm using OpenGL, however I am working in a coordinate system where the positive direction of the Z axis points into the screen, rather than out. This might be messing up some of the transformations... I calculate the frustum planes as follows: * Define the frustum planes in camera space. * Use OpenGL to do some transformations to bring camera space to world space. * Extract the matrix, and premultiply the 4-dimensional frustum vectors by it. * Normalise. To render the frustum, I'm finding the corners of the frustum by testing the intersection of 3 of the frustum planes, e.g. to get the near-top-left corner, I find the coordinates of intersection of the near, top, and left frustum planes. Like I say, it nearly works! But not quite. Perhaps some frustum-gurus have some advice for me? I've examined the plane normals, and they are most definitely correct in all the cases I've tried. I think it might be the D values that are messing up. Here's the frustum-plane calculating code: Few things to note: * e is calculated as 1 / tan(fovX), where fovX is the horizontal fov. * aspect is 0.75, in most cases. * One of the rotation lines is rot[1] - 90 rather than rot[1] because of the way I want my angles to point. This works.
// Precalculate frustum planes, from the viewer's position and orientation.
void Viewer::updateFrustumPlanes()
{
// In camera coordinate space, the planes are easy to specify.
// They are stored in the order near, far, left, right, bottom, top.
float f[6][4];
vec4Set(f[0], 0, 0, 1, near);
vec4Set(f[1], 0, 0, -1, -far);
vec4Set(f[2], e, 0, 1, 0);
vec4Set(f[3], -e, 0, 1, 0);
vec4Set(f[4], 0, e, aspect, 0);
vec4Set(f[5], 0, -e, aspect, 0);

// Now we must transform the planes from camera space to world space.
glPushMatrix();
// Perform the transformations.
glRotatef(rot[0],         1.0f, 0.0f, 0.0f);
glRotatef(rot[1] - 90.0f, 0.0f, 1.0f, 0.0f);
glRotatef(rot[2],         0.0f, 0.0f, 1.0f);
glTranslatef(-pos[0], -pos[1], -pos[2]);
// Store the current matrix.
float m[16];
glGetFloatv(GL_MODELVIEW_MATRIX, m);
glPopMatrix();

// Treating each plane as a 4-dimensional vector, transform each one by
// the matrix we just saved to get the planes' coordinates in world space.
for (int i = 0; i < 6; ++i)
{
frustum[0] =
m[0] * f[0] + m[1] * f[1] + m[2] * f[2] + m[3] * f[3];
frustum[1] =
m[4] * f[0] + m[5] * f[1] + m[6] * f[2] + m[7] * f[3];
frustum[2] =
m[8] * f[0] + m[9] * f[1] + m[10] * f[2] + m[11] * f[3];
frustum[3] =
m[12] * f[0] + m[13] * f[1] + m[14] * f[2] + m[15] * f[3];
}

// Normalise the vectors.
for (int i = 0; i < 6; ++i)
vec3Normalise(frustum);
}


Oh, I also posted this to flipcode too. Hope that kind of cross-posting doesn't offend anybody :). [Edited by - smidge on October 25, 2004 11:16:41 AM]

##### Share on other sites
Ok, I'm lazy so I didn't read the whole message, from the topic I think you want that : http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf

Extracting View Frustum Planes from the Camera matrix.

##### Share on other sites
Quote:
 Original post by IngenuOk, I'm lazy so I didn't read the whole message, from the topic I think you want that : http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdfExtracting View Frustum Planes from the Camera matrix.

Yes, that's not quite what I'm after - that article deals with extracting frustum planes from the existing projection matrix; however, I'm working with arbitrary camera coordinates and orientation, and don't want to have to alter the projection matrix each time I calculate something.

But not to worry, I fixed it the problem:

This:

vec4Set(f[0], 0, 0, 1, near);
vec4Set(f[1], 0, 0, -1, -far);

.. should have been this:

vec4Set(f[0], 0, 0, 1, -near);
vec4Set(f[1], 0, 0, -1, far);

(silly mistake)

And the problem with the frustum changing shape, I noticed, made the d values of the top and bottom plane scale incorrectly with the other d values (in fact, they scaled at a ratio the same as the aspect ratio).

Normalising the f plane normals before transforming fixed that. All working nicely now.

1. 1
2. 2
3. 3
Rutin
15
4. 4
5. 5

• 10
• 9
• 9
• 11
• 11
• ### Forum Statistics

• Total Topics
633682
• Total Posts
3013306
×