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!