Archived

This topic is now archived and is closed to further replies.

messiah2k

camera movement or world movement

Recommended Posts

messiah2k    122
Hello I''m new with OpenGL. I have been working a bit on a program that lets you move freely in 3D space. Iv''e read in many places that you should move the world around you rather then the camera itself. Iv''e tried to do this using the following commands. GLTranslatef(xpos, ypos, zpos); //Can''t remeber the exact GLRotatef(xrot, yrot, zrot); //syntax Iv''e got the translate part to work but rotates get all mixed upp when you fly around and change many ?rot att once. I guess you need to do quite a lot of calculating here since the cameras system is always fixed cause you never move the cameras angeles. My question is if i''m on the right track or is it better to move the camera around. If anyone could give me some gidelines or some example codes i would be very happy. Is world movement realy that mush faster? //Messiah

Share this post


Link to post
Share on other sites
zedzeek    529
speed is the least of your concerns
i think the problems u are having are to do with ''gimbal lock'' google it and u will prolly also find a solution

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
You do need some sines and cosines for moving in 3D space, not just for viewing.
You need three variables: Pitch, Yaw, and Roll. Pitch is looking up and down, Yaw is right and left, and Roll is like popping your eyeballs out and turning them upside down (only games with flying vehicles use Roll).

Each variable is an angle between 0 and 360.
To set the camera up correctly, all you have to do is:

glRotatef(Pitch, 1.0f, 0.0f, 0.0f);
glRotatef(Yaw, 0.0f, 1.0f, 0.0f);
glRotatef(Roll, 0.0f, 0.0f, 1.0f);

glTranslatef(CameraX, CameraY, CameraZ);

Note: If you use -Pitch instead of Pitch, you get an inverse Y axis (up looks down and vice-versa).

Now, to actually move in 3D space is a different story. First, I wrote new sin and cos functions to use degrees instead of radians.

Here they are:

#define PI 3.141592654
#define DEG2RAD ((2*PI)/360)

GLfloat CosDeg(GLfloat Angle)
{

return ((GLfloat)cos( Angle*DEG2RAD) );

}

GLfloat SinDeg(GLfloat Angle) {

return ((GLfloat)sin( Angle*DEG2RAD) );

}

I won''t go into the math of moving forward in 3D space, but it''s pretty simple.

void MoveForward(GLfloat Distance)
{

GLfloat TempAngle;

Distance = (GLfloat)fabs(Distance);
Distance = -Distance;

TempAngle = 90 - Yaw;

CameraX += ( (CosDeg(TempAngle)*Distance) );
CameraY += ( (SinDeg(Pitch)*Distance) );
CameraZ += ( -(SinDeg(TempAngle)*Distance) );

}

If you want to move backwards, just remove the
Distance = -Distance. To move side to side (strafing), use this code:

void MoveLeft(GLfloat Distance)
{

Distance = (GLfloat)fabs(Distance);

CameraX += ( (CosDeg(Yaw)*Distance) );
CameraZ += ( (SinDeg(Yaw)*Distance) );

}

Stick a Distance = -Distance in there to move right.

Hope this helps!

Share this post


Link to post
Share on other sites
messiah2k    122
Thank you everybody. Iv''e got the forward movement to work using trigonometric calculations simular to the ones above. I looked up the gimbal lock thing and understood the problem you get with Eulers representation. So I guess I will have to look into using quaternions ? If anyone is a expert on this I would appreciate some example code on this =)
//messiah

Share this post


Link to post
Share on other sites
Lev Povalahev    122
quote:
Original post by Nazrix
I am rather new to OGL but is it not better to use the Lookat() function directly rather than rotating the world around the camera?



There is no difference gluLookAt composes a modelview matrix which rotates and moves the "world" as required. So do the routines
glRotate/glTranslate. You can also compose the matrix manually, which gives you much more control once you''ve understood how things work.

-Lev

Share this post


Link to post
Share on other sites
guille    122
using quaterions, here is the code to create a rotation matrix given and angle (radians) and an axis of rotation:
  
void vector_copy(const double *v1, double *v2); //copy v1 in v2

double vector_length(const double *v); //length of v

void vector_scale(double *v, double div); //v*div

void vector_normal(double *v); //normalize v


// build the quaternion, given an angle and an axis

void axis_to_quat(double a[3], double phi, double q[4])
{
vector_normal(a);
vector_copy(a,q);
vector_scale(q,sin(phi/2.0));
q[3] = cos(phi/2.0);
}
// build a rotation matrix given a quaternion

void quat_to_matrix(double m[4][4], double q[4])
{
m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]);
m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]);
m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]);
m[0][3] = 0.0;

m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]);
m[1][1]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]);
m[1][3] = 0.0;

m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]);
m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]);
m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]);
m[2][3] = 0.0;

m[3][0] = 0.0;
m[3][1] = 0.0;
m[3][2] = 0.0;
m[3][3] = 1.0;


}

void build_rotmatrix(double angle, double axis[3], double rot_matrix[4][4])
{

double q[4];

vector_normal(axis);
axis_to_quat(axis, angle,q);
quat_to_matrix(rot_matrix, q);
}


g

Share this post


Link to post
Share on other sites