mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 19:34:01 +00:00
fix(infrastructure): test the ground, not the ellipsoid, for in-view sampling
An unsampled base sits at ellipsoid height 0. Over high terrain seen at an angle that point projects below the screen while the ground above it is in view, so the gate skipped ground the camera could see and never sampled it. The gate now tests loaded globe terrain when there is some, and otherwise the whole span of heights a sample can accept (0 to 9,000 m). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
189b30b545
commit
ecc0ced47c
4 files changed
+106
-15
No files matched your search
@@ -1,4 +1,4 @@
|
||||
- Ground-sample Data Centers and Dams markers only when the camera sees their
|
||||
base. An off-screen base read through the Earth and retried every 2 s, which
|
||||
held the page near 2 s a frame over Ashburn, Virginia on the Esri map
|
||||
- Ground-sample Data Centers and Dams markers only when the camera sees the
|
||||
ground under them. Unseen ground read through the Earth and retried every
|
||||
2 s; over Ashburn, Virginia on the Esri map, slow frames reached 2 s
|
||||
(quanticsoul4772, #1464).
|
||||
@@ -1959,9 +1959,11 @@ during continuous motion. Disable/re-enable resets selection cleanly.
|
||||
Close-up stem sizing uses camera-to-feature distance without a 5 km minimum.
|
||||
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, samples only markers whose base is in the
|
||||
camera's view and above the horizon (an unseen base reads through the Earth
|
||||
and would retry every 2 s), and uses valid loaded terrain as a floor while
|
||||
visible globe tiles to settle, samples only markers whose ground is in the
|
||||
camera's view and above the horizon (unseen ground reads through the Earth
|
||||
and would retry every 2 s; until it is seen, a stem keeps its unsampled
|
||||
height, which can show for a stem whose base is just off screen), 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. Already sampled
|
||||
nearby markers follow higher settled terrain on existing bounded walks, without
|
||||
|
||||
@@ -787,6 +787,64 @@ test('an unseen base is not sampled and arms no retry until it is in view', asyn
|
||||
assert.ok(Math.abs(baseHeightM(env) - 117) < 0.01);
|
||||
});
|
||||
|
||||
for (const [label, globe] of [
|
||||
['loaded terrain', { show: true, tilesLoaded: true, getHeight: () => 2_500 }],
|
||||
['a hidden globe', { show: false, tilesLoaded: true, getHeight: () => undefined }],
|
||||
]) {
|
||||
test(`high ground in view is sampled with ${label} although its unsampled base projects off screen`, async (t) => {
|
||||
// A base on 2,500 m terrain, seen from 3 km away at a shallow angle: its
|
||||
// ellipsoid-height point is far below the bottom of the screen.
|
||||
const env = await createRealLocalLayerHarness({
|
||||
sampleHeightSupported: true, sampleHeight: () => 2_500,
|
||||
});
|
||||
const clock = installFakeClock(t);
|
||||
t.after(() => { env.layer.destroy(env.viewer); env.cleanup(); });
|
||||
env.viewer.scene.globe = globe;
|
||||
const entity = env.dataSources[0].entities.values[0];
|
||||
const base = Cesium.Cartographic.fromCartesian(entity.__localBaseCartesian);
|
||||
const ground = Cesium.Cartesian3.fromRadians(base.longitude, base.latitude, 2_500);
|
||||
const position = Cesium.Cartesian3.fromRadians(
|
||||
base.longitude,
|
||||
base.latitude - 3_000 / 6_371_000,
|
||||
2_500 + 1_000,
|
||||
);
|
||||
const direction = Cesium.Cartesian3.normalize(
|
||||
Cesium.Cartesian3.subtract(ground, position, new Cesium.Cartesian3()),
|
||||
new Cesium.Cartesian3(),
|
||||
);
|
||||
const right = Cesium.Cartesian3.normalize(
|
||||
Cesium.Cartesian3.cross(
|
||||
direction,
|
||||
Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(position),
|
||||
new Cesium.Cartesian3(),
|
||||
),
|
||||
new Cesium.Cartesian3(),
|
||||
);
|
||||
const up = Cesium.Cartesian3.cross(right, direction, new Cesium.Cartesian3());
|
||||
const frustum = new Cesium.PerspectiveFrustum({
|
||||
fov: Math.PI / 3,
|
||||
aspectRatio: 800 / 600,
|
||||
near: 1,
|
||||
far: 1e8,
|
||||
});
|
||||
Object.assign(env.viewer.camera, {
|
||||
positionWC: position,
|
||||
directionWC: direction,
|
||||
upWC: up,
|
||||
frustum,
|
||||
});
|
||||
const offScreen = frustum
|
||||
.computeCullingVolume(position, direction, up)
|
||||
.computeVisibility(new Cesium.BoundingSphere(entity.__localBaseCartesian, 1));
|
||||
assert.equal(offScreen, Cesium.Intersect.OUTSIDE, 'precondition: the ellipsoid-height base is off screen');
|
||||
|
||||
clock.advance(2_100);
|
||||
env.preRender.raise();
|
||||
assert.equal(env.sampleCalls.count, 1, 'the ground in view is sampled');
|
||||
assert.ok(Math.abs(baseHeightM(env) - 2_500) < 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,
|
||||
|
||||
@@ -1140,29 +1140,60 @@ const groundSampleOccluder = new Cesium.EllipsoidalOccluder(
|
||||
Cesium.Ellipsoid.WGS84,
|
||||
);
|
||||
|
||||
const groundSampleCarto = new Cesium.Cartographic();
|
||||
const groundSampleTop = new Cesium.Cartesian3();
|
||||
|
||||
/**
|
||||
* Whether the camera sees the record's base: inside the view frustum and
|
||||
* above the horizon. scene.sampleHeight reads only surface rendered for the
|
||||
* current view, so a sample of an unseen base passes through the Earth (about
|
||||
* -6,344 km near Ashburn on Esri) and fails on every 2 s retry, each one a
|
||||
* full offscreen render: 110 unseen data centres there held the page near 2 s
|
||||
* a frame indefinitely. An unseen base keeps its stem at the unsampled height
|
||||
* and is sampled on the first walk that sees it.
|
||||
* Whether the camera can see the ground under the record: inside the view
|
||||
* frustum and above the horizon. scene.sampleHeight reads only surface
|
||||
* rendered for the current view, so a sample of unseen ground passes through
|
||||
* the Earth (about -6,344 km near Ashburn on Esri) and fails on every 2 s
|
||||
* retry, each one a full offscreen render; 110 unseen data centres there held
|
||||
* rest frames at 58-589 ms. Unsampled bases sit on the ellipsoid, so the test
|
||||
* uses loaded globe terrain when there is some, and otherwise every height a
|
||||
* sample can accept (0 to GROUND_SAMPLE_MAX_ABS_HEIGHT_M): high ground in
|
||||
* view is never mistaken for an unseen base. Unseen ground is sampled on the
|
||||
* first walk that sees it.
|
||||
*/
|
||||
function groundSampleInView(viewer, record) {
|
||||
const camera = viewer.camera;
|
||||
const globe = viewer.scene.globe;
|
||||
const terrain = globe?.show ? globe.getHeight?.(record.carto) : undefined;
|
||||
const known =
|
||||
Number.isFinite(terrain) &&
|
||||
Math.abs(terrain) <= GROUND_SAMPLE_MAX_ABS_HEIGHT_M;
|
||||
const span = GROUND_SAMPLE_MAX_ABS_HEIGHT_M / 2;
|
||||
groundSampleCarto.longitude = record.carto.longitude;
|
||||
groundSampleCarto.latitude = record.carto.latitude;
|
||||
groundSampleCarto.height = known ? terrain : span;
|
||||
Cesium.Cartographic.toCartesian(
|
||||
groundSampleCarto,
|
||||
Cesium.Ellipsoid.WGS84,
|
||||
groundSampleSphere.center,
|
||||
);
|
||||
groundSampleSphere.radius = known ? 1 : span;
|
||||
const culling = camera.frustum.computeCullingVolume(
|
||||
camera.positionWC,
|
||||
camera.directionWC,
|
||||
camera.upWC,
|
||||
);
|
||||
Cesium.Cartesian3.clone(record.base, groundSampleSphere.center);
|
||||
if (
|
||||
culling.computeVisibility(groundSampleSphere) === Cesium.Intersect.OUTSIDE
|
||||
)
|
||||
return false;
|
||||
// The highest ground the sample could find is the last to drop below the
|
||||
// horizon.
|
||||
if (!known) groundSampleCarto.height = GROUND_SAMPLE_MAX_ABS_HEIGHT_M;
|
||||
groundSampleOccluder.cameraPosition = camera.positionWC;
|
||||
return groundSampleOccluder.isPointVisible(record.base);
|
||||
return groundSampleOccluder.isPointVisible(
|
||||
known
|
||||
? groundSampleSphere.center
|
||||
: Cesium.Cartographic.toCartesian(
|
||||
groundSampleCarto,
|
||||
Cesium.Ellipsoid.WGS84,
|
||||
groundSampleTop,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function sampleLocalGroundHeight(viewer, record, now) {
|
||||
|
||||
Reference in new issue
Block a user