private CollisionInfo AABBvsAABB(AABB_Collider lhs, AABB_Collider rhs) { Vec2 lhsPos = new Vec2(lhs.transform.position.x, lhs.transform.position.y) + lhs.LocalOffset; Vec2 rhsPos = new Vec2(rhs.transform.position.x, rhs.transform.position.y) + rhs.LocalOffset; Vec2 lhsBottomLeft = lhs.BottomLeft + lhsPos; Vec2 lhsTopRight = lhs.TopRight + lhsPos; Vec2 rhsBottomLeft = rhs.BottomLeft + rhsPos; Vec2 rhsTopRight = rhs.TopRight + rhsPos; if (lhsBottomLeft.x < rhsTopRight.x && lhsTopRight.x > rhsBottomLeft.x && lhsTopRight.y > rhsBottomLeft.y && lhsBottomLeft.y < rhsTopRight.y) { Vec2 vMult = Vec2.One; Vec2 depth = Vec2.Zero; Vec2 colNorm = Vec2.Zero; if (lhsPos.x > rhsPos.x) { colNorm.x = -1f; depth.x = rhsTopRight.x - lhsBottomLeft.x; } else { colNorm.x = 1f; depth.x = rhsBottomLeft.x - lhsTopRight.x; } if (lhsPos.y > rhsPos.y) { colNorm.y = -1f; depth.y = rhsTopRight.y - lhsBottomLeft.y; } else { colNorm.y = 1f; depth.y = rhsBottomLeft.y - lhsTopRight.y; } if (Mathf.Abs(depth.x) > Mathf.Abs(depth.y)) { colNorm.x = 0f; depth.x = 0f; vMult.y = 0f; } else { colNorm.y = 0f; depth.y = 0f; vMult.x = 0f; } return(new CollisionInfo(true, depth, colNorm)); } return(new CollisionInfo()); }
private CollisionInfo CIRCLEvsAABB(Circle_Collider lhs, AABB_Collider rhs, bool invertNormal) { // Vector from A to B Vector3 n = lhs.transform.position - rhs.transform.position; // Closest point on A to center of B Vector3 closest = n; // Calculate half extents along each axis float x_extent = rhs.Width * 0.5f; float y_extent = rhs.Height * 0.5f; // Clamp point to edges of the AABB closest.x = Mathf.Clamp(closest.x, -x_extent, x_extent); closest.y = Mathf.Clamp(closest.y, -y_extent, y_extent); bool inside = false; // Circle is inside the AABB, so we need to clamp the circle's center // to the closest edge if (n == closest) { inside = true; // Find closest axis if (Mathf.Abs(n.x) > Mathf.Abs(n.y)) { // Clamp to closest extent if (closest.x > 0) { closest.x = x_extent; } else { closest.x = -x_extent; } } // y axis is shorter else { // Clamp to closest extent if (closest.y > 0) { closest.y = y_extent; } else { closest.y = -y_extent; } } } Vector3 normal = n - closest; float d = normal.sqrMagnitude; float r = lhs.Radius; float penetration = 0f; // Early out if the radius is shorter than distance to closest point and // Circle not inside the AABB if (d > r * r && !inside) { return(new CollisionInfo()); } // Avoided sqrt until needed d = Mathf.Sqrt(d); // Collision normal needs to be flipped to point outside if circle was // inside the AABB if (inside) { normal = invertNormal ? -normal : normal; } else { normal = invertNormal ? normal : -normal; } penetration = r - d; Vec2 depth = new Vec2(normal.x, normal.y).Normalize(); return(new CollisionInfo(true, depth * penetration, depth)); }