viewing transformations help please!!!

Ok here is the problem:

I have a scene and I want to be able to move around in this fashion…

The user may turn the camera wrt

roll, pitch and yaw…
that is roll left/right
turn left/right
look up/down

and then wrt his/her orientation the user may move forward/back left/right and up/down

that is if the user is facing forward (-z) and pushes the forward button then they will go into the -z direction

and if the user is facing down (-Y) and pushes forward they should go down… likewise for the other traslations

the camera should rotate about its local axis… not the world center and should translate wrt its local orientation not the worlds

Also the user may input an initial position
(this is where my problem arose)… that is the user can start at say the world coordinates (30,20, 10) or some other arbitrary pos and also have arbitrary init orientation …

My problem arose when doing the initial pos/ rot …

When I specified an initial position (with glTranslate) the rotations were about this point (e.g. if I specify init pos of 3,2,1) the rot center will be 3, 2, 1 not the cameras local pos…

Here is some code to show how I do translation/rotation now

void getNewPos()
{
float mat[4][4];
glGetFloatv(GL_MODELVIEW_MATRIX,(float *)mat);

Z+=deltaz*mat[2][2]+deltay*mat[2][1]+deltax*mat[2][0];
Y-=deltaz*mat[1][2]+deltay*mat[1][1]+deltax*mat[1][0];
X+=deltaz*mat[0][2]+deltay*mat[0][1]+deltax*mat[0][0];

roll+=deltaroll;
pitch+=deltapitch;
yaw+=deltayaw;

}

void display()
{

VISUALSFrameUpdateStartTime=clock();

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
getNewPos();
glLoadIdentity();

positionchanged=1;

	
glRotatef(-roll, 0,0,1);
glRotatef(pitch,1,0,0);	
glRotatef(-yaw,0,1,0);
//gluLookAt(X,Y,Z,X,Y,-1,0,1,0);


glTranslatef(X, -Y, Z);

if(swCull)
{
	calcViewVolumes();
}


int num=0;
firstone=0;
if(scene)
	num=scene->render();
drawframeinfo(num);

//exit(0);


VisualsIterationCounter++ ;
glFinish();
glutSwapBuffers();

VISUALSFrameUpdateEndTime=clock();
VISUALSTotalFramesUpdateTime+=((double)VISUALSFrameUpdateEndTime/1000.0)-
                       ((double)VISUALSFrameUpdateStartTime/1000.0);

if (!(VisualsIterationCounter%VISUALSNumofFramesToAverageFrameUpdateTimeOver-1))
{
  VISUALSFramesPerSecond=(double)VISUALSNumofFramesToAverageFrameUpdateTimeOver/
                  VISUALSTotalFramesUpdateTime;
  VISUALSTotalFramesUpdateTime=0.0;
}

glutPostRedisplay();

}

void key(unsigned char c, int x, int y)
{
switch ©
{
case ‘Q’:
case ‘q’:
exit(0);
break;
case ‘0’:
deltax=deltay=deltaz=deltaroll=deltapitch=deltayaw=0;
break;
case ‘1’:
deltaz+=.1;
break;
case ‘2’:
deltapitch+=.1;
break;
case ‘3’:
deltaz-=.1;
break;
case ‘4’:
deltayaw+=.1;
break;
case ‘5’:
break;
case ‘6’:
deltayaw-=.1;
break;
case ‘7’:
deltaroll+=.1;
break;
case ‘8’:
deltapitch-=.1;
break;
case ‘9’:
deltaroll-=.1;
break;
case ‘+’:
deltay-=.1;
break;
case ‘-’:
deltay+=.1;
break;
case ‘s’:
if(swCull)
swCull=0;
else
swCull=1;
break;
case ‘w’:
if(wireframe)
{
if(wire)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
wire=0;
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
wire=1;
}
}
break;

	case 'f':
		if(!gamemode)
		{
			if(!full)
			{
				savedwidth=width;
				savedheight=height;
				glutFullScreen();
				full=1;
			}
			else
			{
				full=0;
				glutReshapeWindow(savedwidth, savedheight);
			}
		}


		break;

	case 'c':
		if (current==9)
			current=0;
		else 
			current++;
		
		while(!eyepoints[current].valid)
			current++;
		break;

	default:
		break;
}

glutPostRedisplay();

}