mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
Review follow-ups for the sonar pulses. Wake on user input only: a camera move wakes the pulses only within 1.5 s of a pointer, wheel or touch on the Cesium canvas, where its camera controller listens. Tracking, the cockpit view, an orbit or a fly-to move the camera on every frame and no longer keep the pulses running. Keys don't count: the camera controller reads none. Below the disc: with the camera under 2.5 km the pulses rest completely, with no disc, ring flash, echoes or frame requests. Echo brightness: echoes scale by the contact bracket's drawn alpha, which includes the Cyber sonar sweep, rounded to the nearest band with no floor, so an echo is never brighter than its bracket. Disc follow: the pulse disc follows the subject by a model-matrix rotation about the Earth's centre and is rebuilt only every 20 km instead of every 500 m. Tests: a cap on burst length; teardown through disable(); the echo's spread and alpha on the canvas; echoes under the Cyber sonar never brighter than their bracket; waking by pointer, wheel, touch and drag but not by keys, app camera moves or stale input; the rest below the disc; and tighter asserts. CURRENT-STATE notes that terrain above 2.5 km still cuts through the disc and ring.
80 lines
2.6 KiB
JavaScript
80 lines
2.6 KiB
JavaScript
import * as Cesium from 'cesium';
|
|
|
|
export function createState({ services }) {
|
|
const state = {};
|
|
|
|
state.DIRECTION_SCRATCH = Array.from(
|
|
{ length: 3 },
|
|
() => new Cesium.Cartesian3(),
|
|
);
|
|
|
|
state.SUBJECT_CARTOGRAPHIC_SCRATCH = new Cesium.Cartographic();
|
|
|
|
state.TARGET_CARTOGRAPHIC_SCRATCH = Array.from(
|
|
{ length: 3 },
|
|
() => new Cesium.Cartographic(),
|
|
);
|
|
|
|
Object.assign(state, {
|
|
viewer: null,
|
|
dataManager: null,
|
|
enabled: false,
|
|
// Set once a refresh observes the subject gone from a still-reporting source.
|
|
// The Contact readout turns this into its CONTACT LOST hold state.
|
|
subjectMissing: false,
|
|
// The dedicated Context chooser exposes a passive shell. Operational source
|
|
// layers activate only after Contacts is explicitly selected.
|
|
passive: true,
|
|
ownedDependencies: new Set(),
|
|
subject: null,
|
|
results: null,
|
|
visual: null,
|
|
/** Whether layer views replace the panel's initial markup yet. */
|
|
panelShown: false,
|
|
/** The published panel view, its signature and its subscribers. */
|
|
panelView: null,
|
|
panelSignature: '',
|
|
panelListeners: new Set(),
|
|
/** Result renders, published or not; tests observe repaint storms. */
|
|
panelRenders: 0,
|
|
subjectListener: null,
|
|
contextListener: null,
|
|
clearListener: null,
|
|
subjectClearListener: null,
|
|
runtimeListenersAttached: false,
|
|
preRenderRemover: null,
|
|
/** The published direction overlay, its signature and its subscribers. */
|
|
directionView: null,
|
|
directionSignature: '',
|
|
directionListeners: new Set(),
|
|
/** Each marker's last stable screen angle. */
|
|
directionAngles: [0, 0, 0],
|
|
navigationHistory: [],
|
|
navigationVisited: new Set(),
|
|
navigationIndex: -1,
|
|
suppressedHistoryKey: null,
|
|
pendingSelectionKey: null,
|
|
lastSubjectRefreshMs: 0,
|
|
/** Camera-pose signature observed on the previous rendered frame. */
|
|
lastCameraPoseSig: '',
|
|
/** When the pose signature last changed bins (hysteresis anchor). */
|
|
lastCameraPoseChangeMs: 0,
|
|
/** When the viewer last handled the camera (pointer, wheel, touch, key). */
|
|
lastCameraInputMs: Number.NEGATIVE_INFINITY,
|
|
/** Element the camera-input listeners are attached to. */
|
|
cameraInputTarget: null,
|
|
/** Whether the view currently counts as moving (hysteretic, not per-frame). */
|
|
cameraMoving: false,
|
|
lastEvaluatedPosition: null,
|
|
sourceRevision: '',
|
|
directionFrame: null,
|
|
lastDirectionUpdateMs: 0,
|
|
activationId: 0,
|
|
autoFocusAttempted: false,
|
|
autoFocusRetryPending: false,
|
|
pageTimer: null,
|
|
cohortPages: new Map(),
|
|
});
|
|
return state;
|
|
}
|