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); }
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); }