# Create a fly camera with lookAt

I want to create a free cam with the lookAt matrix in OpenGL. I just made the control with W, A, S and D so you can move around. But now I nee to look around. I thought doing that with sine and cosine on the target of lookAt, and it's partially working. But the problem is the input. I just don't know how to use the mouse coordinates(btw the mouse is fixed) to move the target or how to prepare the coordinates for sine and cosine.

Is there any example of what I'm looking for?

• Why do you need to use lookAt? For a free camera I would just create the transformation matrix myself. – Gigo Aug 5 '13 at 13:36
• What are you trying to do? Lookat is useful if you want the camera to be focused on some point, and just spin around it, but if you want more of an FPS camera I always found translate & rotate (pitch,yaw) to be easier. – Will Aug 5 '13 at 13:37

As my previous answer got a downvote because it was too code-heavy I'll explain a little more:

For a camera which is not locked to any target point you should not use lookAt but rather compute the camera transformation matrix yourself.

You will need a camera position (x,y,z) and at least two rotation angles (i.e. pitch and yaw). To get the full tranformation matrix you multiply a translation matrix and one rotation matrix for each angle together, but as matrix multiplication is not commutative the order is important here. You can either first rotate and then translate, or the other way around, which yields totally different results. To understand the behavior I suggest just messing around with the order, but for a typical first person camera you will want to translate first and then rotate.

To achieve the correct movement of the camera you need to do two things:

• First you need to capture the mouse delta, i.e. the mouse movement since the last time you checked for mouse movement and add these up to your rotation angles. Additionally you may want to incorporate some kind of mouse speed multiplier here.
• Second you need to apply movement to the camera position correctly. This gets a little tricky as soon as the angles are not zero anymore, because movement is not along any of the axis. You will need to calculate the correct movement direction using the current rotation angles and some trigonometry. Here you may want to add some movement speed multiplier.

I hope that cleared things up a bit, and gives more insight into what my code actually does.

I would suggest not using lookAt and just creating the transformation matrix yourself. I did that a while ago in C# using DirectX, but I think it's self-explanatory what happens here:

public void ApplyFreeLookCamera(Context ctx)
{
if (Enabled)
{
HandleInput(ctx);
}
Vector3 transPos = GetPosition();
transPos.Multiply(-1);
Matrix view = Matrix.Translation(transPos);
view *= Matrix.RotationY(Yaw);      // left-right rotation
view *= Matrix.RotationX(Pitch);    // up-down rotation
view *= Matrix.RotationZ(Roll);     // ah snake, snaaake!
ctx.Graphics.Transform.View = view;
}


And to handle input something like that:

private void HandleInput(Context ctx)
{
// calculate movement direction
var distance = MovementSpeed * ctx.FrameSeconds;
var dx = (float)Math.Sin(Yaw) * distance;
var dz = (float)Math.Cos(Yaw) * distance;
//float dy = (float)Math.Sin(Pitch) * distance;
var movement = new Vector3();
// check keys
if (ctx.Input.KeyPressed(Constants.CameraForward))
{
movement.X -= dx;
movement.Z += dz;
}
if (ctx.Input.KeyPressed(Constants.CameraBackward))
{
movement.X += dx;
movement.Z -= dz;
}
if (ctx.Input.KeyPressed(Constants.CameraLeft))
{
movement.X -= dz;
movement.Z -= dx;
}
if (ctx.Input.KeyPressed(Constants.CameraRight))
{
movement.X += dz;
movement.Z += dx;
}
if (ctx.Input.KeyPressed(Constants.CameraUp))
{
movement.Y += distance;
}
{
movement.Y -= distance;
}

• Ok, know I did something like this: glm::translate(glm::mat4(), this->mMainCamera.position) * glm::rotate(glm::mat4(), this->mMainCamera.target.x, glm::vec3(1,0,0)) * glm::rotate(glm::mat4(), this->mMainCamera.target.y, glm::vec3(0,1,0)) * glm::rotate(glm::mat4(), this->mMainCamera.target.z, glm::vec3(0,0,1)) But the problem is, that whem I'm rotating the camera, it is rotation around the origin. But I did the exact same thing on my model transformations. ?! – Liess Jemai Aug 5 '13 at 15:53