mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 07:42:23 +00:00
Layers are to draw through the globe contract on both engines, so Cesium gets back the movers and lines removed as unused: - engine.movers draws sprite sets as a BillboardCollection (atlas cells cropped once per set), point sets as a PointPrimitiveCollection and model sets as one Model per instance. depthTest, disableWithinM, order, scaleByDistance, colorBlend, unlit and minimumPixelSize follow the contract; a model's matrix is written in place, so instances no longer share one scratch matrix. - engine.lines draws each line as a polyline Primitive with width in CSS px, geodesic arcs, dashes, the tactical and arrow materials, depthFailAlpha and modelMatrix; a rebuild keeps its show, matrix, colour and place in order. - The picker returns the pickId a layer wrote last, skips sets that are not pickable and instances behind the horizon, and falls through to what lies under them. Surface samples can exclude mover sets again. movers and lines move from the optional capabilities into the required contract shape, and the contract suite always runs their checks.
140 lines
5.2 KiB
JavaScript
140 lines
5.2 KiB
JavaScript
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);
|
|
});
|
|
|
|
test('sampleHeightDetailed: tiles from sampleHeight, else terrain; no tile size', () => {
|
|
const { surface, scene } = setup();
|
|
const place = geo.cartographic.fromDegrees(20, 10, 0);
|
|
assert.deepEqual(surface.sampleHeightDetailed(place), {
|
|
height: 42,
|
|
source: 'tiles',
|
|
});
|
|
scene.sampleHeight = () => undefined;
|
|
assert.deepEqual(surface.sampleHeightDetailed(place), {
|
|
height: 12.5,
|
|
source: 'terrain',
|
|
});
|
|
assert.throws(
|
|
() => surface.sampleHeightDetailed(place, { exclude: 'x' }),
|
|
TypeError,
|
|
);
|
|
});
|
|
|
|
test('an engine mover set in exclude is hidden for the sample, native objects pass', () => {
|
|
const viewer = createFakeViewer();
|
|
const collection = { show: true };
|
|
const set = { id: 'flights' };
|
|
const { surface } = createCesiumSurface(viewer, {
|
|
engineExclude: (entry) => (entry === set ? collection : null),
|
|
});
|
|
const shownDuring = [];
|
|
viewer.scene.sampleHeight = (position, excluded) => {
|
|
shownDuring.push(collection.show, excluded);
|
|
return 30;
|
|
};
|
|
const native = { primitive: 1 };
|
|
const place = geo.cartographic.fromDegrees(20, 10, 0);
|
|
assert.equal(surface.sampleHeight(place, [set, native]), 30);
|
|
assert.deepEqual(shownDuring, [false, [native]]);
|
|
assert.equal(collection.show, true, 'shown again after the sample');
|
|
shownDuring.length = 0;
|
|
surface.sampleHeightDetailed(place, { exclude: [set] });
|
|
assert.deepEqual(shownDuring, [false, []]);
|
|
assert.equal(collection.show, true);
|
|
// clampToHeight too, and a throwing scene still shows the set again.
|
|
viewer.scene.clampToHeight = (position, excluded) => {
|
|
shownDuring.push(collection.show, excluded);
|
|
throw new Error('no depth texture');
|
|
};
|
|
shownDuring.length = 0;
|
|
assert.equal(
|
|
surface.clampToHeight(geo.cartesian3.fromDegrees(20, 10, 0), [set]),
|
|
undefined,
|
|
);
|
|
assert.deepEqual(shownDuring, [false, []]);
|
|
assert.equal(collection.show, true);
|
|
});
|