Remove a released 3D tileset from Navara's scene and surface queries

With its cache budget on, Navara 0.2.1 deletes a source without emitting
the model-removal events, so the meshes of a released photoreal tileset
stayed in the scene: after switching to another map the buildings were
still drawn, and sampleHeight, clampToHeight, the shared surface
placement and ground drapes still answered from them. The adapter now
disposes the deleted layer's meshes, registry entries and retained
geometry itself, also for tiles that finish decoding afterwards, and
WORKAROUNDS.md records it. A contract check fails when a surface query
still reports tiles after leaving photoreal, with a mutant.
This commit is contained in:
German Khokhlov committed 2026-11-10 22:15:50 +04:00
1 parent 4bbf9949d5
commit cd571dfb32
9 files changed
+440 -6

No files matched your search

+36
View File
@@ -375,6 +375,20 @@ const mutants = [
);
},
],
[
'released photoreal tiles still answer surface queries',
'surface.sampleHeightDetailed: leaving photoreal',
(e) => {
replace(e.maps, 'setPhotorealTiles', (set) => async (source) => {
await set(source);
if (source === null)
e.fake.script('sampleHeightDetailed', () => ({
height: 50,
source: 'tiles',
}));
});
},
],
];
for (const [name, killedBy, mutate] of mutants) {
@@ -400,6 +414,28 @@ for (const [name, killedBy, mutate] of mutants) {
});
}
test('released tile surface check runs without a tileset fixture', async () => {
const engine = createFakeEngine();
try {
const check = createContractSuite(engine, {
...fakeContractOptions(engine),
fixtures: null,
mapSources: null,
}).find(({ name }) =>
name.startsWith('surface.sampleHeightDetailed: leaving photoreal'),
);
assert.ok(check);
await check.run();
engine.fake.script('sampleHeightDetailed', () => ({
height: 50,
source: 'tiles',
}));
await assert.rejects(check.run(), /released photoreal tiles/);
} finally {
engine.destroy();
}
});
test('tiles-only ground pixels on terrain are detected without a tileset fixture or a picking defect', async () => {
for (const drawsOnTerrain of [false, true]) {
const engine = createFakeEngine();