XZ plane strafing was easy but I’m having a bit of trouble with 3D rotation. I’m tracking the x,y,z axis vectors. So my test case is to yaw left 90 degrees and then roll around the new heading. Problem is the rolling is changing the y axis vector so in subsequent frames it all goes wrong. I feel I’m close but frustration is keeping me from thinking clearly What’s the simplest way to implement this without using matrices or quats.?
Or if i had to use a matrix how would i combine a 90 degree yaw then a 90 degree roll? I’ve looked extensively at papers on matrices but there is so much vagueness. Some explain using right hand, others left. some say the combination order doesn’t matter, others say it does e.t.c. I use right hand with positive z going out of the screen.
Code snippet below:
scene.cpp
glRotatef(pitchangle,vXaxis.x,vXaxis.y,vXaxis.z);
glRotatef(yawangle,vYaxis.x,vYaxis.y,vYaxis.z);
glRotatef(rollangle,vZaxis.x,vZaxis.y,vZaxis.z);
glTranslatef(xtrans, ytrans, ztrans);
main.cpp
static void GetMouseInput(void)
{
POINT Point;
long x;
long y;
GetCursorPos(&Point);
x = Point.x;
y = Point.y;
mouseX = ((float) (((float)SCREEN_WIDTH/2.0f) - Point.x));
mouseY = ((float) (((float)SCREEN_HEIGHT/2.0f) - Point.y));
SetCursorPos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
if (yawangle<-360)
{
yawangle +=360;
}
if (yawangle>360)
{
yawangle=yawangle-360;
}
yawangle=mouseX/10;
vXaxis.x=cos(yawangle*PI/180);
vXaxis.z=-sin(yawangle*PI/180);
vZaxis.x=-sin(yawangle*PI/180);
vZaxis.z=cos(yawangle*PI/180);
}
void ProcessUserInput()
{
bool cursorUp, cursorDown, cursorLeft, cursorRight;
bool leftmouse,rightmouse, Akey, Dkey, Wkey, Skey;
cursorLeft = (GetAsyncKeyState(VK_LEFT) & 0x8000) != 0;
cursorRight = (GetAsyncKeyState(VK_RIGHT) & 0x8000) != 0;
cursorUp = (GetAsyncKeyState(VK_UP) & 0x8000) != 0;
cursorDown = (GetAsyncKeyState(VK_DOWN) & 0x8000) != 0;
leftmouse = (GetAsyncKeyState(VK_LBUTTON) & 0x8000) != 0;
rightmouse = (GetAsyncKeyState(VK_RBUTTON) & 0x8000) != 0;
Akey = (GetAsyncKeyState(65) & 0x8000) != 0;
Dkey = (GetAsyncKeyState(68) & 0x8000) != 0;
Wkey = (GetAsyncKeyState(87) & 0x8000) != 0;
Skey = (GetAsyncKeyState(83) & 0x8000) != 0;
GetMouseInput();
if (cursorUp) // pitch down +
{
if (pitchangle<-360)
{
pitchangle +=360;
}
if (pitchangle>360)
{
pitchangle=pitchangle-360;
}
pitchangle +=1.0f*sensitivity;
}
if (cursorDown) // pitch up
{
if (pitchangle<-360)
{
pitchangle +=360;
}
if (pitchangle>360)
{
pitchangle=pitchangle-360;
}
pitchangle -=1.0f*sensitivity;
}
if (cursorLeft) //roll left
{
if (rollangle<-360)
{
rollangle +=360;
}
if (rollangle>360)
{
rollangle=rollangle-360;
}
rollangle -=1.0f*sensitivity;
vXaxis.x=-sin(rollangle*PI/180);
vXaxis.y=cos(rollangle*PI/180);
vYaxis.x=-sin(rollangle*PI/180);
vYaxis.y=cos(rollangle*PI/180);
}
if (cursorRight) //roll right
{
if (rollangle<-360)
{
rollangle +=360;
}
if (rollangle>360)
{
rollangle=rollangle-360;
}
rollangle +=1.0f*sensitivity;
vXaxis.x=-sin(rollangle*PI/180);
vXaxis.y=cos(rollangle*PI/180);
vYaxis.x=-sin(rollangle*PI/180);
vYaxis.y=cos(rollangle*PI/180);
}
vCross(vYaxis,vZaxis,vXaxis); //cross product for strafing
if (Wkey) //move forward
{
vPosition.x-=vZaxis.x*speed;
vPosition.z-=vZaxis.z*speed;
}
if (Skey) //move backward
{
vPosition.x+=vZaxis.x*speed;
vPosition.z+=vZaxis.z*speed;
}
if (Akey) //strafe left
{
vPosition.x -=vXaxis.x*speed;
vPosition.y -=vXaxis.y*speed;
vPosition.z -=vXaxis.z*speed;
}
if (Dkey) //strafe right
{
vPosition.x +=vXaxis.x*speed;
vPosition.y +=vXaxis.y*speed;
vPosition.z +=vXaxis.z*speed;
}
}