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();
}