在 OpenGL 中使用四元数旋转时出现问题 (GLM/C++)

Problem rotating with quaternions in OpenGL (GLM/C++)

我正在为教育目的编写一个游戏引擎,但我有点受困于轮换。问题是我在 UI 中有 3 个方块来表示对象在欧拉角中的方向,从那里我可以更改值。

要更改它们,我调用:

void TransformComponent::SetOrientation(glm::vec3 eulerAxAngles)
{
    glm::vec3 euler_inRadians = glm::radians(eulerAxAngles);

    glm::quat newRot;
    double cy = cos(euler_inRadians.y * 0.5);
    double sy = sin(euler_inRadians.y * 0.5);
    double cp = cos(euler_inRadians.x * 0.5);
    double sp = sin(euler_inRadians.x * 0.5);
    double cr = cos(euler_inRadians.z * 0.5);
    double sr = sin(euler_inRadians.z * 0.5);
    newRot.w = cy * cp * cr + sy * sp * sr;
    newRot.x = cy * cp * sr - sy * sp * cr;
    newRot.y = sy * cp * sr + cy * sp * cr;
    newRot.z = sy * cp * cr - cy * sp * sr;

    m_Orientation = newRot * m_Orientation;
    UpdateTransform();
}

m_Orientation 是一个四元数,存储对象的当前值 orientation.I 知道所有从欧拉到四元数的转换都可以由 glm 处理,但我改成这个来调试正在发生的事情...

然后,UpdateTransform() 执行下一步:

void TransformComponent::UpdateTransform()
{
    m_TransformationMatrix = glm::translate(glm::mat4(1.0f), m_Translation) *
        glm::scale(glm::mat4(1.0f), m_Scale) * glm::mat4_cast(m_Orientation);


    //Set euler angles
    m_Rotation_InEulerAngles = glm::eulerAngles(m_Orientation);
}

而m_Rotation_InEulerAngles就是从UI可以看出的vec3,用来改变物体方向的角度。

问题是,当我尝试修改 3 个欧拉角之一时,这 3 个被修改了,我的意思是,如果我修改 Roll 角(围绕 Z 轴),它也会修改 Pitch 和 Yaw(不是Z 值,就像它为对象设置了另一个方向)。

在这个 gif 中显示了 translation/scaling 如何很好地执行但是旋转(这里现在以弧度显示)执行得不好,它改变了整个方向,而不仅仅是轴中的方向我要:

https://gfycat.com/plushhonestargentineruddyduck

有人看到我做错了什么吗?

改变,或设置方向,与旋转不同:

要设置你的方向,你想这样做:

void setOrientation(glm::vec3 eular)
{
    m_Orientation = glm::quat(eular); // very simple
}

void setRotation(glm::vec3 eular)
{
    m_Rotation = glm::quat(eular); // very simple
}

为了旋转,我们要对旋转四元数进行积分,使用SLERP:

void update(float deltaTimeS)
{
    glm::quat ident(1.0f);
    glm::quat rotation = glm::mix(ident, m_Rotation, deltaTimeS);
    m_Orientation = rotation * m_Orientation;
}

并获取旋转矩阵:

void setTransform()
{
    m_RotationMatrix = glm::gtx::quaternion::toMat4(quaternion);
}

有关四元数旋转的更多信息,请参见here