fix(infrastructure): follow refined terrain after initial sampling

This commit is contained in:
Sameh Khamis committed 2026-09-11 09:05:41 -07:00
1 parent b5568de9fa
commit 412ee211b5
4 files changed
+63 -5

No files matched your search

+1
View File
@@ -16,6 +16,7 @@ of current runtime behavior, see [`docs/CURRENT-STATE.md`](docs/CURRENT-STATE.md
- Unchanged local infrastructure overlays no longer sustain idle rendering.
Ground samples wait for visible terrain to settle and cannot place a marker
below its loaded surface; roofs and valid below-sea-level heights are retained.
Already sampled markers also follow higher terrain as close-up tiles refine.
- Datacenter and dam marker stems use bounded, zoom-dependent active sets with
stable selection during camera motion. Close-up stems scale to the actual
+3 -1
View File
@@ -12,7 +12,9 @@ Unchanged overlay entries do not request another frame; moved positions,
changed membership and re-enabling still publish. Ground sampling waits for
visible globe tiles to settle and uses valid loaded terrain as a floor while
retaining rooftop and below-sea-level elevations. A hidden globe does not
constrain photoreal geometry, and retry work remains bounded.
constrain photoreal geometry, and retry work remains bounded. Already sampled
nearby markers follow higher settled terrain on existing bounded walks, without
additional GPU samples or timers, when close-up tile detail refines the floor.
The submarine-cable renderer is unchanged. These limits bound active stem work;
they do not reduce the materialized entity count or establish an FPS gain.
+23 -3
View File
@@ -807,7 +807,8 @@ export function createLocalGeoJsonLayer({
if (!isActive) continue;
const wasGroundSampled = record.groundSampled;
if (refreshStemGeometry) {
const terrainFloorChanged = refreshLocalTerrainFloor(viewer, record);
if (refreshStemGeometry || terrainFloorChanged) {
updateLocalStemGeometry(viewer, record, now);
} else if (canSampleGround && !record.groundSampled
&& now - record.lastGroundSampleMs >= GROUND_SAMPLE_RETRY_MS) {
@@ -911,6 +912,21 @@ function insertLocalCellContender(contenders, record) {
if (contenders.length > LOCAL_OVERLAY_CELL_SURPLUS) contenders.length = LOCAL_OVERLAY_CELL_SURPLUS;
}
function refreshLocalTerrainFloor(viewer, record) {
const globe = viewer.scene.globe;
if (!record.groundSampled || !globe?.show || globe.tilesLoaded === false) return false;
if (Cesium.Cartesian3.distance(viewer.camera.positionWC, record.base)
>= GROUND_SAMPLE_MAX_DISTANCE_M) return false;
// Camera motion can refine terrain after the first successful depth sample.
// Reuse the loaded mesh on existing bounded walks; never arm a timer or do
// another GPU readback just to maintain this floor. Keep roof elevations.
const height = globe.getHeight?.(record.carto);
if (!Number.isFinite(height) || Math.abs(height) > GROUND_SAMPLE_MAX_ABS_HEIGHT_M
|| height <= record.groundHeight) return false;
setLocalGroundHeight(record, height);
return true;
}
function sampleLocalGroundHeight(viewer, record, now) {
if (record.groundSampled || !viewer.scene.sampleHeightSupported) return false;
if (now - record.lastGroundSampleMs < GROUND_SAMPLE_RETRY_MS) return false;
@@ -933,7 +949,12 @@ function sampleLocalGroundHeight(viewer, record, now) {
sampled = Math.max(sampled, terrainHeight);
}
record.groundSampled = true;
record.groundHeight = sampled;
setLocalGroundHeight(record, sampled);
return true;
}
function setLocalGroundHeight(record, height) {
record.groundHeight = height;
Cesium.Cartesian3.fromRadians(
record.carto.longitude,
record.carto.latitude,
@@ -942,7 +963,6 @@ function sampleLocalGroundHeight(viewer, record, now) {
record.base,
);
record.entity.__localBaseCartesian = record.base;
return true;
}
function updateLocalStemGeometry(viewer, record, now, knownDistance = null) {
+36 -1
View File
@@ -497,7 +497,7 @@ test('local infrastructure creates no native labels or per-frame geometry callba
assert.match(source, /const stemPositionBuffers = \[\[base, tip\], \[base, tip\]\]/);
assert.match(source, /record\.entity\.polyline\.positions\.setValue\(stemPositions\)/);
assert.match(source, /viewer\.camera\.moveEnd\.addEventListener/);
assert.match(source, /if \(refreshStemGeometry\)/);
assert.match(source, /if \(refreshStemGeometry \|\| terrainFloorChanged\)/);
assert.match(source, /now - _lastVisibilityUpdate < VISIBILITY_UPDATE_MS/);
});
@@ -728,6 +728,41 @@ test('ground sampling waits for visible globe tiles before caching a height', as
assert.ok(Math.abs(baseHeightM(env) - 117) < 0.01);
});
test('settled terrain refinement lifts an already sampled stem without another GPU sample', async (t) => {
const env = await createRealLocalLayerHarness({
sampleHeightSupported: true, sampleHeight: () => 117,
});
const clock = installFakeClock(t);
t.after(() => { env.layer.destroy(env.viewer); env.cleanup(); });
let terrain = 117;
const globe = { show: true, tilesLoaded: true, getHeight: () => terrain };
env.viewer.scene.globe = globe;
setCameraAltitude(env, 20_000);
env.preRender.raise();
assert.ok(Math.abs(baseHeightM(env) - 117) < 0.01);
terrain = 120;
globe.tilesLoaded = false;
clock.advance(500);
env.preRender.raise();
assert.ok(Math.abs(baseHeightM(env) - 117) < 0.01, 'wait for the refined mesh to settle');
globe.tilesLoaded = true;
clock.advance(500);
env.preRender.raise();
assert.ok(Math.abs(baseHeightM(env) - 120) < 0.01, 'a parked marker must follow the refined floor');
terrain = 110;
clock.advance(500);
env.preRender.raise();
assert.ok(Math.abs(baseHeightM(env) - 120) < 0.01, 'a lower floor must not flatten existing geometry');
terrain = 140;
globe.show = false;
clock.advance(500);
env.preRender.raise();
assert.ok(Math.abs(baseHeightM(env) - 120) < 0.01, 'hidden globe terrain must not constrain geometry');
assert.equal(env.sampleCalls.count, 1, 'terrain maintenance must not repeat the GPU readback');
});
for (const [terrainHeight, sampledHeight, expectedHeight, globeShown] of [
[117, -2238, 117, true],
[-400, -410, -400, true],