# LookAt rotation matrix computation

This topic is 4090 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

How can I calculate a rotation matrix given a Position and ViewVector?

##### Share on other sites
Depending on the type of coordinate system and vectors you're using, take a look at the documentation for D3DXMatrixLookAtLH (left-handed, row vectors), D3DXMatrixLookAtRH (right-handed, row vectors), and gluLookAt (right-handed, column vectors). They all contain some matrix diagrams showing you how to construct the matrix. If you're looking more for why's than how's, then ask away. Note that I didn't reference anything for left-handed, row vector configurations, because then you're just asking for trouble [smile]

##### Share on other sites
Thanks Zipster, but I have a few more questions.
I'm crating a camera class, and I use Euler angles. Since I want a FPS-like camera I use only 2 angles: angle around X axis and angle around Y axes.
I need to have a function that passed in EyePos and ViewPoint would return a matrix with rotation and translation, that will orient/translate the scene correctly. I can use the gluLookAt function or the code to actually create the matrix, but there are problems. Whenever I look down th positive or negative Y axis(something like this:
gluLookAt(eye.x, eye.y, eye.z, eye.x, eye.y+1/eye.y-1, eye.z, 0, 1, 0))
problems occur. I'm using an Up vector that points dirrectly up ((0,1,0) that is) and because of this the 3 vectors will not create a 3D orthogonal system, because the up vector will be the same or opposite with the view vector.
How can I go arround this? How can I solve this and not use quaternions?

##### Share on other sites
If your eye vector and up vector are parallel (as in this case), simply use a different vector for 'up'. (0,0,-1), for example.

##### Share on other sites
That's one reason why I don't use LookAt-style methods for creating my view transformations, because you have to pick some magic up vector and hope your view is never parallel to it.

Instead of constructing the view matrix directly, what I usually do is construct it from three Euler angle rotations for yaw, pitch, and roll. Since you're not using roll, this boils down to a single matrix multiplication, which you can expand explicitly to avoid the matrix multiplication. It's better than using LookAt functions since you already have Euler angles to begin with. So take a Y-axis rotation matrix RY (yaw) and an X-axis rotation matrix RX (pitch) and expand out RXRY (for column vectors) or RYRX (for row vectors).

##### Share on other sites
The up vector you select is niether magical, nor arbitrary... it defines the upward direction of the view space in the world space. If the view vector (also in world space) is (0,1,0), then obviously "up" should not be the same vector.

##### Share on other sites
Exactly, and then you have a degenerate case to deal with [smile] Especially so in an FPS, where the player looking straight up or straight down is quite common. So I'll concede it's not as much arbitrary or magical as it is problematic in those cases.

##### Share on other sites
Thanks for the replies guys, I've managed to get around the degenerate case.

##### Share on other sites
If you use the up vector from the last frame, you're quite unlikely to bump into the degenerate case. That is unless you can spin 90 degrees in a single frame, which I find unlikely in any game. And if it did happen, you could then use the forward vector from the prior frame to construct the matrix.

##### Share on other sites
void	Matrix4x4::BuildLookAtMatrix(float posx,float posy,float posz,float eyex,float eyey, float eyez,float upx,float upy, float upz){   float x[3], y[3], z[3];   float mag;   z[0] = eyex - posx;   z[1] = eyey - posy;   z[2] = eyez - posz;   mag = sqrt( z[0]*z[0] + z[1]*z[1] + z[2]*z[2] );   if (mag>.0001)    {  	  mag	=	1/mag;      z[0] *= mag;      z[1] *= mag;      z[2] *= mag;   }   y[0] = upx;   y[1] = upy;   y[2] = upz;   x[0] =  y[1]*z[2] - y[2]*z[1];   x[1] = -y[0]*z[2] + y[2]*z[0];   x[2] =  y[0]*z[1] - y[1]*z[0];   y[0] =  z[1]*x[2] - z[2]*x[1];   y[1] = -z[0]*x[2] + z[2]*x[0];   y[2] =  z[0]*x[1] - z[1]*x[0];   mag = sqrt( x[0]*x[0] + x[1]*x[1] + x[2]*x[2] );   if (mag > .0001)    {	  mag	=	1/mag;      x[0] *= mag;      x[1] *= mag;      x[2] *= mag;   }   mag = sqrt( y[0]*y[0] + y[1]*y[1] + y[2]*y[2] );   if (mag > .0001)    {	  mag = 1/mag;	  y[0] *= mag;      y[1] *= mag;      y[2] *= mag;   }#define M(row,col)  mat[row][col]   M(0,0) = x[0];  M(0,1) = x[1];  M(0,2) = x[2];  M(0,3) = -x[0]*eyex + -x[1]*eyey + -x[2]*eyez;   M(1,0) = y[0];  M(1,1) = y[1];  M(1,2) = y[2];  M(1,3) = -y[0]*eyex + -y[1]*eyey + -y[2]*eyez;   M(2,0) = z[0];  M(2,1) = z[1];  M(2,2) = z[2];  M(2,3) = -z[0]*eyex + -z[1]*eyey + -z[2]*eyez;   M(3,0) = 0.0;   M(3,1) = 0.0;   M(3,2) = 0.0;   M(3,3) = 1.0;#undef M	}

##### Share on other sites

This topic is 4090 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628676
• Total Posts
2984179

• 13
• 12
• 9
• 10
• 10