From 2d0aa25e3551e1f0599ba5b3c613b82452956e97 Mon Sep 17 00:00:00 2001 From: German Khokhlov Date: Wed, 11 Nov 2026 14:01:29 +0400 Subject: [PATCH] Fix the trail and decoded-weather probes on both engines Both probes called waitForEngine without the engine kind, which can never match and timed out after 120 s; waitForEngine now rejects a missing kind. The trail probe passed no result vectors to the geo helpers, and drew its trail below the ground, where only the dimmed occluded pass showed it; it now draws halfway down to the ground and both engines count the same pixels. --- scripts/qa-strict-harness.mjs | 2 ++ scripts/qa-trail-freeze.mjs | 28 ++++++++++++++++++++++------ scripts/qa-weather-decoded-tiles.mjs | 2 +- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/scripts/qa-strict-harness.mjs b/scripts/qa-strict-harness.mjs index 2b2252b15..c570bf9bd 100644 --- a/scripts/qa-strict-harness.mjs +++ b/scripts/qa-strict-harness.mjs @@ -747,6 +747,8 @@ export async function pickEngine( /** Wait until `kind` runs, its picker is idle and its view is restored. */ export async function waitForEngine(page, kind, { timeout = 120000 } = {}) { + if (kind !== 'cesium' && kind !== 'navara') + throw new TypeError(`waitForEngine needs the engine kind, got ${kind}`); const started = Date.now(); await page.waitForFunction( (expected) => diff --git a/scripts/qa-trail-freeze.mjs b/scripts/qa-trail-freeze.mjs index 9a17cc156..581b38961 100644 --- a/scripts/qa-trail-freeze.mjs +++ b/scripts/qa-trail-freeze.mjs @@ -20,24 +20,40 @@ try { await page.setViewport({ width: 960, height: 640 }); await blockPaidQaMaps(page); await page.goto(url, { waitUntil: 'domcontentloaded' }); - await waitForEngine(page); + await waitForEngine( + page, + new URL(url).searchParams.get('engine') ?? 'navara', + ); const result = await evaluateWithGeo(page, async (geo) => { const { createTrail, CHUNK_POINTS } = await import('/src/data/trailRenderer.js'); const { engine } = window.__godsEyeView; engine.camera.cancelFlight(); const camera = engine.camera.pose(); + const offset = (direction, metres) => + geo.cartesian3.multiplyByScalar( + direction, + metres, + geo.cartesian3.create(), + ); + // Halfway down to the ground along the view, so the trail is drawn in + // front of the surface on both engines rather than through it. + const below = geo.cartographic.fromCartesian(camera.position); + const clearance = below.height - (engine.surface.terrainHeight(below) ?? 0); + const distance = Math.min( + 3000, + (0.5 * clearance) / Math.max(Math.sin(-camera.pitch), 0.05), + ); const ahead = geo.cartesian3.add( camera.position, - geo.cartesian3.multiplyByScalar(camera.direction, 3000), + offset(camera.direction, distance), + geo.cartesian3.create(), ); const points = Array.from({ length: CHUNK_POINTS + 1 }, (_, index) => geo.cartesian3.add( ahead, - geo.cartesian3.multiplyByScalar( - camera.right, - -1200 + (2400 * index) / CHUNK_POINTS, - ), + offset(camera.right, distance * (-0.4 + (0.8 * index) / CHUNK_POINTS)), + geo.cartesian3.create(), ), ); const gl = diff --git a/scripts/qa-weather-decoded-tiles.mjs b/scripts/qa-weather-decoded-tiles.mjs index b5659de1d..e21986c41 100644 --- a/scripts/qa-weather-decoded-tiles.mjs +++ b/scripts/qa-weather-decoded-tiles.mjs @@ -17,7 +17,7 @@ try { const url = new URL(base); url.search = `?engine=${kind}&welcome=0`; await page.goto(url.href, { waitUntil: 'domcontentloaded' }); - await waitForEngine(page); + await waitForEngine(page, kind); await evaluateWithGeo(page, (geo) => { window.__godsEyeView.engine.camera.setView({ destination: geo.cartesian3.fromDegrees(-79.38, 43.65, 500000),