0

I have been searching for a long time, and can't find an answer to this seemingly simple question. I have a 3d space and my camera has x, y, z, yaw, pitch and roll variables, and I want to be able to move the camera forward toward whatever I am looking at. Most Camera classes have something like this:

//moves the camera forward relitive to its current rotation (yaw)
public void walkForward(float distance)
{

    position.x -= distance * (float)Math.sin(Math.toRadians(yaw));
    position.z += distance * (float)Math.cos(Math.toRadians(yaw));

}

This works well for moving forward depending on your yaw, but your y position will never change. How can this be changed to also be relative to your pitch, so that you will always move toward whatever the camera is looking at?

EDIT:

By moving forward, I mean that by moving your camera a certain amount on each axis, that amount depending on your yaw, pitch and roll, whatever is in front of you, will appear to get larger. This could be used:

    position.x += -Math.sin(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance;
    position.z += Math.cos(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance;
    position.y -= -Math.sin(Math.toRadians(rotation.x)) * distance;

Note: rotation.y = yaw, rotation.x = pitch, rotation.z would be roll. The distance is simply how much to move, let's say 0.1.

This will work if you don't change the roll of the camera (rotation on the z axis), otherwise it won't. This post is probably very similar to this now, but I don't know how to apply that matrix multiplication which was the solution into my camera class which looks like this

public class Camera
{
// Field Of View
private float fov;
// Aspect Ratio
private float aspect;
// Near Plane
private float zNear;
// Far Plane
private float zFar;

// Projection matrix
private Matrix4f projection;
// View matrix
private Matrix4f view;

// Camera position
private Vector3f position;
// Camera rotation
private Vector3f rotation;

// Vectors for axes
private Vector3f xAxis, yAxis, zAxis;

/**
 * Creates a simple 3D Perspective Camera.
 * 
 * @param fov The field of view in degrees.
 * @param aspect The aspect ratio.
 * @param zNear The near clipping plane.
 * @param zFar The far clipping plane.
 */
public Camera(float fov, float aspect, float zNear, float zFar)
{
    // Set the local variables
    this.fov = fov;
    this.aspect = aspect;
    this.zNear = zNear;
    this.zFar = zFar;

    // Create matrices
    projection = MatrixUtil.createPerspectiveProjection(fov, aspect, zNear, zFar);
    view = MatrixUtil.createIdentityMatrix();

    // Initialize position and rotation vectors
    position = new Vector3f(0, 0, 0);
    rotation = new Vector3f(0, 0, 0);

    // Create normalized axis vectors
    xAxis = new Vector3f(1, 0, 0);
    yAxis = new Vector3f(0, 1, 0);
    zAxis = new Vector3f(0, 0, 1);

    // Enable depth testing
    glEnable(GL_DEPTH_TEST);
}

/**
 * Apply the camera's transformations.
 */
public void apply()
{
    // Make the view matrix an identity.
    view.setIdentity();

    // Rotate the view
    Matrix4f.rotate((float) Math.toRadians(rotation.x), xAxis, view, view);
    Matrix4f.rotate((float) Math.toRadians(rotation.y), yAxis, view, view);
    Matrix4f.rotate((float) Math.toRadians(rotation.z), zAxis, view, view);

    // Move the camera
    Matrix4f.translate(position, view, view);
}

//moves the camera forward relitive to its current rotation (yaw and pitch)
public void moveForward(float distance)
{
    position.x += -Math.sin(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance;
    position.z += Math.cos(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance;
    position.y -= -Math.sin(Math.toRadians(rotation.x)) * distance;
}

(This camera class is based on this tutorial)

So how can I make the camera move forward depending on it's yaw, pitch and roll.

Community
  • 1
  • 1
Alex Socha
  • 13
  • 5

1 Answers1

1

You have 3 rotations: roll, yaw, and pitch. These can also be imagined as points on a disk drawn on a flat plane in 3d space: xy-plane(roll), xz-plane(yaw), zy-plane(pitch).

To help you visualize this, imagine you're inside a cube. The cube has 6 faces, each with a circle drawn on it. The 2 faces below and above you are the xz planes; to your right and to your left are the zy planes; front and back are the familiar xy planes.

Your example is a rotation around the centre of a circle drawn on the xz plane. When a plane yaws, it obviously doesn't change its pitch. A roll(xy) would look something like:

position.x -= distance * (float)Math.cos(Math.toRadians(amount));
position.y += distance * (float)Math.sin(Math.toRadians(amount));

You may have to change the signs because I'm not sure how this is implemented.

On the xy plane(a typical 2d view), if you draw a circle with radius r, any point on the circle at angle theta can be given by P(r*cos(theta), r*sin(theta)). In 3d space, you have 3 planes, and you'll have to apply the same logic on all planes in order to find the appropriate values for the rotation on that plane.

I'm not sure what you mean by "moving the camera forward", though.

Valentin
  • 654
  • 2
  • 7
  • 15