Math Magician – LookAt Algorithm

W00t! 2,000 views on the blog today! Probably most are spammers, but who cares? Still a victory!

Anyway, What I’m going to do is use this blog to not only rant about useless stuff I find interesting, but to also store code snippets and algorithms for later use in applications and such. And I guess I’ll share them too.

So, today, since it’s been a few years since College, I’m going to bone up on some of my math. I’m going to do a step-by-step of the LookAt Algorithm.

Variables

First, we have our object that’s doing the looking. Since the most common usage of the LookAt algorithm is for cameras, lets call it camera.

camera is simple; it only contains a 4×4 Matrix which contains the camera’s orientation and position in the world. We’ll call this variable orientation;

So we have camera and camera.orientation.

LookAt Function

The LookAt function prototype is fairly straight-forward.

void LookAt(Matrix4& orient, const vec3& target, const vec3& Up);

Nothing scary; the Matrix4& orient is the matrix we’re modifying, and the vec3& target is the position of what we want to look at. The vec3& Up is our worlds’ Up vector, which is normally {0, 1, 0}. So, if we know this, why pass it in? Because not every situation will have the same Up vector! Maybe this isn’t a camera doing the looking, but the head on a model. Or maybe this is Super Mario Galaxy!

 

Where is your Up now?

Before we start, Here’s an easy breakdown of the matrix, so I don’t confuse anyone with terminology. You should have a general concept of Linear Algebra and Trigonometry if you’re trying to pull this off.

{Xx     Xy     Xz     Xw} <- X Axis
{Yx     Yy     Yz     Yw} <- Y Axis
{Zx     Zy     Zz     Zw} <- Z Axis
{Wx     Wy     Wz     Ww} <- W Axis

Now it’s time to break down the algorithm.

Step 1: First, we create a vec3 called ZAxis. This is a vector pointing to our target’s position from our camera’s position, which is stored in the W Axis of the orient matrix. Afterwards, we normalize the vector.

vec3 ZAxis = target - orient.WAxis();
ZAxis.normalize();

Step 2: Now we create the vector XAxis and initialize it to the cross product of the Up vector crossed with the ZAxis we just made. Then we normalize that, too.

vec3 XAxis = CrossProduct(Up, ZAxis);
XAxis.normalize();

Step 3: Next, we create the vector YAxis, and initialize that to the cross product of ZAxis crossed with XAxis. Then, you guessed it: normalize the sucker.

vec3 YAxis = CrossProduct(ZAxis, XAxis);
YAxis.normalize();

Step 4: Finally, we set all of orient‘s axises with the corresponding ones we just created, and there! We now have a Stalking Matrix — err, I mean, uhh, a LookAt Matrix.

orient.XAxis(XAxis);
orient.YAxis(YAxis);
orient.ZAxis(ZAxis);

All Together Now!

vec3 ZAxis = target - orient.WAxis();
ZAxis.normalize();
vec3 XAxis = CrossProduct(Up, ZAxis);
XAxis.normalize();
vec3 YAxis = CrossProduct(ZAxis, XAxis);
YAxis.normalize();
orient.XAxis(XAxis);
orient.YAxis(YAxis);
orient.ZAxis(ZAxis);

There. Simple, right? I’ll post up more code snippets over time, usually whenever I feel like it.

And on that note, Tootles!

(Yeah, I couldn’t think of a witty way to end the post. Big Whoop. Wanna fight about it?)

Advertisements

Published by

KeithM

Computer Scientist for Engility, and Indie Game Dev from New Jersey. Loves playing games, and loves making them, too.

5 thoughts on “Math Magician – LookAt Algorithm”

  1. Hi,
    Suppose that the lookAt vector is 0,0,1 (World Z Axis) and the camera up vector is 0,1,0 (World Y Axis ), in order to calculate the camera coodrinates we do the following:
    1- Camera Z axis: is the lookAt vector
    2- Camera X axis: is the cross product of the lookAt and the Camera up vector
    3- Camera Y axis: is the Cross product of Camera X and Camera Z
    Now assume that the camera up vector is tilted a little in the YZ plane so it is 0,1,1, now the cross product of the lookAt and the up vector will give a vector in the same direction as the case when the camera up vector was 0,1,0 so the camera Y axis will have the same direction as the camera up vector 0,1,0 case. Then the rotation matrix that transfers from the wrold coordinates to camera coordinates will have the same values. whic will give a similar view as if the camera is not tilted.
    If this is true then there is something wrong, because when the camera is tilted the view should change. What is wrong in my understanding?

  2. There’s one special case, though. If the camera to target direction aligns with the up vector parameter, should you use the global x-axis or y-axis and cross it with the new z-direction to find the new y-axis or x-axis respectively as a workaround on this dilemma?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s