4
\$\begingroup\$

I have a question in regards to using quaternions for the rotation of my graphics object.

I have a Transform class which has the following constructor with default parameters:

Transform(const glm::vec3& pos = glm::vec3(0.0), const glm::quat& rot = glm::quat(1.0, 0.0, 0.0, 0.0),
    const glm::vec3& scale = glm::vec3(1.0))
{
    m_pos = pos;
    m_rot = rot;
    m_scale = scale;
}

In my Transform class calculate the MVP as follows:

glm::mat4 Transform::GetModelMatrix() const
{
    glm::mat4 translate = glm::translate(glm::mat4(1.0), m_pos);
    glm::mat4 rotate = glm::mat4_cast(m_rot);
    glm::mat4 scale = glm::scale(glm::mat4(1.0), m_scale);

    return translate * rotate * scale;
}

The issue I'm facing is that when I use const glm::quat& rot = glm::quat(1.0, 0.0, 0.0, 0.0) my object appears normal on screen. The following image shows it: enter image description here

However if I try to use for example const glm::quat& rot = glm::quat(glm::radians(90.0f), 0.0, 1.0, 0.0) (rotating on y axis by 90 degrees) my object appears as if it has been scaled. The following image shows it: enter image description here

I can't figure out what is causing it to become like this when I try to rotate it. Am I missing something important?

If it's of any relevance, the following is how I calculate my view matrix:

glm::mat4 Camera::GetView() const
{
    glm::mat4 view = glm::lookAt(m_pos, m_pos + m_forward, m_up);

    return view;
}
\$\endgroup\$
3
\$\begingroup\$

the glm::quat(float, float, float, float); constructor doesn't do what you think it does. It sets the values directly.

The values of the quaternion (w, x, y, z) are in order: the cosine of half the angle, the sine of half the angle times the x coordinate of the normalized rotation axis, and the same for the y and z components.

So instead you want to use glm::quat(cos(glm::radians(90.0f/2)),0,sin(glm::radians(90.0f/2))*1,0); or after inlining the result of the trig: glm::quat(sqrt(1/2),0,sqrt(1/2),0);

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Thanks for the answer. Can you please explain what the constructor actually does? Also is there a way to initialize the quaternion for every axis based on your answer? Thanks \$\endgroup\$ – Kakalokia Feb 14 '15 at 12:55
  • \$\begingroup\$ Something in your answer must be wrong. The (0,0,1,0) quaternion represents a 180-degree rotation. \$\endgroup\$ – sam hocevar Feb 14 '15 at 13:56
  • \$\begingroup\$ oh right it's the half angle slipped my mind... \$\endgroup\$ – ratchet freak Feb 14 '15 at 14:00
11
\$\begingroup\$

You should probably use glm::angleAxis() (documentation here):

glm::quat rot = glm::angleAxis(glm::radians(90.f), glm::vec3(0.f, 1.f, 0.f));
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.