mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-12 06:12:18 +00:00
Build the catalog from one layer manifest and attach one tools tree
src/app/layers/renderers.js now holds LAYER_MANIFEST, one entry per layer in directory order: a display (the same render/display.js on every engine, with the contract primitives it needs and, for CCTV and Global Context, a Navara backend loaded by import()), a layer that draws itself through the contract, or per-engine renderers for the layers not on a display yet (weather, wind, Bhote Koshi, sea marks, ski pistes). A layer is available where the engine has the primitives it needs. The Cesium renderer table, CESIUM_BUILTIN, the registry and the Navara mode's map of about 35 loaders go; the application loads a kind's renderers before it builds the catalog. The tools attach through one tree over the engine, in Cesium's order. Each engine kind adds its own tools from one backend that reads its extension once: the Cesium backend holds the viewer-only tools, the Navara backend the annotation renderer, draw surface and file import drawing. Coupling: engine.extensions reads fall from 12 to 8, engine-name literal lines from 73 to 66.
This commit is contained in:
1 parent
f1ec9d4a22
commit
48885d9e61
46 files changed
+1057
-899
No files matched your search
+45
-12
@@ -194,14 +194,25 @@ one application, and only the globe-bound parts move to the next engine.
|
||||
corridors (a width in px or m), draped over terrain and 3D tiles. Each
|
||||
item has its own fill, outline and `pickId`. A set has a draw `order`, and
|
||||
shows, hides and replaces its items in bulk.
|
||||
- A pixel corridor can take Cesium's old looks: a `glow`
|
||||
(PolylineGlow's falloff), an alpha `pulse` and a flowing `dash` (the
|
||||
annotation route's). The GPU works them out from the time each frame;
|
||||
while a shown set has a pulse or a dash, the engine draws a frame after
|
||||
every frame, as Cesium's continuous render did. Traffic's jam heat
|
||||
lines glow and pulse, and the Directions route's dashes flow (it also
|
||||
holds continuous render again while drawn).
|
||||
- Cesium draws them with batched `GroundPrimitive` and
|
||||
`GroundPolylinePrimitive`.
|
||||
`GroundPolylinePrimitive`; a corridor with a look draws through one
|
||||
material of its own (`GevGroundCorridor`), which drew the jam lines and
|
||||
the route pixel for pixel as the old PolylineGlow and route flow
|
||||
materials did.
|
||||
- Navara draws them in one screen pass classified on the scene depth
|
||||
(`src/globe/navara/ground/`).
|
||||
(`src/globe/navara/ground/`). A corridor set is tiles of binned
|
||||
segments (`corridors.js`): 10,000 corridors draw in about 12 ms still
|
||||
and 15 ms moving, where Cesium takes 23 ms (the chunks before took 151
|
||||
and 196 ms).
|
||||
- Navara's vector layers were measured against that pass and lost
|
||||
(`docs/GLOBE-PRIMITIVES.md`).
|
||||
- No layer draws through `engine.ground` yet. Earthquakes and fire
|
||||
perimeters have prototypes in `render/ground.js`.
|
||||
- On November 7, 2026, `scripts/qa-ground-suite.mjs` (the ground checks
|
||||
with pixels) passed 3 of 3 on both engines.
|
||||
- **Rasters on the ground** (`engine.imagery`) are required of every engine
|
||||
@@ -254,20 +265,42 @@ one application, and only the globe-bound parts move to the next engine.
|
||||
contract has no primitive for yet, draw behind one seam,
|
||||
`src/layers/awareness/render/pulseDisc.js` (`render/cesiumPulses.js`, a
|
||||
material disc, on Cesium; `render/navaraPulses.js`, a surface pass that the
|
||||
Navara mode loads and passes in).
|
||||
layer manifest loads and passes in).
|
||||
The Active Fires far-zoom heatmap is an `engine.imagery` layer, and Recent
|
||||
Imagery draws its days through `engine.imagery` from its own
|
||||
`render/display.js`. CCTV's monitor plane and viewshed volume, which the
|
||||
contract has no primitive for yet, draw behind one seam,
|
||||
`src/layers/cctv/render/meshes.js` (`render/cesiumMeshes.js` on Cesium;
|
||||
`render/navaraMeshes.js`, which the Navara mode loads and passes in). Cesium
|
||||
renderers are listed in `src/app/layers/renderers.js`
|
||||
(`CESIUM_LAYER_RENDERERS`), Navara ones are loaded by
|
||||
`registerNavaraLayerRenderers` in `src/app/navaraMode.js`; both register the
|
||||
same display factory for a layer that has one. Navara
|
||||
ground effects (heat, pulses, trails, pads, drapes) are declared with
|
||||
`defineGroundEffect` (`src/layers/shared/render/navaraGroundEffect.js`);
|
||||
`render/navaraMeshes.js`, which the layer manifest loads and passes in).
|
||||
Navara ground effects (heat, pulses, trails, pads, drapes) are declared
|
||||
with `defineGroundEffect` (`src/layers/shared/render/navaraGroundEffect.js`);
|
||||
their insert order is pinned by `navaraGroundOrder.test.mjs`.
|
||||
- **One layer manifest.** `LAYER_MANIFEST` in `src/app/layers/renderers.js`
|
||||
says how each directory layer draws: its display with the contract
|
||||
primitives it needs (and an engine-specific backend option keyed by engine
|
||||
kind: CCTV's meshes and Global Context's pulses on Navara), a layer that
|
||||
draws itself through the contract (Wildlife Sightings), or, without a
|
||||
display, its drawing per engine kind (wind, the weather rasters and the
|
||||
Bhote Koshi event and locator draw themselves on Cesium and through a
|
||||
Navara renderer on Navara; Sea Marks and Ski Pistes drape themselves on
|
||||
both). A layer is available on an engine when that engine has the
|
||||
primitives it needs, or, without a display, when its entry lists that
|
||||
kind; today every layer shows on both. The manifest's Navara backends
|
||||
and renderers load through `import()` (`loadLayerRenderers(kind)`, awaited
|
||||
by `src/standalone/application.js` before the engine's catalog), so
|
||||
Cesium mode fetches none of them; `rendererFor(id, engine, options)`
|
||||
answers synchronously after that. The layer list reads
|
||||
`createLayerAvailability(kind)`.
|
||||
- **One tools tree.** `src/app/tools.js` attaches the same tools to every
|
||||
engine (`attachEngineTools`): the annotation board, Draw, Import, the
|
||||
Recent Imagery box and panel, the render governor, the scope mask,
|
||||
hidden-tab handling and voice. Each engine kind's tool backend says where
|
||||
they draw; Cesium's also holds the tools that still drive its viewer
|
||||
(release trim, tracked-entity hold, the render-loop suspension, the
|
||||
embedded views), which read it through `engine.extensions.cesium?.viewer`
|
||||
and so stay absent on Navara. Navara's backend (`navaraToolBackend` in
|
||||
`src/app/navaraMode.js`, loaded with its mode) adds the daylight of a
|
||||
restored view and the engine notice.
|
||||
- **Cesium only on demand.** The production build loads `/cesium/Cesium.js`
|
||||
when a Cesium globe starts or a Navara user turns on a feature that still
|
||||
uses Cesium's maths or entity model (traffic, Street Level, the Bhote Koshi
|
||||
|
||||
@@ -86,6 +86,31 @@ Item options:
|
||||
- `drape` is `'both'` (the default), `'terrain'` or `'tiles'`. Cesium
|
||||
honours it; Navara drapes on whatever surface it draws.
|
||||
|
||||
A `widthPx` corridor can also take the looks Cesium's ground polyline
|
||||
materials gave it. The GPU works them out every frame from the time, so a
|
||||
commit never rebuilds them:
|
||||
|
||||
| look | fields | Cesium's |
|
||||
| ------- | ------------------------------------------------ | ---------------------------------------------------------------- |
|
||||
| `glow` | `power`, `taper` (1: none) | `PolylineGlow`'s `glowPower` and `taperPower` |
|
||||
| `pulse` | `periodMs`, `min`, `max` | the alpha times a factor from `min` to `max` and back, a sine |
|
||||
| `dash` | `cells`, `duty`, `speed`, `gapAlpha`, `emission` | the annotation route's `GevRouteFlow`: dashes flowing to the end |
|
||||
|
||||
- `glow` brightens the line toward white along its centre and fades it to
|
||||
nothing at its edges.
|
||||
- `pulse` follows the page's monotonic clock (`performance.now()`), as the
|
||||
old materials did, not the app clock.
|
||||
- `dash` lays `cells` dashes along the whole line. Each is lit for its first
|
||||
`duty`, with soft edges of 0.08 of a cell, and brightened by `emission`
|
||||
times its colour. Between them the alpha is times `gapAlpha`. The dashes
|
||||
move toward the line's end at `speed` cells a second.
|
||||
- A shown set with a `pulse` or a `dash` makes the engine draw a frame after
|
||||
every frame, as Cesium's continuous render did. `list()` reports it as
|
||||
`animated`. A `glow` alone does not animate.
|
||||
|
||||
Traffic's jam heat lines glow (power 0.25) and pulse (alpha 0.35 to 0.75,
|
||||
1.63 s). The Directions route's 64 dashes flow at 0.55 cells a second.
|
||||
|
||||
### How each engine draws the ground
|
||||
|
||||
**Cesium** (`src/globe/cesium/ground.js`) builds at most two batches per set:
|
||||
@@ -94,7 +119,11 @@ Item options:
|
||||
metre corridors);
|
||||
- one `GroundPolylinePrimitive` for all the outlines and pixel corridors.
|
||||
|
||||
Both use per-instance colours and the set's `classificationType`. Cesium
|
||||
Both use per-instance colours and the set's `classificationType`. A
|
||||
corridor with a look draws in a `GroundPolylinePrimitive` of its own look
|
||||
and colour, over the set's other batches. Its material does the glow, pulse
|
||||
and dash. The engine writes its time before every frame, and asks for the
|
||||
next frame after every frame while the set is shown. Cesium
|
||||
builds them in workers; the set's `ready()` turns true once they are drawn.
|
||||
A set that is not pickable stays out of the pick pass, so it never hides
|
||||
what lies under it.
|
||||
@@ -106,7 +135,7 @@ its screen cell:
|
||||
|
||||
- a disc against its radius;
|
||||
- an area against its edges;
|
||||
- a corridor against its distance to the line.
|
||||
- a corridor tile against the corridor segments near the pixel.
|
||||
|
||||
The tests run in each item's own gnomonic plane, so great-circle edges stay
|
||||
straight. Fills and outlines are anti-aliased across one pixel and blended
|
||||
@@ -116,9 +145,38 @@ Large shapes get extra structure:
|
||||
|
||||
- An area with more than 32 edges gets a grid of bins. A pixel then tests
|
||||
only the edges of its own bin.
|
||||
- A long corridor is split into chunks of 4 segments.
|
||||
- A corridor set becomes tiles, set-wide grids of bins
|
||||
(`src/globe/navara/ground/corridors.js`). See below.
|
||||
- The terrain heights under each item bound its screen box.
|
||||
|
||||
**Corridor tiles.** A set's lines are cut into pieces of at most 0.5°
|
||||
along their great circles. The pieces fall into a tree of longitude and
|
||||
latitude tiles, each with at most 20 000 pieces and at most 20° a side. A
|
||||
tile is one pass item:
|
||||
|
||||
- a gnomonic plane of its own;
|
||||
- the pieces that come near it, as segments in that plane;
|
||||
- a pyramid of square bins. A bin of level z is 2^z times the finest bin.
|
||||
It lists runs of segments, item by item in draw order: the segments that
|
||||
reach within its margin. The margin is half a bin for the set's thinnest
|
||||
corridor, more for a wider one, plus a width in metres.
|
||||
|
||||
The finest bin is sized so that it holds about two runs per piece. The
|
||||
coarsest level has at most 8 bins across.
|
||||
|
||||
A pixel finds its ground in world space once. It takes the one tile of the
|
||||
set whose cell holds it: the cells are tested with the meridians' normals
|
||||
and the parallels' sines, so two neighbouring tiles never both draw a
|
||||
pixel. The pixel then takes the finest level whose margin covers the
|
||||
reach of the set's thinnest corridor, and tests only its bin's runs. Each
|
||||
item takes its nearest segment there, and blends once, in item order. When
|
||||
the pixel is wider than the coarsest margin covers (a tile under about 30
|
||||
pixels), lines near a tile's edge can lose a little of a neighbour's
|
||||
reach; the tile is a solid blur by then.
|
||||
|
||||
A commit packs the tiles once. Only the heights are sampled again when the
|
||||
terrain loads later.
|
||||
|
||||
Picks are CPU picks at the ground under the pointer (`src/globe/ground.js`).
|
||||
|
||||
Navara's vector layers (`src/globe/navara/ground/vector.js`) were measured
|
||||
@@ -178,6 +236,24 @@ Corridors (40-point lines, 2.5 px), still / moving:
|
||||
At 10 000 corridors Cesium allocated 613 MB of WebGL memory, the pass 44 MB
|
||||
and the vector layers about 70 MB.
|
||||
|
||||
The pass with corridor tiles, measured again with the pass before them on
|
||||
the same afternoon (the machine busier, the empty scene 6.0–8.9 ms):
|
||||
|
||||
| N | Cesium | pass before | pass with tiles |
|
||||
| ------ | -------------- | -------------- | --------------- |
|
||||
| 1 000 | 12.8 / 13.9 ms | 19.8 / 24.9 ms | 9.1 / 12.6 ms |
|
||||
| 10 000 | 23.1 / 23.2 ms | 151 / 196 ms | 12.1 / 15.4 ms |
|
||||
| 15 000 | 31.8 / 31.4 ms | 226 / 289 ms | 17.7 / 19.7 ms |
|
||||
|
||||
The tiles hold about what the chunks held: 47 MB of textures at 10 000
|
||||
corridors (46 MB before), 68 MB at 15 000 (69 MB). Packing takes longer:
|
||||
the commit of 10 000 corridors went from 0.6 s to about 1.9 s, and 15 000
|
||||
from 0.8 s to 3.0 s.
|
||||
|
||||
A pixel corridor's width is now measured across the line (the gradient of
|
||||
the distance to it), so it is the same at any angle, as on Cesium. Before,
|
||||
a diagonal line drew up to √2 wider.
|
||||
|
||||
Edge quality over the Hajar mountains, oblique view:
|
||||
|
||||
- **Cesium:** a sharp drape with its outline.
|
||||
@@ -207,10 +283,9 @@ more on every frame the camera moves, whatever their count. They draw no
|
||||
ground outlines and no metre widths. Their colours are lit, and hiding them
|
||||
needs a rebuild.
|
||||
|
||||
Corridors are the pass's limit: about 1 000 lines draw at 18 ms, but 10 000
|
||||
take 135 ms. A layer with more lines than that (Street Level's up to 14 400
|
||||
sequences) needs a set-wide grid of bins first, as areas have, before it
|
||||
moves to `engine.ground`.
|
||||
Corridors were the pass's limit: 10 000 lines took 135 ms. With a
|
||||
set-wide grid of bins (corridor tiles), 10 000 take 12 ms, under Cesium's
|
||||
23 ms.
|
||||
|
||||
## Imagery: rasters on the ground
|
||||
|
||||
@@ -335,7 +410,8 @@ near the camera from one 8×8 atlas over the whole view.
|
||||
- a line on the ground: `corridor`, with `widthM` when its width is a
|
||||
real width (an outline in metres) and `widthPx` otherwise.
|
||||
- Group items that change together into one set, and replace them in bulk.
|
||||
A ground set is rebuilt on every commit, so an animated fill (a pulse, a
|
||||
flowing route) is not a ground set yet.
|
||||
A ground set is rebuilt on every commit, so a fill that changes over time
|
||||
is not a ground set, except a pixel corridor's glow, pulse and dash, which
|
||||
the engine animates.
|
||||
- **Pixels on the ground** (tiles, a raster, a photo): an imagery layer.
|
||||
Fade it with `setAlpha`, and give a new raster to `setSource`.
|
||||
Reference in new issue
Block a user