Game Development Community

Angle to a wall...

by Paul /*Wedge*/ DElia · in Technical Issues · 03/09/2006 (7:24 am) · 3 replies

I've been working on some wall running code, and it's nearly complete save for some bugginess in the wall detection code. To determine if you can run on a wall, I do a forward raycast from the player when they jump, and compare the normal of the wall to the raycast to determine if it's within the "range" you can start a wall run from. The code is like this:

//This is an angle taken from the players forward vector
      %testAngle = mAtan(getWord(%offsetForward, 0), getWord(%offsetForward, 1));
      //This is an angle taken from the walls normal
      %wallAngle = mAtan(getWord(getNormalFromCollision(%forwardTest), 0), getWord(getNormalFromCollision(%forwardTest), 1));

      %differenceAngle = VectorSub(mRadToDeg(%testAngle), mRadToDeg(%wallAngle));
      
      //Is the wall to your right or left?
      if(%differenceAngle > 0)
         {%player.wrSide = "right"; %side = 3;}
         else
         {%player.wrSide = "left"; %side = 2;}         
      
      //Now we don't care if it's to the right or left
      %differenceAngle = mAbs(%differenceAngle);
            
      //Here we see if the relative angle is within the legal "range" to start a wall run
      //If so, we find a the vector along the wall to move the player on
         if(%differenceAngle >= $WallRunLowRange && %differenceAngle <= $WallRunHighRange ){
        ...(wall run setting code follows)

And this works in most cases, returning a value from 100-140 or so (the wall run range is set at 115-135), but in other cases I get an increase (or decrease) of 115 degrees and opposite polarity of the usual returns. I'm guessing this is what happens when the two angles come from other ends of the 180 to -180 return values, but I'm not sure if what I'm doing in the first place is at all right, or how to fix it.

#1
03/09/2006 (8:24 am)
I'm not sure what a wall run is,
but typically if you want to compare the direction of two vectors you're way ahead using vector dot-product instead of angles. dot product is loads faster and more stable than all the trigonometry stuff.

for example, in the above code it looks like you've got
%testVector and %wallVector, and want to compare them for similar direction.

try this:
pseudo code - i don't have the torquescript reference handy, but all these are doable in script.
%testVector = %offsetForward;
%wallVector = getNormalFromCollision(%forwardTest);

%testVector = vectorNormalize(%testVector);
%wallVector = vectorNormalize(%wallVector);

%dot = vectorDotProduct(%testVector, %wallVector);

// %dot is now in the range -1 to 1:
// 1 indicates the two vectors are exactly parallel,
// -1 indicates they're anti-parallel,
// 0 indicates they're perpendicular,
// and values in between indicate stuff in between.
// if you really want, you could get back your original %differenceAngle back like this:

%differenceAngle = aCos(%dot);

// %differenceAngle will range from 0 to 180, you might want to take the abs() of it to be safe.

// OR better, you could skip the aCos,
// and pre-calculate $wallRunLowRange and $wallRunHighRange as dot-product values.
// that is, $WRLRCos = cos($wallRunLowRange), $WRHRCos = cos($wallRunHighRange),
// and then do:

if (%dot > $WRLRCos || %dot < $WRHRCos)
   .. wall run setting code ..

one thing dot-product won't tell you is the left or right-ness of the two vectors.
eg, if wallVector is pointing to left or right hand side of testVector.

to determine that, you could do want something like:

%testVecRot90 = vectorRotate90DegreesCounterClockWiseAroundZ(%testVector);
%dot2 = vectorDotProduct(%testVecRot90, %wallVector);
if (%dot2 > 0)
  // wallVec is pointing to the left of testVec.
else
  // wallVec is pointing to the right of testVec. (or is perfectly parallel or anti-parallel)


function vectorRotate90DegreesCounterClockWiseAroundZ(%vec)
{
   %newVec.x = -%vec.y;
   %newVec.y =  %vec.x;
   %newVec.z =  %vec.z;
}


okay!
sorry for the long windedness and probably confusion.
i just woke up.

orion
#2
03/09/2006 (6:56 pm)
Thank you so much, I've been able to port all that stuff into my code and it works great now!
#3
03/09/2006 (8:14 pm)
Rock !