在 OpenGL 4.0 中是不是有围绕局部坐标(即从模型视图矩阵)旋转的标准方法?

Posted

技术标签:

【中文标题】在 OpenGL 4.0 中是不是有围绕局部坐标(即从模型视图矩阵)旋转的标准方法?【英文标题】:Is there a standard way to rotate around local coordinates (that is, from a modelview matrix) in OpenGL 4.0?在 OpenGL 4.0 中是否有围绕局部坐标(即从模型视图矩阵)旋转的标准方法? 【发布时间】:2014-04-27 04:04:49 【问题描述】:

我一直在研究game engine,最近我可以轻松创建一个Camera 类来管理视图矩阵(或允许轻松切换到另一个)。我从概念上知道它必须做什么,但我遇到的麻烦是弄清楚如何围绕本地原点旋转(对于视图矩阵,它与乘以旋转矩阵的平移矩阵相同)。

我知道在直接模式下,你会

glTranslatef(x, y, z);   //move back to origin
glRotatef(angle, x_rot, y_rot, z_rot);   //turn using a quaternion
glTranslatef(-x, -y, -z);   //move back to original location

但我不确定这将如何转化为更现代的应用程序。你会做同样的事情,让一个平移矩阵回到原点,旋转,然后平移回来吗?对于您要旋转的每个对象?从我目前测试的结果来看,该方法适用于查看,但在 3D 空间中控制它很笨拙(我不确定如何不断调整旋转。将运动组件转换为单个 vec4,乘以旋转,应用于平移,然后进行实际旋转?)

似乎有一种比我缺少的三个或更多 4x4 矩阵乘法更有效的方法。

Here's the specific section 在尝试了建议的解决方案之后。

【问题讨论】:

【参考方案1】:

您可以做与您发布的序列基本相同的事情,而无需在运行时进行完整的矩阵乘法。由于转换矩阵非常简单,您可以手动进行乘法运算。 R 是一个 3x3 旋转矩阵,p 是您想要旋转的位置,您可以通过以下方式构建您的 4x4 矩阵:

    R 存储在4x4 矩阵的旋转部分。 计算p - R * p,并将结果存储在4x4矩阵的转换部分。

这会将其减少为一个矩阵 * 向量乘法和一个向量减法。您可能需要仔细检查我的数学,因为我只是在纸上得出它。

另一种方法是在 CPU 代码中将旋转和平移分开,根据需要更新它们,并仅在更新制服时将它们组合成 4x4 矩阵。

由于您可以控制着色器代码,因此您甚至不必使用 4x4 矩阵来包含整个转换。例如,如果在旋转之前应用平移更方便,您可以将 mat3 旋转矩阵和 vec3 平移向量输入着色器,并将平移向量添加到与旋转矩阵相乘之前的位置。如果您比另一个更频繁地更新其中一个,则将两者分开也会很有好处。

【讨论】:

我将在 Camera 类之外测试它,看看它是否有帮助,我想你可能已经明白了。 不幸的是,它仍在围绕世界原点旋转,而且速度较慢。 等等,我想我误解了你的指示。我将使用实际的 Camera 类进行测试,看看是否真的做到了。 好的,测试实际的 Camera 类,它完全停止所有轴的运动,除非旋转。我认为这不适用于游戏。 不确定您到底测试了什么。描述的是如何计算围绕任意点旋转的旋转矩阵。您仍然需要将其与您的其他转换结合起来。【参考方案2】:

我认为您考虑到旧管道过于复杂了。

形成您的新变换矩阵 T。假设您有现有的相机矩阵 C。您想要 C',即修改后的相机矩阵。

实际上只有两种选择。要么:

C' = CT, or
C' = TC

因为你还有什么其他信息?

实际上,您选择的是新变换在现有相机矩阵“之前”生效,在这种情况下它将在世界坐标中起作用,或者在“之后”在这种情况下它将在相机中发生坐标。

你似乎想要预乘法。所以用那个。然后转换将在全局坐标空间中生效。

旧的 OpenGL 例程总是后乘。

【讨论】:

我不太清楚你的意思。将模型/视图矩阵乘以平移矩阵?或者创建一个新的模型/视图矩阵并将旧的矩阵乘以它(你说“变换矩阵”对我来说是模棱两可的)。如果只是平移矩阵,那旋转呢? 一个矩阵描述了相机。那是相机矩阵。一个矩阵描述了您希望如何转换相机。这就是变换矩阵。你如何描述矩阵并没有什么不同——如旋转、平移、倾斜或其他。根本没有模型视图矩阵,因为它是由模型和视图矩阵组成的,至少其中一个与您的问题完全无关。 好吧,我的意思是模型或视图,它们本质上是相同的,只是一个人的旋转和位置相对于另一个人是“相反的”——除非我从根本上误解了某些东西。那么在相机的情况下,它很可能是一个视图矩阵,简单地乘以一个新的旋转和/或平移矩阵? 视图矩阵(非正式地)是模型矩阵的逆矩阵(因此来自模型的视图在原点显示该模型)但我认为只是将那里的东西倒置然后再反转更正常而不是花费全部时间以相反的顺序编写各个逆变换。但是,是的,在每种可能的情况下,您都会乘以另一个矩阵、旋转或平移,就像后置而不是前置一样(反之亦然,如果您正在逐步组合逆向而不是在最后一分钟)。 所以你是说我应该简单地组合我的转换然后乘以旧的视图矩阵(因为这是一个相机)? mat4f transformation = rotation.toRotationMatrix() * translation;rotation 是一个四元数)然后是view_mat = view_mat * transformation;?还是与您所说的完全相反?

以上是关于在 OpenGL 4.0 中是不是有围绕局部坐标(即从模型视图矩阵)旋转的标准方法?的主要内容,如果未能解决你的问题,请参考以下文章

c++ OpenGL坐标变换

在OpenGL中围绕坐标旋转四边形

围绕世界轴OpenGL旋转对象

opengl导入一个3维物体,如何修改其局部坐标系?

在 3D 中组合旋转

OpenGL - 围绕 Y 轴旋转“曲线”