OpenGL:组合平移/旋转/缩放矩阵或将它们分开?

Posted

技术标签:

【中文标题】OpenGL:组合平移/旋转/缩放矩阵或将它们分开?【英文标题】:OpenGL: combined Translate/Rotate/Scale matrix or keep them separate? 【发布时间】:2012-07-31 18:48:23 【问题描述】:

在我的 opengl 应用程序中,我有一个 GameObject 类来描述模型 每个模型都有一个矩阵来描述它的平移/旋转/缩放 每当我想平移/旋转/缩放时,我只需调用 类似于 Model_Matrix->translate(dx, dy, dz) 直接对模型矩阵进行操作 从而永久改变它。 所以首先我想知道,这是正确的方法吗?因为网上很多文章 讨论三个矩阵,平移、旋转和缩放,然后将它们相乘以创建变换矩阵。我只用一个 所有计算。

任何人都可以对这个问题有所了解,因为现在,我很困惑

注意:我确实知道一些矩阵数学,但只是一点点

【问题讨论】:

【参考方案1】:

我建议将转换保持为矩阵(每个对象),因为 - 如果将它们分开保存,则会引入有关这些操作执行顺序的隐含知识(因此可能会产生不同的结果)。

防止转换的隐式排序影响您的一种方法是使用一个类,比如 TransformGroup,它可以包含任意数量的 TranslateTransform、RotateTransform 和 ScaleTransform,每个都允许您修改和检查单个属性。要查看此方法的示例 - 请查看 here。

【讨论】:

动画通常执行单个转换操作:这可能是保持它们分开的原因。 我倾向于使用关键帧,即使它们在那里单独描述(我上面解决方案的“编辑器”位),我的代码也会返回矩阵给我。 也许我可以使用一个矩阵进行整个转换,然后使用 3 个矩阵进行平移/旋转/缩放,这样我就可以轻松跟踪我的对象,所以当我旋转对象时,我需要旋转主矩阵,然后是旋转矩阵 查看我上面的编辑,这些编辑扩展了你上面提到的内容并指向一个示例。【参考方案2】:

如果您真的只需要矩阵本身,那么简单地维护一个矩阵并没有错。这可能会变得很棘手,但如果您想要执行诸如相机转换之类的操作。

假设您有一个矩阵 A(之前)和一个矩阵 B(之后),并希望您的程序能够将相机(或对象)从 A 视角连续移动到 B 视角。如果你只有一个矩阵来确定每个位置,这很难(特别是,不是由纯矩阵代数唯一确定)。

但是,如果您确实分别维护缩放、旋转和平移,则完全不使用矩阵,而是根据@987654321 维护eyecenterup 向量可能是合适的@函数。

【讨论】:

【参考方案3】:

只有一个矩阵的一个缺点是操作会相互影响。 IE。如果你做一个缩放(2,2,2),而不是一个平移(2,2,2),你的模型将在每一个轴上移动 4,而不是你想象的那样移动两个。 旋转也有同样的问题,但更难理解;)

下一个问题是 scale() 和 rotate() 总是使用原点,这意味着如果你想旋转或缩放,你必须考虑你当前的平移在哪里,并用这个值进行计算。这很难做到。

要找到缩放/平移/旋转的策略,您必须考虑在对象生命周期的哪个阶段要做什么。构建与后期移动。

但是,您可以通过将现有的矩阵运算结合在一起来实现“更好的”矩阵运算。 即伪代码

scale(float[3] s, float[3] originPoint)

将被实现为

translate(-originPoint); scale(s); translate(originPoint);

rotate(float alpha, float[3] p1, float[3] p2)

将被实现为

translate(-p1); rotate(alpha, p2-p1); translate(p1);

而且,根本不使用 scale() 会让生活更轻松。

干杯,弗兰克

【讨论】:

以上是关于OpenGL:组合平移/旋转/缩放矩阵或将它们分开?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用现代 OpenGL 的 GLM 或 JOML 矩阵正确转换(平移、旋转、缩放)对象

Android OpenGLES2.0——OpenGL中的平移旋转缩放

生成组合仿射变换矩阵,裁剪+缩放+平移+斜切+旋转

生成组合仿射变换矩阵,裁剪+缩放+平移+斜切+旋转

组合变换

openGL 坐标系的互相转换