Skip to content

P5.js camera not working with multiple rotation matrices

I’ve been working for some time on making a 3D first person camera in p5.js for games and random projects, but I’ve been having some trouble.

For some time now I’ve been using a single y-rotation matrix with my projects to allow the player to look around, but I’ve felt like having an upgrade recently, so I decided to use x and y rotation matrices for my camera code. I was able to botch together a system that kind of worked by dividing both calculated z values, but there were some issues, not to mention that’s not how rotation matrices work. I recently tried doing a proper implementation, but I’ve come across some issues.

I’ve been using this: camera(0, 0, 0, -200*sin(rot.y), -200*sin(rot.x), (200*cos(rot.x)) + (200*cos(rot.y)), 0, 1, 0); as my test camera code, which in theory would work, but in an actual setting, it doesn’t for some reason, as you can see here. Right now if you look around too far it will randomly spaz out and mess up the way you’re looking.

I also can confirm that I am using the correct formulas as here. I used the (almost) exact same code for calculating the values, and it looks completely fine.

Is there any weird trick to using the p5.js camera or is this some error that needs to be fixed?

Answer

You actually don’t have the correct formulas. The example you showed uses orbitControl(), not camera. It also doesn’t have two different angles it’s rotating through.

The middle 3 coordinates of camera() define the point toward which the camera is pointing. That means that you want that point to move the same way you want the focus of the camera to move. It might help to draw a box at that point like this (in your original):

push();
translate(-200*sin(rot.y), -200*sin(rot.x), (200*cos(rot.x)) + (200*cos(rot.y)));
box(50);
pop();

You’ll notice that the box is not always the same distance from the camera. It stays on a torus whose major and minor radii are both 200. What you want is a sphere with radius 200 (really it can have any radius).

The way you define these three coordinates depends on how you want the user’s interactions to be. Here’s one way:

camera(0, 0, 0,
       cos(rot.x) * cos(rot.y),
       cos(rot.x) * sin(rot.y),
       sin(rot.x),
       0, 0, 1);

This points the camera based on latitude and longitude, with the north pole on the positive Z axis. Moving the mouse right and left affects the longitude, and up and down affects the latitude.