1
0

feat: one California as one pack, behind ?one=1

The nesting preview is gone and this replaces it. That one drew each metro's
built scene inside the state board's under a similarity transform; the transform
was right and two independently built terrains then occupied the same ground and
interpenetrated. `cities/unify.ts` is the version with no seam to stitch,
because the way to not have two grids is to not have two grids: one `City`
carrying the state's landform and both metros' detail, so the engine builds one
world, one lattice and one terrain mesh.

**The merge is mostly a union and twice it must not be.** Everything that
describes a place in a `City` is absolute lat/lng, so hills, districts,
landmarks, bridges, ports and airports concatenate. Two do not:

  - `World.elevationAt` *blends* every hill covering a point, so leaving the
    state's coarse hills under a metro's fine ones adds their heights and lifts
    the whole Bay. 25 state hills are dropped where a metro replaces them.
  - The state's 17 districts include coarse stand-ins for both metros against
    the metros' 99 real ones, and both drawn is two cities in one place. 9 go.

Filtering is by centre-in-bounds, which is honest and not exact, and the file
says so rather than hiding it.

**The lattice was the whole question and the answer was measured, twice.**
`TODO.md` records a statewide lattice at metro fidelity as 23.7M points and
dead. That is true at San Francisco's own 45 m cell, because `buildAxis` refines
per *axis* — a plus, not a box — so two metros at opposite corners refine most
of the state. The blowup is a function of the fine cell and is gentle until 45 m,
so the first pass took 150 m / x8, or 1.23M points.

That rendered **1,114,226 triangles at the whole-board pose against a 440,000
cap**, and the useful part is where it did *not* come from: with every metro
building hidden, triangles fell by 43,000 and draw calls by 111. The buildings
were never the cost. Terrain was. So the fine cell is what a statewide board can
afford without terrain LOD, and that is **300 m / x16** — 0.18M points, 11.6x
finer than the state pack's 3,473 m cell and 6.7x coarser than San Francisco's
own board. Measured at that size: california 392,862 triangles of 440,000 and
california-drive 405,124 of 430,000, both green on desktop.

**And the detail LOD is the cheapest kind there is.** `createBlocks` now orders
every `detail` district's lots *last*, so hiding 99 districts' buildings is one
assignment to `InstancedMesh.count` — no second mesh, no second draw call, no
allocation, and nothing for `nightlights.ts` to learn, since it holds the same
mesh either way. Landmarks are one mesh each so theirs is a `visible` flag.

The reveal is two tests and needed both. Stand-off alone passes for the drive
chapter, whose camera sits a few tens of metres off the ground half way up the
state while being two hundred kilometres from the nearest building this governs
— measured, it failed `california-drive` on triangles for lots nobody could see.
So detail draws only when the camera is inside `DETAIL_STANDOFF_M` *and* its
**target** is within `DETAIL_REACH_M` of a detail district. The target rather
than the camera, because the target is what is being looked at.

`src/test/unify.test.ts` pins the two non-union merges, the detail marking and
the lattice size. Writing it turned up something worth keeping: **six hills are
named in both the state pack and a metro pack** — Marin Headlands, San Bruno
Mountain, Mount Diablo, Bolinas Ridge, Mount Gleason, Mount Wilson — so the
first version failed on San Francisco's own Marin Headlands, identified as a
state hill by its name. `ladder.ts` hit this with "Whole Board" on two boards.
A name is not an identity; the test keys on the object.

Known and not fixed: mobile draw calls are 428 of 415 and 315 of 280 on the
merged board, from the port, vessel and bridge layers that the state board never
carried before and that no LOD hides yet. That is why this is still a flag.
Default is untouched and the full budget passes with it off.

1,700 tests pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-24 02:19:14 -07:00
parent 122497088c
commit 15d7accdbb
6 changed files with 531 additions and 92 deletions
+16 -90
View File
@@ -73,6 +73,7 @@ import { createStage, deviceProfile } from "./engine/stage.ts";
import { daylightPhase } from "./engine/solar.ts";
import type { Aircraft, City, Marker, MarkerPalette, Port, View } from "./engine/types.ts";
import CALIFORNIA from "./cities/california.ts";
import { unifiedCalifornia } from "./cities/unify.ts";
import { reconciledCity } from "./cities/reconcile.ts";
import SAN_FRANCISCO from "./cities/sf.ts";
import SOCAL from "./cities/socal.ts";
@@ -151,7 +152,7 @@ import {
type WebcamFaceTextureAdapter,
} from "./profile/index.ts";
import type { ActorIdentity } from "./actors/controller.ts";
import { Group, SRGBColorSpace, Vector3, VideoTexture } from "three";
import { SRGBColorSpace, Vector3, VideoTexture } from "three";
import {
CALIFORNIA_AIR_ROUTE,
createAircraftPoseSnapshot,
@@ -224,8 +225,21 @@ import type {
} from "./realtime/index.ts";
import type { PresenceIndicator } from "./realtime/presenceIndicator.ts";
/**
* One full California, as **one pack**, behind `?one=1`.
*
* The first attempt at this nested each metro's built scene inside the state
* board's under a similarity transform. The transform was right and the result
* was not: two independently built terrains occupied the same ground and
* interpenetrated. `cities/unify.ts` is the answer that has no seam to stitch
* one `City` carrying the state's landform and both metros' detail, so the
* engine builds one world, one lattice and one terrain mesh. See that file for
* the measured lattice cost and for the two merges that are not a union.
*/
const ONE_CALIFORNIA = new URLSearchParams(location.search).get("one") === "1";
const CITIES: { id: string; label: string; city: City }[] = [
{ id: "california", label: "California", city: CALIFORNIA },
{ id: "california", label: "California", city: ONE_CALIFORNIA ? unifiedCalifornia().city : CALIFORNIA },
{ id: "sf", label: "Bay Area", city: SAN_FRANCISCO },
{ id: "socal", label: "SoCal", city: SOCAL },
];
@@ -2112,92 +2126,6 @@ async function buildBoard(
* `prefers-reduced-motion` collapses the whole thing to a cut, exactly as
* `arrive()` and `beginOfficeArrival` already do.
*/
/**
* One full California, as a **preview behind `?nest=1`. Off by default, and it
* is not finished.**
*
* ## What it is for
*
* The owner has asked for one map of the whole state rather than three boards,
* and the question that had to be answered before anyone spent a week on it was
* whether the three packs already *are* the detail tiers of one map and only
* ever needed drawing in one scene. They are. This is the evidence, shipped
* behind a flag for the same reason `reconcile` was: an argument about how a
* board looks is settled by looking at it.
*
* ## Why the placement is a similarity and nothing more
*
* `World.project` is a uniform scale in x/z with no vertical term, so a metro's
* ground enters the state board's space under a plain similarity transform:
* scale x/z by the ratio of metres-per-unit, scale y by the ratio of
* `exaggeration / metresPerUnit` separately, because the two boards stretch
* height by different amounts and translate to where the state board projects
* the metro's own centre. Measured: San Francisco is xz 0.04915, y 0.12764, at
* (-146.2, -27.5) on a 551-unit board; Southern California is xz 0.20351,
* y 0.89640, at (55.4, 201.8). Both land where they should, at the size they
* should be.
*
* ## What is broken in it, precisely
*
* **Two terrains occupy the same ground.** The state board's coarse mounds are
* still drawn under the metro's fine surface, so they interpenetrate: a block
* sits on a smooth coarse hill in one place and is buried in it three hundred
* metres away. That is the nested-grid stitching problem and it is the whole of
* the remaining work the coarse lattice needs a hole cut over each fine
* rectangle and the seam sewn. Nothing about the transform above is implicated.
*
* Also not done, and visible: the metros keep their own lighting-free lift into
* a scene whose rig belongs to the state board, no LOD decides which of the two
* grounds should draw, and the triangles are additive rather than traded.
*
* ## Why the cheap statewide lattice is possible at all
*
* `buildAxis` refines per **axis** a focus region refines its whole row and
* its whole column, a plus rather than a box which is why `TODO.md` records a
* statewide lattice at metro fidelity as 23.7M points and dead. Measured against
* the packs' real focus regions, per-*rectangle* refinement is **2.93M points
* and about 26 MB** at a 720 m coarse cell, against 0.75M for all three boards
* as they stand. The verdict in TODO is a fact about the lattice's shape, not
* about one California.
*/
const NEST = new URLSearchParams(location.search).get("nest") === "1";
/** The ground of a board, without its sky, its sea or its rig. */
const NESTED_LAYERS = ["terrain", "shorePlates", "blocks", "landmarks"] as const;
async function nestMetros(host: MountedBoard): Promise<void> {
if (!NEST || host.id !== "california") return;
const hostWorld = host.handle.world;
for (const id of ["sf", "socal"]) {
const entry = CITIES.find((candidate) => candidate.id === id);
if (entry === undefined) continue;
const built = await buildBoard(entry, new AbortController(), { quiet: true });
if (built === null) continue;
const metro = built.handle.world;
const group = new Group();
group.name = `nested:${id}`;
const xz = metro.metresPerUnit / hostWorld.metresPerUnit;
const y =
(hostWorld.city.verticalExaggeration / hostWorld.metresPerUnit) /
(metro.city.verticalExaggeration / metro.metresPerUnit);
const [px, pz] = hostWorld.project(metro.city.center.lat, metro.city.center.lng);
group.scale.set(xz, y, xz);
group.position.set(px, 0, pz);
/*
* `water` and `sea` are deliberately left behind. The state board already
* has an ocean at y=0 and a second one nested inside it is a z-fight rather
* than a sea which is the same defect the terrain still has, and the one
* place it was cheap to avoid.
*/
for (const name of NESTED_LAYERS) {
const source = built.handle.stageScene.scene.getObjectByName(name);
if (source === undefined) continue;
group.add(source);
}
host.handle.stageScene.scene.add(group);
}
}
async function presentBoard(record: MountedBoard): Promise<void> {
const outgoing = visibleBoard;
if (outgoing === record) {
@@ -2238,8 +2166,6 @@ async function presentBoard(record: MountedBoard): Promise<void> {
activateBoard(record);
hideSwitchProgress();
// The one-California preview. A no-op unless `?nest=1`; see `nestMetros`.
void nestMetros(record);
/*
* Arriving is itself a reason to look ahead.
*