PDA

View Full Version : 3D Movement Algorithm



Oynx
06-27-2001, 08:53 AM
Are there any programmers out there that can help me? I am writing a game that allows you to move around a 3D grid in any direction by turning to face the way you want to go (up, down, left or right) and then pressing a key to go forwards (or backwards) in that direction. I found some code online that does this but there is a problem with it - when you are looking straight up (90 degrees) and then head straight in that direction, you end up travelling at about 80 degree or so. In other words, you can never head straight up or down, only at a slope.
Here is the code... I hope someone can make some sense out of it because I can't. I would be perfect if it wasn't for this little problem.

--------------------------------------------------------------

float piover180 = 0.0174532925f;

if (nChar == VK_UP)
{
m_fXPos -= (float)sin(m_fHeading*piover180) * 0.03f;
m_fYPos -= (float)sin(m_fLookUpDown*piover180) * 0.03f;
m_fZPos -= (float)cos(m_fHeading*piover180) * 0.03f;
InvalidateRect(NULL);
}

if (nChar == VK_DOWN)
{
m_fXPos += (float)sin(m_fHeading*piover180) * 0.03f;
m_fYPos += (float)sin(m_fLookUpDown*piover180) * 0.03f;
m_fZPos += (float)cos(m_fHeading*piover180) * 0.03f;
InvalidateRect(NULL);
}

if (nChar == VK_RIGHT)
{
m_SectYRotate -= 1.0f;
m_fHeading = m_SectYRotate;
InvalidateRect(NULL);
}

if (nChar == VK_LEFT)
{
m_SectYRotate += 1.0f;
m_fHeading = m_SectYRotate;
InvalidateRect(NULL);
}

if (nChar == VK_PRIOR)
{
if (m_fLookUpDown < -90) m_fLookUpDown = -90;
m_fLookUpDown-= 1.0f;
InvalidateRect(NULL);
}

if (nChar == VK_NEXT)
{
if (m_fLookUpDown > 90) m_fLookUpDown = 90;
m_fLookUpDown+= 1.0f;
InvalidateRect(NULL);
}

--------------------------------------------------------------


If anyone can help, I'd be very thankful,
Jamie

Eber Kain
06-27-2001, 09:54 AM
Just learn how to use a matrix, start here.
http://web2.airmail.net/sjbaker1/matrices_can_be_your_friends.html

06-27-2001, 02:49 PM
Oynx probably doesnt have to do any of his own matrix calculations for this simple program. The problem might simple lie in the call to gluPerspective or glFrustrum

Oynx
06-27-2001, 10:30 PM
Here is the call, do you have any idea how I can fix it?

void CDominationView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);

GLsizei width, height;
GLdouble aspect;

width = cx;
height = cy;

if (cy==0)
aspect = (GLdouble)width;
else
aspect = (GLdouble)width/(GLdouble)height;

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 0.05, 40.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glDrawBuffer(GL_BACK);
//glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}

Thanks,
Jamie

[This message has been edited by Oynx (edited 06-28-2001).]

[This message has been edited by Oynx (edited 06-28-2001).]

Tron
06-27-2001, 10:56 PM
m_fXPos -= (float)sin(m_fHeading*piover180) * 0.03f;
m_fYPos -= (float)sin(m_fLookUpDown*piover180) * 0.03f;
m_fZPos -= (float)cos(m_fHeading*piover180) * 0.03f;


i think your movement calcualtions are wrong, i'm using these:



mX += -2.0f * cos(mPitch / 180 * M_PI) * sin(mYaw / 180 * M_PI);
mY += 2.0f * sin(mPitch / 180 * M_PI);
mZ += 2.0f * cos(mPitch / 180 * M_PI) * cos(mYaw / 180 * M_PI);

mX, mY, mZ: position
mPitch: angle up/down
mYaw: angle left/right


i derived these formulae from the multiplication of the x-rotation-matrix (pitch) and the y-rotation-matrix (yaw), the result multiplied with the starting eye-vector (pitch = yaw = 0): (0, 0, 1) (also looking along the positive z axis)
this might be the reason for your problem

Tim Stirling
06-27-2001, 11:49 PM
Here is a snippet of my code:



void TCamera::Move_Forwards(float frametime)
{

xpos += float(cos(xrot*piover180)*sin(yrot*piover180))*Mov e_Speed * frametime;
zpos -= float(cos(xrot*piover180)*cos(yrot*piover180))*Mov e_Speed * frametime;
ypos -= float(sin(xrot*piover180))*Move_Speed * frametime;

}

This allows you to go straight up and down although isn't entirely correct.
Tim

Tron
06-28-2001, 01:43 AM
@Tim Stirling:
that's quite the same as my code, as i mentioned before Onyx' calculations are wrong, so his results are wrong (what a conclusion *g*)