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?
我需要一个简单的方法把我的对象坐标转换成世界坐标,这样a就可以在那个坐标系中定位它们并进行碰撞检测?
2 个解决方案
#1
24
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
- 模型空间——这些通常是您指定给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. - 投影空间——屏幕上的一切都符合每个维度的间隔[-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 modelview矩阵。你可以把你的模型矩阵作为一个统一的材质传递给你的材质。您可以以类似的方式维护自己的视图和投影矩阵。这是OpenGL的最新版本所需要的;不赞成使用所有的矩阵处理函数。
#2
4
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:
您将在即将绘制对象的点上获得V*M,即使用相同的GL函数完成所有glTranslatef()、glRotatef()和glScale()命令之后:
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/
#1
24
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
- 模型空间——这些通常是您指定给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. - 投影空间——屏幕上的一切都符合每个维度的间隔[-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 modelview矩阵。你可以把你的模型矩阵作为一个统一的材质传递给你的材质。您可以以类似的方式维护自己的视图和投影矩阵。这是OpenGL的最新版本所需要的;不赞成使用所有的矩阵处理函数。
#2
4
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:
您将在即将绘制对象的点上获得V*M,即使用相同的GL函数完成所有glTranslatef()、glRotatef()和glScale()命令之后:
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/