예제 #1
0
        private static bool AABBvsAABBOverlap(GameObject item1, GameObject item2, ref Collision collision)
        {
            float eps = 1e-3f;

            BoxAABB rect1 = item1.AABB;
            BoxAABB rect2 = item2.AABB;

            if (rect1.max.X <= rect2.min.X || rect1.min.X >= rect2.max.X ||
                rect1.max.Y <= rect2.min.Y || rect1.min.Y >= rect2.max.Y)
            {
                return(false);
            }

            bool biasX = item1.transform.position.X < item2.transform.position.X;
            bool biasY = item1.transform.position.Y < item2.transform.position.Y;

            float penX = biasX ? (rect1.max.X - rect2.min.X) : (rect2.max.X - rect1.min.X);
            float penY = biasY ? (rect1.max.Y - rect2.min.Y) : (rect2.max.Y - rect1.min.Y);
            float diff = penX - penY;

            collision.penetration = new Vector2(penX, penY);

            if (diff > eps)
            {
                collision.normal = new Vector2(0, biasY ? 1 : -1);
                return(true);
            }

            if (diff < -eps)
            {
                collision.normal = new Vector2(biasX ? 1 : -1, 0);
                return(true);
            }

            collision.normal = new Vector2(biasX ? 1 : -1, biasY ? 1 : -1);
            return(true);
        }
예제 #2
0
        private static bool AABBvsCircleOverlap(GameObject item1, GameObject item2, ref Collision collision)
        {
            float eps = 1e-3f;

            BoxAABB       rect   = item1.AABB;
            TransformBase rectTr = item1.transform;
            TransformBase circle = item2.transform;

            if (rectTr.position == circle.position)
            {
                return(false);
            }

            float   radius  = Math.Max(circle.size.X, circle.size.Y) / 2f;
            Vector2 closest = Vector2.Clamp(circle.position, rect.min, rect.max);

            if (closest == circle.position)
            {
                closest = circle.position.MoveTowards(rectTr.position, eps);
            }

            Vector2 normal = circle.position - closest;

            if (radius * radius <= normal.LengthSquared())
            {
                return(false);
            }

            float normalLen = normal.Length();
            float pen       = radius - normalLen;

            collision.penetration = new Vector2(pen);
            collision.normal      = normal / normalLen;

            return(true);
        }