WIP
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
# Step 07 — Swept AABB (the Minkowski trick)
|
||||
|
||||
Step 06 handled a moving **point** vs a box. But in a real game the thing that
|
||||
moves is a **box** (the player), not a point. This step turns "moving box vs box"
|
||||
into "moving point vs box" so you can reuse step 06 *unchanged*. That conversion
|
||||
is the single cleverest idea in the whole engine.
|
||||
moves is a **box** (the player), not a point. This step turns "moving box vs
|
||||
box" into "moving point vs box" so you can reuse step 06 _unchanged_. That
|
||||
conversion is the single cleverest idea in the whole engine.
|
||||
|
||||
## The problem
|
||||
|
||||
Box A (the player) sits at corner `(a.x, a.y)` with size `a.w × a.h`, and moves by
|
||||
`v` this frame. Box B (a wall) is static. When do they touch?
|
||||
Box A (the player) sits at corner `(a.x, a.y)` with size `a.w × a.h`, and moves
|
||||
by `v` this frame. Box B (a wall) is static. When do they touch?
|
||||
|
||||
It's fiddly because *both* shapes have size. You'd have to track four edges of A
|
||||
It's fiddly because _both_ shapes have size. You'd have to track four edges of A
|
||||
against four edges of B. Ugh.
|
||||
|
||||
## The trick: grow B, shrink A to a point
|
||||
@@ -22,14 +22,14 @@ spans `[b.x, b.x + b.w]`. They overlap when:
|
||||
a.x < b.x + b.w AND b.x < a.x + a.w
|
||||
```
|
||||
|
||||
Rearrange the second one (`b.x - a.w < a.x`) and you get a statement purely about
|
||||
**`a.x`**, the corner of A:
|
||||
Rearrange the second one (`b.x - a.w < a.x`) and you get a statement purely
|
||||
about **`a.x`**, the corner of A:
|
||||
|
||||
```
|
||||
b.x - a.w < a.x < b.x + b.w
|
||||
```
|
||||
|
||||
Read that: A's *corner* `a.x` behaves exactly like a **point** sliding inside a
|
||||
Read that: A's _corner_ `a.x` behaves exactly like a **point** sliding inside a
|
||||
**wider interval** — one that starts `a.w` earlier and is `a.w` longer than B.
|
||||
The same happens on y with `a.h`.
|
||||
|
||||
@@ -45,18 +45,18 @@ inflated = {
|
||||
point = { x: a.x, y: a.y } // A is now just its corner
|
||||
```
|
||||
|
||||
This grown box is the **Minkowski sum** of B with A. And "does this point, moving
|
||||
by `v`, hit `inflated`?" is *exactly* `rayVsAABB` from step 06. You're done in
|
||||
three lines.
|
||||
This grown box is the **Minkowski sum** of B with A. And "does this point,
|
||||
moving by `v`, hit `inflated`?" is _exactly_ `rayVsAABB` from step 06. You're
|
||||
done in three lines.
|
||||
|
||||
> Sanity picture: player box 2 wide with its right edge at x=2, wall left edge at
|
||||
> x=5 → real gap is 3. Inflate: `inflated.x = 5 - 2 = 3`, and the player's corner
|
||||
> sits at x=0, so the corner-to-inflated-edge gap is also 3. Same answer, simpler
|
||||
> shape. The inflation *bakes A's size into the wall* so the corner can pretend to
|
||||
> be a point.
|
||||
> Sanity picture: player box 2 wide with its right edge at x=2, wall left edge
|
||||
> at x=5 → real gap is 3. Inflate: `inflated.x = 5 - 2 = 3`, and the player's
|
||||
> corner sits at x=0, so the corner-to-inflated-edge gap is also 3. Same answer,
|
||||
> simpler shape. The inflation _bakes A's size into the wall_ so the corner can
|
||||
> pretend to be a point.
|
||||
|
||||
This is the heart of your real engine's `sweptAABB` — the `inflAABB` it builds is
|
||||
this very inflated box, and `(ax, ay)` is this corner point.
|
||||
This is the heart of your real engine's `sweptAABB` — the `inflAABB` it builds
|
||||
is this very inflated box, and `(ax, ay)` is this corner point.
|
||||
|
||||
## Task
|
||||
|
||||
|
||||
Reference in New Issue
Block a user