6
\$\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\$

2 Answers 2

4
\$\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);

\$\endgroup\$
3
  • 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, 2015 at 12:55
  • \$\begingroup\$ Something in your answer must be wrong. The (0,0,1,0) quaternion represents a 180-degree rotation. \$\endgroup\$ Feb 14, 2015 at 13:56
  • \$\begingroup\$ oh right it's the half angle slipped my mind... \$\endgroup\$ Feb 14, 2015 at 14:00
13
\$\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));
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .