Troubles with the 3D Camera

Hey Guys,
as I try to develop a little Voxel Engine to improve my 3D Skills I think this is the right place?

I started with some Cubes and Chunks and now I try to manage those Chunks… However, atm I have problems to set up a camera. I just want to fly around my Chunks and later implement a player, but for now I have trouble with the movement of the camera.

Here is my Camera.class:

import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.util.vector.Vector3f;
import static org.lwjgl.opengl.GL11.*;

public class Camera {	
	//3d vector to store the camera's position in
    //the rotation around the Y axis of the camera
    //the rotation around the X axis of the camera
    public Vector3f position = null;
    private float yaw = 0.0f;
    private float pitch = 0.0f;
	private float movementSpeed = 5.0f;
	private float mouseSensitivity = 0.5f;
	
	private float dtt;
  
    /**
     * Creates a new Camera that takes the starting x, y, z location

     * Call the update() method every frame to use the camera

     * Do not forget to set the movementSpeed(default 10) and mouseSensitivity (default 0.5) by calling the
     * setMovementSpeed() and setMouseSensitivity() methods
     * 
     * @param x x location
     * @param y y location
     * @param z z location
     */
    public Camera(float x, float y, float z)
    {
        position = new Vector3f(x, y, z);
    }

    /**
     * updates the camera

     * CALL THIS <b>BEFORE</b> YOU RENDER YOUR SCENE!

     * @param dt deltaTime for indie movement
     */
    public void update(float dt) {
    	
    	// ignore this :D
    	dtt = dtt + dt;
    	if(dtt >= 1) {
    		System.out.println(position);
    		dtt = 0;
    	}
    		
        //control camera yaw from x movement from the mouse
        yaw(-Mouse.getDX() * mouseSensitivity);
        //control camera pitch from y movement from the mouse
        pitch(Mouse.getDY() * mouseSensitivity);
        
        if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
        	moveCamera(0, movementSpeed*dt);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
        	moveCamera(180, movementSpeed*dt);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
        	moveCamera(90, movementSpeed*dt);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
        	moveCamera(270, movementSpeed*dt);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
            flyUp(movementSpeed*dt);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
            flyDown(movementSpeed*dt);
        }
        glLoadIdentity();
        lookThrough();
    }
    
    /**
     * 	increment the camera's current yaw rotation
     * @param amount increment the yaw by the amount param
     */
    private void yaw(float amount) {
        yaw += amount;
        if(yaw > 359)
        	yaw = yaw - 359;
        else if(yaw < 0)
        	yaw = yaw + 360;
    }

    /**
     * increment the camera's current pitch rotation
     * @param amount increment the pitch by the amount
     */
    private void pitch(float amount) {
    	pitch += amount;
    	if(pitch > 90)
    		pitch = 90;
    	else if(pitch < -90)
    		pitch = -90; 
    }
    
    private void moveCamera(float direction, float distance) {
    	position.x += Math.sin(Math.toRadians(yaw + direction)) * distance;
    	position.z += Math.cos(Math.toRadians(yaw + direction)) * distance;
    }
    
    private void flyUp(float distance) {
    	position.y += distance;
    }
    
    private void flyDown(float distance) {
    	position.y -= distance;
    }

    /**
     * translates and rotate the matrix so that it looks through the camera
     */
    private void lookThrough() {
        //roatate the pitch around the X axis
        glRotatef(-pitch, 1.0f, 0.0f, 0.0f);
        //roatate the yaw around the Y axis
        glRotatef(-yaw, 0.0f, 1.0f, 0.0f);
        //translate to the position vector's location
        glTranslatef(-position.x, -position.y, -position.z);
    }
}

Maybe some of you can try out this class? There is something weird about the movement and I think thats because of positive and negative… Well I don’t really got this :frowning:
I just wanted to write a camera based on this tutorial, but it seems not to work…


So 0 degrees should be moving forward, 180 degree backward, 270 right and 90 left.

Try translating to position before you rotate to face. If you rotate first then the translation is with respect to the new coordinate system defined by the rotation. (probably not what you want)

well, thanks for the reply, but jeah, thats not rly what I want :smiley:
This sounds correct for me:


void moveCamera(float direction) { // direction is in degrees
   pos.x += Math.sin(Math.toRadians(yaw + direction));
   pos.z += Math.cos(Math.toRadians(yaw + direction));
}

so lets say I look forward and move forward. yaw = 0, direction = 0
pos.x = 0;
pos.z = 1 * SPEED
This is correct math. But in fact it feels wrong, because pressing W for moving forward will make you moving backwards.! And thats what I don’t understand.

Your forward is not fixed.

You give the movement direction as a fixed angle (0, 90, 180, …) - this will result in moving along the z & x axis.

You have to calculate your direction every time you turn your camera.

right, my forward is not fixed.
and i don’t give the movement direction as a fixed angle. I already calculate my direction every time i turn the camera.
and i think every movement will result in moving along the z & x axis :smiley:
I am just looking for the error in my code, why W = moving backwards, S = moving forward and maybe a little math explanation.

OK, I see. OpenGL uses a right handed coordinate system, which means that unless you do something funky, positive z is pointing out of the screen towards you. You can try it with your right hand - put thumb, 1st and 2nd finger (or 1st, 2nd, 3rd if you’re a pianist) at 90 degrees to each other. Then put it against the screen with thumb pointing right (x axis), 1st finger pointing up (y axis) and see where your second finger (z axis) points.

This is one of the things that sets OpenGL apart from most other libraries like DirectX which tend to use left handed system by default.

ahhh ok :smiley: moving in the positiv z direction looks like moving backwards. thank you :smiley:
looking forward and moving forward. yaw = 0, direction = 0
pos.z = cos(0 + 0)
pos.z = 1!!! so this should make the camera moving into the screen, but the opposite is true. I got it! :smiley:

Just a note… Modern OpenGL doesn’t use one or the other. In the programmable pipeline, you need to construct your own projection and modelview matrices.

This is different from the fixed-function pipeline (glTranslate, glRotate, glOrtho, etc), which became deprecated five years ago.

Modern OpenGL? so OpenGL > 3?
“You need to construct your own projection and modelview matrices” sounds really hard… is this very complicated? I am asking, because I just started using OpenGL so I might swap to the “modernGL” :smiley:
Is there anything you can recommend to read or to look up?

Its not massively complicated. The documentation for OpenGL actually shows how it constructs the matrices in all of the glTranslate, glRotate etc functions. The LWJGL util.vector.Matrix4f class provides all you need to perform operations on matrices. You could probably do this with very little understanding of the transformation matrices, I wouldn’t recommend it but you could.

So a couple of links:

http://www.wildbunny.co.uk/blog/vector-maths-a-primer-for-games-programmers/
Still the best tutorial for beginners I’ve ever found. (IMO)

http://www.opengl.org/sdk/docs/man2/
The OpenGL docs to see how “they” do it. Make sure you view this in a browser with support for proper mathematical notation. (Chrome and (I think) IE don’t out of the box for example) Firefox works without any extra plugins but I couldn’t say for any other browsers.