AndrewVS2013
AndrewVS2013

Reputation: 658

Rotating object along all 3 axes to map to the player's camera LookAt vector

I have a simple 3D LookAt vector, and I wish to rotate the player model (a simple cube) to show where the player/cube is looking at.

For sideways camera movement I've managed to figure it out and do the following:

 glTranslatef(position.x, position.y, position.z);
 glRotatef(atan2(lookAt.z, lookAt.x) * 180 / PI, 0, 1, 0);

Now I know that to get up-down camera movement to map to the rendered cube model, I need to rotate the cube around it's x and z axes as well, but I can't seem to figure out what formula to use for those two.

Upvotes: 1

Views: 550

Answers (2)

Jorge Rodriguez
Jorge Rodriguez

Reputation: 613

If you're familiar with matrix math, matrices are an easier way to think about it. If you're not familiar with matrices, this series explains how to use them to solve common game development problems: https://www.youtube.com/playlist?list=PLW3Zl3wyJwWNQjMz941uyOIq3Nw6bcDYC Getting good with matrices is a good idea if you want to be a 3D game programmer.

For your problem, you want to make a translation/rotation matrix which will transform the box to the proper place for you. You can make a translation matrix and a rotation matrix individually, and then at the end take the product of the two. I'll try to break that down.

The translation matrix is simple, if your position is then your matrix will be

To construct a rotation matrix, you need to rotate the standard basis vectors the way you want. Then when you create a matrix from those rotated basis vectors, the matrix will rotate other vectors in the same way. As an example of that, take the standard basis vectors:

Now I'm going to rotate and around by 90 degrees clockwise:

Now put them into a matrix:

and you have R is a matrix that rotates things around by 90 degrees.

In your case you want to rotate stuff such that it faces a vector that you provide. That makes things easy, we can calculate our basis vectors from that vector. If your vector is then and we can solve for the other two basis vectors using cross products. You know that the character won't ever roll their view (right?) so we can use the global up vector as well. I'll call the global up vector . In your case you're using y as the "up" dimension so the global up vector will be

Then:

In the first line you do a cross product between the view vector and the up vector to get a vector orthogonal to both - this will serve as the third basis vector after it is normalized, which is the second line. In the third line another cross product generates the second basis vector. These three vectors represent what happens when the standard basis vectors are rotated the way you want them to be. Use them as the columns in a matrix like so:

Now the last step in the math is to make a final matrix that will do both translation and rotation, and this step is easy:

Then load that matrix into OpenGL with glLoadMatrix:

glLoadMatrixf(&M);

All of this gets explained in the video series I linked as well :)

Upvotes: 1

mufnull
mufnull

Reputation: 341

OpenGL will rotate the whole coordinate system (whole space, not only a cube) so after first rotation you just need to rotate only around z axis.

// first rotation
glRotatef(-atan2(lookAt.z, lookAt.x) * 180 / PI, 0, 1, 0);
// second rotation    
float d = sqrt(pow(lookAt.x,2) + pow(lookAt.z,2));
float pitch = atan2(lookAt.y, d);
glRotatef(pitch * 180 / PI, 0, 0, 1);

First and second rotation:

first and second rotation

I assume your model is looking along x axis (red arrow). I also assume lookAt is given relative to the position of the model.

Upvotes: 1

Related Questions