Avoiding introducing roll while changing pitch & yaw with quaternions

Started by
2 comments, last by RichardS 17 years, 7 months ago
I just got my basic quaternion camera almost working, except that some motions introduce undesired roll to the view. Specfically, if I move the view in a circle around it's original direction, the view rolls clockwise (contents roll counter-clockwise). Does anyone know what might be introducing this issue, and how I may be able to resolve it? As a worst case solution, I can entirely disallow roll, and remove it in a post-processing step, but I would like to preserve the ability to do a deliberate roll if at all possible. The relevant bit of code:

quaternionf input;
	
input = quaternionf::axisAngleToQuaternion(vector3f(1.0f, 0.0f, 0.0f), -dy);
orientation = orientation.multiply(input);
	
input = quaternionf::axisAngleToQuaternion(vector3f(0.0f, 1.0f, 0.0f), -dx);
orientation = orientation.multiply(input);

Advertisement
That's how rotations work. Roll accumulates if you just rotate around the two main world-space axes. You have to rotate around the quaternion-local axes to avoid that.

A better way to do a camera is to keep the values in a space where you know what they mean (such as pitch and yaw), and converting to quaternion each step. When the player inputs "rotate right" then you just add to the yaw.
enum Bool { True, False, FileNotFound };
Just for reference, I found the solution to the problem.

I needed to swap the order of multiplication for the second axis. I haven't yet convinced myself *why* it works though.
Again, for reference, the final working bit, which emulates the behavior of a FPS view.

dx and dy are scaled mouse position deltas.

quaternionf inputx, inputy;inputx = quatf_from_axisangle(vector3f(1.0f, 0.0f, 0.0f), -dy);inputy = quatf_from_axisangle(vector3f(0.0f, 1.0f, 0.0f), -dx);orientation = quatf_multiply(quatf_multiply(inputy, orientation), inputx);

This topic is closed to new replies.

Advertisement