PS2 Linux Programming



Moving the Camera Around




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.






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