I am working on a camera class that will have full range of motion (pitch, yaw, and roll). When only altering pitch and yaw, I am getting a large amount of roll.
I understand that the issue is related to: I'm rotating an object on two axes, so why does it keep twisting around the third axis?
However, I have not been able to come up with a solution. I would like the camera to have all motion (i.e. like a spaceship). Here is the relevant code:
void Camera3D::update(const glm::vec2 & current_mouse_coords){ if (m_mouse_first_movement) { if (current_mouse_coords.x != 0 || current_mouse_coords.y != 0) { m_mouse_first_movement = false; } } else { const glm::vec2 mouse_delta = (current_mouse_coords - m_old_mouse_coords) * mouse_sensitivity; pitch(-mouse_delta.y); yaw(-mouse_delta.x); } m_old_mouse_coords = current_mouse_coords; } void Camera3D::pitch(const float angle){ // Pitch Rotation const glm::quat pitch_quaternion = glm::angleAxis(-angle, m_camera_right); // Update Vectors m_camera_up = glm::normalize(glm::rotate(pitch_quaternion, m_camera_up)); m_camera_forward = glm::normalize(glm::rotate(pitch_quaternion, m_camera_forward)); } void Camera3D::yaw(const float angle){ // Yaw Rotation const glm::quat yaw_quaternion = glm::angleAxis(angle, m_camera_up); // Update Vectors m_camera_right = glm::normalize(glm::rotate(yaw_quaternion, m_camera_right)); m_camera_forward = glm::normalize(glm::rotate(yaw_quaternion, m_camera_forward)); } glm::mat4 Camera3D::get_view_matrix(){ m_view_matrix = glm::lookAt( m_camera_position, m_camera_position + m_camera_forward, m_camera_up ); return m_view_matrix; } I would like the movement of the camera to be based on local coordinates so the controls (up/down/left/right/vertical up/vertical down) move the camera along its own local axis.
Additional clarification based on the comment below: If I look up 60 degrees and then left, I would like the horizon to stay level (essentially adding roll in the opposite direction to keep the horizon level)
Any help is appreciated. Thank you!


