tower / cascadia / files / src / views / raster.ts
Branch cascadia · default branch · all branches
raster.ts
| 1 | /** |
| 2 | * Metadata for the rasters `npm run terrain` writes into static/. |
| 3 | * |
| 4 | * These must match the `render` block of content/geography.json — the generator |
| 5 | * reads that file, the browser only ever sees the PNGs, and nothing in between |
| 6 | * carries the numbers across. test/raster.test.ts asserts the two agree, because |
| 7 | * a silent disagreement here would displace the terrain rather than break it, and |
| 8 | * that failure mode has already cost this project once (D-024). |
| 9 | */ |
| 10 | export const RASTER_WIDTH = 2048 |
| 11 | export const RASTER_HEIGHT = 1192 |
| 12 | /** |
| 13 | * The working range terrain-height.png is stretched across: black is the floor of |
| 14 | * it, white the ceiling. It is deliberately not a round number and not anchored at |
| 15 | * zero — it only has to cover the terrain that exists, and the tighter it is the |
| 16 | * finer every step in it. Below zero is real: lake and sea floors are cut beneath |
| 17 | * the datum, and the old fixed 0..5,000 m encoding clipped them flat. |
| 18 | */ |
| 19 | export const RASTER_MIN_HEIGHT_M = -560 |
| 20 | export const RASTER_MAX_HEIGHT_M = 4400 |
| 21 | export const RASTER_HEIGHT_SPAN_M = RASTER_MAX_HEIGHT_M - RASTER_MIN_HEIGHT_M |
| 22 | |
| 23 | export const COLOR_RASTER = 'terrain-color.png' |
| 24 | export const HEIGHT_RASTER = 'terrain-height.png' |
| 25 | |
| 26 | /** |
| 27 | * Which surface the rasters describe. |
| 28 | * |
| 29 | * `canon` is Tower: authored geography, generated by `npm run terrain` from |
| 30 | * content/geography.json. `cascadia` is **not Tower** — it is the Pacific |
| 31 | * Northwest at 1:1, laid on the same cylinder because the ground from the Pacific |
| 32 | * surf east to the Columbia is 312.8 km and Tower's circumference is 314.2, so the |
| 33 | * real coast closes the ring on real terrain. It exists as a ruler, to answer "how |
| 34 | * big is this actually", and it carries no Tower geography whatsoever. See D-055. |
| 35 | */ |
| 36 | export type Surface = 'canon' | 'cascadia' |
| 37 | |
| 38 | export const isSurface = (v: unknown): v is Surface => v === 'canon' || v === 'cascadia' |
| 39 | |
| 40 | /** |
| 41 | * The two rasters for a surface. |
| 42 | * |
| 43 | * Every surface shares RASTER_WIDTH, RASTER_HEIGHT and the height window above — |
| 44 | * that is not a coincidence to be relied on quietly but a requirement, because the |
| 45 | * interior view bakes the window into its GLSL as literals and would otherwise |
| 46 | * need one shader per surface. test/raster.test.ts holds the generators to it. |
| 47 | */ |
| 48 | export function rasterSet(surface: Surface): { color: string; height: string } { |
| 49 | return surface === 'cascadia' |
| 50 | ? { color: 'cascadia-color.png', height: 'cascadia-height.png' } |
| 51 | : { color: COLOR_RASTER, height: HEIGHT_RASTER } |
| 52 | } |