Separate vessel records and acquisition from scene resources

This commit is contained in:
Sameh Khamis committed 2026-09-14 16:37:41 -07:00
1 parent 852008df4d
commit bdc026e50a
26 files changed
+877 -508

No files matched your search

+19 -12
View File
@@ -33,10 +33,10 @@ export function createSelection({
function bindVesselInteraction(viewer, handler, keyTarget) {
state.clickHandler = handler;
handler.setInputAction((click) => {
if (!state.enabled) return;
if (!state.feed.enabled) return;
const picked = viewer.scene.pick(click.position);
const pickedId = resolvePickId(picked);
let record = pickedId ? state.vesselMap.get(pickedId) : null;
let record = pickedId ? state.records.byMmsi.get(pickedId) : null;
const rawId = picked?.id ?? picked?.primitive?.id;
const ownRecordPick =
rawId && typeof rawId === 'object' && Object.hasOwn(rawId, 'mmsi');
@@ -69,7 +69,7 @@ export function createSelection({
const mmsi = String(cardHit.entryId || '').startsWith('vessel:')
? cardHit.entryId.slice('vessel:'.length)
: null;
record = mmsi ? state.vesselMap.get(mmsi) || null : null;
record = mmsi ? state.records.byMmsi.get(mmsi) || null : null;
// A stale card id is not empty terrain and must not clear a newer
// selection. The next paint will evict its hit rectangle.
if (!record) return;
@@ -115,7 +115,9 @@ export function createSelection({
kind: 'vessel',
id: record.mmsi,
label: record.name || record.mmsi,
position: record.billboard?.position || record.position,
position:
components.rendering.getVisual(record).billboard?.position ||
components.rendering.getVisual(record).position,
});
return true;
}
@@ -137,7 +139,7 @@ export function createSelection({
}
function onVesselKeyDown(event) {
if (!state.enabled || event.key !== 'Escape') return;
if (!state.feed.enabled || event.key !== 'Escape') return;
const transition = components.queries.reduceVesselSelection({
selectedMmsi: state.selectedRecord?.mmsi,
gesture: 'escape',
@@ -153,9 +155,11 @@ export function createSelection({
clearSelection({ preserveTrail: reuseTrail });
state.selectedRecord = record;
record.missedRefreshes = 0;
if (record.billboard) {
record.billboard.image = components.rendering.shipIcon(record, true);
record.billboard.scale = components.rendering.shipScale(record) * 1.2;
if (components.rendering.getVisual(record).billboard) {
components.rendering.getVisual(record).billboard.image =
components.rendering.shipIcon(record, true);
components.rendering.getVisual(record).billboard.scale =
components.rendering.shipScale(record) * 1.2;
}
// Rebuild the card set immediately so the full-detail card appears on the
// click, not up to VISIBILITY_UPDATE_MS later.
@@ -207,14 +211,17 @@ export function createSelection({
function clearSelection({ preserveTrail = false, evicted = false } = {}) {
const record = state.selectedRecord;
if (record?.billboard) {
record.billboard.image = components.rendering.shipIcon(record, false);
record.billboard.scale = components.rendering.shipScale(record);
if (components.rendering.getVisual(record)?.billboard) {
components.rendering.getVisual(record).billboard.image =
components.rendering.shipIcon(record, false);
components.rendering.getVisual(record).billboard.scale =
components.rendering.shipScale(record);
}
state.selectedRecord = null;
// Drop the full-detail card right away (no-op when the layer is disabled —
// disable() clears the entry set itself).
if (record && state.enabled) components.rendering.updateVisibility(true);
if (record && state.feed.enabled)
components.rendering.updateVisibility(true);
if (!preserveTrail) components.tracking.clearSelectedVesselTrail();
try {
clearSelectedEntityContextForLayer('ais-live-vessels', { evicted });