mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 03:14:00 +00:00
Extract military-flight components and shared aircraft mechanics
This commit is contained in:
1 parent
b5e546daf1
commit
cb790ddea1
25 files changed
+4849
-3930
No files matched your search
@@ -0,0 +1,291 @@
|
||||
import * as Cesium from 'cesium';
|
||||
|
||||
|
||||
/**
|
||||
* @module militaryFlights
|
||||
* @description Real-time military flight tracking layer powered by the adsb.lol API.
|
||||
*
|
||||
* Renders aircraft as amber chevron billboards in a single BillboardCollection
|
||||
* for GPU-efficient batch drawing. Supports click-to-track: selecting an aircraft
|
||||
* spawns an Entity the camera follows, whose position is driven by a
|
||||
* dead-reckoning CallbackProperty. The whole fleet renders at
|
||||
* now - RENDER_DELAY_SEC so positions interpolate BETWEEN two known fixes
|
||||
* instead of extrapolating ahead and snapping back when the next poll lands.
|
||||
*
|
||||
* Billboard orientation uses alignedAxis set to the WGS84 surface normal at each
|
||||
* position so that the rotation angle (heading/track) operates in the local tangent
|
||||
* plane where 0 deg = north; near nadir the icons switch to screen-aligned
|
||||
* rotation (camera.heading - track) with hysteresis.
|
||||
*/
|
||||
|
||||
/** @constant {number} Milliseconds to wait before retrying after a transient error */
|
||||
|
||||
export const ERROR_BACKOFF_INTERVAL = 20000;
|
||||
|
||||
/** @constant {number} Max position samples retained per aircraft for dead reckoning */
|
||||
|
||||
export const POSITION_HISTORY_LIMIT = 5;
|
||||
|
||||
/** @constant {number} Base billboard display scale */
|
||||
|
||||
export const BILLBOARD_SCALE = 0.7;
|
||||
|
||||
|
||||
/** @constant {Cesium.Color} Default amber tint for untracked military billboards */
|
||||
|
||||
export const MIL_ICON_COLOR = Cesium.Color.fromCssColorString('#FFB800');
|
||||
|
||||
/** @constant {Cesium.Color} Lighter amber tint applied to the actively tracked aircraft */
|
||||
|
||||
export const TRACKED_ICON_COLOR = Cesium.Color.fromCssColorString('#FFD166');
|
||||
|
||||
|
||||
// --- Ground traffic (owner reversal 2026-07-03; mirror of flights.js) ---------------
|
||||
// adsb.lol/readsb flags ground traffic with alt_baro === "ground" (no separate
|
||||
// boolean). Such aircraft are RENDERED instead of floating at the 3 km altitude
|
||||
// fallback: same silhouette + rotation pipeline, clickable/trackable/detectable,
|
||||
// sticky metadata updating normally. The on-ground flip restyles the existing
|
||||
// billboard IN PLACE (landing/takeoff transition, never a removal); ground planes
|
||||
// draw no trails. In 3D mode they take model slots like airborne planes (owner
|
||||
// decision 2026-07-03 — no air/ground distinction), placed by the one-shot
|
||||
// ground snap (see _modelDisplayPosition).
|
||||
//
|
||||
// TINT: full-strength amber, same as airborne (owner verdict 2026-07-03 field
|
||||
// test: the day-1 slate-gray 50%-alpha muted tint was unreadable — "in NYC I can
|
||||
// barely see them"). "On the ground" reads from the ×0.8 scale + missing trail;
|
||||
// "feed-dropped, coasting" stays the 45%-alpha stale fade.
|
||||
/** Ground billboards render slightly smaller so airport clutter stays visually minor. */
|
||||
|
||||
export const GROUND_SCALE = 0.8;
|
||||
|
||||
|
||||
// --- 3D model rendering (mirrors flights.js) -----------------------------------------
|
||||
// When enabled, military aircraft render as 3D glTF jet models once the camera is below
|
||||
// MODEL_ALT_CEIL_M (zoomed in); higher up they stay flat billboards. Eligibility is
|
||||
// FRUSTUM-based (on-screen), and the slots go to either the nearest planes ('proximity')
|
||||
// or every in-view plane ('all'), each backed by a hard cap so a draw-call explosion
|
||||
// can't tank the frame (no instancing yet). Distinct asset + amber tint set this layer
|
||||
// apart from the commercial flights layer.
|
||||
|
||||
export const JET_MODEL_URL = '/models/jet.glb';
|
||||
|
||||
|
||||
export const MODEL_ALT_CEIL_M = 800000;
|
||||
// m: below this camera altitude, draw 3D models (raised so it's easy to trigger)
|
||||
|
||||
export const MODEL_MIN_PX = 24;
|
||||
// floor so distant models stay visible without ballooning into a min-pixel blob (mirror of flights.js, whose models now share this layer's ~30 m world size)
|
||||
|
||||
export const TRACKED_MODEL_MIN_PX = 40;
|
||||
// keep the glTF silhouette comparable to the selected 2D glyph at handoff
|
||||
|
||||
export const TRACKED_MODEL_MAX_PX = 200;
|
||||
// owner-selected close-range tracked-target feel
|
||||
|
||||
export const MODEL_NATIVE_RADIUS_M = 29.83;
|
||||
|
||||
// jet.glb is transform-applied at real-world scale — native bounding radius
|
||||
// 29.83 m at scale 1. ×1 → ~22–43 m aircraft across CLASS_SCALE_3D, matching
|
||||
// flights.js world sizes. At the old copied ×24, models rendered
|
||||
// 600–1000 m across (invisible at the ~6 km follow range where minimumPixelSize
|
||||
// dominates, but zoom under ~1 km put the camera INSIDE the plane). Locked by
|
||||
// modelScale.test.mjs.
|
||||
|
||||
export const MODEL_SCALE = 1;
|
||||
|
||||
// Per-mode caps + radii — mirror of flights.js. Modes differ by RADIUS (not just cap) so Proximity
|
||||
// and All aren't identical when few planes are in range; on-screen planes win the cap (see flights.js).
|
||||
|
||||
export const MODEL_MAX = 150;
|
||||
// 'proximity' cap
|
||||
|
||||
export const MODEL_MAX_ALL = 350;
|
||||
// 'all' cap
|
||||
|
||||
export const MODEL_PROX_ADD_M = 150000;
|
||||
// proximity: model NEW planes within 150 km
|
||||
|
||||
export const MODEL_PROX_KEEP_M = 185000;
|
||||
// proximity: KEEP modeled planes out to 185 km
|
||||
|
||||
// Cockpit keeps the standard Display radii but lowers the GLB budget. Contacts
|
||||
// inside the selected band remain AIR silhouettes when they cannot own a model;
|
||||
// contacts outside the band use compact dots.
|
||||
|
||||
export const COCKPIT_MODEL_MAX = 60;
|
||||
// max concurrent GLBs in cockpit (never raises the map cap)
|
||||
|
||||
export const MODEL_ALL_ADD_M = 400000;
|
||||
// all: model NEW planes within 400 km (~to the horizon)
|
||||
|
||||
export const MODEL_ALL_KEEP_M = 450000;
|
||||
// all: KEEP modeled planes out to 450 km
|
||||
|
||||
export const MODEL_HEADING_OFFSET_DEG = 180;
|
||||
// every aircraft GLB is exported nose -X in the shared transform-applied convention
|
||||
// Preserve the layer's amber identity while reducing approved texture/livery
|
||||
// contribution to a weak diffuse hint, matching civilian launch presentation.
|
||||
|
||||
export const MODEL_COLOR_BLEND_AMOUNT = 0.94;
|
||||
|
||||
// airplane.glb (the shared 747) constants for this layer's heavy classes. The
|
||||
// asset has its former 24× runtime calibration baked into transform-applied
|
||||
// meter-scale geometry; these values mirror flights.js and are regression-pinned.
|
||||
|
||||
export const PLANE_MODEL_URL = '/models/airplane.glb';
|
||||
|
||||
|
||||
export const PLANE_MODEL_SCALE = 1;
|
||||
|
||||
|
||||
export const PLANE_NATIVE_RADIUS_M = 34.41;
|
||||
|
||||
|
||||
export const PLANE_BELLY_OFFSET_NATIVE = 6.719;
|
||||
|
||||
// Grounded-model belly offset: jet.glb's centred origin sits 5.631 native units (= meters — this
|
||||
// asset is real-world scale) ABOVE its lowest vertex (glTF Y-up scene AABB with node
|
||||
// transforms applied — same reader as modelScale.test.mjs, measured 2026-07-03).
|
||||
// × MODEL_SCALE(1) × class multiplier ≈ 4.4–8.6 m of lift, so a ground-snapped model
|
||||
// rests its lowest geometry (gear/belly) ON the sampled tile skin instead of sinking to
|
||||
// the fuselage-centerline origin. Locked against the GLB by modelScale.test.mjs.
|
||||
|
||||
export const MODEL_BELLY_OFFSET_NATIVE = 5.631;
|
||||
|
||||
/** Amber fade target for the tracked billboard once the model takes over (mirrors flights.js CYAN_TRANSPARENT). */
|
||||
|
||||
export const AMBER_TRANSPARENT = MIL_ICON_COLOR.withAlpha(0);
|
||||
|
||||
|
||||
|
||||
export const COCKPIT_CONTACT_SIZE_PX = 6;
|
||||
|
||||
|
||||
export const TRACKED_BILLBOARD_SCALE_BY_DISTANCE = new Cesium.NearFarScalar(
|
||||
1000, 3.0, 8000000, 0.5,
|
||||
);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Track-history trail state (PRD WS-F F2/F4): a fading polyline behind the
|
||||
// tracked aircraft. The accumulation array is intentionally SEPARATE from
|
||||
// _positionHistory (capped at POSITION_HISTORY_LIMIT=5 for dead reckoning)
|
||||
// so the visible trail can grow to TRAIL_MAX_POINTS fixes.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** @constant {string} Military trail hue (PRD F4, pinned). */
|
||||
|
||||
export const TRAIL_COLOR = '#FFB800';
|
||||
|
||||
/** @constant {number} Combined cap on trail vertices (backfill + live accumulation). */
|
||||
|
||||
export const TRAIL_MAX_POINTS = 400;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Render-behind smoothing (mirrors flights.js): the fleet renders at
|
||||
// now - RENDER_DELAY_SEC so positions interpolate BETWEEN two known fixes
|
||||
// instead of extrapolating ahead and snapping back when the next poll lands.
|
||||
// Removing the delay reintroduces the back/forward oscillation and is a
|
||||
// regression.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** @constant {number} Display latency in seconds (= one poll interval). */
|
||||
|
||||
export const RENDER_DELAY_SEC = 15;
|
||||
|
||||
/** @constant {number} Polls an aircraft may miss before removal (transient adsb.lol dropouts). */
|
||||
|
||||
export const MISSING_POLL_LIMIT = 3;
|
||||
|
||||
// --- Landed-plane fast cull (mirror of flights.js; owner field report
|
||||
// 2026-07-02: "phantom" planes lingered ~2 min at airports after touchdown).
|
||||
// The feed's ground flag lags the actual landing, so a landed plane's last
|
||||
// airborne fixes show it low + slow on the runway; when it then drops out of
|
||||
// the poll it has landed, not hit a transient gap — evict after ONE missed
|
||||
// poll. Thresholds: below ~500 ft baro (≈150 m MSL — near-sea-level fields
|
||||
// only; a high-elevation airport ghost falls back to the normal grace) AND
|
||||
// below ~45 kts ground speed (≈23 m/s — rollout/taxi; nothing in normal
|
||||
// FLIGHT is this slow, so cruise planes always keep the full grace).
|
||||
/** @constant {number} Max baro altitude (ft, MSL) for the landed fast cull (~150 m). */
|
||||
|
||||
export const LANDED_ALT_MAX_FT = 500;
|
||||
|
||||
/** @constant {number} Max ground speed (m/s) for the landed fast cull (~45 kts). */
|
||||
|
||||
export const LANDED_SPEED_MAX_MPS = 23;
|
||||
|
||||
/** @constant {number} Missed-poll allowance for likely-landed planes (1 = removed on the first missed poll). */
|
||||
|
||||
export const LANDED_MISSING_POLL_LIMIT = 1;
|
||||
|
||||
// Field-test fix (RS46, 2026-07-06): only contacts rendering below this
|
||||
// ellipsoidal height get the below-ground floor clamp + a coarse floor-cell
|
||||
// warm. Terrain outside the extreme Himalaya tops out well under this, so
|
||||
// cruise traffic (which can never be below ground) costs zero terrain
|
||||
// lookups; low pattern/heli work — the class that actually clips hillsides —
|
||||
// gets the floor.
|
||||
/** @constant {number} Max render altitude (m, ellipsoidal) eligible for the ground-floor clamp. */
|
||||
|
||||
export const GROUND_FLOOR_WARM_MAX_ALT_M = 4500;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Nadir-stable icon orientation (mirrors flights.js): surface-normal alignment
|
||||
// degenerates when the camera looks straight down (the normal is parallel to
|
||||
// the view direction and the shader's screen-projected angle is 0/0). Near
|
||||
// nadir we switch to screen-aligned billboards with
|
||||
// rotation = camera.heading - track (screen-up points at azimuth
|
||||
// camera.heading; a CW track t appears t-h from screen-up; billboard rotation
|
||||
// is CCW-positive => r = h - t). Discrete switch with hysteresis; rotations
|
||||
// are continuous at the boundary with this formula.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** @constant {number} Fleet dead-reckoning tick interval (ms) — ~12Hz, not per-frame. */
|
||||
|
||||
export const FLEET_DR_INTERVAL_MS = 80;
|
||||
|
||||
/** @constant {number} Max ms between rotation passes while the camera is idle. */
|
||||
|
||||
export const ROTATION_REFRESH_MS = 1000;
|
||||
|
||||
/** Max course slew (deg/s) — well above real turns (≤4°/s), hides fix-boundary
|
||||
* steps. Scaled down toward COURSE_MIN_DPS at low speed (courseSlewCapDps). */
|
||||
|
||||
export const COURSE_MAX_DPS = 60;
|
||||
|
||||
/** Never spend a long render stall's full elapsed time in one visible course step. */
|
||||
|
||||
export const COURSE_SLEW_DT_MAX_SEC = 0.25;
|
||||
|
||||
|
||||
// -- Tracked-display reconciliation (see flights.js for the rationale): absorb a raw
|
||||
// position step (warm-up→interpolation handoff, feed glitch, backfill splice) into a
|
||||
// correction offset that decays to zero over DR_CORRECTION_MS, so the tracked icon,
|
||||
// camera, and trail head never visibly jump — with zero steady-state lag. --
|
||||
|
||||
export const DR_CORRECTION_MS = 900;
|
||||
|
||||
|
||||
/** Bounded on-demand loading for the tracked model (mirror of flights.js). The
|
||||
* tracked regime is DEFAULT-ON and its driver runs every `scene.preUpdate`, so
|
||||
* a missing or corrupt GLB — or a dead network — would otherwise spin
|
||||
* load→reject at frame rate for as long as the contact stays selected.
|
||||
* Failures are counted PER SELECTION: a short backoff absorbs a transient
|
||||
* blip, then the layer stops asking until the operator selects something else.
|
||||
* The billboard is the visual throughout (the handoff only fades it once a
|
||||
* model actually renders), so a latched failure degrades to exactly the
|
||||
* pre-3D presentation. */
|
||||
|
||||
export const TRACKED_MODEL_MAX_LOAD_FAILS = 3;
|
||||
|
||||
|
||||
export const TRACKED_MODEL_RETRY_BACKOFF_MS = 1500;
|
||||
|
||||
/** Boost flip = BATCHED release through the fleet tick (mirror of flights.js —
|
||||
* destroying the whole fleet synchronously in the style handler stalls the
|
||||
* render thread). Models tagged with their load-time boost state; stale queue
|
||||
* entries skip; in-flight loads invalidated immediately; tracked reloads
|
||||
* synchronously (single primitive). */
|
||||
|
||||
export const IR_RELOAD_BATCH = 40;
|
||||
Reference in new issue
Block a user