3D Camera rotating objects instead of the scene? [SOLVED]

Started by shadowstryker10, September 27, 2015, 23:57:48

Previous topic - Next topic

shadowstryker10

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).



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.

Kai

What exactly is it that you want to do?
Do you want to have a "free fly/look camera," that you can use to move around the scene freely, maybe with WSAD/mouse controls?
It looks like you maybe used the code from this: r3dux.org article, which is absolutely not suited to implement a proper free look camera.
This is due to the fact that whenever you rotate your camera, all your rotation axes must also change to remain in a camera-local coordinate frame and cannot simply be your world yaw/pitch/roll axes anymore.
So in order to do a proper free fly/look camera you need to keep track of your current rotation axes and then apply rotations to them after which you update your rotation axes again.
Currently, your rotation axes are always just (1,0,0), (0,1,0) and (0,0,1). This does not work.
You have to compute your new rotation axes whenever you apply a rotation somewhere.
So how to do this?
People generally model such cameras with "forward," "up" and (implied) "right" (or "left") vectors, which are all orthogonal to each other and thus span an orthonormal basis, which represents your rotation.
This way, whenever you rotate "to the left," you always know that you have to rotate your "forward" vector about the "up" vector (and recompute the "right" vector).
And when you rotate "up and down," you always have to rotate your "up" vector about the "right/left" vector.
For this you have to have some math functions to "rotate a vector about another vector."
Google that.
Then you can simply use "gluLookAt" to setup a view matrix based on those vectors.

emris

I would suggest you take a closer look at this .. https://www.youtube.com/watch?v=VS8wlS9hF8E&list=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP

ThinMatrix takes the extra time to explain things in detail, and he also uses the new dynamic rendering pipeline, which is awesome :).
His tutorials are not the copy/paste kind, he tries to teach you how things really work.
If you follow his tutorials you will get a working engine with third and first person camera view, lights, terrain, entities, dynamic skybox and a few other things.. all with shader support :)

He answered a ton of questions that i used to have
=====================================================
Nothing is impossible....except that the state of your mind makes it so.
=====================================================

shadowstryker10

Quote from: Kai on September 28, 2015, 09:38:58
What exactly is it that you want to do?
Do you want to have a "free fly/look camera," that you can use to move around the scene freely, maybe with WSAD/mouse controls?

Yeah, I'm trying to get a 3D camera that I will eventually implement in a 3D game similar to CS:GO. I've had games using the same rotation method I'm using here that resulted in a camera functioning the way I need it to, so I can't understand why it won't work this time. This isn't even I first 3D game, I should be able to figure this out. :(

shadowstryker10

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.   :)