0
votes

I have:

  • screen coordinates x,y (0,0 being the middle of the screen, 1,1 being top left)
  • screen dimensions
  • camera location vector
  • camera look vector
  • projection matrix
  • ModelView matrix
  • y=0 Plane normal of (0,1,0,0)
  • y=0 plane location of (0,0,0,0)

And am looking to get the location (x,0,z) on the y=0 plane of where i click on my window (should be a line - plane intersection, but has to take into account the camera properties).

Annoyingly, I don't have the access to the GLU calls for unprojecting and the like. Just basic vector and matrix calculations. I don't really need the exact code as such, but just the technique - as a line plane intersection is easy enough to do. Finding the line that goes from the eye through the point on the screen is the hard part.

I thought it was just using the camera look vector for a ray projected from the camera location, but this doesn't take into account the mouse co-ordinates. So do i need to take into account the camera FOV too?

1
Either you want the coordinate of the intersection between an object and the ray casted from the camera center towards a certain (x,y) on the z = 0 plane (the camera center is located at (0, 0, -1) when the view transform has been applied), or you're missing something as there is an infinity of point along the above-mentionned ray.ixM
a ray cast from the camera on the y = 0 plane, the cam is currently located in the positive y and looking downwards towards it. but the position and viewing angle are variablefoips

1 Answers

2
votes
// get line of sight through mouse cursor

GLint viewport[4];
GLdouble mvmatrix[16], projmatrix[16];
GLint realy;  /*  OpenGL y coordinate position  */
GLdouble wx, wy, wz;  /*  returned world x, y, z coords  */
GLdouble wx2, wy2, wz2;  /*  returned world x, y, z coords  */
glGetIntegerv (GL_VIEWPORT, viewport);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
/*  note viewport[3] is height of window in pixels  */
realy = viewport[3] - (GLint) point.y - 1;
gluUnProject ((GLdouble) point.x, (GLdouble) realy, 0.0,
    mvmatrix, projmatrix, viewport, &wx, &wy, &wz);
//printf ("World coords at z=0.0 are (%f, %f, %f)\n",
//  wx, wy, wz);
gluUnProject ((GLdouble) point.x, (GLdouble) realy, 1.0,
    mvmatrix, projmatrix, viewport, &wx2, &wy2, &wz2);
//printf ("World coords at z=1.0 are (%f, %f, %f)\n",     
//  wx, wy, wz);

// line of sight intersection with y = 0 plane

double f = wy / ( wy2 - wy );
double x2d = wx - f * (wx2 - wx );
double z2d = wz - f * (wz2 - wz );

point.x, point.y are the mouse screen co-ords, 0.0 being top left.

The code assumes that the y = 0 plane fills the viewport. ( You are looking down on the world from a narrow aircraft port and cannot see any of the sky. ) If the y=0 plane does NOT fill the view port, you have to test for the x,y location being 'in the sky' ( wy2 - wy < small value ) and do something appropriate for your application.