LWJGL Funky Camera Rotation? (SOLVED)

For some reason, the rotation in my game is screwed up. Instead of rotating the scene/world like the camera should be, it’s rotating the objects that are drawn around a point. (Demonstrated in the GIF). Throughout the .gif in the game I am moving only on the X and Z axis, so none of the tilting/rolling that you see should be occuring. The rolling in place is caused by changing the rotation.y (pitch) variable, and the going-in-circles is caused by modifying the rotation.x (yaw) variable.

This is the part of the Camera class handling rotation/translation of the world


	public void lookThrough()
	{		
		if (rotation.y / 360 > 1)
		{
			rotation.y -= 360;
		}
		else if (rotation.y / 360 < 0)
		{
			rotation.y += 360;
		}		
		if (rotation.x / 360 > 1)
		{
			rotation.x -= 360;
		}
		else if (rotation.x / 360 < 0)
		{
			rotation.x += 360;
		}

		glLoadIdentity();
		glRotatef(rotation.x, 0f, 1f, 0f); //Yaw
		glRotatef(-rotation.y, 1f, 0f, 0f); //Pitch
		glRotatef(rotation.z, 0f, 0f, 1f); //Roll
		glTranslatef(-position.x, -position.y, -position.z);
	}

This is how I initiate GL for 3D graphics:


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, Main.oglWindow.getAspect(), zNear, zFar);
glMatrixMode(GL_MODELVIEW);
		
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);

And here’s the main part of the game-loop where player input happens and the cube is drawn. This is all set up as a test, so I’ll switch to VBOs and an actual player-input framework soon:


For some reason, the rotation in my game is screwed up. Instead of rotating the scene/world like the camera should be, it's rotating the objects that are drawn around a point. (Demonstrated in the GIF).


http://i.imgur.com/8PC49tX.gif


This is the part of the Camera class handling rotation/translation of the world

public void lookThrough()
{		
	if (rotation.y / 360 > 1)
	{
		rotation.y -= 360;
	}
	else if (rotation.y / 360 < 0)
	{
		rotation.y += 360;
	}		
	if (rotation.x / 360 > 1)
	{
		rotation.x -= 360;
	}
	else if (rotation.x / 360 < 0)
	{
		rotation.x += 360;
	}

	glLoadIdentity();
	glRotatef(rotation.x, 0f, 1f, 0f); //Yaw
	glRotatef(-rotation.y, 1f, 0f, 0f); //Pitch
	glRotatef(rotation.z, 0f, 0f, 1f); //Roll
	glTranslatef(-position.x, -position.y, -position.z);
}


This is how I initiate GL for 3D graphics:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, Main.oglWindow.getAspect(), zNear, zFar);
glMatrixMode(GL_MODELVIEW);

glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);



And here's the main part of the game-loop where player input happens and the cube is drawn. This is all set up as a test, so I'll switch to VBOs and an actual player-input framework soon.

		if (Keyboard.isKeyDown(Keyboard.KEY_W))
		{
			player.camera.position.x += Math.sin(Math.toRadians(player.camera.rotation.x)) * 0.09f;
			player.camera.position.z -= Math.cos(Math.toRadians(player.camera.rotation.x)) * 0.09f;
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_S))
		{
			player.camera.position.x -= Math.sin(Math.toRadians(player.camera.rotation.x)) * 0.09f;
			player.camera.position.z += Math.cos(Math.toRadians(player.camera.rotation.x)) * 0.09f;
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_A))
		{
			player.camera.position.x += Math.sin(Math.toRadians(player.camera.rotation.x - 90)) * 0.09f;
			player.camera.position.z -= Math.cos(Math.toRadians(player.camera.rotation.x - 90)) * 0.09f;
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_D))
		{
			player.camera.position.x -= Math.sin(Math.toRadians(player.camera.rotation.x - 90)) * 0.09f;
			player.camera.position.z += Math.cos(Math.toRadians(player.camera.rotation.x - 90)) * 0.09f;
		}
		if (dx != 0)
			player.camera.rotation.x += dx / 2.5f;
		if (dy != 0)
			player.camera.rotation.y += dy / 2.5f;

		player.camera.lookThrough();
		
		GL11.glBegin(GL11.GL_QUADS);
		GL11.glColor3f(1.0f, 1.0f, 0.0f);
			GL11.glVertex3f(1.0f, 1.0f, -1.0f);
			GL11.glVertex3f(-1.0f, 1.0f, -1.0f);
			GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
			GL11.glVertex3f(1.0f, 1.0f, 1.0f);
			GL11.glColor3f(1.0f, 0.5f, 0.0f);
			GL11.glVertex3f(1.0f, -1.0f, 1.0f);
			GL11.glVertex3f(-1.0f, -1.0f, 1.0f);
			GL11.glVertex3f(-1.0f, -1.0f, -1.0f);
			GL11.glVertex3f(1.0f, -1.0f, -1.0f);
			GL11.glColor3f(1.0f, 0.0f, 0.0f);
			GL11.glVertex3f(1.0f, 1.0f, 1.0f);
			GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
			GL11.glVertex3f(-1.0f, -1.0f, 1.0f);
			GL11.glVertex3f(1.0f, -1.0f, 1.0f);
			GL11.glColor3f(1.0f, 1.0f, 0.0f);
			GL11.glVertex3f(1.0f, -1.0f, -1.0f);
			GL11.glVertex3f(-1.0f, -1.0f, -1.0f);
			GL11.glVertex3f(-1.0f, 1.0f, -1.0f);
			GL11.glVertex3f(1.0f, 1.0f, -1.0f);
			GL11.glColor3f(0.0f, 0.0f, 1.0f);
			GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
			GL11.glVertex3f(-1.0f, 1.0f, -1.0f);
			GL11.glVertex3f(-1.0f, -1.0f, -1.0f);
			GL11.glVertex3f(-1.0f, -1.0f, 1.0f);
			GL11.glColor3f(1.0f, 0.0f, 1.0f);
			GL11.glVertex3f(1.0f, 1.0f, -1.0f);
			GL11.glVertex3f(1.0f, 1.0f, 1.0f);
			GL11.glVertex3f(1.0f, -1.0f, 1.0f);
			GL11.glVertex3f(1.0f, -1.0f, -1.0f);
			GL11.glColor3f(1.0f, 1.0f, 1.0f);
		GL11.glEnd();



I've made other 3D games with similar camera setups so I really have no clue what's going wrong with this. I've tried comparing the code between games and I can't find anything that's different about them that would cause this. Can anyone help me out? These are the only portions of code that I can think of that could possibly be causing this.

I’ve made other 3D games with similar camera setups so I really have no clue what’s going wrong with this. I’ve tried comparing the code between games and I can’t find anything that’s different about them that would cause this. Can anyone help me out? These are the only portions of code that I can think of that could possibly be causing this.

Hmm, I think you need to change


glRotatef(-rotation.y, 1f, 0f, 0f); //Pitch

to


glRotatef(-rotation.y, (float) Math.cos(rotation.x), 0f, (float) Math.sin(rotation.x)); //Pitch

I’m pretty bad at explaining things, but here we go: Looking up/down is a rotation around the x axis in your local space, but after you rotate around the y axis for the yaw rotation your x and z axes are not in your local space, but world space. You need to rotate your x axis by yaw to get them in world space, and rotating the x axis by yaw is cos(yaw), 0, sin(yaw).

You need to do something similar to get roll to work correctly, but you usually don’t need roll and you can’t do it with single cosines and sines.

EDIT: What I mean by “can’t do it with single cosines and sines” is your axis becomes something like cos(pitch)*sin(yaw), sin(pitch), cos(pitch)*cos(yaw)

http://forum.lwjgl.org/index.php?topic=5962.msg31941#msg31941

I have already requested that the moderators take down that post, no point in posting it here. :stuck_out_tongue:

This is the result I receive from doing what was suggested. I’m not sure that this is right, because it seems that the cube is following the wave of a sin graph which causes this wacky behavior. It’s really strange that this is occurring, because the last 3D game I made used a camera that worked fine and didn’t require any trig in the rotation functions.

No, please don’t take down the solution to your problem. Oh, you’re so mean… :’(

Oh my bad, I didn’t even read the response fully last night as it was late. I requested that it not be deleted, however I initially sent the request because I believed this to be a better place for the question.

Okay, not going to lie…I solved it and it was really simple. And the answers everyone else has been trying to give me way over-complicated the simple issue…

In the code where I do the translation/rotation:


glLoadIdentity();
glRotatef(rotation.x, 0f, 1f, 0f); //Yaw
glRotatef(-rotation.y, 1f, 0f, 0f); //Pitch
glRotatef(rotation.z, 0f, 0f, 1f); //Roll
glTranslatef(-position.x, -position.y, -position.z);

The simple problem that was overlooked that was the sole cause of the issue: Pitch should always be rotated first, followed by yaw and roll.


glLoadIdentity();
glRotatef(-rotation.y, 1f, 0f, 0f); //Pitch rotated first
glRotatef(rotation.x, 0f, 1f, 0f); //Yaw
glRotatef(rotation.z, 0f, 0f, 1f); //Roll
glTranslatef(-position.x, -position.y, -position.z);

That’s all it was. Problem solved. :point:

^ damn I was just about to say that.