0

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?

2
  • 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. Commented Dec 9, 2011 at 18:26
  • 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 variable Commented Dec 9, 2011 at 21:06

1 Answer 1

1
// 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.

Sign up to request clarification or add additional context in comments.

8 Comments

I understand what's going on here, but it just returns nan for x and inf or -inf for y. Not sure where the maths is going wrong either, since the printf's show up fine and calculating the doubles at the bottom shouldn't be a problem... Any idea what might be causing it?
couple more debug checks shows it's wy2 and wy coming up as the same, so f comes out as a /0 error.
In that case the line of sight does not intersect the y = 0 plane. Suggestion: if wy2 and wy test to differ by less than a small value, set wy2 = wy - (small value ) so the intersection is 'calculated' to be very far away.
that's what i thought, but looks as though it's just my modelview and projectionview matrix that don't change. Reckon it's because I've got my own camera class with it's own modelview and projection matrices now that i realize it. (edit: all the wx,wy and wy values come out the same)
BTW in my app the line of sight is inclined to the y=0 plane and the view port is narrow enough that the 'horizon' is out of sight. If reasonable, this is the best solution to the /0 problem - make it impossible.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.