PDA

View Full Version : 3D Camera movement??

jaymystro
12-21-2005, 12:31 PM
hi there, I am trying to get a camera working in 3D so i can freely navigate a room. This is how I have set it up so far. My WM_SIZE function hold the perpective operations etc....

glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
//sets projection matrix
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 1.0f, 100.0f);

glMatrixMode(GL_MODELVIEW);

OK so the rest of it is really just the render function and the input funciton...

//Variables for tranlation and rotation
GLfloat planeZ = -4.0f;
GLfloat yRotate = 0.0f;

//sets initial camera location to -4 so you can see the scene.
glTranslatef(0.0, 0.0, planeZ);

Then the input function is..

if([VK_UP])
planeZ += (0.1f);

Now, i have a simple object located at the origin of the scene(0,0,0). When up is pressed, the camera moves forward, but when it passes the object and you turn around, forward now moves backwards and vice versa. I understand I must use vector manipulation to achive efficent and proper camera manipulation, but none of the many tutorials on the web want to explain any of this. There examples work well but the code is not explained, and im not in to taking peoples code. Even if its free, i need to understand how it works.

Also I have tried LookAt but same results.
One more thing, it will only tranlate in a straight line even once i rotate. Can thi be fixed by modifying the up vector of a LookAt function.

Ehsan Kamrani
12-21-2005, 11:33 PM
Have you used from the glRotate() funcion in your code? What's the variable yRotate ?
-Ehsan-

12-22-2005, 10:59 AM
i need help
that is if any body have an opengl code for
-moving hilicophter
-moving robot arm
-somthing like paitn program paint program

Thanks evrybody

jaymystro
12-23-2005, 09:46 AM
i am using the rotate to just rotate the camera, i have used it and it works but i just forgot to type it. Does my setup look ok? It still only wants to translate on the one fixed line. strange. Also can anyone explain how the cos and sin functions actually apply when rotating. I know the basics but not all. thanks

GMan
12-23-2005, 03:45 PM
Hey, I'm currently having trouble on this subject as well, and I think I've come pretty close to solving it. Here is what I have:

BTW: It uses SIN and COS so make sure to put
#include <math.h> at the beginning.

//I will be using the glLookAt(); so x1 and z1 are
//for camera position and x2 and z2 are for the
//point the camera is looking at
float x1=0.0, z1=2.0, x2=0.0, z2=0.0;
float angle=0.0;

//In display function
gluLookAt(x1, 0.0, z1,
x2, 0.0, z2,
0.0, 1.0, 0.0);

//if player is moving forward
x1 += sin(angy)*0.1;
x2 += sin(angy)*0.1;
z1 -= cos(angy)*0.1;
z2 -= cos(angy)*0.1;

//if player is moving forward just switch the +'s
//to -'s and -'s to +'s.

//if player is rotating to the left
angle -= 0.1;
x2 = sin(angy);
z2 = cos(angy);

//same thing if rotating right, except switch the
// "angle -= 0.1;" to "angle += 0.1;"

That's what I have. It works perfectly for movement. For example at first when you move forward it moves in the -z direction which is correct, then If I rotate 180 degrees, forward will move the camera in the +z direction. So the translations are correct but for some reason the camera is always looking down the -z direction. I'm not sure why.

If anyone can think of how to fix this, or just a better way of doing it please let me know.

K A Z E
12-24-2005, 03:03 PM
I think the reason your camera is always looking at one place is because of this:

angle -= 0.1;
x2 = sin(angy);
z2 = cos(angy);

First of all, "angle" is the variable that's changed by the rotation and the code that changes your x2 and z2 uses "angy". Second, assuming that was just a typo or you fixed it, if you tried to rotate 180 degress to be facing opposite of what you originally do, the angle would be equal to pi, and the sin of pi radians is 0, and the cos is -1. So if you inserted those values into gluLookAt, you would be looking at the point (0, 0, -1). And at any given time, based on your rotation, your x2 and z2 would always be between -1 and 1, so you would always be looking at a point near 0, 0, 0. So it should be more like this:

x2 = sin(angle+pi) + x1
z2 = cos(angle+pi) + z1

The reason I'm adding pi to the angle is because by default you start off looking into the negative z axis. And I'm assuming the program starts off with your angle at 0. Except the cos of 0 is 1. By adding pi to the angle it makes it -1. Of course if you wanted you could not add pi and start off facing 0, 0, 1. But then you'd need to modify your movement to add cos(angy)*0.1 to the z instead of subtract.

Okay... I think all of the above is right... I get confused by all these angles and rotations too. Tricky stuff =). Hope that helps.

GMan
12-25-2005, 07:51 AM
Thank you K A Z E, That really helped. That makes the rotations correct, however after rotating it doesn't always translate the right way.

also, the 'angy' was a typo.

K A Z E
12-25-2005, 05:05 PM
Okay, I think what the problem is is that you actually ARE moving the right direction, you're just not facing it. I messed up on this part:

x2 = sin(angle+pi) + x1
z2 = cos(angle+pi) + z1

x2 should actually equal sin(angle) + x1, w/o adding the pi. Only the z2 should be like that because counting 0, 0, -1 as 0 degrees means the z axis is basically inverted. Also, alternatively, you could do:

z2 = -cos(angle) + z1 and it should work too. And I would think that way might be a little more accurate since you don't add a truncated version of pi.

Okay, now I think that's right, but I could be wrong again. =)

GMan
12-26-2005, 01:09 PM
Yes that makes it work perfectly. OK then, here is the final version of it:
remember to #include <math.h>

//when moving forward
x1 += sin(angle)*0.1;
x2 += sin(angle)*0.1;
z1 -= cos(angle)*0.1;
z2 -= cos(angle)*0.1;

//backward is same except change + to - and - to +

//when turning left
angle -= 0.1;
x2 = sin(angle) + x1;
z2 = -cos(angle) + z1;

//to turn right change 'angle -= 0.1;' to 'angle += 0.1;'.

that will make it move in the x and z axis at least. Also, in the moving portion where it does the calculation 'sin(angle)*0.1' twice, it might be more efficient to have it perform the calculation once and assign the value to a variable then use that instead.

[EDIT]
sorry I forgot to mention this, just to clarify.
x1 and z1 are the camera positions and x2 and z2 is the point the camera is facing. So the command should then look like this:

gluLookAt(x1, 0.0, z1, x2, 0.0, z2, 0.0, 1.0, 0.0);