如图所示,我的对象有自己的“局部坐标系”。(实际上我有一个pointcloud而不是网格)
然后我将变换/缩放...等应用于ModelView矩阵,变换坐标系为“模型视图坐标系”。
现在我要使用gluUnproject选择“顶点”,如下所示。
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewport);
winX = (GLfloat) mousePosition.x();
winY = (GLfloat) viewport[3] - (float) mousePosition.y();
glReadPixels((int)winX , int(winY) , 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,&winZ);
GLdouble posX, posY, posZ;
gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
这个“gluUnProject”应该给我相对于“局部坐标系”的位置还是相对于“模型视图坐标系”?
答案 0 :(得分:5)
Modelview不是(特定)坐标系,而是从对象局部空间(模型 - )到眼睛空间(-view)的转换。
在上图中我们看到了物体空间(三脚架“在”茶壶中)和世界空间(大三脚架)。但是那里有眼睛空间,没有给出三脚架,虽然我们可以想象它很容易:一个垂直轴向上,一个水平轴在中间,一个轴伸出图片。
我们没有“看到”的是投影,即将图片投影到屏幕的转换(技术上剪辑空间,然后再通过一个步骤从那里到NDC)。
所以我们有以下转换:
顶点经过那些
v_eye = MV * v
v_clip = P * v_eye = P * (MV * v) = P * MV * v
此后应用剪辑到NDC变换。
[x,y,depth] = clip_to_NDC( v_clip ) = clip_to_NDC(P * MV * v)
gluUnProject的作用是反转上述表达式:
gluUnProject(MV, P, x, y, depth):
v_clip = clip_to_NDC^-1([x,y,depth])
v = MV^-1 * P^-1 * v_clip = MV^-1 * P^-1 * clip_to_NDC^-1([x,y,depth])
或者换句话说,给定模型视图和投影矩阵,gluUnProject将从屏幕空间投射回由转换链转换到的空间。
它还有助于记住OpenGL不是一个场景图,即它不会跟踪所有的变换,你绘制的对象等。如果你想这么说它就“活在当下”。