Appologies for the delay, RL has been busy... After looking at a few camera class implementations, I decided to split it into 2 classes. I genric Camera class, and one more specific GameCamera class. As mentioned all feedback, constructive critisism welcome.

So this is what it looks like so far...

[pascal]
unit camera;

interface

uses
vector;

type
TCamera = class
private

protected

public
CameraPosition : TVector; // position of camera
CameraVelocity : TVector; // velocity of camera
CameraAcceleration : TVector; // acceleration of camera
CameraLookAt : TVector; // lookat vector

// up, forward, right vectors
CameraUp : TVector;
CameraForward : TVector;
CameraRight : TVector;

// yaw and pitch angles
CameraYaw : TScalar;
CameraPitch : TScalar;

ScreenWidth, ScreenHeight : integer;
ScreenCenterX, ScreenCenterY : integer;

constructor Create; overload; virtual;
constructor Create( aLook : TVector ); overload; virtual;
constructor Create( aPosition : TVector; aLook : TVector ); overload; virtual;
destructor Destroy; override;

procedure LookAt( aX : TScalar; aY : TScalar; aZ : TScalar ); overload;
procedure LookAt( aLook : TVector ); overload;
procedure MoveTo( aX : TScalar; aY : TScalar; aZ : TScalar ); overload;
procedure MoveTo( aPosition : TVector ); overload;

// right rotation along y-axis (yaw)
procedure RotateYaw( aRadians : TScalar );
procedure RotatePitch( aRadians : TScalar );
procedure RotateRoll( aRadians : TScalar );
procedure RotatePYR( aPitch : TScalar; aYaw : TScalar; aRoll : TScalar );
end;

implementation

{ TCamera }

constructor TCamera.Create;
begin
inherited;
CameraPosition := TVector.Create( 0.0, 0.0, 0.0 );
CameraLookAt := TVector.Create( 0.0, 0.0, 1.0 );

CameraForward := CameraLookAt;
CameraUp := TVector.Create( 0.0, 1.0, 0.0 );
CameraRight := TVector.Create( 1.0, 0.0, 0.0 );

CameraVelocity := TVector.Create( 0.0, 0.0, 0.0 );
CameraAcceleration := TVector.Create( 0.0, 0.0, 0.0 );

CameraYaw := 0.0;
CameraPitch := 0.0;
end;

constructor TCamera.Create( aPosition, aLook : TVector );
begin
inherited Create;
CameraPosition := aPosition;
CameraLookAt := aLook.UnitVector;

CameraForward := CameraLookAt;
CameraUp := TVector.Create( 0.0, 1.0, 0.0 );
CameraRight := TVector.Create( 1.0, 0.0, 0.0 );

CameraVelocity := TVector.Create( 0.0, 0.0, 0.0 );
CameraAcceleration := TVector.Create( 0.0, 0.0, 0.0 );

CameraYaw := 0.0;
CameraPitch := 0.0;
end;

constructor TCamera.Create( aLook : TVector );
begin
inherited Create;
CameraPosition := TVector.Create( 0.0, 0.0, 0.0 );
CameraLookAt := aLook.UnitVector;

CameraForward := CameralookAt;
CameraUp := TVector.Create( 0.0, 1.0, 0.0 );
CameraForward.CrossProduct( CameraUp, CameraRight );

CameraVelocity := TVector.Create( 0.0, 0.0, 0.0 );
CameraAcceleration := TVector.Create( 0.0, 0.0, 0.0 );

CameraYaw := 0.0;
CameraPitch := 0.0;
end;

destructor TCamera.Destroy;
begin
if CameraPosition <> nil then
CameraPosition.Free;
if CameraLookAt <> nil then
CameraLookAt.Free;

if CameraForward <> nil then
CameraForward.Free;
if CameraUp <> nil then
CameraUp.Free;
if CameraRight <> nil then
CameraRight.Free;

if CameraVelocity <> nil then
CameraVelocity.Free;
if CameraAcceleration <> nil then
CameraAcceleration.Free;
inherited;
end;

procedure TCamera.LookAt( aX, aY, aZ : TScalar );
begin
CameraLookAt.x := aX;
CameraLookAt.y := aY;
CameraLookAt.y := aZ;
end;

procedure TCamera.LookAt( aLook : TVector );
begin
CameraLookAt.Assign( aLook );
end;

procedure TCamera.MoveTo( aX, aY, aZ : TScalar );
begin
CameraPosition.x := aX;
CameraPosition.y := aY;
CameraPosition.z := aZ;
end;

procedure TCamera.MoveTo( aPosition : TVector );
begin
CameraPosition.Assign( aPosition );
end;

procedure TCamera.RotatePitch( aRadians : TScalar );
var
sine, cosine : TScalar;
begin
sine := sin( aRadians );
cosine := cos( aRadians );

CameraUp.y := cosine * CameraUp.Length;
CameraUp.z := sine * CameraUp.Length;

CameraForward.y := -sine * CameraForward.Length;
CameraForward.z := cosine * CameraForward.Length;
{* x y z p
| 1 0 0 0 |
M = | 0 cos(A) -sin(A) 0 |
| 0 sin(A) cos(A) 0 |
| 0 0 0 1 |
*}
end;

procedure TCamera.RotatePYR(aPitch, aYaw, aRoll: TScalar);
begin
RotatePitch( aPitch );
RotateYaw( aYaw );
RotateRoll( aRoll );
end;

procedure TCamera.RotateRoll( aRadians : TScalar );
var
sine, cosine : TScalar;
begin
sine := sin( aRadians );
cosine := cos( aRadians );

CameraRight.x := cosine * CameraRight.Length;
CameraRight.y := sine * CameraRight.Length;

CameraUp.x := -sine * CameraForward.Length;
CameraUp.y := cosine * CameraForward.Length;
{*
| cos(A) -sin(A) 0 0 |
M = | sin(A) cos(A) 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
*}
end;

procedure TCamera.RotateYaw( aRadians : TScalar );
var
sine, cosine : TScalar;
begin
sine := sin( aRadians );
cosine := cos( aRadians );

CameraRight.x := cosine * CameraRight.Length;
CameraRight.z := sine * CameraRight.Length;

CameraForward.x := -sine * CameraForward.Length;
CameraForward.z := cosine * CameraForward.Length;

{* x y z p
| cos(A) 0 -sin(A) 0 |
M = | 0 1 0 0 |
| sin(A) 0 cos(A) 0 |
| 0 0 0 1 |
*}
end;

end.
[/pascal]

And a more game specific one looks like this....

[pascal]
unit gamecamera;

interface

uses
gl,
glu,
vector,
camera,
gameobject;

type
TGameCamera = class( TCamera )
private
CalcVector : TVector; // A sort of cached dummry vector used in Update methods.
protected
// these are used for moving and changing camera orientation
// through the MoveTo/LookTo methods
initPosition, finalPosition : TVector;
initLookAt, finalLookAt : TVector;

LookAtVelocity : TVector; // velocity for looking at objects
LookAtAcceleration : TVector; // acceleration for looking at objects

procedure UpdateLookAt;
procedure UpdateMoveTo;
public
constructor Create; override;
constructor Create( aLook : TVector ); override;
constructor Create( aPosition : TVector; aLook : TVector ); override;
destructor Destroy; override;

procedure LookAtGameObject( aGameobject : TGameObject );
procedure LookAtGameObjectNow( aGameobject : TGameObject );
procedure MoveToGameObject( aGameobject : TGameObject );
procedure MoveToGameObjectNow( aGameobject : TGameObject );

// do animation/collision/ai/physics calculations
procedure Update( aDeltaTime : TScalar );
end;

implementation

{ TGameCamera }

procedure TGameCamera.Update( aDeltaTime : TScalar );
var
cosYaw, sinYaw, sinPitch, cosPitch, speed, strafeSpeed : single;
begin
if ( ( CameraYaw >= 360.0 ) or ( CameraYaw <= -360.0 ) ) then
CameraYaw := 0.0;

// Set boundaries for pitch
if ( CameraPitch > 60.0 ) then
CameraPitch := 60.0;
if ( CameraPitch < -60.0 ) then
CameraPitch := -60.0;

cosYaw := cos( DegreesToRadian( CameraYaw ) );
sinYaw := sin( DegreesToRadian( CameraYaw ) );
sinPitch := sin( DegreesToRadian( CameraPitch ) );

cosPitch := cos( DegreesToRadian( CameraPitch ) );

speed := CameraVelocity.z * aDeltaTime;
strafeSpeed := CameraVelocity.x * aDeltaTime;

if ( speed > 15.0 ) then
speed := 15.0;
if ( strafeSpeed > 15.0 ) then
strafeSpeed := 15.0;
if ( speed < -15.0 ) then
speed := -15.0;
if ( strafeSpeed < -15.0 ) then
strafeSpeed := -15.0;

if ( CameraVelocity.Length > 0.0 ) then
begin
CameraVelocity.Negative( CameraAcceleration );
CameraAcceleration.Scale( 1.5 );
end;

CameraVelocity.Add( CameraAcceleration.Scale( aDeltaTime ), CameraVelocity );

CameraPosition.x := CameraPosition.x + cos( DegreesToRadian( CameraYaw + 90.0 ) ) * strafeSpeed;
CameraPosition.z := CameraPosition.z + sin( DegreesToRadian( CameraYaw + 90.0 ) ) * strafeSpeed;
CameraPosition.x := CameraPosition.x + cosYaw * speed;
CameraPosition.z := CameraPosition.z + sinYaw * speed;

// added *cosPitch
CameraLookAt.x := CameraPosition.x + ( cosYaw * cosPitch );
CameraLookAt.y := CameraPosition.y + sinPitch;
CameraLookAt.z := CameraPosition.z + ( sinYaw * cosPitch );

gluLookAt( CameraPosition.x, CameraPosition.y, CameraPosition.z,
CameraLookAt.x, CameraLookAt.y, CameraLookAt.z,
0.0, 1.0, 0.0 );
end;

constructor TGameCamera.Create;
begin
inherited;
CalcVector := TVector.Create( 0.0, 0.0, 0.0 );
end;

constructor TGameCamera.Create(aLook: TVector);
begin
inherited;
CalcVector := TVector.Create( 0.0, 0.0, 0.0 );
end;

constructor TGameCamera.Create(aPosition, aLook: TVector);
begin
inherited;
CalcVector := TVector.Create( 0.0, 0.0, 0.0 );
end;

destructor TGameCamera.Destroy;
begin
if CalcVector <> nil then
CalcVector.Free;
inherited;
end;

procedure TGameCamera.LookAtGameObject( aGameobject : TGameObject );
begin
initLookAt.Assign( CameraLookAt );
finalLookAt.Assign( aGameobject.Position );

CameraLookAt.Scale( 0.25 ).Negative( LookAtAcceleration );

UpdateLookAt;
end;

procedure TGameCamera.LookAtGameObjectNow( aGameobject : TGameObject );
begin
CameralookAt.Assign( aGameobject.Position );
end;

procedure TGameCamera.MoveToGameObject( aGameobject : TGameObject );
begin
initPosition.Assign( CameraPosition );
finalPosition.Assign( aGameobject.Position );

CameraPosition.Scale( 0.25 ).Negative( CameraAcceleration );

UpdateMoveTo;
end;

procedure TGameCamera.MoveToGameObjectNow( aGameobject : TGameObject );
begin
CameraPosition.Assign( aGameobject.Position );
end;

procedure TGameCamera.UpdateLookAt;
begin
CalcVector.Assign( finalLookAt.x - CameralookAt.x,
finalLookAt.y - CameralookAt.y,
finalLookAt.z - CameralookAt.z );

LookAtVelocity.Assign( CalcVector.Scale( 0.5 ) );
end;

procedure TGameCamera.UpdateMoveTo;
begin
CalcVector.Assign( finalPosition.x - Cameraposition.x,
finalPosition.y - Cameraposition.y,
finalPosition.z - Cameraposition.z );

CameraVelocity.Assign( CalcVector.Scale( 0.5 ) );
end;

end.
[/pascal]

Once these have been picked apart I'll post the proposed gamenode and gameobject classes.