First off, I'm sorry if there are duplicates of this. I did an extensive Google search but was unable to find anything that made sense to me. (I am new to 3D rendering and such.)
I want to make a first person camera that the user can control with the mouse. My current implmentation in Processing looks like this:
PMatrix3D cam;
int oldMouseX=0, oldMouseY=0;
void setup(){
// ...
cam = new PMatrix3D();
}
void draw(){
// ...
int deltaX=oldMouseX-mouseX;
int deltaY=oldMouseY-mouseY;
oldMouseX=mouseX;
oldMouseY=mouseY;
cam.rotateY((PI/600)*deltaX);
cam.rotateX((PI/600)*deltaY);
PVector x = cam.mult(new PVector(1, 0, 0), new PVector(0, 0, 0));
PVector y = cam.mult(new PVector(0, 1, 0), new PVector(0, 0, 0));
PVector d = x.cross(y); d.normalize(); d.mult(R);
float fov = PI/3.0;
float cameraZ = (height/2.0) / tan(fov/2.0);
perspective(fov, float(width)/float(height), cameraZ/10.0, cameraZ*1000.0);
camera(0, 0, 0, d.x, d.y, d.z, y.x, y.y, y.z);
// render objects
}
It works well, but there is a problem. When the mouse is moved along the x-axis of the screen, and then the y-axis, or in some way one axis at a time, the camera rolls. I understand that 3D rotation is supposed to work like that, 2 consecutive rotations around 2 axes make a rotation around the third. The problem is that once the camera is in this rolled state, it is difficult to get it to be straight again.
How can I make it so it is easy to point the camera in any direction? Please explain in easy to understand terms, if possible.
Also, I am a bit confused on
cam.rotateY((PI/600)*deltaX);
cam.rotateX((PI/600)*deltaY);
Before, I had it as
cam.rotateX((PI/600)*deltaX);
cam.rotateY((PI/600)*deltaY);
But that cause the x and y axes to be switched. (i.e., moving the mouse horizontally caused the camera to rotate vertically.) Why is this?