在不使用OpenGL调用的情况下从鼠标坐标获取y = 0平面上的点

时间:2011-12-09 18:15:26

标签: c++ opengl 3d mouse

我有:

  • 屏幕坐标x,y(0,0是屏幕的中间,1,1是左上角)
  • 屏幕尺寸
  • 相机位置矢量
  • 相机外观矢量
  • 投影矩阵
  • ModelView矩阵
  • y = 0平面法线(0,1,0,0)
  • y = 0平面位置(0,0,0,0)

我希望在我点击窗口的y = 0平面上得到位置(x,0,z)(应该是线 - 平面交点,但必须考虑相机属性)。

令人讨厌的是,我无法访问GLU调用unjectjects等。只是基本的矢量和矩阵计算。我并不真正需要这样的确切代码,只是技术 - 作为一个线平面交叉点很容易做到。找到从眼睛到屏幕上的点的线是困难的部分。

我认为只是使用相机外观矢量来拍摄从相机位置投射的光线,但这并未考虑鼠标坐标。那么我是否也需要考虑相机FOV?

1 个答案:

答案 0 :(得分:2)

// 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是鼠标屏幕共同点,0.0是左上角。

代码假定y = 0平面填充视口。 (你从狭窄的飞机港口俯视世界,无法看到任何天空。)如果y = 0飞机没有填满视野,你必须测试x,y位置是否在天空中'(wy2 - wy<小值)并做适合你的应用的事情。