Clip Space Approach – Implementation Details
| Prev: Clip Space Approach - Extracting the Planes | Next: Radar Approach - Testing Points |
The following function, from class FrustumG, performs the plane extraction as described above, assuming that the matriz A=M*P is given as a parameter:
#define m(row,col) m[col*4+row-5]
void FrustumG::setFrustum(float *m) {
pl[NEARP].setCoefficients(
m(3,1) + m(4,1),
m(3,2) + m(4,2),
m(3,3) + m(4,3),
m(3,4) + m(4,4));
pl[FARP].setCoefficients(
-m(3,1) + m(4,1),
-m(3,2) + m(4,2),
-m(3,3) + m(4,3),
-m(3,4) + m(4,4));
pl[BOTTOM].setCoefficients(
m(2,1) + m(4,1),
m(2,2) + m(4,2),
m(2,3) + m(4,3),
m(2,4) + m(4,4));
pl[TOP].setCoefficients(
-m(2,1) + m(4,1),
-m(2,2) + m(4,2),
-m(2,3) + m(4,3),
-m(2,4) + m(4,4));
pl[LEFT].setCoefficients(
m(1,1) + m(4,1),
m(1,2) + m(4,2),
m(1,3) + m(4,3),
m(1,4) + m(4,4));
pl[RIGHT].setCoefficients(
-m(1,1) + m(4,1),
-m(1,2) + m(4,2),
-m(1,3) + m(4,3),
-m(1,4) + m(4,4));
}
#undef M
The function setCoefficients from the class Plane is as follows:
void Plane::setCoefficients(float a, float b, float c, float d) {
// set the normal vector
normal.set(a,b,c);
//compute the lenght of the vector
float l = normal.length();
// normalize the vector
normal.set(a/l,b/l,c/l);
// and divide d by th length as well
this->d = d/l;
}
To extract the matrices M and P from OpenGL state the function glGetFloatv can be used:
float m[16],p[16]; glGetFloatv(GL_PROJECTION_MATRIX,p); glGetFloatv(GL_MODELVIEW_MATRIX,m);
Matrix multiplication is then performed to compute A = M*P. A simple matrix multiplication such as the one below will do:
void multMat(float *res,float *a, float *b) {
for (int i=0;i<4;i++) {
for (int j = 0;j < 4;j++) {
res[i*4+j] = 0.0;
for (int k = 0; k < 4; k++) {
res[i*4+j] += a[i*4+k] * b[k*4+j];
}
}
}
}
The following is a solution for lazy people, using OpenGL to perform the multiplication for you (in my laptop it is actually slightly faster!) :
void multMat2(float *res, float *a, float *b) {
glPushMatrix();
glLoadMatrixf(b);
glMultMatrixf(a);
glGetFloatv(GL_MODELVIEW_MATRIX, res);
glPopMatrix();
}
Once the planes are extracted, testing points, spheres or boxes, works exactly as in the geometric approach.
| Prev: Clip Space Approach - Extracting the Planes | Next: Radar Approach - Testing Points |
2 Responses to “Clip Space Approach – Implementation Details”
Leave a Reply Cancel reply
This site uses Akismet to reduce spam. Learn how your comment data is processed.

I am attempting to implement this approach (based on the Hartmaan and Gribb method found here; http://www.cs.otago.ac.nz/postgrads/alexis/planeExtraction.pdf) but I am having little success.
I’m not using the fixed-function pipeline, so I have access to the model, view and projecton matrices seperately. Am I correct in thinking that, in this example, the Model matrix is always an identity?
When I move my camera, the frustum plane normals always seem to point toward the origin, regardless of camera position – I’m not sure where I’m going wrong.
I might be wrong here, in that case please excuse my ignorance, but when transforming a vertex (v) from object space to view space (v’), the order of multiplications is:
v' = P * V * M * vWhere P is the projection matrix, V is the view matrix, and M is the model matrix (of course, in OpenGL model and view are represented as a single model-view-matrix). And the order is important, since matrix multiplication is not commutative:
A * B != B * ASo is it really correct that
A = M * Psince that is exactly the opposite order used when transposing a vertex.