如何将本地对象坐标转换为世界坐标?

Sha*_*ved 9 c++ opengl

我需要一种简单的方法将我的对象坐标转换为世界坐标,以便a可以在那个坐标系中找到它们并进行碰撞检测?

Jay*_*rod 26

首先,一些背景.在3D图形中,您需要担心几个向量空间:

  • 模型空间 - 这些通常是您为OpenGL指定的坐标
  • 世界空间 - 相对于世界上的某个中心点指定坐标.
  • 视图空间 - 相对于摄像机指定坐标
  • 投影空间 - 屏幕上的所有内容都适合[-1, +1]每个维度的间隔.

坐标是均匀指定的,因此每个矢量都有分量(x, y, z, w),其中w是比例因子.您可以获得3空格中的坐标(x/w, y/w, z/w).某些变换需要缩放因子,例如透视投影,这对非均匀坐标是不可能的.

需要4x4矩阵来将坐标从一个向量空间转换为另一个向量空间.你可以有三种不同的矩阵:

  • 模型矩阵(模型到世界)
  • 查看矩阵(世界观看)
  • 投影矩阵(投影空间视图)

您可以C使用以下公式将坐标投影到屏幕上:

C' = P * V * M * C
Run Code Online (Sandbox Code Playgroud)

OpenGL内部维护两个矩阵:modelview(模型和视图相乘)和投影.还有一个我们不会担心的纹理矩阵.当你打电话时glMatrixMode,你正在这些矩阵之间切换.使用标识矩阵替换当前矩阵glLoadIdentity.您应用转换到当前的矩阵状的功能glTranslatef,glRotatefgluProjection.这些函数中的每一个只创建一个4x4矩阵,即特定变换的实现,然后将当前矩阵乘以它.您可以在OpenGL 2.1参考页面中看到转换矩阵是什么.


现在为实际答案.您需要为场景中的每个对象维护一个4x4模型矩阵.模型矩阵将包含将模型坐标更改为世界坐标所需的所有变换.例如,每次调用时glTranslate,都会更新模型矩阵:

T  = [ 1 0 0 x ]
     [ 0 1 0 y ]
     [ 0 0 1 z ]
     [ 0 0 0 1 ]
M' = M * T
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用模型矩阵将坐标转换为世界空间(确保它们首先是同质坐标; w = 1如果不是,则设置它们):

V' = V * M
Run Code Online (Sandbox Code Playgroud)

由于您并行维护这些转换,因此实际上不需要维护OpenGL模型视图矩阵.您可以将模型矩阵作为制服传递到着色器.您可以用类似的方式维护自己的视图和投影矩阵.这在最近的OpenGL版本中是必需的; 不推荐使用所有矩阵处理函数.


tar*_*zan 5

您可以使用虚拟摄像机视图矩阵的逆(V -1)乘以对象的模型视图矩阵(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/