# Processing - implement a first person camera?

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);


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?

• Judging by the amount of new posts on Stack Overflow, I think a lot of people have time on their hands to code during Christmas. Especially non Christians. – DankMemes Dec 24 '13 at 20:24
• Well, "Happy Holidays" then :P – Moo-Juice Dec 24 '13 at 20:25
• peasycam is a library for that... If you like :) – v.k. Dec 25 '13 at 0:09
• Thanks! I'll try it. But in the meantime can you explain how this is supposed to work? – DankMemes Dec 26 '13 at 23:04
• it seems you are having a gimbal lock, but I am not 100% sure from your description. Maybe you need to check this gamedev.stackexchange.com/questions/67199/… – concept3d Dec 29 '13 at 8:47

You can use just the camera() method to change the perspective more easily.

To use it, you probably want two variables: rotationAngle and elevationAngle. Moving the mouse sideways changes rotationAngle between 0 and TWO_PI. You can then set variable centerY to sin(rotationAngle) and centerX to cos(rotationAngle). Moving the mouse up and down would change elevationAngle to anywhere between 0 and PI. Multiply centerX and centerY by sin(elevationAngle) and set centerZ to -cos(elevationAngle). You can then call camera() with the calculated values.

Final code:

float rotationAngle;
float elevationAngle;

float centerX;
float centerY;
float centerZ;

void setup() {
// ...
}

void draw() {
// ...
updateCamera();
// render objects
}

void updateCamera() {
rotationAngle = map(mouseX, 0, width, 0, TWO_PI);
elevationAngle = map(mouseY, 0, height, 0, PI);

centerX = cos(rotationAngle) * sin(elevationAngle);
centerY = sin(rotationAngle) * sin(elevationAngle);
centerZ = -cos(elevationAngle);

camera(0, 0, 0, centerX, centerY, centerZ, 0, 0, 1);
}