Пример #1
0
        public bool CastRay(
            Vector2 origin,
            Vector2 normal,
            float distance,
            T attributes,
            out Raycast hit)
        {
            hit = default;

            if (IsCollidable)
            {
                var tileSize = TileSize.ToVector2();
                var gStart   = origin.ToGrid(tileSize, AbsolutePosition);
                var gEnd     = (origin + normal * distance).ToGrid(tileSize, AbsolutePosition);

                foreach (var location in PlotLine(gStart, gEnd))
                {
                    var tile        = GetTileShape(location);
                    var hitDetected = tile?.CastRay(origin, normal, distance, out hit) ?? false;
                    if (hitDetected && HasTags(location, attributes))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #2
0
        public static bool CastRay(
            Vector2 origin,
            Vector2 normal,
            float distance,
            Shape shape,
            out Raycast hit)
        {
            hit = default;

            if (shape is Circle)
            {
                return(CastRay(origin, normal, distance, shape as Circle, out hit));
            }

            var vertices  = shape.GetVertices();
            var polyNorms = vertices.Normalize();
            var polyNorm  = Vector2.Zero;
            var minDist   = 0f;
            var maxDist   = distance;

            for (int i = 0; i < vertices.Length; i++)
            {
                var num   = Vector2.Dot(polyNorms[i], vertices[i] - origin);
                var denom = Vector2.Dot(polyNorms[i], normal);
                if (denom == 0f && num < 0f)
                {
                    return(false);
                }

                if (denom < 0f && num < minDist * denom)
                {
                    minDist  = num / denom;
                    polyNorm = polyNorms[i];
                }
                else if (denom > 0f && num < maxDist * denom)
                {
                    maxDist = num / denom;
                }

                if (maxDist < minDist)
                {
                    return(false);
                }
            }

            if (polyNorm != Vector2.Zero)
            {
                hit.Contact  = origin + normal * minDist;
                hit.Normal   = polyNorm;
                hit.Depth    = distance - minDist;
                hit.Percent  = minDist.Divide(distance);
                hit.Distance = minDist;

                return(true);
            }

            return(false);
        }
Пример #3
0
        static bool CastRay(
            Vector2 origin,
            Vector2 normal,
            float distance,
            Circle circ,
            out Raycast hit)
        {
            hit = default;

            var m = origin - circ.Center;
            var b = Vector2.Dot(m, normal);
            var c = Vector2.Dot(m, m) - circ.Radius * circ.Radius;

            if (b > 0f && c > 0f)
            {
                return(false);
            }

            var discr = b * b - c;

            if (discr < 0f)
            {
                return(false);
            }

            var depth = -b - discr.Sqrt();

            if (depth.Between(0f, distance))
            {
                var contact = origin + normal * depth;

                hit.Contact  = contact;
                hit.Normal   = Vector2.Normalize(contact - circ.Center);
                hit.Depth    = distance - depth;
                hit.Percent  = depth.Divide(distance);
                hit.Distance = depth;

                return(true);
            }

            return(false);
        }
Пример #4
0
 public virtual bool CastRay(Vector2 origin, Vector2 normal, float distance, out Raycast hit)
 {
     hit = default;
     return(IsCollidable);
 }
Пример #5
0
 public bool CastRay(Vector2 origin, Vector2 normal, float distance, out Raycast hit)
 {
     return(Collision.CastRay(origin, normal, distance, this, out hit));
 }
Пример #6
0
 public sealed override bool CastRay(Vector2 origin, Vector2 normal, float distance, out Raycast hit)
 {
     return(base.CastRay(origin, normal, distance, out hit) &&
            Shape.CastRay(origin, normal, distance, out hit));
 }
Пример #7
0
        public sealed override bool CastRay(Vector2 origin, Vector2 normal, float distance, out Raycast hit)
        {
            if (base.CastRay(origin, normal, distance, out hit))
            {
                var tileSize = TileSize.ToVector2();
                var gStart   = origin.ToGrid(tileSize, AbsolutePosition);
                var gEnd     = (origin + normal * distance).ToGrid(tileSize, AbsolutePosition);

                foreach (var location in PlotLine(gStart, gEnd))
                {
                    var tile        = GetTileShape(location);
                    var hitDetected = tile?.CastRay(origin, normal, distance, out hit) ?? false;
                    if (hitDetected)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }