Getting 2d mouse position on a 3d plane

I’ve looked for this on the forum and so far I’ve seen a few things that seem to do what I want, but don’t actually seem to work. I’m relatively new to 3d geometry so obviously I’ve got stuck. I know it must be something simple but I’m not sure what. I know I have to raycast the cursor into the scene and get the intersection point of the plane. I just don’t know exactly how and need someone to point me in the right direction.

I’ll explain it in this image if I’ve lost anybody:

[img]http://dummyworld.net/plane.gif[/img]     

The floor in that picture is along the XZ plane. When I click where the mouse cursor is, the program needs to calculate the X and Z positions of that green dot on the plane.

This is what I’ve tried so far, based on things I’ve seen around the forum:

void GetCursorPlane(int x, int y, vertex *to)
{
GLint viewport[4];
GLdouble modelview[16], projection[16];
GLfloat mouseX, mouseY;

glPushMatrix();
glLoadIdentity();

//Setup the camera (referencing angles from the openGL class)
glRotatef(openGL.cameraRotate.x, 1.0f, 0.0f, 0.0f);
glRotatef(openGL.cameraRotate.y -180.0f, 0.0f,-1.0f, 0.0f);
glRotatef(openGL.cameraRotate.z, 0.0f, 0.0f, 1.0f);
glTranslatef( 0.0f - openGL.cameraPos.x,
0.0f - openGL.cameraPos.y,
0.0f - openGL.cameraPos.z);

//Get the matrices and viewport details
glGetDoublev (GL_MODELVIEW_MATRIX, modelview);
glGetDoublev (GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewport);

//Mouse cursor pos correction (opengl’s upside down)
mouseX = (float)x;
mouseY = (float)viewport[3] - (float)y;

//Unproject
gluUnProject( mouseX, mouseY, 1.0f, modelview, projection, viewport, &to->x, &to->y, &to->z);

glPopMatrix();
return;
}

This gives me coordinates that are way off what I need, and doesn’t seem to give remotely right values (eg, I click repeatadly along the top edge of the wall, left to right, and all the XYZ positions change instead of Z staying near constant).

[This message has been edited by dummstah (edited 11-25-2003).]

I moved all the modelview, projectionview and such into my openGL and theyre now automatically stored after I set up my actual camera. This seems to give better results than last time. I’ve also gone a different route by getting the near and far xyz points:

void GetCursorPlane(int x, int y, vertex *to)
{
GLfloat mouseX, mouseY;

GLdouble posX1, posY1, posZ1;
GLdouble posX2, posY2, posZ2;

mouseX = (float)x;
mouseY = (float)openGL.viewport[3] - (float)y;

gluUnProject( mouseX, mouseY, 0.0, openGL.modelview, openGL.projection, openGL.viewport, &posX1, &posY1, &posZ1);
gluUnProject( mouseX, mouseY, 1.0, openGL.modelview, openGL.projection, openGL.viewport, &posX2, &posY2, &posZ2);
}

posX/Y/Z1 store the near plane x/y/z
posX/Y/Z2 store the far plane x/y/z

Can anyone tell me an easy way to find out what X and Z are when Y is 0.0?

[This message has been edited by dummstah (edited 11-25-2003).]

Ok so I shouldn’t have posted this here. Figured it out now I’ll post the code in case it helps anyone.

void GetCursorPlane(int x, int y, vertex *to)
{
GLfloat mouseX, mouseY;

GLdouble posX1, posY1, posZ1;
GLdouble posX2, posY2, posZ2;

mouseX = (float)x;
mouseY = (float)openGL.viewport[3] - (float)y;

gluUnProject( mouseX, mouseY, 0.0, openGL.modelview, openGL.projection, openGL.viewport, &posX1, &posY1, &posZ1);
gluUnProject( mouseX, mouseY, 1.0, openGL.modelview, openGL.projection, openGL.viewport, &posX2, &posY2, &posZ2);

//Find X and Z when Y is 0
float zeropoint, zeroperc;
double posXt, posYt, posZt;
posXt = posX1 - posX2;
posYt = posY1 - posY2;
posZt = posZ1 - posZ2;

//Check the Y’s pass through the plane on 0
if (posY1 < 0.0 && posY2 < 0.0 | | posY1 > 0.0 && posY2 > 0.0)
return;

//Now we’ll nudge out stuff up and find out the zero point
zeropoint = 0.0f - (float)posY1;

//Find the percentage that this point is between them
zeroperc = (zeropoint / (float)posYt);

to->x = (float)posX1 + (float)(posXt * zeroperc); to->y = (float)posY1 + (float)(posYt * zeroperc); to->z = (float)posZ1 + (float)(posZt * zeroperc);
return;
}