c++ - GLM 矩阵中的旋转方向,使用四元数

标签 c++ opengl matrix quaternions glm-math

我正在处理 3D 渲染设置(所有数学运算都是使用 GLM for OpenGL 完成的),并且一切正常,除了我希望我的转换如何工作。 我像这样为每个实体创建一个矩阵:

matrix = mat4(1);
vec3 scale = GetWorldScale();
vec3 pos = GetWorldPosition(); // Returns pos + parent->pos
quat rot = GetWorldRotationQuat(); // Returns parent->rot * rot

matrix = glm::translate(matrix, pos);
matrix *= mat4_cast(rot);
matrix = glm::scale(matrix, scale);

right = matrix[0].xyz;
up = matrix[1].xyz;
direction = matrix[2].xyz;

使用它,它通常可以正常工作,除了我不确定如何根据偏好调整它的一部分。也就是说,使用它,X 轴上的平移被翻转(例如,左为正,Z 轴上的前向为正,但我对此不太区分),并且 Y 轴上的旋转被翻转。

为此目的查看其他代码,似乎很多人都否定了我用于方向(相机)的内容。我也这样做了,翻译是正确的,但所有旋转轴都与首选相反(尽管 X 上的旋转是相同的,无论方向是否取反)。

我不太确定我应该做些什么来帮助纠正这个问题,除非在使用前可能取消 X 轴平移和 Y 轴旋转,但我觉得这不是最好的方法。想法?

最佳答案

我认为问题出在您混合转换顺序,尤其是平移和旋转顺序。这些转换(缩放、平移和旋转)中的每一个都定义了如何将一个坐标系转换为另一个坐标系。

让我们来看一个例子:你有一个子对象 c 和它的父对象 p。它们每个都有平移 t、旋转 r 和比例 s。为简单起见,每个都是 4x4 矩阵。目前你做

matrix = p.t * c.t * p.r * c.r * p.s * c.s

想象一下被这个矩阵变换的 child 的局部坐标系(长度为 1 的 xyz 轴)。点数是从右边相乘的,所以我们要从右往左读。首先,坐标系由子级缩放,然后由父级缩放。然后它被 child 旋转。然后由 parent 。现在应用了 child 的翻译。这意味着子翻译应用于旋转坐标系。由于您已经应用了子项的 父项的旋转,因此它会旋转到父项的坐标系中。因此子坐标被解释为父坐标。

那么您应该做什么:在您的方法中,计算对象矩阵 m = c.t * c.r * c.s。那么你对象的世界矩阵定义为wm = pm * m,其中parent matrix pm是parent的world matrix。这样你就会得到一个世界矩阵:

c.wm = (c.pm) * (c.o) = (p.t * p.r * p.s) * (c.t * c.r * c.s)

这意味着子项的平移在子项的坐标系中,而父项的平移在父项的坐标系中。

关于c++ - GLM 矩阵中的旋转方向,使用四元数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17038681/

相关文章:

java - LWJGL - 如何有效且高效地追踪光线?

opengl - glsl算术运算符

c++ - 使用二维线程在CUDA中添加两个矩阵

c++ - cv::Mat 在 Visual C++ Express 2010 中给出错误

c++ - 返回 std::make_pair 与 std::forward

c++ - libpng 在 png_write_into 上崩溃(Windows 10,VS2013,自建,所有测试通过 ok)

opengl - 基于四元数的相机

excel - VBA - 创建 n × m 矩阵的函数

javascript - 有效地转置javascript数组

C++ - 读取 CSV 文件的列并仅保留以特定字符串开头的列