Remove the corner helpers akgl_collide_rectangles no longer uses
akgl_rectangle_points, akgl_collide_point_rectangle, akgl_Point and akgl_RectanglePoints go. They were the intermediate form of an implementation that changed: akgl_collide_rectangles was eight corner-containment tests built on them, and it has been four span comparisons since the cross-case fix. Nothing outside tests/ called either function, and a point-in-rectangle test is four comparisons a caller can write without a struct conversion in front of them. akgl_collide_rectangles stays. It has two correct callers in the sidescroller asking a game-level overlap question -- a coin, a hazard, from an updatefunc -- where a bool is the whole answer and a proxy plus a narrowphase call would be computing a normal nothing reads. TODO.md records the split rather than leaving it to be rediscovered. Public API removal, so 194 exported akgl_ symbols against 196, and the manual's counts move with them. The perf suite loses its rectangle_points row; the all-pairs sweep stays as the control it is now labelled, and PERFORMANCE.md says what 0.8.0 measured against it -- 188.5 us for 32,640 pairs at 256 actors, where a whole step with collision attached is 54.1 us doing strictly more. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
This commit is contained in:
@@ -6,14 +6,12 @@ everything else passes around. The JSON accessors are the valuable part of this
|
||||
their status semantics are what every asset loader in the library is written against, and
|
||||
they are documented nowhere else.
|
||||
|
||||
## Rectangle overlap helpers
|
||||
## The rectangle overlap test
|
||||
|
||||
Three functions, all axis-aligned, all in `util.h`:
|
||||
One function, in `util.h`:
|
||||
|
||||
| Function | Question it answers |
|
||||
|---|---|
|
||||
| `akgl_rectangle_points(dest, rect)` | What are the four corners of this `SDL_FRect`? |
|
||||
| `akgl_collide_point_rectangle(p, r, collide)` | Is this point inside those corners? |
|
||||
| `akgl_collide_rectangles(r1, r2, collide)` | Do these two rectangles overlap? |
|
||||
|
||||
```c
|
||||
@@ -28,38 +26,19 @@ akerr_ErrorContext *boxes_touch(SDL_FRect *a, SDL_FRect *b, bool *hit)
|
||||
PASS(errctx, akgl_collide_rectangles(a, b, hit));
|
||||
SUCCEED_RETURN(errctx);
|
||||
}
|
||||
|
||||
/* Is the mouse over a button? Corners first, then the point test. */
|
||||
akerr_ErrorContext *point_in_box(int x, int y, SDL_FRect *box, bool *hit)
|
||||
{
|
||||
akgl_RectanglePoints corners;
|
||||
akgl_Point p;
|
||||
|
||||
PREPARE_ERROR(errctx);
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
p.z = 0;
|
||||
PASS(errctx, akgl_rectangle_points(&corners, box));
|
||||
PASS(errctx, akgl_collide_point_rectangle(&p, &corners, hit));
|
||||
SUCCEED_RETURN(errctx);
|
||||
}
|
||||
```
|
||||
|
||||
Four properties, all deliberate:
|
||||
Three properties, all deliberate:
|
||||
|
||||
**Axis-aligned only.** There is no rotation support and no separating-axis test. An actor
|
||||
drawn with a non-zero `angle` still collides as its unrotated box.
|
||||
**Axis-aligned only.** There is no rotation support and no separating-axis test here. If you
|
||||
want either, you want a collision shape — [Chapter 15](15-collision.md).
|
||||
|
||||
**Edges count as touching.** A point exactly on a boundary is inside; two rectangles sharing
|
||||
an edge and no area overlap. Both comparisons are `>=` and `<=`.
|
||||
**Edges count as touching.** Two rectangles sharing an edge and no area overlap. Every
|
||||
comparison is `<=`, and a version written with `<` would silently change what every pickup
|
||||
test in a consumer answers.
|
||||
|
||||
**`akgl_rectangle_points` truncates from `float` to `int`.** A rectangle at `x = 10.9` has
|
||||
its corners at 10. That is right for tile-grid work and wrong for sub-pixel work; if you
|
||||
need the latter, do not round-trip through it. **`akgl_collide_rectangles` no longer does**
|
||||
— it compares the spans in `float` directly, so a sub-pixel overlap registers.
|
||||
|
||||
**`z` is carried and never used.** `akgl_Point` has one, `akgl_rectangle_points` never
|
||||
writes it, and neither collision test reads it. These are 2D tests.
|
||||
**The comparison is in `float32_t`.** No intermediate form, no truncation, so an overlap
|
||||
smaller than a pixel registers.
|
||||
|
||||
### The arrangement it used to miss
|
||||
|
||||
@@ -84,21 +63,34 @@ tall thin character is exactly that shape. The header carried a `@note` describi
|
||||
than a fix.
|
||||
|
||||
It is four comparisons now, `r1.x <= r2.x + r2.w && r2.x <= r1.x + r1.w` on both axes.
|
||||
`<=` rather than `<` because [`akgl_collide_point_rectangle`](#rectangle-overlap-helpers) is
|
||||
inclusive on all four edges and these two have always agreed: touching counts.
|
||||
|
||||
**If you are upgrading from 0.7.x, two answers change.** The cross now reports `true`, which
|
||||
is the point. And because the comparison no longer round-trips through `akgl_Point`'s `int`
|
||||
members, overlaps and gaps smaller than a pixel are now seen rather than truncated away — so
|
||||
a pickup test that was accidentally forgiving by up to a pixel is no longer forgiving.
|
||||
**If you are upgrading from 0.7.x, three things change.** The cross now reports `true`, which
|
||||
is the point. The comparison no longer round-trips through an `int` intermediate, so overlaps
|
||||
and gaps smaller than a pixel are seen rather than truncated away — a pickup test that was
|
||||
accidentally forgiving by up to a pixel is no longer forgiving. And **four symbols are
|
||||
gone**:
|
||||
|
||||
**The library runs its own collision now** — see [Chapter 15](15-collision.md) — and it does
|
||||
not use these. `akgl_collision_test` works in centres and half-extents, answers with a normal
|
||||
and a depth rather than a boolean, and handles circles and capsules as well as boxes.
|
||||
| Removed in 0.8.0 | Why | What to write instead |
|
||||
|---|---|---|
|
||||
| `akgl_rectangle_points` | Built the corner form `akgl_collide_rectangles` no longer uses | Nothing. It had no other caller |
|
||||
| `akgl_collide_point_rectangle` | Same | `p.x >= r.x && p.x <= r.x + r.w` on both axes — four comparisons, and no `SDL_FRect`-to-corners conversion in front of them |
|
||||
| `akgl_Point` | Existed to carry an `int` position into the above, with a `z` nothing ever read | `SDL_FPoint`, if you want a point type |
|
||||
| `akgl_RectanglePoints` | Existed to carry four of them | — |
|
||||
|
||||
These stay because a game-level overlap question is not always a physics question: a
|
||||
minimap marker, a UI hit test, "is the cursor over this". For anything that should push or be
|
||||
pushed, use a collision shape.
|
||||
Nothing outside `tests/` called either function. They were the intermediate form of an
|
||||
implementation that changed.
|
||||
|
||||
### What stays, and why it is not collision
|
||||
|
||||
**The library runs its own collision** — [Chapter 15](15-collision.md) — and it does not use
|
||||
this. `akgl_collision_test` works in centres and half-extents, answers with a normal and a
|
||||
depth rather than a boolean, and handles circles and capsules as well as boxes.
|
||||
|
||||
`akgl_collide_rectangles` stays because a game-level overlap question is not always a physics
|
||||
question: a coin, a minimap marker, a UI hit test, "is the cursor over this". Both tutorials
|
||||
use it for pickups and hazards from an `updatefunc`, where a `bool` is the whole answer and a
|
||||
proxy, a broad-phase insert and a narrowphase call would be computing a normal nothing reads.
|
||||
For anything that should push or be pushed, use a collision shape.
|
||||
|
||||
## Path resolution
|
||||
|
||||
|
||||
Reference in New Issue
Block a user