The second type of camera usually found in games is a simple look-at camera. It is defined by the following:

A position in space.

An up vector. Think of this as an arrow coming out of the top of your skull, pointing in the direction of the top of your skull.

A look-at position in space or alternatively a direction vector. We'll use the former.

A field of view in degrees.

A viewport aspect ratio.

The only difference from the Euler camera is the way we encode the orientation of the camera. In this case we specify the orientation by the up vector and the look-at position. Let's write a helper class for this type of camera. Listing 11-11 shows you the code.

Listing 11-11. LookAtCamera.java, a Simple Look-At Camera Without Bells and Whistles package com.badlogic.androidgames.framework.gl;

import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLU;

import com.badlogic.androidgames.framework.math.Vector3;

public class LookAtCamera { final Vector3 position; final Vector3 up; final Vector3 lookAt; float fieldOfView; float aspectRatio; float near; float far;

public LookAtCamera(float fieldOfView, float aspectRatio, float near, float far) { this.fieldOfView = fieldOfView; this.aspectRatio = aspectRatio; this.near = near; this.far = far;

position = new Vector3(); up = new Vector3(0, 1, 0); lookAt = new Vector3(0,0,-1);

public Vector3 getPosition() { return position;

public Vector3 getUp() { return up;

public Vector3 getLookAt() { return lookAt;

public void setMatrices(GL10 gl) {

gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity();

GLU.gluPerspective(gl, fieldOfView, aspectRatio, near, far);

gl.glMatrixMode(GL10.GL_MODELVIEW);

gl.glLoadIdentity();

GLU.gluLookAt(gl, position.x, position.y, position.z, lookAt.x, lookAt.y, lookAt.z, up.x, up.y, up.z); }

No real surprises here. We just store the position, up, and lookAt values as Vector3 instances along with the perspective projection parameters we also had in the EulerCamera. Additionally, we provide a couple of getters so we can modify the attributes of the camera. The only interesting method is setMatrices(). But even that is an old hat for us. We first set the projection matrix to a perspective projection matrix, based on the field of view, aspect ratio, and near and far clipping plane distances. Then we set the model-view matrix to contain the camera position and orientation matrix via gluLookAt() as discussed in the previous chapter. This will actually produce a matrix very similar to the matrix we "handcrafted" in the EulerCamera example. It will also rotate the objects around the camera instead of the other way around. However, the nice interface of the gluLookAt() method shields us from all those silly things like inverting positions or angles.

We could in fact use this camera just like an EulerCamera. All we need to do is create a direction vector by subtracting the camera's position from its look-at point and normalizing it. Then we just rotate this direction vector by the yaw and pitch angles. Finally we set the new look-at to the position of the camera and add the direction vector. Both methods would produce exactly the same transformation matrix. It's just two different ways to handle camera orientation.

We'll refrain from writing an explicit example for the LookAtCamera, as the interface is perfectly simple. We'll use it in our last game in this book, were we let it follow a neat little space ship! If you want to play around with it a little, add it to the LightTest we wrote earlier or modify the EulerCameraTest in such a way that the LookAtCamera can be used like a first-person-shooter camera, as outlined in the previous paragraph.

Was this article helpful?

## Post a comment