Beispiel #1
0
        public static Collision2? FindCollision(Rectangle2 rectangle, Vector2 movement, Line2 line)
        {
            if (Vector2.Dot(movement, line.Normal()) >= 0)
                return null;

            var h = InFrontOf(rectangle.Center, line);
            var j = InFrontOf(rectangle.Center + movement, line);
            if (!h && !j)
                return null;

            var f1 = LineSegmentIntersection(line.Start, line.End, rectangle.TopLeft, rectangle.TopLeft + movement);
            var f2 = LineSegmentIntersection(line.Start, line.End, rectangle.TopRight, rectangle.TopRight + movement);
            var f3 = LineSegmentIntersection(line.Start, line.End, rectangle.BottomLeft, rectangle.BottomLeft + movement);
            var f4 = LineSegmentIntersection(line.Start, line.End, rectangle.BottomRight, rectangle.BottomRight + movement);

            if (!f1.HasValue && !f2.HasValue && !f3.HasValue && !f4.HasValue)
                return null;

            f1 = LinesIntersection(line.Start, line.End, rectangle.TopLeft, rectangle.TopLeft + movement);
            f2 = LinesIntersection(line.Start, line.End, rectangle.TopRight, rectangle.TopRight + movement);
            f3 = LinesIntersection(line.Start, line.End, rectangle.BottomLeft, rectangle.BottomLeft + movement);
            f4 = LinesIntersection(line.Start, line.End, rectangle.BottomRight, rectangle.BottomRight + movement);

            List<float> fs = new List<float>();

            if ((Vector2.Dot(rectangle.Top.Normal(), line.Normal()) <= 0) && (Vector2.Dot(rectangle.Left.Normal(), line.Normal()) <= 0))
                fs.Add(f1.Value);

            if ((Vector2.Dot(rectangle.Top.Normal(), line.Normal()) <= 0) && (Vector2.Dot(rectangle.Right.Normal(), line.Normal()) <= 0))
                fs.Add(f2.Value);

            if ((Vector2.Dot(rectangle.Bottom.Normal(), line.Normal()) <= 0) && (Vector2.Dot(rectangle.Left.Normal(), line.Normal()) <= 0))
                fs.Add(f3.Value);

            if ((Vector2.Dot(rectangle.Bottom.Normal(), line.Normal()) <= 0) && (Vector2.Dot(rectangle.Right.Normal(), line.Normal()) <= 0))
                fs.Add(f4.Value);

            var array = fs.OrderBy(x => x);

            if (!array.Any())
                return null;

            if (array.Last() < 0)
                return null;

            if (array.First() > 1)
                return null;

            Collision2 collision = new Collision2();

            collision.Value = MinLinesIntersection(rectangle, movement, line);
            collision.Line = line;

            return collision;
        }
Beispiel #2
0
        public static Vector2? FindCollision(Rectangle2 rectangle, Line2 line)
        {
            var f1 = SegmentsIntersection(rectangle.Top, line);
            var f2 = SegmentsIntersection(rectangle.Left, line);
            var f3 = SegmentsIntersection(rectangle.Right, line);
            var f4 = SegmentsIntersection(rectangle.Bottom, line);

            if (!f1.HasValue && !f2.HasValue && !f3.HasValue && !f4.HasValue)
                return null;

            var d = Math.Min(Math.Min(Distance(rectangle.TopLeft, line), Distance(rectangle.TopRight, line)), Math.Min(Distance(rectangle.BottomLeft, line), Distance(rectangle.BottomRight, line)));

            return -line.Normal() * d * 1.01f;
        }
Beispiel #3
0
 public bool IsGrounded(Rectangle2 rectangle)
 {
     var groundGeometry = GetCollisionGeometry().Where(x => x.Normal().Y > 0.5f);
     return CollisionDetector.FindCollision(rectangle + CollisionDetector.GetStaticCollisionResolvingVector(rectangle, groundGeometry), new Vector2(0, -0.1f), groundGeometry).HasValue;
 }
Beispiel #4
0
 public Vector2 GetFinalVelocity(Rectangle2 rectangle, Vector2 velocity)
 {
     return CollisionDetector.GetFinalMovement(rectangle, velocity, GetCollisionGeometry());
 }
Beispiel #5
0
 public Vector2 GetCollisionResolvingVector(Rectangle2 rectangle)
 {
     return CollisionDetector.GetStaticCollisionResolvingVector(rectangle, GetCollisionGeometry());
 }
Beispiel #6
0
 private static float MinLinesIntersection(Rectangle2 rectangle, Vector2 movement, Line2 line)
 {
     return Math.Min(
         Math.Min(
             LinesIntersection(rectangle.TopLeft, rectangle.TopLeft + movement, line.Start, line.End) ?? 1f,
             LinesIntersection(rectangle.TopRight, rectangle.TopRight + movement, line.Start, line.End) ?? 1f),
         Math.Min(
             LinesIntersection(rectangle.BottomLeft, rectangle.BottomLeft + movement, line.Start, line.End) ?? 1f,
             LinesIntersection(rectangle.BottomRight, rectangle.BottomRight + movement, line.Start, line.End) ?? 1f));
 }
Beispiel #7
0
 public static bool Collides(Rectangle2 rectangle, Vector2 movement, Line2 line)
 {
     return FindCollision(rectangle, movement, line).HasValue;
 }
Beispiel #8
0
 public static Vector2 GetStaticCollisionResolvingVector(Rectangle2 rectangle, IEnumerable<Line2> lines)
 {
     var staticCollisionResolvingVector = Vector2.Zero;
     foreach (var line in lines)
     {
         var partial = CollisionDetector.FindCollision(rectangle, line);
         if (partial.HasValue)
             staticCollisionResolvingVector = staticCollisionResolvingVector + partial.Value;
     }
     return staticCollisionResolvingVector;
 }
Beispiel #9
0
        public static Vector2 GetFinalMovement(Rectangle2 rectangle, Vector2 movement, IEnumerable<Line2> lines)
        {
            float damp = 0.99f;

            var v = movement;
            var v2 = Vector2.Zero;
            var step = rectangle;

            var collision = CollisionDetector.FindCollision(step, v, lines);

            while (collision.HasValue)
            {
                if (collision.Value.Value < 0)
                    break;

                v2 += v * collision.Value.Value * damp;
                step = step + v * collision.Value.Value * damp;
                //step = step + CollisionDetector.GetStaticCollisionResolvingVector(step, lines);

                v = GetSlidingVector(v, collision.Value.Line.Direction(), collision.Value.Value) * damp;

                collision = CollisionDetector.FindCollision(step, v, lines);
            }

            return v2 + v;
        }
Beispiel #10
0
        public static Vector2 FindMaxMovement(Rectangle2 rectangle, Vector2 movement, IEnumerable<Line2> lines)
        {
            var collision = FindCollision(rectangle, movement, lines);

            if (collision.HasValue)
                return movement * collision.Value.Value;
            else
                return movement;
        }
Beispiel #11
0
        public static Collision2? FindCollision(Rectangle2 rectangle, Vector2 movement, IEnumerable<Line2> lines)
        {
            var collisions = lines.Select(x => FindCollision(rectangle, movement, x)).Where(x => x.HasValue);

            if (collisions.Any())
                return collisions.OrderBy(x => x.Value.Value).First();
            else
                return null;
        }