我有一个场景,我正在使用 openGL 在其中渲染几个立方体(程序结构不使用 GLUT,它在 win32 程序结构中,但我只是用 绘制立方体glutSolidCube
)现在我想通过鼠标选择这些立方体。这就是我正在做的事情:首先,当用户在场景上单击鼠标按钮时,我得到鼠标位置并尝试在场景坐标中找到它的坐标(templateSkeletons 是我用立方体创建的骨架,仅此而已):
if (mouse.buttonPressed(Mouse::BUTTON_LEFT))
{
mouse.update();
templateSkeletons[0].selectionMode = true;
Vector3* points;
points = GetOGLPos();
templateSkeletons[0].setIntersectionPoints(points[0],points[1]);
}else
templateSkeletons[0].selectionMode = false;
这是GerOGLPos
我在场景中检索坐标的函数(请注意,我有自己的 camrea 和它自己的投影矩阵,但我只是通过调用在这个函数中获取投影矩阵这glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
是错误的,我应该得到我自己的 camrea 的投影矩阵 ? ) :
Vector3* GetOGLPos()
{Vector3 pointsOnLine[2];
double mvmatrix[16];
double projmatrix[16];
int viewport[4];
double dX, dY, dZ, dClickY,zz;
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
dClickY = double (viewport[3] - mouse.yPos());
// OpenGL renders with (0,0) on bottom, mouse reports with (0,0) on top
//glReadPixels( mouse.xPos(), int(dClickY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &zz );
gluUnProject ((double) mouse.xPos(), dClickY, 0.0, mvmatrix, projmatrix, viewport, &dX, &dY, &dZ);
pointsOnLine[0] = Vector3( (float) dX, (float) dY, (float) dZ );
gluUnProject ((double) mouse.xPos(), dClickY, 1.0, mvmatrix, projmatrix, viewport, &dX, &dY, &dZ);
pointsOnLine[1] = Vector3( (float) dX, (float) dY, (float) dZ );
return pointsOnLine;
}
现在我想我有两个点指示我在场景中的拾取射线。现在,当我渲染立方体时,我尝试计算由射线和立方体创建的线的距离,如果它小于某个值,我会更改立方体的颜色以知道我选择了它(jointsOfSkeleton 表示每个立方体创建骨架仅此而已,在这里我只测试数组中的 6 号立方体):
if(selectionMode)
{
distToLine = Vector3::PointToLineDistance3D(rayPoints[0],rayPoints[1],Vector3::Vector3(jointsOfSkeleton[6].x,
jointsOfSkeleton[6].y,jointsOfSkeleton[6].z));
//distToLine = sqrt(distToLine);
if(distToLine < 0.5)
glColor3f(1.0,0.0,0.0);
else
glColor3f(1.0,1.0,1.0);
}
当我单击窗口上不相关的位置时,我看到立方体的颜色发生了变化,它无法正常工作,我正在查看调试器上的距离并且距离看起来不正确。这是我用来查找线点距离的函数:
static float PointToLineDistance3D(Vector3 a, Vector3 b, Vector3 point)
{
Vector3 lineDirection = b - a;
float t = (Vector3::dot(point,lineDirection) - Vector3::dot(lineDirection,a))/(Vector3::dot(lineDirection,lineDirection));
Vector3 direction;
direction.x = a.x + (lineDirection.x *t) - point.x;
direction.y = a.y + (lineDirection.y *t) - point.y;
direction.z = a.z + (lineDirection.z *t) - point.z;
float ShortestDistance = sqrtf((direction.x*direction.x)+(direction.y*direction.y)+(direction.z*direction.z));
return ShortestDistance;
}