// 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();
glLoadIdentity();
// 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);
}
Calculating frustum planes from arbitrary position/rotation [FIXED]
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.
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]
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.
Extracting View Frustum Planes from the Camera matrix.
Quote:Original post by Ingenu
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement