.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   General Programming (http://forums.bots-united.com/forumdisplay.php?f=25)
-   -   Looking to trace out at 45 degrees off the players center... (http://forums.bots-united.com/showthread.php?t=1997)

Maleficus 18-06-2004 08:43

Looking to trace out at 45 degrees off the players center...
 
Trying to find a better and cheaper way to find what the 45 degree angles are of a player.

EX:



\*******/*
*\*****/**
**\***/***
***\*/****
****P****

P = The player.

The two 45 degree lines represent the tracelines I would like to make - but how do I find those angles cheaply?? I have one way to do it, but its VERY expensive. I keep thinking I'm missing something, and theres a faster way to find out this info.

Help?

Pierre-Marie Baty 18-06-2004 09:33

Re: Looking to trace out at 45 degrees off the players center...
 
*edit* what I wrote applies as much to HL as to any other engine (such as RTCW)

Use the player's angles, flatten them if needed
Code:

Vector v_myangles = pPlayerEdict->v.angles;
v_myangles.z = 0;

Add 45° on one side (horizontal plane), make sure it stays in bounds
Code:

v_myangles.y += 45;
if (v_myangles.y > 180)
  v_myangles.y -= 360;

Build a referential out of it
Code:

MAKE_VECTORS (v_myangles);
then use the forward, right and upwards vectors generated to fire your traceline
Code:

TraceResult tr;
TRACE_LINE (pPlayerEdict->v.origin,
                        pPlayerEdict->v.origin + (gpGlobals->v_forward * 9999),
                        ignore_monsters,
                        pPlayerEdict,
                        &tr);

Do the same for the other side.

That's it.

If you want something faster than MAKE_VECTORS(), or if MAKE_VECTORS() is not available for your engine, well it can look like this:
Code:

void BuildReferential (const Vector &v_angles)
{
  // this function builds a 3D referential from a view angle, that is to say, the relative
  // "forward", "right" and "upwards" direction that a player would have if he were facing this
  // view angle. World angles are stored in Vector structs too, the "x" component corresponding
  // to the X angle (horizontal angle), and the "y" component corresponding to the Y angle
  // (vertical angle). Beware, heavy math here.
 
  static float degrees_to_radians = 2 * MATH_PI / 360;
  float angle;
  float sin_pitch;
  float sin_yaw;
  float sin_roll;
  float cos_pitch;
  float cos_yaw;
  float cos_roll;
 
  // compute the sin and cosine of the pitch component
  angle = v_angles.x * degrees_to_radians;
  sin_pitch = sinf (angle);
  cos_pitch = cosf (angle);
 
  // compute the sin and cosine of the yaw component
  angle = v_angles.y * degrees_to_radians;
  sin_yaw = sinf (angle);
  cos_yaw = cosf (angle);
 
  // compute the sin and cosine of the roll component
  angle = v_angles.z * degrees_to_radians;
  sin_roll = sinf (angle);
  cos_roll = cosf (angle);
 
  // build the FORWARD vector
  referential.v_forward.x = cos_pitch * cos_yaw;
  referential.v_forward.y = cos_pitch * sin_yaw;
  referential.v_forward.z = -sin_pitch;
 
  // build the RIGHT vector
  referential.v_right.x = (-(sin_roll * sin_pitch * cos_yaw) - (cos_roll * -sin_yaw));
  referential.v_right.y = (-(sin_roll * sin_pitch * sin_yaw) - (cos_roll * cos_yaw));
  referential.v_right.z = -(sin_roll * cos_pitch);
 
  // build the UPWARDS vector
  referential.v_up.x = ((cos_roll * sin_pitch * cos_yaw) - (sin_roll * -sin_yaw));
  referential.v_up.y = ((cos_roll * sin_pitch * sin_yaw) - (sin_roll * cos_yaw));
  referential.v_up.z = cos_roll * cos_pitch;
 
  return;
}

Comes straight from RACC 8)
If you're using only the forward vector you can get rid of 60% of this function
Code:

Vector BuildForwardVector (const Vector &v_angles)
{
  // this function builds a "forward" vector from a view angle
 
  static float degrees_to_radians = 2 * MATH_PI / 360;
  float angle;
  float sin_pitch;
  float sin_yaw;
  float cos_pitch;
  float cos_yaw;
  Vector v_forward;
 
  // compute the sin and cosine of the pitch component
  angle = v_angles.x * degrees_to_radians;
  sin_pitch = sinf (angle);
  cos_pitch = cosf (angle);
 
  // compute the sin and cosine of the yaw component
  angle = v_angles.y * degrees_to_radians;
  sin_yaw = sinf (angle);
  cos_yaw = cosf (angle);
 
  // build the FORWARD vector
  v_forward.x = cos_pitch * cos_yaw;
  v_forward.y = cos_pitch * sin_yaw;
  v_forward.z = -sin_pitch;
 
  return (v_forward);
}

Nothing faster - AFAIK.

sPlOrYgOn 18-06-2004 09:36

Re: Looking to trace out at 45 degrees off the players center...
 
I thought he was making a bot for RTCW..

@$3.1415rin 18-06-2004 10:44

Re: Looking to trace out at 45 degrees off the players center...
 
as far as I know, the current fpus support sin and cos support, therefore it's not taking to long to calculate them. Another possibility is using lookup tables for them, but since the fpu normally runs faster than your mem, I guess this is the way to go.

@pierre : why should your code be faster than those of the engine ? don't you think they just do the same ? and in terms of cache usage using the engines one might even be better ... just a thought

Pierre-Marie Baty 18-06-2004 12:38

Re: Looking to trace out at 45 degrees off the players center...
 
because engine facilities usually compute ALL THREE vectors... the last function I posted computes only the one we want :)

@$3.1415rin 18-06-2004 16:35

Re: Looking to trace out at 45 degrees off the players center...
 
:D that's true ...

Maleficus 18-06-2004 19:39

Re: Looking to trace out at 45 degrees off the players center...
 
Thx for the info!

I'll give it a try later today when I have the time.



btw: yes, RTCW does have a "make_vectors" function, but its called "AngleVectors", which works exactly the same way (finds the forward, right, up vectors of a client).

Maleficus 18-06-2004 20:01

Re: Looking to trace out at 45 degrees off the players center...
 
Hmm. gave it a quick try, but it created a traceline facing upwards at 45 degrees, instead of outward (forward). I'll play with it some more when I have time (should be leaving for work already!).

btw: heres what the code looks like in RTCW:

Code:

  vec3_t angles, forward, start;
  trace_t tr;
 
  VectorCopy(ent->s.angles, angles);
  AngleVectors (angles, forward, NULL, NULL);
  start[2] += ent->client->ps.viewheight;
  forward[2] = 0;
  forward[1] += 45;
  if (forward[1] > 180)
  forward[1] -= 360;
 
  vectoangles(forward, right);
  VectorMA(start, 100, right, end);
  trap_Trace(&tr, start, NULL, NULL, end, ent->s.number, MASK_SHOT);


Maleficus 19-06-2004 08:36

Re: Looking to trace out at 45 degrees off the players center...
 
Ugh - nevermind the above post or the posted code, in my hurray to leave for work, I made a TON of mistakes. I've got it working now just fine, thx for the help!

BTW: here is the correct code. :)

Code:

  VectorCopy(ent->s.angles, angles);
  angles[YAW] += 45;
  AngleVectors (angles, forward, NULL, NULL);
  VectorCopy(ent->r.currentOrigin, start);
  VectorMA(start, 100, forward, end);
  trap_Trace(&tr, start, NULL, NULL, end, ent->s.number, MASK_SHOT);


Pierre-Marie Baty 19-06-2004 23:57

Re: Looking to trace out at 45 degrees off the players center...
 
that looks very similar to HL code in fact... because our MAKE_VECTORS is actually a macro that calls AngleVectors()...

And Vector is a class to handle better the engine's vec3_t structure :)

VERY similar. Very interesting for the United Bot...

Whistler 20-06-2004 01:57

Re: Looking to trace out at 45 degrees off the players center...
 
HL is based on Quake1, and RTCW is based on Quake3 so that's why they are similar :) and Quake1, Quake2, Quake3, RTCW are all in C instead of C++.

"because our MAKE_VECTORS is actually a macro that calls AngleVectors()..."
it doesn't call AngleVectors() but g_engfuncs.pfnMakeVectors() although they are actually the same thing :)

sfx1999 20-06-2004 04:09

Re: Looking to trace out at 45 degrees off the players center...
 
Pierre haven't you looked at Quake code yet? Please note that HL is based off Quake I and not Quake II. Also, make sure it is the QuakeWorld server code (unless you want client stuff).

In Quake I's mathlib.h:

Code:

/*
 Copyright (C) 1996-1997 Id Software, Inc.
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 
 See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 */
 // mathlib.h
 
 typedef float vec_t;
 typedef vec_t vec3_t[3];
 typedef vec_t vec5_t[5];
 
 typedef        int        fixed4_t;
 typedef        int        fixed8_t;
 typedef        int        fixed16_t;
 
 #ifndef M_PI
 #define M_PI                3.14159265358979323846        // matches value in gcc v2 math.h
 #endif
 
 struct mplane_s;
 
 extern vec3_t vec3_origin;
 extern        int nanmask;
 
 #define        IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
 
 #define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
 #define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];}
 #define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
 #define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
 
 void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc);
 
 vec_t _DotProduct (vec3_t v1, vec3_t v2);
 void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out);
 void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out);
 void _VectorCopy (vec3_t in, vec3_t out);
 
 int VectorCompare (vec3_t v1, vec3_t v2);
 vec_t Length (vec3_t v);
 void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross);
 float VectorNormalize (vec3_t v);                // returns vector length
 void VectorInverse (vec3_t v);
 void VectorScale (vec3_t in, vec_t scale, vec3_t out);
 int Q_log2(int val);
 
 void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
 void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]);
 
 void FloorDivMod (double numer, double denom, int *quotient,
                int *rem);
 fixed16_t Invert24To16(fixed16_t val);
 fixed16_t Mul16_30(fixed16_t multiplier, fixed16_t multiplicand);
 int GreatestCommonDivisor (int i1, int i2);
 
 void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
 int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
 float        anglemod(float a);
 
 void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
 
 
 #define BOX_ON_PLANE_SIDE(emins, emaxs, p)        \
        (((p)->type < 3)?                                        \
        (                                                                    \
                ((p)->dist <= (emins)[(p)->type])?        \
                    1                                                        \
                :                                                            \
                (                                                            \
                        ((p)->dist >= (emaxs)[(p)->type])?\
                            2                                                \
                    :                                                        \
                            3                                                \
                )                                                            \
        )                                                                    \
        :                                                                    \
                BoxOnPlaneSide( (emins), (emaxs), (p)))


sfx1999 20-06-2004 04:13

Re: Looking to trace out at 45 degrees off the players center...
 
Make sure that you can change that angle!!!

When your bots zoom in with a rifle, it WILL change their FOV. If you don't the bots will be able to see anything as if they were not zoomed in.


Whistler 20-06-2004 04:24

Re: Looking to trace out at 45 degrees off the players center...
 
well, here's some more implementions of HL engine functions. Some of them are "crazily" optimized :D
I also inlined all of them to make them faster
Code:

inline float UTIL_AngleMod(float a)
{
  // this function adds or substracts 360 enough times needed to the given angle in
  // order to set it into the range [0, 360) and returns the resulting angle. Letting
  // the engine have a hand on angles that are outside these bounds may cause the
  // game to freeze by screwing up the engine math code.

  return (360.0 / 65536) * ((int)(a * (65536.0 / 360.0)) & 65535);
}

inline float AngleNormalize(float angle)
{
  // this function adds or substracts 360 enough times needed to the given angle in
  // order to set it into the range [-180, 180) and returns the resulting angle. Letting
  // the engine have a hand on angles that are outside these bounds may cause the game
  // to freeze by screwing up the engine math code.

  return (360.0 / 65536) * ((int)((angle + 180) * (65536.0 / 360.0)) & 65535) - 180;
}

inline void ClampAngles(Vector &vecAngles)
{
  vecAngles.x = AngleNormalize(vecAngles.x);
  vecAngles.y = AngleNormalize(vecAngles.y);
  vecAngles.z = 0;
}

void
#ifndef __BORLANDC__
inline
#endif
SinCos( float rad, float *flSin, float *flCos )
{
#ifdef __linux__
  register double __cosr, __sinr;
  __asm __volatile__ ("fsincos" : "=t" (__cosr), "=u" (__sinr) : "0" (rad));
  *flSin = __sinr;
  *flCos = __cosr;
#else
#if !defined(__BORLANDC__) && !defined(_MSC_VER)
  *flSin = sinf(rad);
  *flCos = cosf(rad);
#else
  __asm
  {
      fld DWORD PTR[rad]
      fsincos
      mov edx, DWORD PTR[flCos]
      mov eax, DWORD PTR[flSin]
      fstp DWORD PTR[edx]
      fstp DWORD PTR[eax]
  }
#endif
#endif
}

inline float UTIL_AngleDiff( float destAngle, float srcAngle )
{
  return AngleNormalize(destAngle - srcAngle);
}

inline float UTIL_VecToYaw( const Vector &vec )
{
  // the purpose of this function is to convert a spatial location determined by the vector
  // passed in into an absolute Y angle (yaw) from the origin of the world.

  if (vec.x == 0 && vec.y == 0)
      return 0;
  else
      return atan2(vec.y, vec.x) * (180 / M_PI);
}

inline Vector UTIL_VecToAngles( const Vector &vec )
{
  // the purpose of this function is to convert a spatial location determined by the vector
  // passed in into absolute angles from the origin of the world.

  float yaw, pitch;

  if (vec.x == 0 && vec.y == 0)
  {
      yaw = 0;
      pitch = (vec.z > 0) ? 90 : 270;
  }
  else
  {
      yaw = atan2(vec.y, vec.x) * (180 / M_PI);
      pitch = atan2(vec.z, vec.Length2D()) * (180 / M_PI);
  }

  return Vector(pitch, yaw, 0);
}

inline void UTIL_MakeVectors( const Vector &vecAngles )
{
  float sp = 0, cp = 0, sy = 0, cy = 0, sr = 0, cr = 0;
  float angle = vecAngles.x * (M_PI / 180);
  SinCos(angle, &sp, &cp);
  angle = vecAngles.y * (M_PI / 180);
  SinCos(angle, &sy, &cy);
  angle = vecAngles.z * (M_PI / 180);
  SinCos(angle, &sr, &cr);

  gpGlobals->v_forward.x = cp * cy;
  gpGlobals->v_forward.y = cp * sy;
  gpGlobals->v_forward.z = -sp;
  gpGlobals->v_right.x = -sr * sp * cy + cr * sy;
  gpGlobals->v_right.y = -sr * sp * sy - cr * cy;
  gpGlobals->v_right.z = -sr * cp;
  gpGlobals->v_up.x = cr * sp * cy + sr * sy;
  gpGlobals->v_up.y = cr * sp * sy - sr * cy;
  gpGlobals->v_up.z = cr * cp;
}


sfx1999 20-06-2004 04:43

Re: Looking to trace out at 45 degrees off the players center...
 
Hey look Quake I's mathlib.h is extremely similar to Half-life's mathlib.h.

Pierre-Marie Baty 20-06-2004 07:53

Re: Looking to trace out at 45 degrees off the players center...
 
@Whistler: somehow these comments remind me of something, but I cant remember what ? I can swear I've seen them earlier......
the style looks like the comments I was making in the first RACC preview.....

Whistler 21-06-2004 10:44

Re: Looking to trace out at 45 degrees off the players center...
 
Yes, that is your comments. Besides, I have changed "-180/+180" to "[-180, 180)".


All times are GMT +2. The time now is 15:34.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.