# How do I determine the look-at vector of a free-look camera?

I'm trying to create a free-look camera with DirectX 10.

I've figured out how to get the directions for forward and back and left to right. However, I don't know how to rotate the look-at vector of my view matrix around the camera position so as to rotate in-place. How can I do this?

• Not related to your question, but I always have to ask: why Direct3D 10? 11 works on every OS that 10 does, has more features, a similar API to make porting to it easy, and supports all the same hardware levels. There's zero reason I can think of to use D3D 10 ever. Mar 3, 2014 at 20:45
• @SeanMiddleditch one reason i would give is that the programmer's hardware doesn't support dx11.so he/she cant test things made. That is the case with me, at least.😜 Nov 29, 2014 at 17:08
• @TheLightSpark: DX11 feature levels make hardware support a non-issue: msdn.microsoft.com/en-us/library/windows/desktop/… Jan 28, 2015 at 17:52

You need to rotate around the X axis to have "up-down rotation", Z axis if you want "roll rotation", and Y if "left-right" rotation. Rotate the "front" (or look at vector) and "up" vector around the desired axes. Make sure to rotate those vectors before translating the camera. If you applied your rotation and translation then recreate the view matrix with those values.

• well that's my problem. i don't know exactly how to rotate the look at vector around the eye vector.. like i know i could use D3DXMatrixRotateY but i don't want to rotate around the y of the look at vector, i want it to rotate around the eyes y axis.. right?
– Dave
Mar 3, 2014 at 20:55
• Your eye is a position, your lookat vector is, say pointing in the z direction(0,0,1). First you must rotate the lookat around the origin (0,0,0), then translate it with the eye position: lookat=rotate(lookat,pi/2)+eye. For the up vector you only need to rotate that. ;) Mar 3, 2014 at 21:30
• O.o sooooooo i have to normalize the lookat direction by: [code] D3DXVec3Normalize(&LookAt_Norm, &(lookAt - eye)); [/code] and then rotate it around 0??? huh.. i dont understand where you are getting the origin from.. like i understand thats dead center but whats that have to do with the center of my cameraa if my camera is not in the center of the world? sorry for my lack of understanding.. but thanks for your patience. also what's the function to rotate around a specific coord like as you say origin(0, 0, 0);
– Dave
Mar 3, 2014 at 21:36
• If you use D3DXMatrixRotateY as you said, it will most likely rotate around the origin, Just don't rotate like: rotate(camerapos+lookat,angle), but rotate(lookat,angle)+camerapos. Yes it is best to keep your lookat vector relative to your camera position. Mar 3, 2014 at 21:49
• ok so one more question. your params for rotate are not the same as MatrixRotateY. it would just create the matrix in order to rotate it. so i would use MatrixRotateY(RotateMat, 0.5f); and D3DXVec3TransformCoord(&lookAt, &lookAt, RotationMat);? how and why am i adding the camera pos? i thought its already at the correct distance and im just rotating it around the origin at the same distance?
– Dave
Mar 3, 2014 at 23:48

some link to crunch the math side if you want to prepare a one matrix that rotates about the 2 angles at once:

http://inside.mines.edu/fs_home/gmurray/ArbitraryAxisRotation/

Otherwise I personally do it this way:

void ThisApplication::UpdateClient0Positions(void)
{

Direction.x = (float)( sin(RotateCamera.x) * cos(RotateCamera.y) );
Direction.y = (float)( sin(RotateCamera.y) );
Direction.z = (float)( cos(RotateCamera.x) * cos(RotateCamera.y) );

up.x = (float)( sin(RotateCamera.x) * sin(RotateCamera.y) * -1 );
up.y = (float)( cos(RotateCamera.y) );
up.z = (float)( cos(RotateCamera.x) * sin(RotateCamera.y) * -1 );

if (Active[STRAFE_LEFT])
{
TravelCamera.x -= (float)(cos (RotateCamera.x) * g_CameraSpeed * FrameTime);
TravelCamera.z += (float)(sin (RotateCamera.x) * g_CameraSpeed * FrameTime);
}
else if (Active[STRAFE_RIGHT])
{
TravelCamera.x += (float)(cos (RotateCamera.x) * g_CameraSpeed * FrameTime);
TravelCamera.z -= (float)(sin (RotateCamera.x) * g_CameraSpeed * FrameTime);
}

if (Active[GO_FORWARD])
{
TravelCamera.x += (float)(Direction.x * g_CameraSpeed * FrameTime);
TravelCamera.y += (float)(Direction.y * g_CameraSpeed * FrameTime);
TravelCamera.z += (float)(Direction.z * g_CameraSpeed * FrameTime);
}
else if (Active[GO_BACKWARD])
{
TravelCamera.x -= (float)(Direction.x * g_CameraSpeed * FrameTime);
TravelCamera.y -= (float)(Direction.y * g_CameraSpeed * FrameTime);
TravelCamera.z -= (float)(Direction.z * g_CameraSpeed * FrameTime);
}

if (Active[JUMP])
{
TravelCamera.x += (float)(up.x * g_CameraSpeed * FrameTime);
TravelCamera.y += (float)(up.y * g_CameraSpeed * FrameTime);
TravelCamera.z += (float)(up.z * g_CameraSpeed * FrameTime);
}
else if (Active[CROUCH])
{
TravelCamera.x -= (float)(up.x * g_CameraSpeed * FrameTime);
TravelCamera.y -= (float)(up.y * g_CameraSpeed * FrameTime);
TravelCamera.z -= (float)(up.z * g_CameraSpeed * FrameTime);
}

D3DXMatrixLookAtLH (&MatView, &D3DXVECTOR3(TravelCamera.x, TravelCamera.y, TravelCamera.z),
&D3DXVECTOR3(TravelCamera.x + Direction.x,
TravelCamera.y + Direction.y,
TravelCamera.z + Direction.z),
&up);
g_pD3DDevice->SetTransform (D3DTS_VIEW, &MatView);
}

{
RotateCamera.x += MouseStt.lX * g_Sensitivity * 0.005f;
RotateCamera.y -= MouseStt.lY * g_Sensitivity * 0.005f;
}


The MouseStt comes from direct input get device state, updated by frame basis (therefore the traveled distance is accumulated correctly for the delta time, by the driver).

I've figured out how to get the directions for forward and back and left to right.

This means that you are on a home stretch😉 Just take a cross-product of your forward & right vectors to get the rotation axis. Then construct the rotation around axis quaternion and use it to rotate your view vector either by rotation matrix or just by multiplication of a vector and quaternion.

Hope this helps 🙄

P.S. looks like you can directly plug that rotation axis to XMMatrixRotationAxis method. P.P.S. for a first person camera like in most FPS games you don't have to take a cross-product, instead just use the constant <0, 0, 1> axis.