如何找到鼠标点击和3D网格的交集?

时间:2010-12-03 05:39:20

标签: c++ opengl 3d

在我的程序中,我正在加载3D网格以查看和交互。用户可以旋转和缩放视图。我将使用旋转矩阵进行旋转,并调用multmatrix来旋转视图,并使用glScalef进行缩放。用户还可以绘制网格,这就是我需要翻译鼠标坐标以查看它是否与网格相交的原因。

我已经阅读了http://www.opengl.org/resources/faq/technical/selection.htm以及我在近距离和远距离平面上使用gluUnproject并减去的方法,并且我有一些成功,但只有当gluLookAt的位置为(0,0,z)时z可以是任何合理的数字。当我将位置移动到说(0,1,z)时,它会变得混乱,并返回一个只有空格的交叉点,并且不返回网格明显位于鼠标下方的交叉点。

这就是我从鼠标点击到场景的方式:

float hx, hy;
hx = mouse_x;
hy = mouse_y;

GLdouble m1x,m1y,m1z,m2x,m2y,m2z;
GLint viewport[4];
GLdouble projMatrix[16], mvMatrix[16];
glGetIntegerv(GL_VIEWPORT,viewport);
glGetDoublev(GL_MODELVIEW_MATRIX,mvMatrix);
glGetDoublev(GL_PROJECTION_MATRIX,projMatrix);

//unproject to find actual coordinates
gluUnProject(hx,scrHeight-hy,2.0,mvMatrix,projMatrix,viewport,&m1x,&m1y,&m1z);
gluUnProject(hx,scrHeight-hy,10.0,mvMatrix,projMatrix,viewport,&m2x,&m2y,&m2z);

gmVector3 dir = gmVector3(m2x,m2y,m2z) - gmVector3(m1x,m1y,m1z);
dir.normalize();

gmVector3 point;
bool intersected = findIntersection(gmVector3(0,0,5), dir, point);

如果有任何不同,我正在使用glFrustum。

findIntersection代码真的很长,我很有信心它的工作原理,所以除非有人想看,否则我不会发布它。它的要点是,对于网格中的每个面,找到光线和平面之间的交点,然后查看交点是否在面内。

我相信它与相机的位置和矢量有关,但我不知道如何以及如何处理它们以便鼠标正确点击网格。任何人都可以帮我这个吗?

我还没有使用glScalef制作旋转矩阵或任何东西,所以有人能让我对此有所了解吗?比如,在计算时,是否会对multmatrixglScalef来电进行取消项目?

非常感谢!

2 个答案:

答案 0 :(得分:0)

解决方案是光线追踪。你拍摄的光线是通过两点来定义的。第一个是摄像机的原点,第二个是投影在场景视图平面上的鼠标位置(使用glFrustum描述的平面)。此光线与您的模型的交点是鼠标单击模型

的点

答案 1 :(得分:0)

使用光线dir将光线从相机拍摄到场景,我应该使用:

bool intersected = findIntersection(gmVector3(m1x,m1y,m1z), dir, point); 

(注意传递给函数的不同向量)。这解决了我的问题,毕竟与gluLookAt没有任何关系!

另外,对于我提出的问题的第二部分,是的,unproject确实考虑了glScale和glmultmatrix函数。