1
votes

I have a camera in OpenGL and it can move on the X and Z axises.

You can rotate the camera with the left and right arrow buttons and move forward, backward, left and right with the WASD buttons. Here is the method for movement.

public void move(float amount, float dir) {
    z += amount * Math.sin((Math.toRadians(ry + 90 * dir)));
    x += amount * Math.cos((Math.toRadians(ry + 90 * dir)));
}

"amount" is the speed and "dir" is either "0" or "1" so it sets "90" to "0" or leaves it as "90". "z" is the position on the z axis. So as "x" and "y". "rz" is rotation on the z axis. So as "rx" and "ry".

With these, I can not move on the Y axis, which is UP and DOWN. I managed to add the rotation code to make the camera LOOK UP and DOWN but I can't make the camera go where you are LOOKING at. Here is the rotation method:

public void rotate(float amount, float way) {
    if (way == ROTATE_RIGHT)
    ry += amount;
    else if (way == ROTATE_LEFT)
    ry -= amount;
    if (way == ROTATE_UP && rx >= -90)
    rx -= amount;
    else if (way == ROTATE_DOWN && rx <= 90)
    rx += amount;
}

This is how I call the move() method.

if (Keyboard.isKeyDown(Keyboard.KEY_W))
    cam.move(0.01f, Camera.MOVE_STRAIGHT);

if (Keyboard.isKeyDown(Keyboard.KEY_S))
    cam.move(-0.01f, Camera.MOVE_STRAIGHT);

if (Keyboard.isKeyDown(Keyboard.KEY_A))
    cam.move(0.01f, Camera.MOVE_STRAFE);

if (Keyboard.isKeyDown(Keyboard.KEY_D))
    cam.move(-0.01f, Camera.MOVE_STRAFE);

Camera.MOVE_STRAIGHT = 1 and Camera.MOVE_STRAFE = 0 and cam is a Camera object.

1

1 Answers

1
votes

Edit 1: Forgot about changing X/Z movement. This should fix those issues.

Edit 2: Changed amount to walkAmount and strafeAmount for both types of horizontal movement. y now also uses walkAmount.

Edit 3: Added move()

public void move(float amount, float dir) {
    /* If you are moving straight ahead, or in reverse, modify the Y value for ascent/descent
     * Since you do not change your elevation if you are strafing, dir will be 0. sin(0) = 0, and the elevation will not change (regardless of whether rx is 0).
     * When you are moving forward or in reverse, dir will be 1, so the rotation about the x axis will be used, and the elevation will change (unless rx is 0).
     */
    y += amount * Math.sin(Math.toRadians(rx) * dir);

    /* If you are moving straight ahead, or in reverse, scale the delta X/Z (what comes after the +=) so that you don't move as far.
     * For example, if you are aimed straight up, and you move straight ahead (W/S), Math.cos(Math.toRadians(rx) * dir) will evaluate to 0, since you only want to move in the Y direction.
     * If you are aimed perfectly straight ahead (rotation about the x axis is 0), and you move straight ahead (A/D), Math.cos(Math.toRadians(rx) * dir) will evalute to 1, and your X/Z
     * movement would use the entire amount, since you are no longer moving in the Y direction.
     * If you are strafing (A/D), dir will be 0, and Math.cos(Math.toRadians(rx) * dir) will evalute to 1 (cos(0) == 1)). You will ONLY move in the X/Z directions when strafing.
     */
    z += amount * Math.cos(Math.toRadians(rx) * dir) * Math.sin((Math.toRadians(ry + 90 * dir)));
    x += amount * Math.cos(Math.toRadians(rx) * dir) * Math.cos((Math.toRadians(ry + 90 * dir)));
}

Please let me know if this helps you or if you have any issues.