我需要一种简单的方法将我的对象坐标转换为世界坐标,以便a可以在那个坐标系中找到它们并进行碰撞检测吗?
答案 0 :(得分:24)
首先,一些背景知识。在3D图形中,您需要担心几个向量空间:
[-1, +1]
区间。坐标是均匀指定的,因此每个向量都有组件(x, y, z, w)
,其中w
是缩放系数。您可以获得3空格中的坐标(x/w, y/w, z/w)
。某些变换需要缩放因子,例如透视投影,这是非均匀坐标无法实现的。
将坐标从一个向量空间转换为另一个向量空间需要4x4矩阵。你可以有三种不同的矩阵:
您可以使用以下公式将坐标C
投影到屏幕上:
C' = P * V * M * C
OpenGL内部维护两个矩阵:modelview(模型和视图相乘)和投影。还有一个我们不会担心的纹理矩阵。当您致电glMatrixMode
时,您正在这些矩阵之间切换。使用glLoadIdentity
将当前矩阵替换为单位矩阵。您可以使用glTranslatef
,glRotatef
或gluProjection
等函数将变换应用于当前矩阵。这些函数中的每一个只创建一个4x4矩阵,即特定变换的实现,然后将当前矩阵乘以它。您可以在OpenGL 2.1 reference pages中查看转换矩阵的内容。
现在回答实际问题。您需要为场景中的每个对象维护一个4x4模型矩阵。模型矩阵将包含将模型坐标更改为世界坐标所需的所有变换。例如,每次调用glTranslate
时,都会更新模型矩阵:
T = [ 1 0 0 x ]
[ 0 1 0 y ]
[ 0 0 1 z ]
[ 0 0 0 1 ]
M' = M * T
然后,您可以使用模型矩阵将坐标转换为世界空间(确保它们首先是同质坐标;如果不是,则设置w = 1
):
V' = V * M
由于您并行维护这些转换,因此您实际上不再需要维护OpenGL模型视图矩阵。您可以将模型矩阵作为制服传递到着色器。您可以用类似的方式维护自己的视图和投影矩阵。这在最近的OpenGL版本中是必需的;所有矩阵处理函数都已弃用。
答案 1 :(得分:4)
您可以使用虚拟摄像机视图矩阵的逆的乘积( V -1 )乘以对象的ModelView矩阵(V * M)世界坐标。
使用:
在gluLookAt()函数之后得到V.glGetFloatv(GL_MODELVIEW_MATRIX,camViewMatrix)
然后反转矩阵并存储它(用于稍后在代码中相乘。)
在使用相同GL函数的所有glTranslatef(),glRotatef()和glScale()命令之后,您将在要绘制对象的位置获得V * M:
glGetFloatv(GL_MODELVIEW_MATRIX,objectsModelViewMatrix);
V -1 *( V * M )== M
然后多个两个矩阵,得到的矩阵包含位置,m12 = x,m13 = y和m14 = z
C代码的更多细节: https://sourceforge.net/p/openantz/wiki/Local_to_World_Coordinates/