如何将局部物体坐标转换为世界坐标?

发布于 2024-11-06 00:55:54 字数 52 浏览 1 评论 0原文

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

I need a simple way to convert my objects coordinate into world coordinates, so that a can locate them in that coordinate system and do collision detection?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

魔法少女 2024-11-13 00:55:54

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

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

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

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

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

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

C' = P * V * M * C

OpenGL内部维护两个矩阵:模型视图(模型和视图相乘)和投影。还有一个我们不用担心的纹理矩阵。当您调用glMatrixMode时,您正在这些矩阵之间进行切换。您可以使用glLoadIdentity 将当前矩阵替换为单位矩阵。您可以使用 glTranslatefglRotatefgluProjection 等函数将转换应用于当前矩阵。这些函数中的每一个都只是创建一个 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

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

V' = V * M

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

First, some background. In 3D graphics, you need to worry about several vector spaces:

  • Model space - these are usually the coordinates you specify to OpenGL
  • World space - coordinates are specified with respect to some central point in the world.
  • View space - coordinates are specified with respect to the camera
  • Projection space - everything on the screen fits in the interval [-1, +1] in each dimension.

Coordinates are specified homogeneously, so each vector has components (x, y, z, w), where w is a scaling factor. You can obtain coordinates in 3-space as (x/w, y/w, z/w). The scaling factor is needed for certain transformations like perspective projection that wouldn't be possible with non-homogenous coordinates.

4x4 matrices are needed to transform coordinates from one vector space to another. You could have three different matrices:

  • Model matrix (model to world)
  • View matrix (world to view)
  • Projection matrix (view to projection space)

You would project a coordinate C onto the screen using the formula:

C' = P * V * M * C

OpenGL internally maintains two matrices: modelview (model and view multiplied together), and projection. There is also a texture matrix we won't worry about. When you call glMatrixMode, you are switching between these matrices. You replace the current matrix with the identity matrix using glLoadIdentity. You apply transformations to the current matrix with functions like glTranslatef, glRotatef, or gluProjection. Each of these functions just creates a 4x4 matrix the implements that specific transformation, then multiplies the current matrix by it. You can see what the transformation matrices are in the OpenGL 2.1 reference pages.


Now for the actual answer. You need to maintain a 4x4 model matrix for each object in your scene. The model matrix will contain all the transformations needed to change model coordinates into world coordinates. For instance, every time you call glTranslate, you would update your model matrix:

T  = [ 1 0 0 x ]
     [ 0 1 0 y ]
     [ 0 0 1 z ]
     [ 0 0 0 1 ]
M' = M * T

You can then use your model matrix to get coordinates into world space (make sure they are homogenous coordinates first; just set w = 1, if they aren't):

V' = V * M

Since you are maintaining these transformations in parallel, you don't actually need to maintain the OpenGL modelview matrix anymore. You can pass in your model matrix as a uniform to your shaders. You can maintain your own view and projection matrices in similar ways. This is required in recent versions of OpenGL; all of the matrix handling functions are deprecated.

稍尽春風 2024-11-13 00:55:54

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

您可以在 gluLookAt() 函数之后使用以下命令获得 V:

glGetFloatv (GL_MODELVIEW_MATRIX, camViewMatrix),

然后反转矩阵并存储它(用于稍后在代码中进行乘法。)

您在要绘制的点处获得 V*M对象,就在使用相同 GL 函数的所有 glTranslatef()、glRotatef() 和 glScale() 命令之后:

glGetFloatv (GL_MODELVIEW_MATRIX,对象模型视图矩阵);

V-1 * ( V * M ) == M

然后乘以两个矩阵,结果矩阵包含位置 m12 = x、m13 = y 和 m14 = z

更多详细信息,C 代码位于:

You can use the product of the inverse of the virtual camera view matrix(V-1) times the ModelView Matrix (V*M) of the object to get World coordinates.

You get V just after the gluLookAt() function using:

glGetFloatv (GL_MODELVIEW_MATRIX, camViewMatrix)

then invert the matrix and store it, (used for multiply later in the code.)

You get V*M at the point where you are about to draw the object, just after all the glTranslatef(), glRotatef() and glScale() commands using the same GL function:

glGetFloatv (GL_MODELVIEW_MATRIX, objectsModelViewMatrix);

V-1 * ( V * M ) == M

Then multiple the two matrices, resulting matrix contains the position, m12 = x, m13 = y and m14 = z

more details with C code at:
https://sourceforge.net/p/openantz/wiki/Local_to_World_Coordinates/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文