feat: Add support to use convex/concave Path shapes in PolygonComponent, PolygonHitbox and Polygon - #4048
Merged
Conversation
…n polygons Reports vertex counts and sampling error of walkContours, per-ray intersection cost, agreement between the crossings heuristic, containment, and odd parity for the inside-hitbox check on concave shapes, the effect of simplifying the sampled contour, and polygon-polygon intersection cost.
chore: Add benchmark comparing Path contour hitboxes with hand-written polygons
Runs the collision detection system with a hitbox sampled from a Path contour against circles, rectangles, hand-written polygons, and itself, next to the same scenes with a hand-written polygon of the same shape. The polygon scenes also compile on main, so the two can be compared by running the file on both branches.
…cations from segment intersection ShapeHitbox.intersections now passes the overlap of the two AABBs to the intersection systems, which already knew how to filter edges by a rect but never received one. LineSegment.intersections rejects segment pairs whose bounding boxes do not overlap before doing any math and no longer allocates Line objects or result lists for misses.
chore: Add a collision benchmark for Path contour hitboxes
perf: Only test polygon edges inside the hitbox overlap and drop allocations from segment intersection
luanpotter
reviewed
Sep 21, 2026
luanpotter
reviewed
Sep 21, 2026
luanpotter
reviewed
Sep 21, 2026
luanpotter
reviewed
Sep 21, 2026
luanpotter
reviewed
Sep 21, 2026
luanpotter
reviewed
Sep 21, 2026
luanpotter
approved these changes
Sep 21, 2026
luanpotter
left a comment
Member
There was a problem hiding this comment.
Overall, LGTM, nice addition! Left a few comments and questions, but nothing blocking
3 of 4 tasks
Contributor
Author
Thank you very much, Luan. :-) |
…tion and its benchmark
Contributor
Author
|
Apologies for the latest erroneous merge and subsequent revert... blush |
spydon
approved these changes
Sep 21, 2026
spydon
left a comment
Member
There was a problem hiding this comment.
Thanks for this massive undertaking, this will be really useful!
spydon
enabled auto-merge (squash)
September 21, 2026 17:30
spydon
added a commit
that referenced
this pull request
Sep 30, 2026
The `PathComponent` class [introduced](https://github.com/flame-engine/flame/pull/4048/changes#diff-0c50838cfe31110765e9616e8ae15ab9cbbd3818310d5376acf74f9bce14ea4e) in PR #4048 is moved from `examples/lib/commons` into `lib/src/geometry` in the core package, on suggestion from @spydon, and it gets a hitbox counterpart, `PathHitbox`, so that the pair mirrors `PolygonComponent` and `PolygonHitbox`. `PathComponent` renders a `Path` and follows each of its closed contours with a polygon, in the same way as `PolygonComponent.fromPath` follows a single contour. The polygons are kept as vertices, not as child components, and they decide whether a point is inside of the component. The constructor takes `sampling` and `tolerance` to control how the contours are followed, and `filter` to leave out the polygons that lie inside of the largest one, like the eyes of a face. `PathHitbox` is a `PathComponent` with `ShapeHitbox`, and it is a single hitbox: it collides, contains points and is hit by rays as a whole, whichever of its polygons is involved, and it reports one collision to its parent even when several polygons touch the other hitbox. It computes its aabb from all the polygons, a ray hits the nearest polygon, and it takes the `collisionType` like the other hitboxes. `PathPathIntersections`, `PathPolygonIntersections` and `CirclePathIntersections` are added to the intersection systems. The affected examples are updated accordingly, with a `CollidablePathComponent` in the examples that pairs a `PathComponent` with a `PathHitbox`. There is documentation for both classes in `shape_components.md` and `collision_detection.md`, and tests for `PathComponent` and `PathHitbox`. --------- Co-authored-by: Lukas Klingsbo <lukas.klingsbo@gmail.com> Co-authored-by: Lukas Klingsbo <me@lukas.fyi>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The purpose of this PR is to add support for using both convex and concave
Pathshapes when creatingPolygonComponent,PolygonHitboxandPolygonobjects: the contours of aPathobject are sampled and converted to a list of polygon vertices. Support for concave polygons, described below, is available inPolygonRayIntersection.A complete testbed for all changes is available here; the relevant examples have been ported here too.
The changes add to and introduce a few extensions:
PathExtensiononPathgetscontours,walkContours,walkContourAt,resizeTo,toOriginandcenteredPathMetricExtensiononPathMetrichaswalkContourPathMetricListExtensiononList<PathMetric>hascontoursLengthOffsetListExtensiononList<Offset>hasverticesandrectangleRectExtension.fromOffsetsandAabb2Extension.fromVerticescreate the bounds of a list of offsets and of verticesThe
walkContours,walkContourAtandwalkContourmethods extract the vertex lists from the contours of aPath:granularityparameter is that step, which defaults to1.0.toleranceare removed, which defaults to half of thegranularity. This also works across the point where a closed contour starts and ends.Direct construction from
Pathobjects is available via:PolygonComponent.fromPathPolygonHitbox.fromPathPolygon.fromPathAll three take the index of the
contourto use, the first one by default, and thegranularity, and only walk that contour of the path.As long as the
Pathcontours represent valid polygons, thePolygonRayIntersectionmixin now supports both convex and concave polygons. Whether the ray starts inside of the polygon is decided by the parity of the edges that it crosses, instead of their absolute quantity. The hits and the crossings come from the same test of which side of the ray each vertex is on, which both edges of a vertex share, so a ray through or next to a vertex is not misjudged and can not slip through between two edges.isSolidis now an argument of theShapeComponentconstructor, which the polygon, rectangle and circle components and their hitboxes pass on instead of assigning it in their constructor bodies.The shape components and collision detection pages of the documentation describe the new constructors, and no longer say that polygon hitboxes have to be convex.
In terms of performance, @spydon was kind enough to provide the new
path_collisionandpath_contourbenchmarks (thank you very much, Lukas.) There is also a newray_intersectionbenchmark for rays against concave and convex contour hitboxes.Checklist
docsand added dartdoc comments with///.examplesordocs.Breaking Change?
Related Issues
Closes #4040