feat(globe): implement the engine on Cesium

createCesiumEngine wraps an existing viewer without changing it: camera, picker, projector, frames, render (through the render governor), surface, input, credits and maps, with geo values out and Cesium values in at the boundary. Map and surface code is shared with src/maps and services/groundSnap instead of copied. scripts/qa-globe-contract.mjs runs the contract suite against the engine in headless Chrome; the camera-events check now waits for the previous move to end, as Cesium's moveStart marks a move from rest.
This commit is contained in:
German Khokhlov committed 2026-10-15 17:43:05 +04:00
1 parent cd94a26b9f
commit d831cbd23a
33 files changed
+2374 -32

No files matched your search

+86
View File
@@ -0,0 +1,86 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import * as Cesium from 'cesium';
import * as geo from '../../geo/index.js';
import { createCesiumSurface } from './surface.js';
import { createFakeViewer } from './testing/fakeViewer.mjs';
function setup() {
const viewer = createFakeViewer();
const { surface } = createCesiumSurface(viewer);
return { viewer, surface, scene: viewer.scene };
}
test('sampleHeight forwards the point and exclusions to the scene', () => {
const { viewer, surface, scene } = setup();
const place = geo.cartographic.fromDegrees(20, 10, 0);
const exclude = [{ primitive: 1 }];
assert.equal(surface.sampleHeight(place, exclude), 42);
const [position, excluded] = viewer.callsOf('scene.sampleHeight')[0].args;
assert.equal(position.longitude, place.longitude);
assert.equal(position.latitude, place.latitude);
assert.equal(excluded, exclude);
scene.sampleHeight = () => undefined;
assert.equal(surface.sampleHeight(place), undefined);
scene.sampleHeight = () => NaN;
assert.equal(surface.sampleHeight(place), undefined);
scene.sampleHeight = () => {
throw new Error('sampleHeight unsupported');
};
assert.equal(surface.sampleHeight(place), undefined, 'a throw is a miss');
});
test('supported flags follow the scene', () => {
const { surface, scene } = setup();
assert.equal(surface.supported, true);
assert.equal(surface.clampToHeightSupported, true);
assert.equal(surface.terrainHeightSupported, true);
scene.sampleHeightSupported = false;
scene.clampToHeightSupported = false;
scene.globe = undefined;
assert.equal(surface.supported, false);
assert.equal(surface.clampToHeightSupported, false);
assert.equal(surface.terrainHeightSupported, false);
const place = geo.cartographic.fromDegrees(20, 10, 0);
assert.equal(surface.sampleHeight(place), undefined);
assert.equal(surface.terrainHeight(place), undefined);
assert.equal(
surface.clampToHeight(geo.cartesian3.fromDegrees(20, 10, 10)),
undefined,
);
});
test('terrainHeight asks the globe', () => {
const { viewer, surface, scene } = setup();
const place = geo.cartographic.fromDegrees(20, 10, 0);
assert.equal(surface.terrainHeight(place), 12.5);
assert.equal(viewer.callsOf('globe.getHeight')[0].args[0], place);
scene.globe.getHeight = () => undefined;
assert.equal(surface.terrainHeight(place), undefined);
});
test('clampToHeight returns a geo value', () => {
const { viewer, surface } = setup();
const exclude = [];
const clamped = surface.clampToHeight(
geo.cartesian3.fromDegrees(20, 10, 5000),
exclude,
);
assert.ok(!(clamped instanceof Cesium.Cartesian3));
assert.equal(clamped.x, 6378200);
assert.equal(viewer.callsOf('scene.clampToHeight')[0].args[1], exclude);
});
test('tilesLoaded follows the first visible tileset, else the shown globe', () => {
const { viewer, surface, scene } = setup();
assert.equal(surface.tilesLoaded(), true, 'globe loaded');
scene.globe.tilesLoaded = false;
assert.equal(surface.tilesLoaded(), false, 'globe streaming');
scene.globe.show = false;
assert.equal(surface.tilesLoaded(), true, 'nothing streams');
const tileset = { show: true, tilesLoaded: false };
viewer.primitiveList.push({ show: true }, tileset);
assert.equal(surface.tilesLoaded(), false);
tileset.tilesLoaded = true;
assert.equal(surface.tilesLoaded(), true);
});