Search code examples
c++openglglm-math

Calculating roll in an OpenGL camera class


I am trying to add a roll to an OpenGL camera, but when I add a roll using a previous Stackoverflow question the camera rolls, but, the roll affects the yaw and pitch direction.

When should I apply the matrix rotation for the roll, please?

Variables and there types:

    glm::vec3 m_position;
    glm::vec3 m_front;
    glm::vec3 m_up;
    glm::vec3 m_right;
    glm::vec3 m_worldUp;

The main camera update function

void Camera::UpdateCamera ()
{
    glm::vec3 front;
    front.x = cos (glm::radians (m_yaw)) * cos (glm::radians (m_pitch));
    front.y = sin (glm::radians (m_pitch));
    front.z = sin (glm::radians (m_yaw)) * cos (glm::radians (m_pitch));
    m_front = glm::normalize (front);

    m_right = glm::normalize (glm::cross (m_front, m_worldUp));
    m_up = glm::normalize (glm::cross (m_right, m_front));

    glm::mat4 roll_mat = glm::rotate(glm::mat4(1.0f), glm::radians(m_roll), m_front);
    m_up = glm::mat3(roll_mat) * m_up;
}

View Matrix calculation:

lm::mat4 Camera::GetViewMatrix ()
{
    return glm::lookAt (m_position, m_position + m_front, m_up);;
}

This is how the yaw and pitch calculations get called:

void KeyCtrl::CursorPositionChange(double xPosIn, double yPosIn)
{
    float xpos = static_cast<float>(xPosIn);
    float ypos = static_cast<float>(yPosIn);

    if (m_firstMouse)
    {
        m_lastX = xpos;
        m_lastY = ypos;
        m_firstMouse = false;
    }

    float xoffset = xpos - m_lastX;

    // reversed since y-coordinates go from bottom to top
    float yoffset = m_lastY - ypos;

    m_lastX = xpos;
    m_lastY = ypos;

    xoffset *= MouseSensitivity;
    yoffset *= MouseSensitivity;

    m_camera->SetYaw (xoffset);
    m_camera->SetPitch (yoffset);

    m_camera->UpdateCamera ();
}

Somehow I have got the roll maths wrong, but, I understand where.

Solution The following two lines should be removed from Camera::UpdateCamera:

    glm::mat4 roll_mat = glm::rotate(glm::mat4(1.0f), glm::radians(m_roll), m_front);
    m_up = glm::mat3(roll_mat) * m_up;

When you create the model view, add this as the final line:

model = glm::rotate (model, glm::radians (m_camera->GetRoll()), { 0.0f, 0.0f, 1.0f });

Solution

  • Solution

    The following two lines should be removed from Camera::UpdateCamera:

    glm::mat4 roll_mat = glm::rotate(glm::mat4(1.0f), glm::radians(m_roll), m_front);
    m_up = glm::mat3(roll_mat) * m_up;
    

    When you create the model view, add this as the final line:

    model = glm::rotate (model, glm::radians (m_camera->GetRoll()), { 0.0f, 0.0f, 1.0f });