Files
gods-eye-view/src/data/nearbyModelHandoff.test.mjs
T

206 lines
7.0 KiB
JavaScript

// src/data/nearbyModelHandoff.test.mjs
//
// `getNearby()` is the proximity seam behind the Context/Contacts cohort counts
// and the voice framing tools. It used to admit contacts on billboard
// visibility alone, so every plane the fleet 3D-model handoff had taken over
// (billboard hidden, model shown) silently dropped out of the results and the
// counts flapped to zero. The guard now mirrors the sibling
// `getDetectableObjects()` in each layer: a contact stays nearby while EITHER
// visual owns it, and a contact nothing is drawing for stays excluded.
import test from 'node:test';
import assert from 'node:assert/strict';
import * as Cesium from 'cesium';
import flightsLayer, { _setTrackedFlightRefreshStateForTest } from './flights.js';
import militaryFlightsLayer, { _setTrackedMilitaryRefreshStateForTest } from './militaryFlights.js';
const ICAO = 'abc123';
const OTHER = 'def456';
/** ~10.6 km from the seeded contact — well inside the query range either way. */
const CENTER = Cesium.Cartesian3.fromDegrees(-97.7, 30.2, 200);
const RANGE_M = 250_000;
const MODEL_POSITION = Cesium.Cartesian3.fromDegrees(-97.69, 30.22, 10_900);
const MODEL_ROTATION = Cesium.Matrix3.fromRotationZ(Math.PI / 2);
const COMPUTED_SCALE = 7;
function contactBillboard(show) {
return {
position: Cesium.Cartesian3.fromDegrees(-97.71, 30.21, 10_668),
color: Cesium.Color.WHITE,
show,
};
}
function contactViewer() {
return { camera: { positionCartographic: null }, scene: {} };
}
const LAYERS = [
{
name: 'commercial',
layer: flightsLayer,
visualCenterM: Cesium.Cartesian3.ZERO,
seed({ billboardShow, models = [] }) {
_setTrackedFlightRefreshStateForTest({
icao24: ICAO,
entity: null,
billboard: contactBillboard(billboardShow),
billboardCollection: { show: true, remove() {} },
viewer: contactViewer(),
tracked: false,
models,
meta: {
callsign: `${ICAO.toUpperCase()} `,
altitude: 10_668,
klass: 'airliner',
onGround: false,
},
});
},
},
{
name: 'military',
layer: militaryFlightsLayer,
visualCenterM: Cesium.Cartesian3.ZERO,
seed({ billboardShow, models = [] }) {
_setTrackedMilitaryRefreshStateForTest({
icao24: ICAO,
entity: null,
billboard: contactBillboard(billboardShow),
billboardCollection: { show: true, remove() {} },
viewer: contactViewer(),
tracked: false,
models,
meta: {
callsign: `${ICAO.toUpperCase()} `,
altitudeFt: 35_000,
klass: 'fighter',
onGround: false,
},
});
},
},
];
/** ICAO24 identities the layer reports as nearby the fixed center. */
function nearbyIcaos(layer) {
return layer.getNearby(CENTER, RANGE_M, 50).map((contact) => contact.icao24);
}
/** Detection position for the shared fixture contact. */
function detectionPosition(layer) {
return layer.getDetectableObjects({ maxCount: 50 })
.find((contact) => contact.sourceId === ICAO)?.position || null;
}
for (const fixture of LAYERS) {
test(`${fixture.name} getNearby keeps the exact contact whose 3D model owns the visual`, () => {
// The handoff state: the fleet tick hid the sprite and showed the model.
fixture.seed({
billboardShow: false,
models: [[ICAO, { ready: true, show: true, _gevPlacementReady: true }]],
});
assert.ok(
nearbyIcaos(fixture.layer).includes(ICAO),
'a model-owned contact must stay in the proximity cohort',
);
// A model belonging to a DIFFERENT aircraft must not rescue this one.
fixture.seed({ billboardShow: false, models: [[OTHER, { show: true }]] });
assert.ok(
!nearbyIcaos(fixture.layer).includes(ICAO),
'the model lookup must be keyed to the contact, not to any shown model',
);
});
test(`${fixture.name} getNearby still drops a contact nothing is drawing`, () => {
// Positive control: the same contact IS reachable when its sprite shows,
// so the exclusions below cannot pass for an unrelated reason.
fixture.seed({ billboardShow: true });
assert.ok(nearbyIcaos(fixture.layer).includes(ICAO), 'a shown sprite is nearby');
fixture.seed({ billboardShow: false });
assert.ok(
!nearbyIcaos(fixture.layer).includes(ICAO),
'a hidden sprite with no model must stay excluded',
);
fixture.seed({ billboardShow: false, models: [[ICAO, { show: false }]] });
assert.ok(
!nearbyIcaos(fixture.layer).includes(ICAO),
'a released (hidden) model must not resurrect a hidden contact',
);
fixture.seed({
billboardShow: false,
models: [[ICAO, {
ready: false,
show: true,
scale: 0,
_gevPlacementReady: false,
}]],
});
assert.ok(
!nearbyIcaos(fixture.layer).includes(ICAO),
'a zero-scale loading model cannot claim proximity ownership',
);
});
test(`${fixture.name} detection follows the visible 2D sprite and 3D model anchors`, () => {
fixture.seed({ billboardShow: true });
const spritePosition = detectionPosition(fixture.layer);
assert.ok(spritePosition, 'the 2D sprite publishes a detection candidate');
assert.ok(
Cesium.Cartesian3.equalsEpsilon(spritePosition, contactBillboard(true).position, 0, 1e-6),
'the 2D bracket stays welded to the billboard position',
);
const modelMatrix = Cesium.Matrix4.fromRotationTranslation(MODEL_ROTATION, MODEL_POSITION);
fixture.seed({
billboardShow: false,
models: [[ICAO, {
ready: true,
show: true,
_gevPlacementReady: true,
modelMatrix,
computedScale: COMPUTED_SCALE,
}]],
});
const modelPosition = detectionPosition(fixture.layer);
assert.ok(modelPosition, 'the 3D model publishes the same detection candidate');
const expectedVisualCenter = Cesium.Matrix4.multiplyByPoint(
modelMatrix,
Cesium.Cartesian3.multiplyByScalar(
fixture.visualCenterM,
COMPUTED_SCALE,
new Cesium.Cartesian3(),
),
new Cesium.Cartesian3(),
);
assert.ok(
Cesium.Cartesian3.equalsEpsilon(modelPosition, expectedVisualCenter, 0, 1e-6),
'the 3D bracket stays on the normalized model origin at any rendered scale',
);
assert.ok(
Cesium.Cartesian3.equalsEpsilon(modelPosition, MODEL_POSITION, 0, 1e-6),
'origin-centred GLBs keep the bracket welded to the modelMatrix translation',
);
fixture.seed({
billboardShow: true,
models: [[ICAO, {
ready: false,
show: true,
scale: 0,
_gevPlacementReady: false,
modelMatrix: Cesium.Matrix4.clone(Cesium.Matrix4.IDENTITY),
}]],
});
const loadingPosition = detectionPosition(fixture.layer);
assert.ok(loadingPosition, 'the billboard remains detectable while its model loads');
assert.ok(
Cesium.Cartesian3.equalsEpsilon(loadingPosition, contactBillboard(true).position, 0, 1e-6),
'a shown-but-unready zero-scale model cannot steal the detection anchor',
);
});
}