Example #1
0
        bool TryDownCast(ref Ray ray, float length, out bool hasTraction, out SupportRayData supportRayData)
        {
            RayHit     earliestHit;
            Collidable earliestHitObject;

            supportRayData = new SupportRayData();
            hasTraction    = false;
            if (character.QueryManager.RayCast(ray, length, out earliestHit, out earliestHitObject))
            {
                float lengthSquared = earliestHit.Normal.LengthSquared();
                if (lengthSquared < Toolbox.Epsilon)
                {
                    //Don't try to continue if the support ray is stuck in something.
                    return(false);
                }
                Vector3.Divide(ref earliestHit.Normal, (float)Math.Sqrt(lengthSquared), out earliestHit.Normal);
                //A collidable was hit!  It's a support, but does it provide traction?
                earliestHit.Normal.Normalize();
                float dot;
                Vector3.Dot(ref ray.Direction, ref earliestHit.Normal, out dot);
                if (dot < 0)
                {
                    //Calibrate the normal so it always faces the same direction relative to the body.
                    Vector3.Negate(ref earliestHit.Normal, out earliestHit.Normal);
                    dot = -dot;
                }
                //This down cast is only used for finding supports and traction, not for finding side contacts.
                //If the detected normal is too steep, toss it out.
                if (dot > cosMaximumSlope)
                {
                    //It has traction!
                    hasTraction    = true;
                    supportRayData = new SupportRayData()
                    {
                        HitData = earliestHit, HitObject = earliestHitObject, HasTraction = true
                    };
                }
                else if (dot > SideContactThreshold)
                {
                    supportRayData = new SupportRayData()
                    {
                        HitData = earliestHit, HitObject = earliestHitObject
                    };
                }
                else
                {
                    return(false); //Too steep! Toss it out.
                }

                return(true);
            }
            return(false);
        }
Example #2
0
 bool TryDownCast(ref Ray ray, float length, out bool hasTraction, out SupportRayData supportRayData)
 {
     RayHit earliestHit;
     Collidable earliestHitObject;
     supportRayData = new SupportRayData();
     hasTraction = false;
     if (QueryManager.RayCast(ray, length, out earliestHit, out earliestHitObject))
     {
         float lengthSquared = earliestHit.Normal.LengthSquared();
         if (lengthSquared < Toolbox.Epsilon)
         {
             //Don't try to continue if the support ray is stuck in something.
             return false;
         }
         Vector3Ex.Divide(ref earliestHit.Normal, (float)Math.Sqrt(lengthSquared), out earliestHit.Normal);
         //A collidable was hit!  It's a support, but does it provide traction?
         earliestHit.Normal.Normalize();
         float dot;
         Vector3Ex.Dot(ref ray.Direction, ref earliestHit.Normal, out dot);
         if (dot < 0)
         {
             //Calibrate the normal so it always faces the same direction relative to the body.
             Vector3Ex.Negate(ref earliestHit.Normal, out earliestHit.Normal);
             dot = -dot;
         }
         //This down cast is only used for finding supports and traction, not for finding side contacts.
         //If the detected normal is too steep, toss it out.
         if (dot > ContactCategorizer.TractionThreshold)
         {
             //It has traction!
             hasTraction = true;
             supportRayData = new SupportRayData { HitData = earliestHit, HitObject = earliestHitObject, HasTraction = true };
         }
         else if (dot > ContactCategorizer.SupportThreshold)
             supportRayData = new SupportRayData { HitData = earliestHit, HitObject = earliestHitObject };
         else
             return false; //Too steep! Toss it out.
         return true;
     }
     return false;
 }