Inside3D!
     

Angle turning code

 
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming
View previous topic :: View next topic  
Author Message
Wazat



Joined: 15 Oct 2004
Posts: 732
Location: Middle 'o the desert, USA

PostPosted: Wed Nov 24, 2004 6:42 pm    Post subject: Angle turning code Reply with quote

I don't know who, but somebody posted this code on the old forums a while back:
void() meet_new_dir =
{
if (vlen(self.new_way - self.angles) > 2)
self.angles = self.angles + normalize(self.new_way - self.angles) * 2;
else
self.angles = self.new_way;
};

I'd like to know who it is so I can give them credit. Anyway, at first it didn't work, because there is a specific condition needed in order for the code to operate: the angles need to range from -180 to 180, instead of 0-360 or some other system.

So, I've since modified the function to be more general-purpose. Here are the results:

Code:

/*
-----------------------------------------
frik_anglemod (part of FrikBot)

faster version of id's anglemod
-----------------------------------------
*/

float(float v) frik_anglemod =
{
   return v - floor(v/360) * 360;
};

/*
-----------------------------------------
capangle (by Wazat)

Quick little function to save time.
Makes sure an angle's 3 floats range from 0-360
-----------------------------------------
*/

vector(vector ang) capangle =
{
   ang_x = frik_anglemod(ang_x);
   ang_y = frik_anglemod(ang_y);
   ang_z = frik_anglemod(ang_z);

   return ang;
};


/*
-----------------------------------------
nangle (by Wazat)

Basically makes an angle range from -180 to 180.
-----------------------------------------
*/

vector(vector ang) nangle =
{
   ang = capangle(ang);

   if (ang_x > 180)
      ang_x = ang_x - 360;
   else if (ang_x < -180)
      ang_x = ang_x + 360;

   if (ang_y > 180)
      ang_y = ang_y - 360;
   else if (ang_y < -180)
      ang_y = ang_y + 360;

   if (ang_z > 180)
      ang_z = ang_z - 360;
   else if (ang_z < -180)
      ang_z = ang_z + 360;

   return ang;
};


/*
-----------------------------------------
angle_turn (by... actually I forget who wrote this one)
Modified by Wazat to be more general-purpose.

Turns oldang toward newang in 'turnrate' increments.
-----------------------------------------
*/

vector(vector oldang, vector newang, float turnrate) angle_turn =
{
   newang = nangle(newang);
   oldang = nangle(oldang);

   if (vlen(newang - oldang) > turnrate)
      return oldang + normalize(newang - oldang) * turnrate;
   else
      return newang;
};


The new function, renamed to angle_turn, is a lot more general-purpose, allowing any angle to turn toward an ideal angle, and any turn rate specified. I use it for the mini-turrets in Conquest, so that I don't have to rely on ChangeYaw(). Here is the code I use:

Code:

      newang = vectoangles(dir);
      self.angles_z = newang_z; // don't modify roll
      newang = self.angles = angle_turn(self.angles, newang, self.ammo_nails);
      self.angles_z = 0; // stay level (0 roll)
      // set self.movedir so turret will know what direction to fire later on
      newang_x = newang_x * -1; // x angle is always backward for some reason
      makevectors(newang);
      self.movedir = v_forward;


I hope this code comes in handy for someone here... And I hope I can find out who posted the original so I can give them credit.
_________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.
Back to top
View user's profile Send private message MSN Messenger
Wazat



Joined: 15 Oct 2004
Posts: 732
Location: Middle 'o the desert, USA

PostPosted: Wed Nov 24, 2004 10:11 pm    Post subject: Reply with quote

I forgot to mention, I'm having one problem with this code: it often turns in the wrong way. In other words, if the enemy is just to the right of the turret, it will turn left all the way around to hit it.

Can anyone help me fix that?
_________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.
Back to top
View user's profile Send private message MSN Messenger
Urre



Joined: 05 Nov 2004
Posts: 1073
Location: Sweden

PostPosted: Wed Nov 24, 2004 10:57 pm    Post subject: Reply with quote

Wazat wrote:
I forgot to mention, I'm having one problem with this code: it often turns in the wrong way. In other words, if the enemy is just to the right of the turret, it will turn left all the way around to hit it.

Can anyone help me fix that?


Sorry, no, I was just going to mention that I've experienced the very same problem. Ticks one off, for sure.
_________________
Look out for Twigboy
Back to top
View user's profile Send private message Visit poster's website
IceDagger



Joined: 19 Nov 2004
Posts: 20

PostPosted: Thu Nov 25, 2004 3:39 am    Post subject: Reply with quote

You have to check which is the smaller angle, the one on the right, or the one on the left.

I think this is what's causing your problem:

If the turret were facing 160 degrees, and was told to turn to -160 degrees, your code might be rotating 160 down to 0, down to -160, when it would be faster to rotate from 160 up to 200 (which is the same as -160).

If you've done some C programming, you might want to take a look at the QER frame interpolation tutorial (Specifically, the rotation interpolation code). Essentially you want to interpolate the turret's rotation along the smaller angle, which is what is done in frame interpolation when an entity's angle changes.


Hope this helps. Very Happy
Back to top
View user's profile Send private message
Wazat



Joined: 15 Oct 2004
Posts: 732
Location: Middle 'o the desert, USA

PostPosted: Tue Nov 30, 2004 11:44 pm    Post subject: Reply with quote

Hurray, it works!

Here's the new function:
Code:

/*
-----------------------------------------
angle_turn (by Wazat)

Turns oldang toward newang in 'turnrate' increments.
-----------------------------------------
*/

vector(vector oldang, vector newang, float turnrate) angle_turn =
{
   local vector ang, dir;
   local float dist;
   newang = nangle(newang);
   oldang = nangle(oldang);

   if (vlen(newang - oldang) > turnrate)
   {
      //dir = normalize(newang - oldang);
      //ang = oldang + dir * turnrate;

      dist = frik_angcomp(newang_x, oldang_x);
      if(dist > 0 && dist > turnrate)
         dist = turnrate;
      else if(dist < 0 && dist < turnrate * -1)
         dist = turnrate * -1;
      ang_x = oldang_x + dist;

      dist = frik_angcomp(newang_y, oldang_y);
      if(dist > 0 && dist > turnrate)
         dist = turnrate;
      else if(dist < 0 && dist < turnrate * -1)
         dist = turnrate * -1;
      ang_y = oldang_y + dist;

      dist = frik_angcomp(newang_z, oldang_z);
      if(dist > 0 && dist > turnrate)
         dist = turnrate;
      else if(dist < 0 && dist < turnrate * -1)
         dist = turnrate * -1;
      ang_z = oldang_z + dist;

      return ang;
   }
   else
      return newang;
};

_________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.
Back to top
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2004 phpBB Group