private static bool Intersects(CircleCollider circle, ShapeCollider shape) { float2 nearest = shape.position + shape.points[0]; float minDistance = math.distancesq(circle.position, nearest); for (int i = 1; shape.points.Count > i; i++) { float distance = math.distancesq(circle.position, shape.position + shape.points[i]); if (minDistance > distance) { minDistance = distance; nearest = shape.position + shape.points[i]; } } float2 axis = math.normalizesafe(nearest - circle.position); if (LineOverlap(Project(shape, axis), Project(circle, axis)) == 0) { return(false); } for (int i = 0; shape.points.Count > i; i++) { axis = math.normalizesafe(shape.edges[i].perpendicular()); if (LineOverlap(Project(shape, axis), Project(circle, axis)) == 0) { return(false); } } return(true); }
private static bool ContainedBy(ShapeCollider shapeCollider, RectangleCollider rectangleCollider) { for (int i = 0; shapeCollider.points.Count > i; i++) { if (!ContainedBy(shapeCollider.position + shapeCollider.points[i], rectangleCollider)) { return(false); } } return(true); }
private static bool ContainedBy(ShapeCollider shapeColliderA, ShapeCollider shapeColliderB) { for (int i = 0; shapeColliderA.points.Count > i; i++) { if (!ContainedBy(shapeColliderA.position + shapeColliderA.points[i], shapeColliderB)) { return(false); } } return(true); }
private static float2 Depenetrate(CircleCollider circle, ShapeCollider shape) { float2 nearest = shape.position + shape.points[0]; float lowest = math.distancesq(circle.position, nearest); for (int i = 1; shape.points.Count > i; i++) { float distance = math.distancesq(circle.position, shape.position + shape.points[i]); if (lowest > distance) { lowest = distance; nearest = shape.position + shape.points[i]; } } float2 depenetration = float2.zero; float depth = float.PositiveInfinity; float2 axis = math.normalizesafe(nearest - circle.position); float overlap = LineOverlap(Project(shape, axis), Project(circle, axis)); if (overlap == 0) { return(float2.zero); } if (depth > overlap) { depth = overlap; depenetration = axis; } for (int i = 0; shape.points.Count > i; i++) { axis = math.normalizesafe(shape.edges[i].perpendicular()); overlap = LineOverlap(Project(shape, axis), Project(circle, axis)); if (overlap == 0) { return(float2.zero); } if (depth > overlap) { depth = overlap; depenetration = axis; } } return(depenetration * depth * (math.dot(depenetration, shape.position - circle.position) >= 0 ? -1 : 1)); }
private static float2 Project(ShapeCollider shape, float2 axis) { float min = math.dot(shape.position + shape.points[0], axis); float max = min; for (int i = 1; shape.points.Count > i; i++) { float dot = math.dot(shape.position + shape.points[i], axis); min = math.min(min, dot); max = math.max(max, dot); } return(new float2(min, max)); }
private static bool ContainedBy <T>(ShapeCollider shapeColliderA, T colliderB) where T : AbstractCollider { switch (colliderB) { case CircleCollider circleColliderB: return(ContainedBy(shapeColliderA, circleColliderB)); case RectangleCollider rectangleColliderB: return(ContainedBy(shapeColliderA, rectangleColliderB)); case ShapeCollider shapeColliderB: return(ContainedBy(shapeColliderA, shapeColliderB)); default: return(false); } }
private static float2 Depenetrate(ShapeCollider shapeA, ShapeCollider shapeB) { float2 depenetration = float2.zero; float depth = float.PositiveInfinity; for (int i = 0; shapeA.points.Count > i; i++) { float2 axis = math.normalizesafe(shapeA.edges[i].perpendicular()); float overlap = LineOverlap(Project(shapeA, axis), Project(shapeB, axis)); if (overlap == 0) { return(float2.zero); } if (depth > overlap) { depth = overlap; depenetration = axis; } } for (int i = 0; shapeB.points.Count > i; i++) { float2 axis = math.normalizesafe(shapeB.edges[i].perpendicular()); float overlap = LineOverlap(Project(shapeA, axis), Project(shapeB, axis)); if (overlap == 0) { return(float2.zero); } if (depth > overlap) { depth = overlap; depenetration = axis; } } return(depenetration * depth * (math.dot(depenetration, shapeB.position - shapeA.position) >= 0 ? -1 : 1)); }
private static bool Raycast(float2 from, float2 to, ShapeCollider shape) { if (ContainedBy(from, shape) || ContainedBy(to, shape)) { return(true); } int previous = shape.points.Count - 1; for (int i = 0; shape.points.Count > i; i++) { if (Raycast(from, to, shape.points[previous], shape.points[i])) { return(true); } previous = i; } return(false); }
private static bool ContainedBy(float2 point, ShapeCollider shapeCollider) { bool result = false; int j = shapeCollider.points.Count - 1; float2 position = shapeCollider.position; for (int i = 0; shapeCollider.points.Count > i; i++) { float2 current = position + shapeCollider.points[i]; float2 previous = position + shapeCollider.points[j]; if ((point.y > current.y && previous.y >= point.y || point.y > previous.y && current.y >= point.y) && point.x > current.x + (point.y - current.y) / (previous.y - current.y) * (previous.x - current.x)) { result = !result; } j = i; } return(result); }
private static bool Intersects <T>(ShapeCollider shapeColliderA, T colliderB) where T : AbstractCollider { switch (colliderB) { case CircleCollider circleColliderB: return(Intersects(shapeColliderA, circleColliderB)); case RectangleCollider rectangleColliderB: switch (shapeColliderA) { case RectangleCollider rectangleColliderA: return(Intersects(rectangleColliderA, rectangleColliderB)); case PolygonCollider polygonColliderA: return(Intersects(polygonColliderA, rectangleColliderB)); default: return(false); } case PolygonCollider polygonColliderB: switch (shapeColliderA) { case RectangleCollider rectangleColliderA: return(Intersects(rectangleColliderA, polygonColliderB)); case PolygonCollider polygonColliderA: return(Intersects(polygonColliderA, polygonColliderB)); default: return(false); } default: return(false); } }
private static float2 Depenetrate <T>(ShapeCollider shapeColliderA, T colliderB) where T : AbstractCollider { switch (colliderB) { case CircleCollider circleColliderB: return(Depenetrate(shapeColliderA, circleColliderB)); case RectangleCollider rectangleColliderB: switch (shapeColliderA) { case RectangleCollider rectangleColliderA: return(Depenetrate(rectangleColliderA, rectangleColliderB)); default: return(Depenetrate(shapeColliderA, rectangleColliderB as ShapeCollider)); } case ShapeCollider shapeColliderB: return(Depenetrate(shapeColliderA, shapeColliderB)); default: return(float2.zero); } }
private static float2 Depenetrate(ShapeCollider shape, CircleCollider circle) => - Depenetrate(circle, shape);
public AABB(ShapeCollider collider) : this(collider.position, collider.points) { }
private static bool Intersects(ShapeCollider shape, CircleCollider circle) => Intersects(circle, shape);