GLM 四元数反向偏航

GLM quaternion reversed yaw

我正在使用 OpenGL 和 GLM 构建玩具 3D 引擎。我的轴系是右手的,X在右,Y在上,Z在后。

一个实体的变换由一个 3D 向量和一个 GLM 的四元数组成。物理模拟是二维的,所以一个实体的速度是一个二维向量(Y 上没有速度,只有 XZ,地平面)。同样,angular 速度仅围绕 Y 轴(偏航)。

// Properly integrate the change in velocities
auto deltaPos = (physics->velocity + physics->lastVelocity) * 0.5f * deltaTime;
auto deltaYaw = (physics->yawVelocity + physics->lastYawVelocity) * 0.5f * deltaTime;
// Apply the velocities
transform->position += glm::vec3 {deltaPos.x, 0, deltaPos.y} * transform->orientation
transform->orientation = glm::quat(glm::vec3 {0, deltaYaw, 0}) * transform->orientation;

我正在用自上而下的相机渲染世界,将方向转换为 4x4 矩阵,将它(以正确的顺序)与缩放和平移矩阵相乘:

glm::mat4x4 transformMat =
        glm::translate(transform->position) *
        glm::mat4x4(transform->orientation) *
        glm::scale(glm::vec3 {size.x, 1.0f, size.y});

.. 并将其发送到着色器,在那里它与点坐标以及投影和视图矩阵相乘:

// projView is projection * view
gl_Position = projView * transform * vec4(vertPosition.xyz, 1.0);

然而,虽然这段代码看起来很简单,但对象的偏航似乎有时会翻转。当一个对象向左转时,它开始在世界中向左移动(position += deltaPosition * orientation 行正常工作),但它呈现为向右旋转,但向左移动。这是示例图片:

似乎四元数的表示,或者至少是它的四元数-矩阵转换,否定了旋转的偏航 "component",就像 Y 向下而不是向上一样。然而,当一个向量被那个四元数旋转时,它似乎表现得很好,就像 Y 向上一样。有趣的是,代码的另一部分(处理车辆的转弯)似乎只有在四元数通过 -yaw 而不是 yaw 旋转时才能正常工作。 (渲染问题仍然存在)。

任何解决此问题的解释或方法?

原来我错误地应用了四元数: 在这一行:

transform->position += glm::vec3 {deltaPos.x, 0, deltaPos.y} * transform->orientation

GLM 中的乘法定义实际上是将向量旋转四元数的倒数。正确的行是:

transform->position += transform->orientation * glm::vec3 {deltaPos.x, 0, deltaPos.y};

感谢 Nico Schertler 将我的注意力引向正确的方向。