fix(globe): the floor takes no tile coarser than 1 km

Review of Task 6: from 15 km with cold tiles Navara answers from 3.5-4 km
tiles (13.9 km at AUS), below the 4 km floor limit, 6-16 m off; the mesh
floor samples up to 25 km, so those would latch. MAX_FLOOR_TILE_SIZE_M is
now 1 km: from 800 m the answering tiles are 112-314 m. The 1.8 km tile
that read the Austin ground right under a 600 m camera is now a miss too,
which only leaves the DEM prior in place.

qa-surface-heights runs the 15 km pass first in a fresh page (cold), then
the 800 m pass in another, and keeps every answer the floor rule would
take while the tiles stream. Measured: 800 m 19/20 within 2 m of Cesium;
15 km cold 7/20 (the plan's gate of 15 assumed warm tiles - lod 'finest'
can only use what Navara has loaded, and at 15 km it loads 3.5-14 km
tiles), and the floor rule takes 0/20 of those; while streaming it took
answers more than 2 m off at 3 places: the Empire State spire (39 m, also
the settled answer) and two street points 2.2-2.3 m off.
This commit is contained in:
German Khokhlov committed 2026-10-16 22:19:57 +04:00
1 parent f0ce1b04c7
commit d6fe0f3805
3 files changed
+17 -7

No files matched your search

+6 -1
View File
@@ -154,7 +154,12 @@ test('sampler: a coarse tile answer is a miss; a fine one latches', async () =>
engine.fake.script('sampleHeightDetailed', () => ({ height: 143.2, source: 'tiles', tileSizeM: 27_914 }));
sampleMeshFloorCells(engine, [cell], opts);
assert.equal(cachedMeshFloor(cell.lat, cell.lon), null, 'coarse: no latch');
engine.fake.script('sampleHeightDetailed', () => ({ height: 122.5, source: 'tiles', tileSizeM: 1_797 }));
// A 3.5 km tile from 15 km, cold, read 16 m off: still too coarse.
engine.fake.script('sampleHeightDetailed', () => ({ height: 138.7, source: 'tiles', tileSizeM: 3_456 }));
sampleMeshFloorCells(engine, [cell], opts);
assert.equal(cachedMeshFloor(cell.lat, cell.lon), null, '3.5 km: no latch');
// The tiles answering from 800 m are 112-314 m.
engine.fake.script('sampleHeightDetailed', () => ({ height: 122.5, source: 'tiles', tileSizeM: 241 }));
sampleMeshFloorCells(engine, [cell], opts);
assert.equal(cachedMeshFloor(cell.lat, cell.lon), 122.5);
const terrainOnly = nextSite();
+1 -1
View File
@@ -71,7 +71,7 @@ test('a coarse tile answer or only terrain is a miss; a viewer reaches its engin
engine.fake.script('sampleHeightDetailed', () => ({
height: 122.5,
source: 'tiles',
tileSizeM: 1_797,
tileSizeM: 241,
}));
const viewer = {};
const unregister = registerViewerEngine(viewer, engine);
+10 -5
View File
@@ -2,11 +2,16 @@ import * as geo from '../geo/index.js';
import { engineFromViewer } from '../globe/cesium/engineFromViewer.js';
import { acceptedSurfaceHeight } from '../globe/surfaceDetail.js';
/** Answers from tiles larger than this are too coarse to latch (m): on
* Navara at Austin a 1.8 km tile read the ground (122.5 m) and the 28 km
* tile shown while streaming read 143.2 m. Cesium does not size its
* answers, so its gates are the camera height and tilesLoaded below. */
export const MAX_FLOOR_TILE_SIZE_M = 4000;
/** Answers from tiles larger than this are too coarse to latch (m).
* Measured on Navara (scripts/qa-surface-heights.mjs): from 800 m the
* answering tiles were 112-314 m and within 2 m of Cesium; from 15 km, cold,
* 3.5-4 km tiles were off by -16.2 to +6.2 m; while streaming a 27.9 km tile
* read 143.2 m at Austin where the ground is 122.5 m. A 1.8 km tile at
* Austin (the hidden tile under a 600 m camera looking ahead) read the
* ground right, but 1 km keeps every measured coarse error out; such a miss
* only leaves the DEM prior in place. Cesium does not size its answers, so
* its gates are the camera height and tilesLoaded below. */
export const MAX_FLOOR_TILE_SIZE_M = 1000;
/** Construct an instance-owned meshFloorSampler service with explicit dependencies. */
export function createMeshFloorSampler({