C++ 如何将局部对象坐标转换为世界坐标?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5914399/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert local object coordinates to world coordinates?
提问by Shazad Maved
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?
我需要一种简单的方法将我的对象坐标转换为世界坐标,以便可以在该坐标系中定位它们并进行碰撞检测?
回答by Jay Conrod
First, some background. In 3D graphics, you need to worry about several vector spaces:
首先,一些背景。在 3D 图形中,您需要担心几个向量空间:
- 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.
- 模型空间 - 这些通常是您指定给 OpenGL 的坐标
- 世界空间 - 相对于世界中的某个中心点指定坐标。
- 视图空间 - 相对于相机指定坐标
- 投影空间 - 屏幕上的所有内容都适合
[-1, +1]
每个维度的间隔。
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.
坐标是均匀指定的,因此每个向量都有分量(x, y, z, w)
,其中w
是比例因子。您可以获得 3 空间中的坐标作为(x/w, y/w, z/w)
。某些变换(如透视投影)需要缩放因子,而非齐次坐标则无法实现。
4x4 matrices are needed to transform coordinates from one vector space to another. You could have three different matrices:
需要 4x4 矩阵将坐标从一个向量空间转换到另一个向量空间。你可以有三个不同的矩阵:
- 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
使用以下公式将坐标投影到屏幕上:
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.
OpenGL内部维护着两个矩阵:modelview(模型和视图相乘)和投影。还有一个我们不用担心的纹理矩阵。当您调用 时glMatrixMode
,您将在这些矩阵之间切换。您可以使用 用单位矩阵替换当前矩阵glLoadIdentity
。您应用转换到当前矩阵与功能,如glTranslatef
,glRotatef
或gluProjection
。这些函数中的每一个都只是创建一个 4x4 矩阵来实现特定的转换,然后将当前矩阵乘以它。您可以在OpenGL 2.1 参考页中查看转换矩阵。
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:
现在是实际的答案。您需要为场景中的每个对象维护一个 4x4 模型矩阵。模型矩阵将包含将模型坐标更改为世界坐标所需的所有转换。例如,每次调用 时glTranslate
,都会更新模型矩阵:
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):
然后,您可以使用您的模型矩阵将坐标获取到世界空间中(首先确保它们是齐次坐标;w = 1
如果不是,只需设置):
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.
由于您并行维护这些转换,因此您实际上不再需要维护 OpenGL 模型视图矩阵。您可以将模型矩阵作为统一传递给着色器。您可以用类似的方式维护自己的视图和投影矩阵。这在最新版本的 OpenGL 中是必需的;不推荐使用所有矩阵处理函数。
回答by tarzan
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.
您可以使用虚拟相机视图矩阵 ( V -1) 乘以对象的模型视图矩阵(V*M)的倒数的乘积来获得世界坐标。
You get V just after the gluLookAt() function using:
您在 gluLookAt() 函数之后使用以下命令获得 V:
glGetFloatv (GL_MODELVIEW_MATRIX, camViewMatrix)
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:
在使用相同 GL 函数的所有 glTranslatef()、glRotatef() 和 glScale() 命令之后,您将在即将绘制对象的位置获得 V*M:
glGetFloatv (GL_MODELVIEW_MATRIX, objectsModelViewMatrix);
glGetFloatv (GL_MODELVIEW_MATRIX, objectsModelViewMatrix);
V-1* ( V* M) == M
V -1* ( V* M) == M
Then multiple the two matrices, resulting matrix contains the position, m12 = x, m13 = y and m14 = z
然后将两个矩阵相乘,结果矩阵包含位置,m12 = x,m13 = y 和 m14 = z
more details with C code at: https://sourceforge.net/p/openantz/wiki/Local_to_World_Coordinates/
有关 C 代码的更多详细信息,请访问:https: //sourceforge.net/p/openantz/wiki/Local_to_World_Coordinates/