# How to move a camera in “Flight Simulator” style (Roll, Pitch, Yaw) using a joystick

I am working on a video game where the camera movement (what the viewer sees) is controlled by a joystick. I want the camera movement to act like a flight simulator meaning the following:

When the user tilts the joystick down (toward the screen) the camera points down ("pitch").

When the user moves the joystick sideways the camera just "rolls" along the Z-Axis.

Additionally, when the user twists the joystick, the camera would "yaw"

How can I calculate the distance in each direction, X, Y, Z the user would go based on those rotations.  For example, if the user rotated along the X axis 90 degrees, future movement would be 100% in the Y direction.

If the user "rolls" along the Z axis, the movement would be 100% in the Z direction but, as soon as there is rotation along the X axis (and rotation along the Z axis), there would be movement in three directions.

This question comes very close to answering, but is basically asking the inverse. I just want to know, given roll and pitch, how do I calculate yaw. Or, how do I figure the distance in X Y and Z based on their rotations. Thanks

I'd express these rotations as matrices. You'll have to fix one convention, e.g. the following one: when you multiply the matrix by a column vector, then the column vector is in coordinates relative to your view and the resulting vector is in absolute coordinates with respect to some fixed coordinate system. Since the matrix will be orthogonal, its inverse is simply its transpose, which means that multipliying a row vector by the same matrix can be used to turn absolute coordinates into relative ones. (The opposite convention would be possible as well, and you might want to choose that if it fits better to what you are doing in the rest of your application.)

Now you can express each pitch and roll, ans input by the joystick, as a matrix in this way. You combine these matrices by multiplying them in the correct way. But what is the correct way? Well, pitch and roll are relative to the view coordinate system. So they translate between old view coordinates and new view coordinates. When you already have a matrix describing the transformation of old view coordinates into absolute coordinates, then you want to execute the transformation from new view to old view before that. Which in terms of matrix multiplication means that you want to place the new matrix to the right of the old matrix in your matrix multiplication. So if $A$ describes your position so far, and $B$ is an update to that position, i.e. a pitch or roll, you want to update variable $A$ with the matrix product $A\cdot B$.

Since the resulting transformation (this updated matrix $A$) always describes the transformation from view coordinates to absolute coordinates, you can use it to translate a direction relative to your view (e.g. “forward”) into a direction in absolute world coordinates.

When I've done this, I've preferred using a 2-vector system to maintain direction: a "forward" vector and an "up" vector, which express forward and up in local coordinates.

Roll, then is rotation about the forward vector, yaw is about the up vector, and pitch is about the vector produced by the cross product UP cross FORWARD.

The advantage of this representation is that it's easily convertible to matrix form, and it's easy to keep normalized. As you compute successive rotations using a matrix, any finite representation can begin to stray from the unit vector, and add errors to the projection results. Normalizing after each additive transform will prevent that.

You can normalize a matrix, but it's more complex and less intuitive.