存储世界空间坐标

Posted

技术标签:

【中文标题】存储世界空间坐标【英文标题】:Storing World-space Coordinates 【发布时间】:2011-11-09 22:15:25 【问题描述】:

在设计要放置在 OpenGL 世界空间中的对象时,世界空间坐标如何与其对应的对象/模型一起存储?

为了简单起见,我一直在使用 Wavefront Object 文件,我听说过 Collada,但还没有找到任何标准的方法来保存世界空间,就像设计游戏关卡时那样。

我对 OpenGL 很陌生。

【问题讨论】:

【参考方案1】:

世界位置、旋转和缩放始终可以定义为 4x4 矩阵,但如果仅将其存储在一个矩阵中,则会丢失一些信息。因此,三个矩阵是分开存储的:

W = Translation * Rotation * Scale
with
    [ 1 0 0 x ]
    [ 0 1 0 y ]
    [ 0 0 1 z ]
T = [ 0 0 0 1 ]

    [ r r r 0 ]
    [ r r r 0 ]
    [ r r r 0 ]
R = [ 0 0 0 1 ]

    [ sx 0  0  0 ]
    [ 0  sy 0  0 ]
    [ 0  0  sz 0 ]
S = [ 0  0  0  1 ]

旋转很难仅存储在单个矩阵中。所以大多数时候,我们使用Quaternion 来存储旋转,因为它更容易理解它的作用并符合更好的计算。关于gimbal locks (movie),我可以解释很多,但您可能需要一个包含这些数据类型的reference guide for matrices 和一个好的openGL math library。

由于 OpenGL 不是一个引擎,它没有一些您可以使用的基本游戏对象,因此您必须自己创建该类(假设此处为 OOP)。将世界数据存储在这些对象中,并以适当的顺序绘制它们。您不应该将世界数据保存到 3D 模型中,因为您可以实例化同一模型的多个对象(多个看起来相同的敌人)。

这是一个tutorial,向您展示如何创建一个基本引擎。

【讨论】:

感谢您的信息。我熟悉万向节锁和四元数。我不确定是四元数还是欧拉角更常用。尽管进行了很多谷歌搜索,但我没有遇到该教程,它看起来很有用。谢谢。【参考方案2】:

世界空间坐标如何与其对应的对象/模型一起存储?

随你喜欢。

OpenGL 不处理数据管理。这完全取决于您。

【讨论】:

啊,我开始怀疑,但认为可能有一个标准的结构。【参考方案3】:

通常他们不是。对象大多是在自己的空间中设计的。它们在“世界”中的位置是通常表示为矩阵的变换(平移、旋转)的结果。

例如,如果您查看 Collada 规范,您会发现场景是节点的层次结构(DAG)以及可能的平移、旋转、缩放或倾斜。我不认为这样的层次结构(或场景描述)可以用 OBJ 格式表达。

总而言之,它与 OpenGL 没有太大关系。

【讨论】:

Collada 是一个非常广泛的规范,我几乎没有触及表面。我更多地考虑静态对象,例如建筑物之类的东西。我很乐意操纵它们,但不清楚这些对象的实际相对定位(世界空间)是如何管理的。从给出的答案中,我怀疑该对象存储了一个转换?是与每个对象一起存储的模型视图转换以将其放入世界空间吗? 您需要某种形式的结构来表示您的场景。通常,图结构(称为scene graph)是明智的选择。这将创建对象和转换的层次结构,允许您使用(静态)对象及其相对位置来描述场景。您可以使用现有的场景图库,也可以自己创建一些东西。然而,这与我为 Collada 提到的场景层次结构密切相关。你必须以某种方式自己管理它。 OpenGL 不会为你做这件事。

以上是关于存储世界空间坐标的主要内容,如果未能解决你的问题,请参考以下文章

将鼠标坐标转换为世界空间坐标

在 CUDA 中,如何在内核函数中将屏幕空间坐标转换为世界空间坐标

unity 坐标变化

在平面上的世界空间单元中查找一个 (s, t) 纹理坐标单元的长度

世界坐标空间与观察坐标系之间的转换

Unity Shaderlab-从屏幕空间到世界空间的转换