Forward vector y decreasing at certain Y rotation (OpenGL 3D Camera)

Hey there,

I’ve got a problem with not being able to move down or up when the camera is facing right or left. (Forward being y rotation 0 looking along the z- axis)
What I’ve got:

  • An environment with a few boxes
  • A camera that has position and rotation vectors which are converted into an up, left and forward vector and put into a matrix. (the viewmatrix)
  • The move method uses a given direction to translate the camera relative to where it is facing. (I.e. press w = move to forward vector)

Weird stuff: Somehow the Y direction gets inverted when between 90 and 270 rotation. (kinda sorta fixed that, but not very well)
Somehow the Y element of the forward vector decreases when getting closer to 90 & 270 rotation around y axis. (need to fix this)

package varelse;

import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;

//TODO Incorporate getting the time delta, or maybe do that in the inputManager.

public class CameraModelling implements Camera{
	
	private Vector3f cameraPosition;
	private Vector3f cameraRotation;
	private Vector3f maxRotation;
	private Vector3f minRotation;
	private float moveSpeed;
	private float rotationSpeed;
	private Vector3f lVec;				// The left vector, x
	private Vector3f uVec;				// The up vector, y
	private Vector3f fVec;				// The forward vector, z
	private Matrix4f camMatrix;
	
	CameraModelling () {
		cameraPosition = new Vector3f(0,0,0);
		cameraRotation = new Vector3f(0,0,0);
		maxRotation = new Vector3f(269,0,0);
		minRotation = new Vector3f(89,0,0);
		moveSpeed = 0.01f;
		rotationSpeed = 0.2f;
		camMatrix = new Matrix4f();
		
		lVec = new Vector3f(1,0,0);
		uVec = new Vector3f(0,1,0);
		fVec = new Vector3f(0,0,1);
		updateCamMatrix();
	}
	
	CameraModelling (Vector3f pos, Vector3f rot) {
		this.cameraPosition = pos;
		this.cameraRotation = rot;
		moveSpeed = 0.01f;
		rotationSpeed = 0.2f;
		camMatrix = new Matrix4f();
		
		lVec = new Vector3f(1,0,0);
		uVec = new Vector3f(0,1,0);
		fVec = new Vector3f(0,0,1);
		updateCamMatrix();
	}
	
	private void updateCamMatrix() {
		
		float DEG2RAD = 3.141593f / 180;
		float sx, sy, sz, cx, cy, cz, theta;
		
		theta = cameraRotation.x * DEG2RAD;
		sx = (float) Math.sin(theta);
		cx = (float) Math.cos(theta);
		
		theta = cameraRotation.y * DEG2RAD;
		sy = (float) Math.sin(theta);
		cy = (float) Math.cos(theta);
		
		theta = cameraRotation.z * DEG2RAD;
		sz = (float) Math.sin(theta);
		cz = (float) Math.cos(theta);
		
		lVec.x = cy*cz;
		lVec.y = sx*sy*cz + cx*sz;
		lVec.z = -cx*sy*cz + sx*sz;
		
		uVec.x = -cy*sz;				// up.x = -cy*sz;dd
		uVec.y = -sx*sy*sz + cx*cz;		// up.y = -sx*sy*sz + cx*cz;
		uVec.z = cx*sy*sz + sx*cz;		// up.z = cx*sy*sz + sx*cz;
		
		fVec.x = sy;
		fVec.y = -sx*cy;
		fVec.z = cx*cy;
		
		/* Matrix is shaped like this:
		m00 m10 m20 m30		1.0 0.0 0.0 0.0		lx ux fx px
		m01 m11 m21 m31		0.0 1.0 0.0 0.0		ly uy fy py		// No animals were harmed during the testing of matrix order.
		m02 m12 m22 m32		0.0 0.0 1.0 0.0		lz uz fz pz		// My pride, however, was.
		m03 m13 m23 m33		0.0 0.0 0.0 1.0		lw uw fw pw
		*/
		
		camMatrix.m00 = lVec.x;
		camMatrix.m01 = lVec.y;
		camMatrix.m02 = lVec.z;
		
		camMatrix.m10 = uVec.x;
		camMatrix.m11 = uVec.y;
		camMatrix.m12 = uVec.z;
		
		camMatrix.m20 = fVec.x;
		camMatrix.m21 = fVec.y;
		camMatrix.m22 = fVec.z;
		
		camMatrix.m30 = 0;
		camMatrix.m31 = 0;
		camMatrix.m32 = 0;
		
		camMatrix.translate(cameraPosition); // figure out why l, u and f change on translation (lrn2matrix)
		/*
		camMatrix.m30 = cameraPosition.x;
		camMatrix.m31 = cameraPosition.y;	// Doing this causes shenanigans like orbiting around the origin.
		camMatrix.m32 = cameraPosition.z;
		*/
		camMatrix.m33 = 1;
		
	}

	public void rotate(Vector3f v0) {
		this.cameraRotation.x += v0.x;
		this.cameraRotation.y += v0.y;
		this.cameraRotation.z += v0.z;
		if (this.cameraRotation.x > minRotation.x && this.cameraRotation.x < maxRotation.x && v0.x < 0) cameraRotation.x = 269;
		if (this.cameraRotation.x > minRotation.x && this.cameraRotation.x < maxRotation.x && v0.x > 0) cameraRotation.x = 89;
		updateCamMatrix();
	}

	public void move(Vector3f dir, float delta) {
		
		// Moves the camera relative to the way it is looking.
		System.out.println("y rotation is " + cameraRotation.y + " y forward vector is " + fVec.y);
		if (dir.z > 0) {
			cameraPosition.x -= (fVec.x * moveSpeed * delta);
			if (cameraRotation.y > 90 && cameraRotation.y < 270) { cameraPosition.y += (fVec.y * moveSpeed * delta); } 
			else { cameraPosition.y -= (fVec.y * moveSpeed * delta); }
			cameraPosition.z += (fVec.z * moveSpeed * delta);
		} else if (dir.z < 0) {
			cameraPosition.x += (fVec.x * moveSpeed * delta);
			if (cameraRotation.y > 90 && cameraRotation.y < 270) { cameraPosition.y -= (fVec.y * moveSpeed * delta); } // still not sure why exactly Y goes inverse past 90 rot...
			else { cameraPosition.y += (fVec.y * moveSpeed * delta); }
			cameraPosition.z -= (fVec.z * moveSpeed * delta);
		} else if (dir.x > 0) {
			cameraPosition.x += lVec.x * moveSpeed * delta;
			//cameraPosition.y += lVec.y * moveSpeed; //Don't want to move in Y space when going sideways
			cameraPosition.z -= lVec.z * moveSpeed * delta;
		} else if (dir.x < 0) {
			cameraPosition.x -= lVec.x * moveSpeed * delta;
			//cameraPosition.y -= lVec.y * moveSpeed; //Don't want to move in Y space when going sideways
			cameraPosition.z += lVec.z * moveSpeed * delta;
		} else if (dir.y > 0) {
			cameraPosition.y -= moveSpeed * delta;
		} else if (dir.y < 0) {
			cameraPosition.y += moveSpeed * delta;
		}
		updateCamMatrix();
	}
	
	public Matrix4f getCameraMatrix() {
		Matrix4f matrix = camMatrix;
		return matrix;
	}

	public void setRotation(Vector3f v0) {
		this.cameraRotation.x = v0.x;
		this.cameraRotation.y = v0.y;
		this.cameraRotation.z = v0.z;
		updateCamMatrix();
	}

	public void setPosition(Vector3f v0) {
		this.cameraPosition.x = v0.x;
		this.cameraPosition.y = v0.y;
		this.cameraPosition.z = v0.z;
		updateCamMatrix();
	}

	public Vector3f getRotation() {
		Vector3f v0 = new Vector3f();
		v0 = cameraRotation;
		return v0;
	}

	public Vector3f getPosition() {
		Vector3f v0 = new Vector3f();
		v0 = cameraPosition;
		return v0;
	}

	public void setMoveSpeed(float f) {
		moveSpeed = f;
	}

	public void setRotationSpeed(float f) {
		rotationSpeed = f;
	}

	public float getMoveSpeed() {
		float f = moveSpeed;
		return f;
	}

	public float getRotationSpeed() {
		float f = rotationSpeed;
		return f;
	}
	
	public void log() {
		System.out.println(camMatrix.m00 + " " + camMatrix.m10 + " " + camMatrix.m20 + " " + camMatrix.m30 + " " + uVec.x);
		System.out.println(camMatrix.m01 + " " + camMatrix.m11 + " " + camMatrix.m21 + " " + camMatrix.m31);
		System.out.println(camMatrix.m02 + " " + camMatrix.m12 + " " + camMatrix.m22 + " " + camMatrix.m32);
		System.out.println(camMatrix.m03 + " " + camMatrix.m13 + " " + camMatrix.m23 + " " + camMatrix.m33);
	}
}

Since getting even this to work was a real headbreaker I now feel kinda overwhelmed trying to figure out more. Anyways, any help & pointing in the right direction is appreciated!

(Any other feedback on my code is also very welcome :P)