简体   繁体   中英

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

I'm programming a game engine for educational purposes and I'm a bit stucked with rotations. The thing is that I have in the UI 3 squares to represent an object's orientation in Euler Angles, and from there I can change the values.

To change them, I call:

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 is a quaternion storing the object's current orientation.I know all that conversion from eulers to quaternion could be handled by glm but I changed to this to debug what was happening...

Then, UpdateTransform() does the next:

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);
}

And m_Rotation_InEulerAngles is the vec3 that can be seen from the UI to change the angles of the object's orientation.

The problem is that when I try to modify one of the 3 euler angles, the 3 are modified, I mean, if I modify the Roll angle (around Z axis), it modifies also Pitch and Yaw (not with the Z value, it's like it sets another orientation to the object).

In this gif is shown how the translation/scaling are well performed but rotation (here is seen in radians by now), is not well performed, it changes the whole orientation, not just the one in the axis I want:

https://gfycat.com/plushhonestargentineruddyduck

Does somebody sees what I'm I doing wrong?

Changing , or setting orientation, is not the same as rotating :

To set your orientation, you want to do it like this:

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

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

To rotate, we want to integrate the rotation quaternion, using SLERP:

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

And to get your rotation matrix:

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

See here for more information on quaternion rotations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM