mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-14 23:32:20 +00:00
Test layers on one engine and share selection and shader helpers
Layer display tests no longer re-check Cesium primitives in every layer: they run on the fake engine, and one Cesium translation check per ground kind lives in the Cesium engine's ground tests. Their harnesses are shared, and the fake-engine, Cesium-engine and flights tests that repeated the contract suite are gone, 340 tests in all. The press-travel measurement is shared by the selection dispatcher and CCTV, which loses its ScreenSpaceEventHandler shim and world-click module. ALPR, installations and bikeshare share one selection keeper and selected marker write. Layers with their own click rules keep their handlers. Navara's pulse is a class like the ground pass, the ground and imagery passes share the surface uniforms, and the colour, log-depth and occlusion GLSL lives in one chunk module, each caller keeping its depth bias. The ground suite runs inside the contract suite (--only=ground:), and fixture and script names say what they test. Behaviour is unchanged on both engines.
This commit is contained in:
1 parent
7f478e3815
commit
b4556f9763
101 files changed
+1095
-4071
No files matched your search
+28
-140
@@ -183,78 +183,17 @@ point movers retain their independent fill and outline opacity. No story
|
||||
backend is selected by engine. The authored model still uses its existing
|
||||
property records; removing that model dependency is separate work.
|
||||
|
||||
### How each engine draws the ground
|
||||
### Ground drawing guarantees
|
||||
|
||||
**Cesium** (`src/globe/cesium/ground.js`) builds at most two batches per set:
|
||||
Both engines preserve item order, fill and outline colours, pixel and metre
|
||||
widths, visibility, and pick ownership. Non-pickable sets let picks through.
|
||||
`ready()` reports when committed geometry is ready to draw. Animated corridor
|
||||
looks use the shared ground time and request frames while shown.
|
||||
|
||||
- one `GroundPrimitive` for all the fills (polygons, ellipses, rectangles and
|
||||
metre corridors);
|
||||
- one `GroundPolylinePrimitive` for all the outlines and pixel corridors.
|
||||
|
||||
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.
|
||||
|
||||
**Navara** (`src/globe/navara/ground/`) draws every shown set in one screen
|
||||
pass after tone mapping. Each pixel's ground position comes from the scene
|
||||
depth (terrain and 3D tiles), and the pixel is tested against the items in
|
||||
its screen cell:
|
||||
|
||||
- a disc against its radius;
|
||||
- an area against its edges;
|
||||
- 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
|
||||
in display space, in draw order, as Cesium blends them.
|
||||
|
||||
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 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 draws ground shapes through the screen pass. It keeps colours and
|
||||
outlines exact, supports pixel and metre widths, and reliably shows and
|
||||
hides sets. Binned corridor tiles keep draw cost bounded while the camera
|
||||
moves, with compact texture storage.
|
||||
Cesium translates ground items to classified fills and polylines. Navara
|
||||
classifies visible scene depth and blends the ground in display space.
|
||||
Navara picks ground items at the surface under the pointer. Packing, tiling
|
||||
and bin sizes are implementation details in `src/globe/navara/ground/`.
|
||||
|
||||
## Imagery: rasters on the ground
|
||||
|
||||
@@ -324,78 +263,27 @@ On the engine:
|
||||
- `surface()` says where imagery drapes now: `'globe'`, `'tiles'` (3D tiles)
|
||||
or `'none'`.
|
||||
|
||||
### How each engine draws imagery
|
||||
### Imagery drawing guarantees
|
||||
|
||||
**Cesium** (`src/globe/cesium/imagery.js`) gives each layer one
|
||||
`ImageryLayer`:
|
||||
Both engines draw imagery below ground shapes, movers, lines and models,
|
||||
in layer order. Each texel blends by its alpha times the layer alpha.
|
||||
Visibility, split position, rectangle bounds and raised-shell height follow
|
||||
the imagery contract. Replacing or destroying a source releases its owned
|
||||
resources; stale loads cannot replace the current source.
|
||||
|
||||
- on the globe's imagery layers while the globe shows, else on the shown 3D
|
||||
tileset's own imagery layers (Cesium drapes imagery on tiles there), as
|
||||
`engine.imagery.surface()` reports it to layers; with neither, the
|
||||
layers wait;
|
||||
- the engine checks the surface on every frame while it holds a layer, and
|
||||
builds each layer again on the new stack after a switch;
|
||||
- above the base imagery, in order among the engine's layers; imagery other
|
||||
code adds stays where it was put;
|
||||
- tiles: a `UrlTemplateImageryProvider` in Web Mercator, bounded to the
|
||||
rectangle; `maxRequests` gates `requestImage`, and a request the gate or
|
||||
the provider defers asks for one delayed frame, never one per frame;
|
||||
- an image: one geographic tile over the rectangle (as
|
||||
`SingleTileImageryProvider`), handed to Cesium as the canvas or image
|
||||
itself, with no PNG round trip;
|
||||
- geographic tiles: a `GeographicTilingScheme`; a transform wraps
|
||||
`requestImage` (Cesium's tile bitmaps arrive flipped, so the transform
|
||||
gets them upright on a canvas);
|
||||
- a credit is read through the provider's `credit` getter every frame, so a
|
||||
new credit of the same source needs no new layer;
|
||||
- a staged source is a second `ImageryLayer` at alpha 0 right over the
|
||||
drawn one, whose tiles Cesium loads while the drawn one shows. Its own
|
||||
requests are counted (deferrals too); once they are in (the globe's tiles
|
||||
all loaded, or its own requests quiet for 200 ms) for two frames in a
|
||||
row, it takes the drawn one's alpha and the drawn one goes after the next
|
||||
frame. Throttled tiles (429, 503) retry three times; any other failed
|
||||
tile fails the source;
|
||||
- a raised layer is a primitive of its own (`imageryShell.js`): a
|
||||
rectangle at the height with a material of the image and the detail in
|
||||
its window, flat, alpha blended in the opaque pass without depth writes,
|
||||
first in `scene.primitives` in the imagery order, lifted by a uniform
|
||||
scale about the Earth's centre. A new image on the same rectangle swaps
|
||||
once uploaded; another rectangle is a new shell at alpha 0 until drawn;
|
||||
- `split` is the layer's `splitDirection`; Cesium splits on the globe only
|
||||
(not raised layers).
|
||||
Cesium translates sources to imagery providers and raised shells. Navara
|
||||
samples imagery in its surface pass, including raised ellipsoid intersections.
|
||||
The adapters own texture storage, tile selection and depth reconstruction.
|
||||
|
||||
**Navara** (`src/globe/navara/imagery/`) draws every shown layer in one
|
||||
screen pass right after tone mapping, under the other drapes and
|
||||
`engine.ground`:
|
||||
Cesium moves draped layers between the visible globe and tileset surfaces;
|
||||
without either surface, layers wait. Its split applies to globe imagery,
|
||||
not raised shells. Navara draws the top eight visible imagery slots, with
|
||||
detail images consuming a slot. Staged sources keep the current image visible
|
||||
until their replacement is ready; a failed source leaves it intact.
|
||||
|
||||
- each pixel's ground position comes from the scene depth (terrain and 3D
|
||||
tiles), as `engine.ground`'s pass finds it;
|
||||
- up to 8 layers are sampled in draw order at its longitude and latitude,
|
||||
each in its rectangle and on its side of the split (the top 8 when more
|
||||
are shown);
|
||||
- an image is one mipmapped texture, sampled in longitude and latitude;
|
||||
- tiles are an atlas of at most 8×8 Web Mercator or geographic tiles over
|
||||
the part of the rectangle in view, at the level the camera's height asks
|
||||
for (a geographic level one below Web Mercator's); it is rebuilt when the
|
||||
camera moves to another plan and filled as tiles arrive, each through the
|
||||
transform, 6 loads at a time (or `maxRequests`);
|
||||
- a staged source builds its own texture or atlas (for the view now, again
|
||||
when the camera moves) while the drawn one shows, and takes its place
|
||||
once every tile of it has settled; a failed tile fails it;
|
||||
- a raised slot is sampled where the pixel's ray meets the ellipsoid grown
|
||||
by its lifted height, where nothing of the scene is nearer; a detail is a
|
||||
second slot right over its layer's, which draws nothing inside the
|
||||
detail's rectangle;
|
||||
- texels are blended in display space, as Cesium's globe blends imagery;
|
||||
mip levels come from the derivatives of the ground position, taken
|
||||
before any branch, so rectangle edges and the antimeridian show no seams.
|
||||
|
||||
Open map overlays (Sea Marks, Ski Pistes) use `engine.imagery` when the
|
||||
engine has no `maps.addOverlay`. Navara keeps that optional native raster
|
||||
path for its per-tile detail. It adds a native Navara raster layer: Navara's own per-tile levels on
|
||||
the terrain, lit like the base map, but no rectangle, split, alpha or order,
|
||||
and nothing on 3D tiles. Moving that path to imagery needs finer Navara tile detail: a global overlay seen obliquely gets coarse
|
||||
near the camera from one 8×8 atlas over the whole view.
|
||||
Open map overlays use `engine.imagery` when `maps.addOverlay` is absent.
|
||||
Navara's optional native raster path retains terrain detail, but does not
|
||||
provide rectangle bounds, split, alpha, order, or drawing on 3D tiles.
|
||||
|
||||
### Who draws through imagery
|
||||
|
||||
@@ -696,8 +584,8 @@ Run `createContractSuite(engine, { waitFrames, ... })` from
|
||||
`src/globe/testing/contractSuite.mjs`. Supply real pointer delivery, canvases and
|
||||
pixel reads for browser checks; keep the fake-engine tests as fast contract
|
||||
checks. Test ownership and repeated destruction as well as visible output.
|
||||
The browser harness is `scripts/qa-contract-suite.mjs`; ground and imagery pixel
|
||||
checks also run through `scripts/qa-ground-suite.mjs`.
|
||||
The browser harness is `scripts/qa-contract-suite.mjs`; use
|
||||
`--only=ground:,imagery:` for ground and imagery pixel checks.
|
||||
|
||||
The application currently registers two kinds: adding another still requires
|
||||
registration in `ENGINE_KINDS`, scene construction/choice and the corresponding
|
||||
|
||||
Reference in new issue
Block a user