Archived

This topic is now archived and is closed to further replies.

Can't loop the loop correctly!

This topic is 5021 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have tried implimenting the following code to navigate through a simple 3D flight sim, but there is a glitch. Whenever I pitch through 360 degrees it doesn''t maintain the correct camera angle, it flips over at the apex of the loop, if I were flying I would never go inverted as the code always keeps me the right way up regardless of pitch angle. if(keyPressed[VK_LEFT]) { yaw = (float)(yaw - 0.5); if(yaw < 0) yaw = 360; } if(keyPressed[VK_RIGHT]) { yaw = (float)(yaw + 0.5); if(yaw > 360) yaw = 0; } if(keyPressed[''A'']) { pitch = (float)(pitch - 0.5); if(pitch < 0) pitch = 360; } if(keyPressed[''Z'']) { pitch = (float)(pitch + 0.5); if(pitch > 360) pitch = 0; } rads_yaw = (float)(2*PI*(yaw)/360.0); rads_pitch = (float)(2*PI*(pitch)/360.0); if(keyPressed[VK_UP]) { eyex = (float)(eyex + (SPEED * (float(cos(rads_yaw) * cos(rads_pitch))))); eyey = (float)(eyey + (SPEED * float(sin(rads_pitch)))); eyez = (float)(eyez + (SPEED * (float(sin(rads_yaw) * cos(rads_pitch))))); } if(keyPressed[VK_DOWN]) { eyex = (float)(eyex - (SPEED * (float(cos(rads_yaw) * cos(rads_pitch))))); eyey = (float)(eyey - (SPEED * float(sin(rads_pitch)))); eyez = (float)(eyez - (SPEED * (float(sin(rads_yaw) * cos(rads_pitch))))); } centrex = (float)(eyex + (1.0 * (float(cos(rads_yaw) * cos(rads_pitch))))); centrey = (float)(eyey + (1.0 * float(sin(rads_pitch)))); centrez = (float)(eyez + (1.0 * (float(sin(rads_yaw) * cos(rads_pitch))))); Can anyone help me out here? Actually, it mmay have something to do with the LookAt axis function. I''ll play with that too. Many thanks.

Share this post


Link to post
Share on other sites
I think I cracked it: Answered my own question ;-P

You have to invert the LookAt axis so that you are orientated correctly through all pitch angles. Something like this:

if(pitch >= 0 && pitch < 90)
{
upy = 1.0;
}
else if(pitch >= 90 && pitch < 180)
{
upy = -1.0;
}
else if(pitch >= 180 && pitch < 270)
{
upy = -1.0;
}
else if(pitch >= 270 && pitch < 360)
{
upy = 1.0;
}

gluLookAt(eyex, eyey, eyez, centrex, centrey, centrez, upx, upy, upz);

If anyone has a more elegant solution, please let me know.

Cheers

Share this post


Link to post
Share on other sites
quote:
Original post by dave j
quote:
Original post by sPriTe

If anyone has a more elegant solution, please let me know.




The problem you''ve found is known as gimbal lock and the usually recommended elegant solution is quaternions.

See this
article on quaternions.


dave j


Quaternions would obviously work, but I''m not convinced they''d be that elegant in this case, since the OP is already working with matrices.

I''d just store a transformation matrix for the plane and rotate it about the X Y or Z axis when the user changes the yaw, pitch or roll. To place a camera in the plane, you could then use the inverse of the plane''s matrix.

The same thing would apply if you were using a vector/quaternion representation, except you''d have to convert it to a matrix before rendering.

Share this post


Link to post
Share on other sites