Sign in to follow this  

Tank 3D Rotation on Y

This topic is 4401 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

This may get asked a lot since it seems to be a basic game math problem. What I need is the rotation angle on Y so that my game model faces the direction it is running. I believe this is called "angle between vectors." I have MD2 models running on the ground, but they do not face the direction they are running. dx and dz (the x and z vectors) is how much to move on x and z each frame, dy = 0 since no movement on y. From my VazTank.cpp (OpenGL, Win32, Visual C++) source: Enemy[i].dx = dx; Enemy[i].dy = 0.0f; Enemy[i].dz = dz; Enemy[i].Angle = ??? // FIX: FIND CORRECT FACING ANGLE The angle gets put in here (for example): glRotatef(Enemy[i].Angle, 0.0f, 1.0f, 0.0f); // rotate on Y RenderModel(&model_copter, ENEMY_COPTER); // FIX: PASS INSTANCE OF MODEL What is the formula for angle in terms of dx and dz? I have read something about atan2( ) but it doesn't seem to work. Is atan2( ) what I need? For those interested, full CPP source and game I am working on: VazTank2 CPP source (VC 6 project files, source, sounds and resources) VazTankGame EXE (EXE game, bmp textures and MD2 models) VazGames.com (games and demos) Current problems in VazTank2 that need fixing: rotation angle on Y, and animation stutters since I need to pass multiple instances of the MD2 models, rather than the same pointer. Or I need to keep track of unique animation positions for each model instance on screen. Phil P

Share this post


Link to post
Share on other sites
Quote:
What is the formula for angle in terms of dx and dz? I have read something about atan2( ) but it doesn't seem to work. Is atan2( ) what I need?
Yup. If it's not working for you, you might post your code. Common problems are a) mixing degrees and radians, and b) inconsistency between the arguments to atan2() and your rotation conventions. Given your code and a description of how it's not working, it should be easy to identify and fix the problem.

Share this post


Link to post
Share on other sites
If I understood you correctly, you're not looking for the angle of two vectors, but the angle in a right triangle. dx and dz are not vectors but components of your movement vector, right? Then atan2(z,x) is indeed what you need. Check this thread where this topic was discussed recently.

Share this post


Link to post
Share on other sites
Thank you, I am on the right track then with atan2( ). Good.

The way I've tried the formula is simply

Enemy[i].dx = dx; Enemy[i].dy = 0.0f; Enemy[i].dz = dz;
Enemy[i].Angle = (GLfloat)(atan2(dz,dy) * 180.0 / PI);

As far as how it is not working, it seems to generate random angles. What is weird is if I simply do above Enemy[i].Angle = 0.0f this also seems to generate random angles. If angle = 0 however I should see all MD2 models facing the same way in the game, right? Assuming they are standard MD2 models (I got them from Planet Quake).

The struct for Enemy (tank, dragon, goblin, etc)

typedef struct // Struct for Enemy tanks
{
bool alive;
int state; // NORMAL, DIED, CRAWL, TAUNT ?
//t3DModel model; // Model anims, etc ???
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat dx;
GLfloat dy;
GLfloat dz;
GLfloat Angle; // rotate angle on y (facing direction)
int type; // type 1 = tank, 2 = copter, 3 = goblin, 4 = dragon, etc
int count; // count wait to adjust position, fire, death anim, etc
// int currAnim; // current animation
// int currFrame; // current frame of animation
} ENEMY_STRUCT;

Besides the Y rotation problem, I get stutters in the animation. That is because I do not pass unique pointers to the model struct. So when there is more than 1 goblin or more than 1 dragon, the animation stutters and does not loop correctly. I think I have to keep track of the currAnim and currFrame of each model on the screen (but we'll save that for later). Right now I want to fix this darn Y rotation problem. All the source and game is linked above.

Phil P

Share this post


Link to post
Share on other sites
Based on your description it sounds like the problem is not with finding the angle itself (your code for that looks fine) but elsewhere. From a debugging standpoint I would try to get your models rendering with a consistent orientation when angle = 0; the fact that they're not suggests something is awry.

Share this post


Link to post
Share on other sites
I think your code to compute the angle is incorrect. You said that dy is always 0, and movement happens in x and z, but you're using dy in the formula. Let me clarify:


|
/ |
/ | dz
/ |
/a |
------
dx







What you want in this case is the angle at (a), which is given by the formula arctan(dz/dx), or in c++: atan2(dz, dx), instead of atan2(dz, dy). Using dy here, while it is zero, should result in a division by zero. I am not that familiar with how that is handled by c++, but might the behavior not be undefined?

Share this post


Link to post
Share on other sites
Oop, lightbringer is correct (I missed the dy in your atan2() call). atan2() does however handle the division-by-zero case transparently, so that's not a concern.

Share this post


Link to post
Share on other sites
You know what, that may be it. I made a typo dz,dy above. I meant to type dz,dx. I think I had it right in the game however, atan2(dz,dx). Thanks for the insights.

Phil P

Share this post


Link to post
Share on other sites

This topic is 4401 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this