mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-13 06:42:23 +00:00
Fix the follow-up review findings in import, layers, startup and engines
- KML/KMZ import: a per-file canvas budget and cache for ground overlays, limits on rings and vertices of raised polygons, overlays across 360° and near the poles, degenerate holes, polar and single-latitude fills, absolute overlays at their altitude, overlay order by drawOrder as on Cesium, and pins on tiles keep their measured height. - Points on the surface: OSM Places and Street Level cones share the surface sampler and sit on the terrain before they are measured, within a sampling budget per pass; Cockpit's contact-dot bank keeps the dot atlas, and a failed fleet model loads again after a pause. - Startup: the loading screen lifts after the share-link view is restored, the retry screen names the failed engine and takes focus, and the fallback toast stays for 6 s. - Engines: an engine switch lands a running camera flight at its destination (camera.completeFlight on both engines), the sighting card leaves focus on the engine picker after a switch, and a Cesium model error stays with the instance that failed. - The MCP panel builds again: its wind-mesh alias resolves to the stub. - QA: the wildlife switch waits for the camera to rest, GBFS --w2 says it needs the dev server, and test fixtures are shared instead of copied.
This commit is contained in:
1 parent
0ef29781e5
commit
60fb8fee07
82 files changed
+2363
-1574
No files matched your search
@@ -31,14 +31,22 @@ const plausible = (height) =>
|
||||
* placement replaces (keeping the height in `surfaceHeight`); one with
|
||||
* `show === false` is skipped.
|
||||
* @param {() => void} options.request Asks for a frame after a placement.
|
||||
* @param {number} [options.heightOffset=0] Metres above the surface.
|
||||
* @param {boolean} [options.estimateGround=false] Screen-test a point not
|
||||
* measured yet on the loaded terrain (under 3D tiles without it, at the
|
||||
* ground under the camera) rather than where it stands now.
|
||||
* @returns {{ place: () => void, destroy: () => void }} `place()` measures
|
||||
* the points not yet placed on this surface (new points, for example).
|
||||
*/
|
||||
export function createSurfacePoints(engine, { groups, request }) {
|
||||
export function createSurfacePoints(
|
||||
engine,
|
||||
{ groups, request, heightOffset = 0, estimateGround = false },
|
||||
) {
|
||||
let revision = 0;
|
||||
let timer = null;
|
||||
let destroyed = false;
|
||||
let tilesLoaded = engine.surface.tilesLoaded();
|
||||
let photoreal = engine.maps?.photorealActive?.() === true;
|
||||
|
||||
function onScreen(position, size) {
|
||||
const screen = engine.projector.worldToWindow(position);
|
||||
@@ -53,6 +61,16 @@ export function createSurfacePoints(engine, { groups, request }) {
|
||||
);
|
||||
}
|
||||
|
||||
// Under 3D tiles Cesium hides the globe, which then loads no terrain: the
|
||||
// ground under the camera stands in for it in the screen test.
|
||||
function groundUnderCamera(exclude) {
|
||||
const height = engine.surface.sampleHeight(
|
||||
geo.cartographic.fromCartesian(engine.camera.livePosition),
|
||||
exclude,
|
||||
);
|
||||
return plausible(height) ? height : Number.NaN;
|
||||
}
|
||||
|
||||
// Points off screen are passed over until the next move or tile load.
|
||||
function place() {
|
||||
clearTimeout(timer);
|
||||
@@ -63,6 +81,7 @@ export function createSurfacePoints(engine, { groups, request }) {
|
||||
const started = performance.now();
|
||||
let samples = 0;
|
||||
let moved = false;
|
||||
let cameraGround;
|
||||
for (const { set, points, exclude = [set] } of groups()) {
|
||||
if (!set) continue;
|
||||
let changed = false;
|
||||
@@ -79,20 +98,40 @@ export function createSurfacePoints(engine, { groups, request }) {
|
||||
return;
|
||||
}
|
||||
point.surfaceRevision = revision;
|
||||
if (point.show === false || !onScreen(point.position, size)) continue;
|
||||
if (point.show === false) continue;
|
||||
const estimate = estimateGround && point.surfaceHeight === undefined;
|
||||
const terrain = estimate
|
||||
? engine.surface.terrainHeight(point.cartographic)
|
||||
: undefined;
|
||||
let ground = terrain;
|
||||
if (estimate && tiles && !plausible(ground)) {
|
||||
if (cameraGround === undefined) {
|
||||
samples++;
|
||||
cameraGround = groundUnderCamera(exclude);
|
||||
}
|
||||
ground = cameraGround;
|
||||
}
|
||||
const position = plausible(ground)
|
||||
? geo.cartesian3.fromRadians(
|
||||
point.cartographic.longitude,
|
||||
point.cartographic.latitude,
|
||||
ground + heightOffset,
|
||||
)
|
||||
: point.position;
|
||||
if (!onScreen(position, size)) continue;
|
||||
samples++;
|
||||
let height = tiles
|
||||
? engine.surface.sampleHeight(point.cartographic, exclude)
|
||||
: undefined;
|
||||
if (!plausible(height))
|
||||
height = engine.surface.terrainHeight(point.cartographic);
|
||||
height = terrain ?? engine.surface.terrainHeight(point.cartographic);
|
||||
if (!plausible(height)) continue;
|
||||
if (Math.abs(height - point.surfaceHeight) < HEIGHT_EPSILON_M) continue;
|
||||
point.surfaceHeight = height;
|
||||
point.position = geo.cartesian3.fromRadians(
|
||||
point.cartographic.longitude,
|
||||
point.cartographic.latitude,
|
||||
height,
|
||||
height + heightOffset,
|
||||
);
|
||||
set.set(index, { position: point.position });
|
||||
changed = true;
|
||||
@@ -110,8 +149,10 @@ export function createSurfacePoints(engine, { groups, request }) {
|
||||
const removeMoveEnd = engine.camera.moveEnd.addEventListener(refine);
|
||||
const removeFrame = engine.frames.preRender.addEventListener(() => {
|
||||
const loaded = engine.surface.tilesLoaded();
|
||||
if (loaded && !tilesLoaded) refine();
|
||||
const tiles = engine.maps?.photorealActive?.() === true;
|
||||
if ((loaded && !tilesLoaded) || tiles !== photoreal) refine();
|
||||
tilesLoaded = loaded;
|
||||
photoreal = tiles;
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
Reference in new issue
Block a user