【问题标题】:Problem rotating with quaternions in OpenGL (GLM/C++)在 OpenGL (GLM/C++) 中使用四元数旋转的问题
【发布时间】:2020-03-16 14:46:26
【问题描述】:

我正在编写一个用于教育目的的游戏引擎,但我对旋转有点卡住了。问题是我在 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 是一个存储对象当前方向的四元数。我知道从欧拉到四元数的所有转换都可以由 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 中显示了如何很好地执行平移/缩放,但旋转(这里现在以弧度显示)执行得不好,它改变了整个方向,而不仅仅是我想要的轴上的方向:

https://gfycat.com/plushhonestargentineruddyduck

有人看到我做错了吗?

【问题讨论】:

  • 抱歉,没看到 :( ...我已经改过了 :)
  • 不,你必须使用glm-math。我已经为你改好了。
  • 您将新的旋转与旧的方向相乘。那是您想要的吗(即参数是更改而不是新值)? m_Orientation = newRot; 可能更接近你想要的。

标签: c++ opengl 3d quaternions glm-math


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2013-03-13
    • 1970-01-01
    • 2012-08-16
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-06
    相关资源
    最近更新 更多