Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/GameUtils/Types/Geometry/AABB.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ public bool Intersects(Line line, out Vector2[] intersectionPoints)
#pragma warning disable S3267 // LINQ would reintroduce allocations on a hot collision path
public bool Intersects(Polygon2D polygon)
{
if (!Intersects(polygon.BoundingBox)) return false;

// 1. Fast bounds check: compute polygon bounds on the fly
if (polygon.Vertices.Length > 0)
{
Expand Down
2 changes: 2 additions & 0 deletions src/GameUtils/Types/Geometry/Circle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ public bool Intersects(Line line)
#pragma warning disable S3267 // LINQ would reintroduce allocations on a hot collision path
public bool Intersects(Polygon2D polygon)
{
if (!Intersects(polygon.BoundingBox)) return false;

foreach (var v in polygon.Vertices)
{
if (Contains(v)) return true;
Expand Down
27 changes: 27 additions & 0 deletions src/GameUtils/Types/Geometry/Polygon2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@ public readonly struct Polygon2D
/// Normals of each edge of the polygon
/// </summary>
public readonly Vector2[] Normals;

private readonly AABB[] _boundingBox;
#pragma warning restore S3887

/// <summary>
/// The axis-aligned bounding box of the polygon
/// </summary>
public AABB BoundingBox => _boundingBox[0];

/// <summary>
/// Creates a new polygon from the specified vertices. If <paramref name="sort"/> is true, the vertices will be sorted clockwise before creating the polygon.
/// </summary>
Expand All @@ -42,11 +49,18 @@ public Polygon2D(Vector2[] vertices, bool sort = true)
Edges = new Line[Vertices.Length];
Normals = new Vector2[Vertices.Length];

var min = new Vector2(float.MaxValue);
var max = new Vector2(float.MinValue);

for (var i = 0; i < Vertices.Length; i++)
{
Edges[i] = new Line(Vertices[i], Vertices[(i + 1) % Vertices.Length]);
Normals[i] = Vector2.Normalize(new Vector2(Edges[i].End.Y - Edges[i].Start.Y, Edges[i].Start.X - Edges[i].End.X));
min = Vector2.Min(min, Vertices[i]);
max = Vector2.Max(max, Vertices[i]);
}

_boundingBox = [new AABB(min, max)];
}

private static Vector2[] SortClockwise(Vector2[] vertices)
Expand Down Expand Up @@ -79,10 +93,23 @@ public bool Contains(Vector2 point)
/// </summary>
public void TranslateBy(Vector2 translation)
{
var min = new Vector2(float.MaxValue);
var max = new Vector2(float.MinValue);

for (var i = 0; i < Vertices.Length; i++)
{
Vertices[i] += translation;

min = Vector2.Min(min, Vertices[i]);
max = Vector2.Max(max, Vertices[i]);
}

for (var i = 0; i < Vertices.Length; i++)
{
Edges[i] = new Line(Vertices[i], Vertices[(i + 1) % Vertices.Length]);
}

_boundingBox[0] = new AABB(min, max);
}

/// <summary>
Expand Down
Loading