I'm coding a basic OpenGL game and I've got some code that handles the mouse in terms of moving the camera.
I'm using the following method:
int windowWidth = 640;
int windowHeight = 480;
int oldMouseX = -1;
int oldMouseY = -1;
void mousePassiveHandler(int x, int y)
{
int snapThreshold = 50;
if (oldMouseX != -1 && oldMouseY != -1)
{
cam.yaw((x - oldMouseX)/10.0);
cam.pitch((y - oldMouseY)/10.0);
oldMouseX = x;
oldMouseY = y;
if ((fabs(x - (windowWidth / 2)) > snapThreshold) || (fabs(y - (windowHeight / 2)) > snapThreshold))
{
oldMouseX = windowWidth / 2;
oldMouseY = windowHeight / 2;
glutWarpPointer(windowWidth / 2, windowHeight / 2);
}
}
else
{
oldMouseX = windowWidth / 2;
oldMouseY = windowHeight / 2;
glutWarpPointer(windowWidth / 2, windowHeight / 2);
}
glutPostRedisplay();
}
However, after looking around in circles you'll find the camera starts to "roll" (rotate). Since I'm only calling Pitch and Yaw, I don't see how this is possible.
Here is the code I'm using for my Camera class: http://pastebin.com/m20d2b01e
As far as I know, my camera "rolling" shouldn't happen. It should simply pitch up and down or yaw left and right. NOT roll.
What could be causing this?
Congratulations -- you have discovered Lie group theory!
Yes, it's possible. The outcome of a series of transformations
depends on the order in which they're executed. Doing a pitch
followed by a yaw is not the same as a doing a yaw, followed
by a pitch. In fact, in the limit of infinitesimally small yaws
and pitches, the difference amounts to a pure roll; the general
case is a little more complicated.
(Physicists call this the "commutation relationships of
the rotational group".)
If you're familiar with rotation matrices, you can work it out
quite easily.
You will probably need to use quaternions for composing rotations, if you are not doing so already. This avoids the problem of gimbal lock which you can get when orienting a camera by rotation around the 3 axes.
Here is how to convert between them.
Well, if you start off looking forward horizontal to the horizon, pitch up 90 degrees, then yaw left 90 degrees, then pitch down 90 degrees, you'd be looking in the same direction as you started, but the horizon would be vertical (as if you'd rolled 90 degrees left).
Edit: I think the problem is that yaw/pitch/roll would be appropriate if the camera is being treated like an airplane. What you probably want to do is treat it like a point in a sphere, keeping track of where on the sphere you are pointing the camera. Instead of yaw/pitch, use spherical coordinates keeping track of theta (latitude) and phi (longitude). They may sound similar, but consider the extreme case where the camera is pointing directly up. With yaw/pitch, you can still freely adjust the yaw and pitch from that straight-up direction. With theta/phi, you could only adjust theta downward, and no matter how much you adjusted phi, decreasing theta would still give you a camera that is parallel to the horizon. This is how FPS camera's work (you can't look so far down that you're looking behind you).
Edit 2: Looking at the camera code you linked to, you want to be using the rotLati(float angle)
and rotLongi(float angle)
functions.
Mathematically the reason for this is that rotations in 3D space do not commute. What that means is that pitch() followed by yaw() is not the same as yaw() followed by pitch(), but a consequence of that fact is that the three kinds of rotations are inextricably linked and you can't perform any two of them without getting some of the third. In other words, any sequence of pitch()es and yaw()s will produce a noticeable roll() effect over time, unless the second half of the sequence is the exact reverse of the first half. (There's a lot of fairly intricate math involved in this, but the details aren't particularly relevant)
Pitch/yaw/roll are all relative to your vehicle's orientation. When you pitch up/down, you change your axis of yaw. Likewise, when you yaw, you change your pitch axis. So it's possible to change your orientation in a way similar to a roll maneuver just by a combination and pitch & yaw maneuvers.
I believe this circumstance is called Gimbal Lock - there's an example of it with illustrations on the wikipedia page.