Getting the "projection angle" for a point on the screen

Hey there!

I don’t really know how to explain this in a good way, but anyways…

Im looking for a way to find the correct angle for casting a ray from the center of the screen to the triangle that is at the current mouse-coordinate of the screen.

-Casting a ray that hits the center of the screen is no problem, I just use the current camera rotation.
-Casting a ray to anywhere on the screens x OR y-plane is pretty straightforward to.
Just take the distance in x OR y from the center of the screen, and scale it to a -.5 to .5 range * fov.

However, I cant get the correct angles from a point that has both x AND y offset from the center of the screen…

I’ve tried combining the screenoffsets in lots of ways and even tried to multiply the Camera-rotation-vector with the GL_PROJECTION_MATRIX, but nothing works…

Does anybody know how to solve this?
(or perhaps does anybody know what i mean…)?

Thanks
/Fredrik Olsson

The vector can be deduced from the frustum. You know what the eye space frustum is. The x,y point on the screen relates directly to a point on the near clip plane and it’s position on the near clip plane can be deduced with a simple linear interpolation using the window defined on the near clip plane with the glFrustum call.

This gives you a vector in eye space, the other end ofcourse is at the eye 0,0,0.

To get the world space vector you can transform these through the modelview matrix. The 0,0,0 transformed as a point will give you the eye position. The eyespace vector transformed as a vector will give you the direction, transformed as a point will give you the chosen point on the near clip plane in world space.

P.S. when I said transform through the modelview, it should be transformed through the view matrix only for world positions (the modelview matric after viewing transformations only), if you want to intersect with a specific transformed object then it should be transformed through the entire modelview used when that object is drawn.

>The vector can be deduced from the frustum.
Does this mean that I can translate the vector (going straight forward from the center of the screen) using the projection matrix, and get an angle corresponding to the projection ?

example: (pseudo code)
vector v = {0, 0, 1};
matrix m;
glMatrixMode(GL_PROJECTION);
glTranslatef(mouse_x, mouse_y, 0);
glGetfloatfv(&m);
v.multiply(m);
// v is now a vector pointing in the
// direction of the triangle(if any) under
// mouse_x, mouse_y

Is this the way to do it?

Do you want to “cast” a ray from the center of the screen or from the camera? If it is from the camera, then I think Unproject() does that, right?
If it is from the center of the screen, then you have a problem (or not).

Since the screen is the same as the front clipping plane, finding the position of that end of the ray is easy.

Now the hard part – when you pick a point on the screen, you are really picking a line going from the camera out to infinity. So where on that line do you want to “cast” the ray to??? The answer to that determines the other endpoint.

So, you actually said that you want to “cast” a ray to a picked triangle. To do that, just get the position of the triangle that was picked. I believe Unproject() will help you figure out which triangle was picked.

I just got it working, I read about gluUnproject() in another forum.

Just as you said, what I wanted to do was to was to use unproject to get the vector from the camera to the triangle being rendered under the mouse pointer.

I use:
gluUnProject(mouse_x, mouse_y, 1, f_modelview_mat, f_projection_mat, viewport, &target[0], &target[1], &target[2]);

but I do not apply any transformations to the modelview at this stage, only rotations.

Thanks you for your input!

/Fredrik Olsson