visibility test

what’s the easiest way to test if a point (or node…) is within the viewing frustum ?
Thanks for the help !

Easy way is just a series of plane tests ( six ones for sliced pyramid )
also, if you utilize uniform view transform, and don’t want transform your planes back to inverse space ( which is though recommeneded when testing a lot of points ) you can reduce it to four plane tests and two Z-based ones.
Check Z-coord of transformed point to be in [znear;zfar] range, then check it to be in positive ( or negative if you use inversed plane equation or coordinate system ) sub-space of each four side planes.

Can drop a piece of code which tests box according to pre-calculated planes.

The harder ( but faster ) way is to calculate the view frustum matrix, then each test, transform your point with it and result will do everything for you ( really this matrix is just a bunch of reordered plane equations ).

isn’t there a way to obtain the viewing frustum matrix from openGL ? And would you have any useful code for that ? Thanks a lot!

Yes, you can get the frustum by openGL.
The Projection Matrix contains this.
I have not done this myself yet. But here are
two possible ways to do it.
The First way was brought to attention by
Gil and the second(function) by N.Irmer.

Getting the frustum planes from the
projection matrix.

row[3] + row[0]
row[3] - row[0]
row[3] + row[1]
row[3] - row[1]
row[3] + row[2]
row[3] - row[2]

(Where row is definited as in the opengl doc). The nice thing about this
method is it works with any projection Matrix.
Also, if you subtract the rows of the view matrix times the projection matrix, you get the planes in object space which is very handy for culling.

calc frustrum from projection matrix


void GetClip(
GLfloat *rxl, GLfloat *rxr, GLfloat *ryb, GLfloat *ryt,
GLfloat *rzn, GLfloat *rzf, int ortho )
GLfloat M[4][4];
GLfloat sx,tx,xl,xr;
GLfloat sy,ty,yt,yb;
GLfloat sz,tz,zn,zf;

glGetFloatv( GL_PROJECTION_MATRIX, M[0] );

if( !ortho )
tz = M[2][2];
sz = M[3][2];
zn = -sz / (1.0f-tz);
zf = sz / (1.0f+tz);

 tx = M[2][0];
 sx = M[0][0];
 xl = zn*(tx-1.0f)/sx;
 xr = zn*(tx+1.0f)/sx;

 ty = M[2][1];
 sy = M[1][1];
 yb = zn*(ty-1.0f)/sy;
 yt = zn*(ty+1.0f)/sy;

tx = M[3][0];
sx = M[0][0];
xl = (-1.0f-tx)/sx;
xr = (1.0f-tx)/sx;

 ty = M[3][1];
 sy = M[1][1];
 yb = (-1.0f-ty)/sy;
 yt = (1.0f-ty)/sy;

 tz = M[3][2];
 sz = M[2][2];
 zn = (1.0f+tz)/sz;
 zf = (-1.0f+tz)/sz;


*rxl = xl; *rxr = xr; *ryb = yb; *ryt = yt; *rzn = zn; *rzf = zf;

I hope that helped a bit. I havent tried the
code myself, so I dont know if its working.

Good luck,

Marcus “Cruxis” Lenngren - Nopp

[This message has been edited by Cruxis (edited 07-22-2000).]

Another idea, maybe I’m wrong… If you will call gluProject for your coordinates to test, the function will return you the screen coordinates of this point. If this coordinates lie outside of your window, you can’t see them. Maybe the gluProject will return false if the point does not lie inside the viewing frustrum.
Just an idea, did not test it.