C++ 如何将局部对象坐标转换为世界坐标?

C++ 如何将局部对象坐标转换为世界坐标?,c++,opengl,C++,Opengl,我需要一种简单的方法将我的对象坐标转换为世界坐标,以便a可以在该坐标系中定位它们并进行碰撞检测?首先,一些背景。在三维图形中,您需要考虑几个向量空间: 模型空间-这些通常是您指定给OpenGL的坐标 世界空间-指定世界中某个中心点的坐标 视图空间-指定相对于摄影机的坐标 投影空间-屏幕上的所有内容都符合每个维度的间隔[-1,+1] 坐标是均匀指定的,因此每个向量都有分量(x,y,z,w),其中w是一个比例因子。您可以通过(x/w,y/w,z/w)获得3-空间中的坐标。某些变换(如透视投影)需

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

首先,一些背景。在三维图形中,您需要考虑几个向量空间:

  • 模型空间-这些通常是您指定给OpenGL的坐标
  • 世界空间-指定世界中某个中心点的坐标
  • 视图空间-指定相对于摄影机的坐标
  • 投影空间-屏幕上的所有内容都符合每个维度的间隔
    [-1,+1]
坐标是均匀指定的,因此每个向量都有分量
(x,y,z,w)
,其中
w
是一个比例因子。您可以通过
(x/w,y/w,z/w)
获得3-空间中的坐标。某些变换(如透视投影)需要比例因子,而非齐次坐标不可能实现这种变换

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

  • 模型矩阵(模型到世界)
  • 视图矩阵(世界视图)
  • 投影矩阵(视图到投影空间)
您可以使用以下公式将坐标
C
投影到屏幕上:

C' = P * V * M * C
OpenGL在内部维护两个矩阵:模型视图(模型和视图相乘)和投影。还有一个纹理矩阵,我们不必担心。调用
glMatrixMode
时,您正在这些矩阵之间切换。使用
glLoadIdentity
将当前矩阵替换为标识矩阵。可以使用诸如
glTranslatef
glRotatef
gluProjection
之类的函数对当前矩阵应用变换。这些函数中的每一个都只是创建一个4x4矩阵来实现特定的转换,然后将当前矩阵乘以它。您可以在中看到变换矩阵是什么


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

T  = [ 1 0 0 x ]
     [ 0 1 0 y ]
     [ 0 0 1 z ]
     [ 0 0 0 1 ]
M' = M * T
然后,可以使用模型矩阵将坐标输入世界空间(首先确保它们是同质坐标;如果不是,只需设置
w=1
):


由于您并行地维护这些转换,因此实际上不再需要维护OpenGL modelview矩阵。可以将模型矩阵作为统一体传递给着色器。您可以以类似的方式维护自己的视图和投影矩阵。这在OpenGL的最新版本中是必需的;所有矩阵处理函数都已弃用。

您可以使用虚拟摄影机视图矩阵(V-1)的倒数乘以对象的模型视图矩阵(V*M)的乘积来获取世界坐标

在gluLookAt()函数之后,使用以下方法得到V:

glGetFloatv(GL_模型视图_矩阵,camViewMatrix)

然后反转矩阵并存储它(用于代码后面的乘法运算)

在使用相同的GL函数执行所有GLTRANSTEF()、glRotatef()和glScale()命令之后,将在即将绘制对象的点处获得V*M:

glGetFloatv(GL_模型视图_矩阵,objectsModelViewMatrix)

V-1*(V*M)=M

然后将两个矩阵相乘,得到的矩阵包含位置,m12=x,m13=y和m14=z

有关C代码的更多详细信息,请访问:

@Shazad,添加了一些背景信息和更详细的解释。希望能有帮助。@Jay:首先你说的是
C'=P*V*M*C
,但在接近尾声时你说的是
V'=M*V
。我有点困惑,因为有一次是
V*m
,还有一次是
m*V
。矩阵乘法不是可交换的,所以
A*B!=B*A
。你的回答可能是两个顺序都错了吗?也许我的数学也错了,不过,如果是那样的话,请随意纠正我。@Mecki,是的,看起来像个打字错误。谢谢你指出这一点。现在修好了。杰伊,我的投票把你带到了神奇的10k标记,祝贺你,伙计!我建议你阅读线性代数或矩阵代数,以及一本关于图形的书。
V' = V * M