PS2 Linux Programming
Moving the Camera Around
Introduction
This tutorial will describe a simple camera system for use with the PlayStation2. The analogue joy sticks are used to move the camera through a scene and rotate the direction of view as required.
Computing the View Matrix
The camera matrix is calculated every frame, based upon information input by the player. The camera code is repeated below for clarity:
// Set up a nice 3D camera
static float yrot = 0.0f;
static float xrot = 0.0f;
// Reset the camer if requested
if(pad[0].buttons & PAD_R2)
{
CamPos = Vector4(0, 0, 0, 1);
yrot = 0.0f;
xrot = 0.0f;
}
// Get any requested rotations
yrot -= pad[0].axes[PAD_AXIS_RX] * Abs(pad[0].axes[PAD_AXIS_RX]) * 0.07f;
xrot += pad[0].axes[PAD_AXIS_RY] * Abs(pad[0].axes[PAD_AXIS_RY]) * 0.07f;
// Clamp xrot to prevent going upside down.
if(xrot > ROTXMAX)
xrot = ROTXMAX;
if(xrot < -ROTXMAX)
xrot = -ROTXMAX;
// Sort out the rotations
Matrix4x4 roty, rotx;
roty.RotationY( yrot );
rotx.RotationX( xrot );
Matrix4x4 CamRot = rotx * roty;
// Transpose rotation matrix to get camera matrix
CamRot = Transpose(CamRot);
// Get the direction vectors for the camera
Vector4 vXAxis = Vector4(CamRot(0,0), CamRot(1,0), CamRot(2,0), 1);
Vector4 vYAxis = Vector4(CamRot(0,1), CamRot(1,1), CamRot(2,1), 1);
Vector4 vZAxis = Vector4(CamRot(0,2), CamRot(1,2), CamRot(2,2), 1);
// Get any requested translations
float strafe = 0.5f * pad[0].axes[PAD_AXIS_LX];
float forwards = 0.5f * pad[0].axes[PAD_AXIS_LY];
float updown = 0.5f * (pad[0].pressures[PAD_PL1] - pad[0].pressures[PAD_PL2]);
// Work out the requested move for this frame
Vector4 vReqMove;
vReqMove = vXAxis * strafe;
vReqMove += vYAxis * updown;
vReqMove += vZAxis * forwards;
// And add it to the camera position
CamPos += vReqMove;
// Finally build the camera matrix
Matrix4x4 matView;
matView.Translation(-CamPos.x, -CamPos.y, -CamPos.z);
matView = matView * CamRot;
Three variables are used to hold the camera position and orientation: CamPos is a vector which holds the camera position and xrot and yrot hold the orientation of the camera in terms of the rotation around it’s x and y axes respectively. The camera can be reset to be positioned at the origin, with zero x and y rotations by pressing R2 on controller 1. Each frame, the x and y rotation variable are updated from the position of the right hand joy stick. The xrot variable is clamped between -90 and +90 degrees to prevent the camera from turning upside down. Rotation matrices are produced from the rotx and roty angles and these are concatenated to produce the camera rotation matrix CamRot. Note that the correct rotation components of the camera matrix are obtained by transposing the rotation matrix.
From the camera rotation matrix, vectors are obtained which define the x, y and z axes of the camera. Strafe, forwards and updown movement requests are obtained from the controller and these are used to compute the requested translation of the camera for the current frame. Finally, the view matrix is obtained by concatenating the current camera translation matrix with the current camera rotation matrix.
Application Operation.
The application draws 200 boxes randomly positioned around the origin. The camera starts off positioned at the origin looking down the negative world axis. The left joy stick moves the camera forwards, backwards, left and right. The right joy stick rotates the camera left and right and up and down. L1 and L2 translates the camera up and down. Note that all of these movements are relative to the current axes of the camera but this can be changed to accommodate the type of game play required.
Conclusions
A simple 3D camera has been created which can be moved through a 3D scene under control of the analogue joy sticks. This camera can be wrapped up into a class and extra functionality added as required.
Dr Henry S Fortuna
University of Abertay Dundee