Commit graph

2,282 commits

Author SHA1 Message Date
Admin
9c514b601b Map: draw_svg last packed read (clip radius)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
3d5c54f2f3 Map: packed layout v2 — stroke_dist f32 (f16 overflow rainbowed long roads), shape_id+param0 pair, param3+clip_radius pair; draw_svg packed
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
52c836256c Map: GPU-pack on the builder thread — uploads ship pre-packed, drain unthrottled
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
1c563efc20 Shader: unpack2f16/unpack4u8 registered in shader scope + CPU impls (bit-exact)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
63b48a0de5 Map: packed vertex format live — 19 f32 (76B) -> 12 slots (48B) per vertex
VectorVertexPacked: f16 pairs (uv, dist+shape, param0+3, param1+2, clipr)
and unorm8x4 color bitcast into f32 slots, unpacked by the new shader
intrinsics; positions, stroke_mult sentinels, param4 icon composite,
param5 depth ladder and zbias stay f32. Emitters unchanged — one packer
runs at upload (map tiles + generic vector picture path). -37% vertex
fetch bandwidth across every map buffer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
196539995c Shader compiler: unpack2f16/unpack4u8 intrinsics (Metal) — packed map vertex format foundation
One f32 geometry slot carries two f16s or four unorm8s; the vertex fn
unpacks via _mp_ helpers in the MSL preamble. Type checker: float ->
vec2f/vec4f. GLSL/WGSL mappings + headless Rust-backend impl to follow
with the packed layout itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
7ee121d2f6 Map: 3D LOD radii tilt-aware — full frustum keeps 3D, only deep horizon sinks
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
2c8cfd79d5 Map: 3D distance LOD sinks heights instead of alpha-fading (no see-through walls)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
9feb1ebfee Map: 3D-volume LOD — walls/trees/roofs split to fill_3d, ground-circle distance fade
The 3D suffix between the fills and buildings laps splits off; the draw
fades it from 0.75 to 1.5 viewport-heights around the view focus. Under
tilt the far (blurred) field skips the bulk of the fill vertex mass;
flat views are inside the near radius everywhere.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
c073c08596 Revert to known-good: pass batching opt-in (MAKEPAD_BATCH_PASSES=1), AI loading opt-in (MAKEPAD_AI=1)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
b387a6d5be Metal: flush batched offscreen buffer at present-pass ENTRY — restore GPU/CPU pipelining
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
c59fe0b0eb Metal: frame-batched command buffer for offscreen passes + big benchmark window
Texture-mode passes append to one retained command buffer flushed at the
window pass (safety flush at repaint start for texture-only frames) —
the 12-pass gauss pyramid paid ~1ms commit/schedule latency PER PASS.
Profiling mode (MAKEPAD_GPU_PROFILE) keeps per-pass buffers so spans
stay attributable. Startup window 3400x2050 for pixel-heavy iteration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
f1a883729b Map: fringe band split — AA skirts skipped at strong tilt (~2/3 of casing verts)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
d63b4732b4 Map: icon zoom-banding — street-band icons (floor>16) split to a gated pass
Post-build O(n) partition on the per-vertex zoom-floor slot; pass 4 draws
the band only at view >= 16.25. Kills millions of shader-collapsed icon
verts per frame at mid zooms.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
097a57ab70 Metal: MAKEPAD_GPU_PROFILE=1 per-pass GPU profiler + gpu_ms in map frame log
Per command buffer: pass debug name, GPU start->end interval, draw calls,
vertices, instances, upload bytes — accumulated and printed as a 1Hz
table from the completion threads. Map frame stats gain gpu_ms/gpu_max
from the existing PERF_CHANNEL_GPU ring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
e61b9af7fc Fix all compile warnings across map crates (unused mut/import, key visibility)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
ec3c78e892 Map: frame-stats logger splits icons_ms/tail_ms — hunting the 10ms draw baseline
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
768fc340a7 route: NL-first iteration — app reads nl-kf-test 4-keyframe cut (15-18 + shadows)
Europe re-cut with these buckets happens on explicit go; the NL cut
lives in local/maps (untracked) for cross-session stability.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
fea68f8c22 Map: labels pan/zoom on the GPU — cam_scale/cam_shift uniforms, glyphs emit in cached space
The cache-hit path re-emitted every glyph CPU-side with the pan shift
baked into vertices; under tilt that visibly trailed the tile geometry
(which pans purely by uniform). The pan/zoom delta now rides two new
uniforms applied before the existing camera-delta matrix, in the same
frame as map_offset — labels physically cannot lag the map. Pin-interior
text keeps constant px via a billboard instance flag.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
7b02d81023 Map: labels ride the pan — re-place at rest, not every 48px/125ms mid-gesture
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
075f8ed507 Map: switch-only integer keyframes 15-18 (face morph stays opt-in experiment)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
85c1c1a531 Map: morph offsets = smoothed direction x full half-width (constant-width morph)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
c6c5197a10 Map: fringe outer-carrier verts ride rigidly with their boundary partner
Pinned carriers stretched the 1px AA band into a wide smear at corr>1 —
the dirty road edges across the morph band.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
db0f938621 Map: smooth morph-offset vectors along rings — clean interpolation path
At the keyframe corr==1 cancels offsets entirely, so ring-circular 1-2-1
smoothing (3 passes) costs zero keyframe fidelity; mid-morph the edge no
longer saw-tooths where junction wrap-arounds swing miter direction
per vertex.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
edc4c433e0 Map: clamped face_correction uniform + face expand-class band — stale cross-band tiles widen, never invert
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
a7a11c670b Map: bake deck shadows into the shadow section — the last unbaked boolean
The deck-shadow dissolve ran after the bake sink's early return, so no
cut ever contained it and every dz-covered street tile paid ~59ms at
runtime (found via emit-section fencing: ebuild=59). Extracted
dissolve_deck_shadows; the sink concatenates it into the baked shadow
shapes (concat == today's two separate emits exactly); a shadow HIT now
gates the runtime block off. Also: face-arm/stroke-arm/events laps, icon
template cache, batched expanded writer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
83782badc0 Map: icon mesh template cache — memcpy + 4-slot patch per instance
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
82caed10d3 Map: band-top keyframes (15,18) + face-morph file flag
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
406c26c0b6 Map: face morph opt-in (MAKEPAD_FACE_MORPH=1) — inward morph inverts narrow features
Serving above the keyframe needs corr<1 (inward): narrow union features
self-cross into bowties, junction-pinned verts tear shards (user
screenshot, city center). Redesign queued: band-TOP keyframes (15,18)
so corr>=1 everywhere — outward-only morph is opaque-safe. App stable
pinned meanwhile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
c8062a4ad4 Map: morph offsets survive dz subdivision — decked city faces morph too
subdivide_face_mesh_morph carries the offset channel (midpoints average
endpoints); decked bodies emit via the expanded layout with per-vertex
deck override. Fixes the magnified-wide roads across bridge-dz coverage
(all central Amsterdam) at deep zoom.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
9893c8acc2 Map: tree template instancing + stalk-clearance cell grid
Street trees memcpy one origin-built mesh (anchor+zbias patch); icon
stalk clearance queries a building-ring cell grid instead of scanning
icons x groups x rings. Worst AMS 368 -> ~310ms serial.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
b8a126c47b Map: bounded point-key whitelist at the icon horizon — detail-merge 137 -> 54ms
The icon matchers read a finite key set; parsing micro-POI layers with
the whitelist off was ~140ms/tile at kf16. Worst AMS 504 -> 368ms serial.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:43 +02:00
Admin
19d231405b Map: finalcut v5 — actually two keyframes (14,16); v4 edit had not applied
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
b99f328f01 Map: distance-first tile eviction + self-scaling byte budget (street-zoom thrash)
Icon-horizon tiles run 50-85MB; a fixed 1.2GB budget sat below
visible+pan-ring at street zoom and pure LRU evicted the very neighbors
a circling pan re-enters — every loop around a center rebuilt its ring.
Budget now grows to hold 2x the visible set and eviction orders by
distance from the view center (LRU only as tiebreak): the ring survives,
the trail is what dies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
d0f92ed090 Map: finalcut v4 — two-keyframe morph cut (buckets 14,16)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
def3afd360 Map: morphable faces steps 3-5 — band-100 face emit, two-keyframe buckets, icon horizon
Morphable (flat, opaque, non-emissive) face bodies+fringes emit through
append_expanded_stroke_geometry (anchor = pos - miter*hw_key): the live
zoom re-widths them per frame via the existing width_correction path, and
the expanded branch already zeroes the fragment params faces with glow
would need — those stay pinned. render_bucket collapses to keyframes
{<=14 native, 15->14, >=16 -> 16}; icons include to a z18 horizon from
the high keyframe and reveal via the live icon_zoom uniform (mechanism
existed). Existing v3 streams serve both keyframes unchanged — the only
restyle event left on the zoom axis is the single 14<->16 crossover.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
91ddbd0061 Map: morphable faces step 2 — PaintFace carries per-vertex morph offsets
build_paint_faces maps every outline vertex's exact f32 coords to its
miter normal and emits offsets (normal x keyframe half-width) parallel to
body and fringe verts; junction blends, clip cuts, carrier outer edges
and translucent groups pin at zero.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
a23105c890 Map: morphable faces step 1 — ring_outward_normals (miter, winding-aware) + test
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
68fdf19a8e Map: pivot to morphable-faces prototype (AMS) before final Europe cut
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
781dd2c83e Map: bucket ceiling 17 + bake buckets 14-17 (rz18+ magnifies bucket 17)
5-bucket streams priced at ~2.6x (=130GB archive) — clamped instead:
rz18 shows bucket-17 geometry like any mid-gesture frame, GPU strokes
re-derive widths, nav icons survive. Consumption window 10..=18 stays
(harmless; ceiling makes >17 unreachable).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
af02364f40 Map: v3 shipped — shards carry cascade+shadow bakes, app verified on them + status.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
5a0839cb50 Map: finalcut outputs europe-base-br-v3 (shadow-baked cut)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
c2448ae0a9 Map: bake T3 building shadows into v3 faces buckets — docklands 2.7s -> 97ms
BakedFacesBucket v3 carries the dissolved shadow shapes + grounded
footprints under their own input signature (job rings/heights, sun,
scale, min-edge); the runtime shadow block on a HIT skips
sweep/dissolve/diff/open wholesale and tessellates the baked shapes
(b-sh-baked 0.5ms vs 0.2-2.6s). bake_tile_paint_faces now builds 3D so
the shadow pass runs at bake time; faces signatures are road-only and
stay valid. Night/dynamic-sun themes gate at bake_shadows and simply
never submit the shapes. Theme-independence test passes on v3; NL smoke:
8418/5388 2.7s -> 97ms, 8417/5387 1.6s -> 134ms, worst AMS rz16 258ms
honest (was 611ms with runtime shadows).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
d6f5084ad7 Map: honest shadow profiling — probe bakes shadows like the app, b-sh-* laps
The headless probe theme ran with bake_shadows OFF while every app theme
runs it ON, so all headless profiles silently skipped the shadow pass —
'155ms worst tile' excluded the 0.2-2.6s shadow dissolve the app pays
(user's 1.6-3.1s dockland tiles reproduce exactly now). Probe now bakes
shadows; b-jobs/b-sh-sweep/-dissolve/-diff/-open laps split the stage.
Buildings-buffer pre-reservation REVERTED (first-touch of ~240MB zero
pages per builder serialized 12 workers on the kernel fault path: 340ms
-> 3000ms in-app). Minkowski-sweep shadow silhouette tried and REVERTED
(epsilon-concave rings hand i_overlay self-crossing polygons, 10-15s;
also: f32-grid arithmetic in shadow geometry is load-bearing — f64-exact
translated points changed boolean coincidences and tripled dissolve
time). Real fix queued: bake dissolved shadow shapes per bucket.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
627f0bb04b Map: app reads .mkmap shards — MkmapReader + TileArchiveReader, varint-KV index v2
libs/mbtile_reader gains the .mkmap consumer: root.mkidx parse (Hilbert
tile ids, root ranges -> brotli leaf directories -> shard/offset/len),
positioned shard reads, same get_metadata/get_tile_decoded surface as
MbtilesReader; TileArchiveReader sniffs the path so mbtiles_path can
point at either. Index format v2 drops JSON: the metadata section is now
varint KV like the leaves (writer + reader; no serde in the container).
Loader, zoom-range probe and the headless harness go through the enum;
bridge-dz/overlay sidecars stay mbtiles. Harness parity via shards:
worst AMS rz16 164.7ms, z12 native 51.3ms — identical to mbtiles. App
repointed to local/maps/europe-base-br.mkmap (111 shards + root.mkidx,
the exact bytes a CDN would serve).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
e8c21892dd Map: bake bucket 15 (rz15 is a cruising zoom, not a transient band) + status.md
In-app at z15 every tile ran the 460ms runtime cascade (buckets were
14+16 only); NL smoke: worst rz15 key 600 -> 53ms. Europe final cut
rerunning with 14,15,16.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
9b4d871075 Map: repoint app to europe-base-br-v2 (theme-independent final cut) + pipeline script
Final cut: 9.38M tiles, 133,431 baked (9.6GB streams, zooms 10-14,
threshold 100ms), 107 shards under cap, 253,525 sampled byte-identical.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
b77bce2a61 Map: theme-independent paint structure — one faces bake for light/dark/circuit
Road-surface tier identity (RoadSurfaceKey) now carries a theme-stable
class id (fnv of the styling rule's kind) plus geometric fields instead of
resolved colors; identically-styled rules alias to one canonical id at
theme compile so kinds a theme paints the same still union as one tier.
Plaza grouping keys on alpha alone (road-polygon fills are one theme
constant). The bake input signature contains no colors, so recolor-only
themes (night, circuit city — user contract: themes only recolor, shadows
fade via alpha) share one baked stream: proven by
baked_faces_theme_independent (5 keys, identical signatures + regions
under a full recolor via probe_compiled_theme_recolored). Light output:
fills byte-equal, casing within 0.3% (same-rank painter tiebreak moved
from color values to class ids — visual check pending).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
e1b71501ec Map: v2 baked-faces input signature — skip tier ring construction on HIT
The bake guard now hashes the ring-construction INPUT (tier order/styles,
smoothed way points+dz, plaza rings, joint/portal end sets, clip) with a
deterministic FNV std-Hasher instead of hashing the constructed rings, so
a HIT skips road_ribbon_rings + per-ring field classification wholesale:
rings+fields 35.7 -> 0.8ms, worst AMS rz16 3D 224 -> 155ms (NL v2 bake,
byte-equal buffers vs the runtime cascade kill switch). BAKED_FACES_VERSION
2 rejects v1 streams (old semantic) into the safe fallback. Also: part-
centroid cell grid for the building cover test (buildings 25.5 -> 13.6ms,
Paris was 56ms), lookup-only cell maps switch SipHash for a multiply-rotate
hasher (DzField::sample), VisibleRegions: Clone for the OOB-region guard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Admin
fce6c68835 Map: repoint app to europe-base-br-faces-mz (mid-zoom baked) + midzoom pipeline script
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00