Routes: movers along waypoints (roadmap 8)
Deploy web Studio / deploy (push) Successful in 1m4s

New route prefab (routes.rhai): cars, buses, motorbikes, cyclists, people,
deer or elephants move along waypoints, round a loop or there and back.
Each way keeps to the left of the line (or right), corners are rounded
into pieces of at most 45 degrees; there-and-back routes become loops with
U-turns, so the two directions never share a strip.

Engine: Prim::Travel / sprite.begin_travel / script travel(a, b, dur,
windows) ... end(): the mover is drawn at a piece's start and slides to
its end while it is on that piece, hidden otherwise. The renderer writes
keyframes per piece (named by a hash of their content) into one <style>
per view. Each piece is its own sprite with the lane strip as its sort
extent (ext_reset), mitred at the corners, so movers pass in front of and
behind trees, lamps and houses. Movers that look alike and never meet on
a piece share one drawing. iso-travel pauses (not hides) in still,
reduced-motion and ghosted views.

Studio: meta shape "path" draws point by point (snapping like runs) and
saves one object with pts; ending on the first point closes the loop.
MCP: pts in the object schema, route guidance.

Demos: streets gets traffic round the block, a bus, motorbikes, cyclists
and strolling people (replacing the one-axis cars); country gets cars on
the lane.

Tests: Rust 79 (each mover on exactly one piece at every moment, in every
rotation), Studio 125, web 99.
This commit is contained in:
grabowski committed 2026-10-25 17:52:17 +07:00
1 parent ccfd619a99
commit 5ec164a633
20 files changed
+698 -23

No files matched your search

+21
View File
@@ -95,6 +95,8 @@ shaded automatically by face direction.
| `swim(x, y, z, [#{ rx, ry, dur, delay, cw, len, cls[, shape] }, ...])` | fish going round ellipses (radii rx, ry along the object's axes) about (x, y) on the plane at z, one round per `dur` s, clockwise when `cw`; `cls` koi / koiw / koig (the pond); `shape` "bird" (wings `len` across, flapping), "fly" (a butterfly) or "bee" makes it a flock |
| `seq([[x, y, \|q\| …], …])` | items drawn back to front by their anchor |
| `group(cls[, css], \|q\| …)`, `begin(cls[, css])` … `end()` | `<g>` around parts (animation) |
| `travel(a, b, dur, [[s, e], …])` … `end()` | a mover on a straight piece: what is drawn (at a) slides to b during each window (fractions of the `dur`-second cycle, may wrap past 1) and is hidden otherwise |
| `ext_reset()` | forget the sort extent drawn so far (set it with `ext` afterwards) |
| `ext(x, y, z)`, `ext_box(…)` | widen the sort box |
| `raw([x, y, z,] svg)` | raw SVG (`{uid}` becomes the view's id) |
@@ -166,6 +168,25 @@ spread within `r` of the object, each facing its rotation give or take 70°,
each its own sprite. Flocks of birds, butterflies and bees use `swim` with a
`shape`.
## Routes
`routes.rhai` (`route` prefab, meta `shape: "path"`: the Studio draws it point by point and
stores the points in the object's `pts`, relative to its x, y). The movers' path is one closed
line: a loop is offset to the left of the drawn line by the kind's lane (`keep: "right"` the
other way); an open route runs out on one side and back on the other, so it is a loop too, and
its two strips never overlap. Corners are rounded into pieces of at most 45° (`rt_round`;
people keep sharp corners, they look the same from every side).
Each straight piece is its own sprite in the piece's frame: for every group of movers that look
alike and are never on the piece together, `travel([0,0,0], [len,0,0], dur, wins)` with the
mover drawn at the start, then `ext_reset()` and the lane strip as its extent, mitred at both
ends so neighbouring pieces never overlap. Mover k is on a piece that starts `at` metres along
a loop of `total` metres while `(t / dur - at / total + k / n) mod 1` lies in `[0, len / total]`.
The renderer turns each travel into keyframes (visibility and translation, named by a hash of
their content, all in one `<style>` per view). Movers carry `iso-travel`, not `iso-a`: views
without animation (reduced motion, stopped, ghosted) pause them where they are instead of
hiding them.
## Production lines
`producer`, `conveyor` and `robot_arm` (stdlib/industry.rhai) work together