Compare commits

..
Author SHA1 Message Date
German Khokhlov 3953421aad Changelog fragment for #1700 2026-11-13 18:51:09 +04:00
German Khokhlov 209b135ff1 i18n: plural forms and contexts the catalogs could only work around
The last translation review left four kinds of problem it could only
reword around in the catalogs. They are fixed in the code now, and the
catalogs go back to natural wording.

- Counts shown with plain t() are tn() plurals: the wildlife count, the
  Data Library "Showing {shown} of {total}", the News time window (which
  offers 1 h) and the GhostMaps event age (which offers 1 day). The
  English keys stay; the catalogs get real forms, as in "Última 1 h" and
  "Últimas 24 h", or "1 Tag" and "7 Tage".
- The bridge radar range and ring spacing are tn() plurals too. The
  spacing is fractional at the short ranges, and Intl.PluralRules gives
  0.75 and 1.5 their own form: ru "0,75 МОР. МИЛИ", "12 МОР. МИЛЬ".
- Street level no longer passes "the view centre" or "this spot" as
  {place}: each case has a message of its own, so a preposition no
  longer meets a phrase in the wrong case. The progress line had the
  same leak and showed the English phrase.
- Latest, FOCUS, CONFIRMED and "{label} · COURSE {heading}°" are split
  with a context where one key served two places: the News heading, the
  orbital site status, the Wildlife chip and a ship's course.

"CURRENTLY OVER" ended in a preposition that a country name in the
nominative cannot follow in uk, de, it and pt. It reads "under the
satellite" there now, as ru already did.

I18N.md gains the two rules behind these fixes.
2026-11-13 18:50:34 +04:00
245 changed files with 2624 additions and 9009 deletions

No files matched your search

+4 -7
View File
@@ -1,13 +1,13 @@
# Data Sources & Attribution
God's Eye View's **code** is [MIT](LICENSE)-licensed. **The MIT grant covers the source code only — it does NOT extend to third-party data or visual assets.** Every third-party source keeps its own license and terms. This file documents the live and bundled data sources. The bundled 3D models are the project's own procedural fleet models, MIT-licensed with the code ([`public/models/README.md`](public/models/README.md)).
God's Eye View's **code** is [MIT](LICENSE)-licensed. **The MIT grant covers the source code only — it does NOT extend to third-party data or visual assets.** Every third-party source keeps its own license and terms. This file documents the live and bundled data sources; bundled 3D-model provenance is recorded in [`public/models/README.md`](public/models/README.md).
How to read this:
- **The non-permissive datasets are carved out, not omitted.** Some bundled data (e.g. TeleGeography, CC BY-NC-SA) isn't MIT-compatible. Rather than hide it, we **bundle it with a clear license carve-out** so the app works out of the box — but it stays under the provider's terms.
- **If your use doesn't fit a dataset's license, remove that dataset.** Most importantly: TeleGeography is **NonCommercial** — commercial users must delete it (or license it from TeleGeography). It's one self-contained folder.
- **Attribution is shown in-app** and listed here. Keep it intact. The required Google/Cesium credit renders on the on-globe credit line (bottom-left, `#cesium-credits`), and every per-layer credit below is registered into the expandable **"Data attribution"** lightbox on that line (`src/data/dataCredits.js` → `viewer.creditDisplay.addStaticCredit`). Both stay visible in clean-view and recording modes.
- **The bundled 3D models are the project's own.** Every model under `public/models/` is a procedural fleet model generated by the project maintainers and covered by the repository's MIT license; [`public/models/README.md`](public/models/README.md) describes the set.
- **Bundled model attribution lives beside the model files.** [`public/models/README.md`](public/models/README.md) records each shipped model's creator, source, license, and modification status.
---
@@ -564,11 +564,8 @@ Global Forecast System (GFS). The `/api/wind` server-side proxy selects the
latest available 0.25° cycle, reads its `.idx` inventory, byte-range fetches only
the `UGRD`/`VGRD` 10 m GRIB2 messages, optionally adding `TMP` at 2 m or
`PRMSL` at mean sea level from the same run and forecast time. It decodes the
selected messages with ecCodes (WASM) and resamples them to a compact grid (1° by
default) on a worker thread, so a refresh does not stall other API routes, and
serves a manifest plus Float32 U/V and optional scalar values. The sampled wind
of the current forecast file is kept, so choosing a color field fetches only
that field. It is keyless, cached
selected messages with ecCodes (WASM), resamples to a compact grid (1° by
default), and serves a manifest plus Float32 U/V and optional scalar values. It is keyless, cached
per cycle for an hour, and is a **forecast, not an observation**: the particles
show model flow, not measured wind. The renderer bakes bounded curves through
the sampled field and animates their phase on the GPU, with a canvas fallback.
+4 -3
View File
@@ -56,6 +56,7 @@ In short: the MIT grant does not extend to any third-party data. See
DATA_SOURCES.md for the full per-source license + attribution summary, and
remove any dataset whose terms don't fit your use.
The 3D models under public/models/ are the project's procedural fleet
models, generated from code by the project maintainers, and are covered by
the MIT license above like the source code. See public/models/README.md.
The 3D models under public/models/ are also third-party works and are NOT
licensed under MIT. They remain under their individual licenses. See
public/models/README.md for the author, source, license, modification notice,
and attribution covering each model file.
+1 -1
View File
@@ -60,7 +60,7 @@ Start with the included data sources, then add your own. Each layer is a separat
- **📡 Contacts:** A 250 km roster of everything near your target — step through live aircraft and drop into any cockpit.
- **🎯 Click-to-track anything:** Camera locks on, draws a fading trail, surfaces full metadata — and a tracked fire or vessel hands you off to the nearest live camera in one click.
- **🖊️ Voice whiteboard:** Speak annotations onto the world — real boundary polygons, marks, and routes.
- **🛫 3D fleet:** 121 procedural models drawn life size by type — airliners, business jets, helicopters, drones, ships, buses, trams and trains — and every contact swaps from glyph to 3D model as you close in.
- **🛫 3D hangar:** Real per-class aircraft models — 787, ATR-72, Citation, Bell 206, MQ-9 — and a tracked contact swaps from glyph to 3D model as you close in.
- **🎨 Reskin reality:** GLSL sensor looks over the normal globe — CRT, NVG, FLIR/thermal, Noir.
- **🟩 Detection overlay:** Screen-space bounding boxes and IDs on everything in view.
- **🎖️ Military HUD:** Tactical heads-up display with intelligence-style telemetry.
+7
View File
@@ -0,0 +1,7 @@
- Give counts real plural forms in every language: the wildlife count, the
Data Library list, the News time window, the GhostMaps event age and the
bridge radar range now read "1 Tag" and "7 Tage", «0,75 МОР. МИЛИ» and
«12 МОР. МИЛЬ». Street level words "the view centre" in each language's
grammar, and Latest, FOCUS, CONFIRMED and the course readout each have
their own translation where one word served two places (German, @gekh,
#1700).
-8
View File
@@ -1,8 +0,0 @@
- Draw every 3D model from the project's procedural fleet set: 121 models
(about 2 MB, MIT like the code) chosen per vehicle by type and drawn life
size, replacing the eight third-party aircraft models. Flights, Military
Flights and Local ADS-B pick a model by ICAO type, class and emitter
category; Vessels, Transit and Rail now draw models too, under the same 3D
toggle and distances, a ship at its AIS length and beam and a tram, bus or
train in its mode or category colour. The whole set loads once when a layer
starts (samehkhamis, #1714).
-4
View File
@@ -1,4 +0,0 @@
- The Wind server no longer blocks every other request while it decodes a
forecast. Decoding runs on a worker thread (up to 400 ms of blocking down to
about 4 ms), and choosing an overlay after wind has loaded fetches only the
overlay's field (mazy1998, #1717).
+16 -21
View File
@@ -1706,7 +1706,7 @@ Applications supply the existing floor/snap, geoid, picking, sprite, camera,
trail, focus, readout, context, aircraft presentation and render services.
The factory never constructs a second application registry. Configure a source
before initialization; replacing it while initialized is rejected. Model loads
use the supplied asset resolver, including the up-front fleet set load. Enrichment receives
use the supplied asset resolver, including the preload path. Enrichment receives
an abort signal and cannot update a later lifecycle after destruction. Existing
camera, terrain floor, trail, selection and measured model-size policies remain.
@@ -2420,9 +2420,8 @@ is validated against Cesium 1.138.0 and must be revalidated on upgrades.
`scripts/qa-anime-sky.mjs` checks asset readiness, visible Normal sky and
Anime band coverage against a Vite dev server.
`scripts/qa-sky-model-lighting.mjs` compares a lit fleet airliner
(`public/models/fleet/aircraft/a320.glb`) against black and white environment
maps in isolated scenes.
`scripts/qa-sky-model-lighting.mjs` compares a lit `airplane.glb` against
black and white environment maps in isolated scenes.
## Model atmosphere on Apple Metal
@@ -3607,22 +3606,20 @@ This is the current runtime/source-of-truth snapshot for the project.
> 24.09 m aft (70 % of the model's rendered envelope, so inside it), 2.22 m
> below centre (6 %), and 2e-9 m off the centreline.
> - **The tracked trail attaches to REAL HULL, aft and below (2026-08-23):**
> `FLEET_TRAIL_ANCHORS` (`src/data/fleetTrailAnchors.js`, generated by
> `scripts/measure-fleet-trail-anchors.mjs`) holds, per fleet aircraft and
> helicopter model and in RAW glTF coordinates (see the transform-chain entry
> below), the point of the hull's CENTRELINE PROFILE (its centreline slice)
> closest to the aft-belly AABB corner. It is NOT the corner: a bounding-box
> corner is empty space (4.80 m off the nearest triangle on the airliner
> asset this was first measured on, 6.14 m on the jet), so the trail ended in
> mid air beside the aircraft. The head segment
> `MODEL_TRAIL_ANCHOR_NATIVE` (`src/data/modelVisualAnchor.js`) holds, per GLB
> and in RAW glTF coordinates (see the transform-chain entry below), the point
> of the hull's CENTRELINE PROFILE (its y = 0 slice) closest to the aft-belly
> AABB corner. It is NOT the corner: a bounding-box corner is empty
> space, 4.80 m off the nearest triangle on `airplane.glb` and 6.14 m on
> `jet.glb`, so the trail ended in mid air beside the aircraft. The head segment
> is drawn from a point behind the aircraft to this anchor, so the anchor must
> stay aft (83–96 % of each aft extreme) or the segment enters at the tail and
> stops inside the fuselage. `fleetModels.test.mjs` reads the POSITION BUFFERS —
> stops inside the fuselage. `modelScale.test.mjs` reads the POSITION BUFFERS —
> real vertices and triangles, because accessor min/max cannot tell a corner
> from a surface — and re-derives on-hull, aft, lowest-at-its-station,
> on-centreline, and the construction itself. Re-measure, never re-guess.
> - **The trail anchor rides CESIUM'S transform chain, not a hand-rolled one
> (2026-08-23 regression fix):** `FLEET_TRAIL_ANCHORS` stores RAW
> (2026-08-23 regression fix):** `MODEL_TRAIL_ANCHOR_NATIVE` stores RAW
> glTF coordinates and `modelAnchorWorld()` assembles
> `modelMatrix × components.transform × axisCorrection` — the same chain
> `ModelSceneGraph` renders with, built from Cesium's own exported
@@ -3657,7 +3654,7 @@ This is the current runtime/source-of-truth snapshot for the project.
> ENVELOPE, and between them the drawn start slides along the segment so the
> visible length grows CONTINUOUSLY from zero. Three earlier cuts are recorded
> because their shape matters: testing segment LENGTH against the radius HID
> real trail (58 m aft of an airliner's 34.41 m envelope gives a 33.98 m
> real trail (58 m aft of `airplane.glb`'s 34.41 m envelope gives a 33.98 m
> segment, suppressed, though ~23.6 m of it is open air); CLIPPING at the
> envelope and keeping only what lay outside stopped a moving trail visibly
> SHORT of the aircraft, since a bounding sphere encloses a lot of empty space
@@ -4833,9 +4830,8 @@ activeCameraCardEnabled: true })` may publish it through the retained
> - **Flights 3D/cockpit hardening:** the destination-direction cue is an
> inline SVG rather than a remotely loaded Material Icons ligature, so a
> blocked or late font can no longer expand the literal word `navigation`
> across the cockpit. A grounded aircraft stands its fleet model's scaled
> clearance (the catalog's `clearance`, measured below the model's origin)
> above the ground.
> across the cockpit. The grounded `airplane.glb` belly offset is calibrated
> to the current asset's measured Y-up bounds (`0.063` native units).
> Contact Previous/Next and Live Signals aircraft handoffs now
> re-seed the first-person camera anchor at the selected flight immediately;
> bounded feed-correction smoothing remains scoped to the same aircraft.
@@ -7294,9 +7290,8 @@ pins and share links already supply complete boxes.
normal four-samples-per-250-ms budget. Retry timestamps more than the maximum
30-second backoff ahead of the current clock are ignored. A smaller rollback
can retain a bounded retry delay of up to 30 seconds.
- Commercial and military aircraft use the same high-level FLEET model regime: 2D billboards when zoomed out, optional glTF models when closer, controlled by the DISPLAY rail `3D` toggle and `Proximity` / `All` modes. Every model is one of the project's procedural fleet models (`public/models/fleet/`, MIT, 121 GLBs, about 2 MB in all; `public/models/README.md`), chosen per aircraft by `aircraftModelSpec` (`src/data/fleetModels.js`): its ICAO type's entry in `types.json`, else the model of its `classifyAircraft` class for a type the map lacks, else its ADS-B emitter category's, else the default airliner. It is drawn LIFE SIZE: the type's published length over the model's built length (`src/layers/flights/modelSpec.js`, shared by Flights, Military Flights and Local ADS-B), and a grounded aircraft stands the model's scaled clearance above the ground. `classifyAircraft` still picks the 2D icons. The whole set loads once, up front, when a layer that draws it starts (`loadFleetModelSet`, which logs `[Fleet] N/121 models (X MB) loaded in N ms`); models are built from those bytes, never fetched mid-session, and an aircraft stays its billboard until the set has loaded. Textured civilians carry a HEAVY tint, not a light one: `MODEL_COLOR_BLEND_AMOUNT` is `0.94` in BOTH layers under Cesium's `ColorBlendMode.MIX`, so the class colour supplies 94% of the surface and the model's own vertex colour ~6%; military models are flat amber, or emergency red. IR boost raises the blend to a full `1.0`. Under NVG/FLIR (map preset or Cockpit vision) models render unlit flat-white at full alpha and scene fog is disabled (fog otherwise blacks out distant models with the globe hidden); state restores on exit.
- Vessels, Transit and Rail draw fleet models under the same DISPLAY rail `3D` toggle, at the same altitude ceiling, caps and add/keep radii as the aircraft (`FLEET_MODEL_POLICY`, `src/layers/flights/policy.js`; `createFleetModelLayer`, `src/data/fleetModelInstances.js`). A vessel's model follows its AIS ship type and is drawn at its reported length and beam (AIS static dimensions A+B and C+D, now carried on vessel rows as `length` and `beam`), standing at the sea surface, heading by true heading then course. A transit vehicle's model follows its layer mode (bus, tram, subway, rail or ferry; a vehicle of `unknown` mode keeps its icon), a train's its rail category and mode (rail, metro or tram). Neither the transit nor the rail sources carry a GTFS `route_type` or a finer mode (monorail, gondola, funicular, cable car), so the set's models for those and their `transit.elevation` lifts are not reached by any live source today. Both stand on the road or rail top they are drawn on, without the 1.5 m `GROUND_FLOOR_LIFT_M` their icons carry, and are painted in their mode or category colour where the model's `_TINT` attribute marks it. A vessel model is clipped at its waterline (one clipping plane per model, at the model origin's horizontal plane), so its hull below the water never shows through a plain globe, which Cesium does not depth-test models against. Under the NVG/FLIR styles (the Flights `irBoost` parameter) these models render unlit flat white, as aircraft models do. Each vehicle's icon stays the visual until its model is loaded, ready and placed; a model is picked as its icon is, and a vehicle drawn as its model keeps its selection card and its place in the detection overlay.
- **Aircraft models skip Cesium's dynamic environment map (2026-10-24).** Flights, Military Flights and Local ADS-B pass `environmentMapOptions: AIRCRAFT_ENVIRONMENT_MAP_OPTIONS` (`{ enabled: false }`, `src/data/aircraftModelLighting.js`) to every drawn model. Otherwise each `Model` renders the sky around it and reads it back from the GPU (`readPixels`) when it is first placed, and again whenever it moves more than 1 km, the scene's atmosphere settings change, or (under sunlight dynamic lighting) an hour of scene time passes (`DynamicEnvironmentMapManager`, Cesium 1.138). With the class colour supplying 94% of the surface, the models are lit from Cesium's default spherical harmonics instead, with no specular environment map, so the sky's model-lighting cube map no longer reaches aircraft. `src/data/aircraftModelLighting.test.mjs` pins the option at every drawn model call; every model is built from the fleet set loaded up front, so there is no separate preload.
- Commercial and military aircraft use the same high-level FLEET model regime: 2D billboards when zoomed out, optional glTF models when closer, controlled by the DISPLAY rail `3D` toggle and `Proximity` / `All` modes. Since 2026-08-16 (Hangar fleet) models are PER-CLASS: real CC-BY GLBs for light/bizjet/turboprop/widebody/helicopter/uav (`CLASS_MODEL_REAL` in `src/data/aircraftClass.js` — meters-baked, scale 1, per-model belly/radius; provenance in `public/models/README.md`), the shared `airplane.glb` for the remaining civilian classes, and the military layer maps weight classes (real GLBs / 747 heavies / `jet.glb` fastjets, per-model heading offsets, flat amber or emergency red). Textured civilians carry a HEAVY tint, not a light one: `MODEL_COLOR_BLEND_AMOUNT` is `0.94` in BOTH layers under Cesium's `ColorBlendMode.MIX`, so the class colour supplies 94% of the surface and the asset's own texture ~6%. The visual direction is clean light silhouettes with only a weak diffuse contribution from the approved textures, so liveries deliberately do NOT read. IR boost raises the blend to a full `1.0`. Under NVG/FLIR (map preset or Cockpit vision) models render unlit flat-white at full alpha and scene fog is disabled (fog otherwise blacks out distant models with the globe hidden); state restores on exit.
- **Aircraft models skip Cesium's dynamic environment map (2026-10-24).** Flights, Military Flights and Local ADS-B pass `environmentMapOptions: AIRCRAFT_ENVIRONMENT_MAP_OPTIONS` (`{ enabled: false }`, `src/data/aircraftModelLighting.js`) to every drawn model. Otherwise each `Model` renders the sky around it and reads it back from the GPU (`readPixels`) when it is first placed, and again whenever it moves more than 1 km, the scene's atmosphere settings change, or (under sunlight dynamic lighting) an hour of scene time passes (`DynamicEnvironmentMapManager`, Cesium 1.138). With the class colour supplying 94% of the surface, the models are lit from Cesium's default spherical harmonics instead, with no specular environment map, so the sky's model-lighting cube map no longer reaches aircraft. `src/data/aircraftModelLighting.test.mjs` pins the option at every drawn model call; the two preload calls only warm the glTF cache and are never drawn.
- The DISPLAY-rail `3D` toggle is the user-facing activation path for both aircraft layers. Their small approved GLBs build their render resources without Cesium's frame-spread job queue, preventing continuous Photorealistic 3D Tiles streaming from starving model readiness; model caps, tracking, camera, and fallback billboards are unchanged.
- **The `3D` toggle DEFAULTS ON in `proximity` on a first run.** Proximity is itself the budget — models appear only below `MODEL_ALT_CEIL_M` and only for the nearest `MODEL_MAX` in view — so the default costs nothing at globe scale, and `all` remains a deliberate opt-in. A fresh boot runs NO layer-state restoration (`LayerStateCoordinator.start()` returns early with neither a share payload nor stored state), so four independent initializers decide what a first-run operator sees and must agree: `booleanOption('models3d', 'e', true)` in `src/data/layerState.js`, `_models3dEnabled = true` in BOTH flight layers, `this._models3dEnabled = true` in `src/ui/aircraftDisplay.js`, and the `active` / `visible` classes on `#models3d-toggle` / `#models3d-mode-row` in `index.html`. All four are pinned together in `src/data/layerState.test.mjs`. Explicit state still wins: because the codec omits default-valued options, `models3d: false` is now what travels in a link (`lo=…f.e.0`) and restores OFF at both aircraft layers. **Consequence for returning users:** a stored `gev:layer-state:v2` blob is a FULL options snapshot, so a session that wrote one before this change carries `models3d:false` and keeps 3D off until the operator flips it (or clears the key) — the durable snapshot is treated as the recipient's own state, by design.
- **Consequence of the flip on the recorded tracked/fleet inversion:** the 150–800 km band where surrounding contacts draw as models while the SELECTED one is still a glyph is now what an operator sees WITHOUT arming anything. The inversion itself is unchanged and still deliberate (see `src/data/trackedModelRegime.js`); only its reachability changed.
+2 -1
View File
@@ -87,7 +87,8 @@ menu.onChoose = (code) => switchLocale(code); // switched in place and stored (i
- **Pass literals.** `t('Close')`, not `t(label)` (unless `label` holds a `msg()` value) and never a template literal with `${…}`.
- **Use placeholders, not concatenation.** `t('Flying to {place}…', { place })`, not `t('Flying to') + ' ' + place`. Word order differs between languages.
- **Use `tn()` for counts**, not `count === 1 ? … : …`. Russian has three forms.
- **A placeholder takes a name, not a phrase.** When code has no name to pass and would fall back to a phrase ("the view centre", "this spot"), give that case a message of its own: `t('{source} at the view centre', { source })`. Other languages put a phrase in a different case after a preposition, which a name in its nominative form cannot follow.
- **Use `tn()` for counts**, not `count === 1 ? … : …`. Russian has three forms. That includes a number the English writes with a symbol or abbreviation, so both English forms read the same (`tn(hours, 'Last {hours} h', 'Last {hours} h', { hours })`): other languages inflect the words around it («Última 1 h», «Últimas 24 h»). Fractions have a form of their own too (ru «0,75 МОР. МИЛИ»).
- **Translate the label, not the value.** Layer ids, enums, share-link parameters, API fields, voice tool schemas and feed data (callsigns, vessel and place names) stay as they are; translate only the text shown for them.
- **No `t()` at module top level.** Keep the English in `msg()` and call `t()` when rendering.
- **Numbers and dates** go through `formatNumber`, `formatDate`, `formatRelativeTime` and `formatUtcDayMonth` from `src/i18n/index.js`, which follow the active language.
+1 -1
View File
@@ -8,7 +8,7 @@ Catalog: `src/i18n/locales/ru.json`. General rules: [TRANSLATORS.md](../TRANSLAT
- Sentence case, not Title Case: "Live Flights" → «Рейсы в реальном времени».
- Quotes inside Russian text are «ёлочки». Write ё where it belongs: её, ещё, всё.
- In short labels, a standard abbreviation with a period beats a wrapped line: НЕОПРЕД., СЛЕД.
- Units: км, м, км/ч, м/с, уз (knots), фт (feet), ч, мин, с; in UPPERCASE text КМ, М, КМ/С, УЗ, ФТ. MW is МВт in any case. `°` and `%` stay.
- Units: км, м, км/ч, м/с, уз (knots), фт (feet), ч, мин, с; in UPPERCASE text КМ, М, КМ/С, УЗ, ФТ. MW is МВт in any case. `°` and `%` stay. Nautical miles on the bridge radar are «мор. миля», a noun that follows the count: «3 МОР. МИЛИ», «12 МОР. МИЛЬ», «0,75 МОР. МИЛИ».
## Plurals
+1 -1
View File
@@ -12,7 +12,7 @@ Translation source: meirm (#312).
- The apostrophe is always ʼ (U+02BC): обʼєкт, звʼязок, памʼять. Not ' or ’.
- Quotes inside Ukrainian text are «ялинки»; a button or layer name inside a sentence goes in them: Увімкніть «Вуличні знімки».
- In short labels, a standard abbreviation with a period beats a wrapped line: ПОПЕР., ДАЛЬН., КАЛІБР.
- Units: км, м, км/год, м/с, вуз (knots), фт (feet), год, хв, с, МГц, дБ, гПа; in UPPERCASE text КМ, М, КМ/С, ВУЗ, ФТ. MW is МВт in any case. `°` and `%` stay. Decimal comma in coordinates written as text: 28,2710° пн. ш.
- Units: км, м, км/год, м/с, вуз (knots), фт (feet), год, хв, с, МГц, дБ, гПа; in UPPERCASE text КМ, М, КМ/С, ВУЗ, ФТ. Nautical miles on the bridge radar are «мор. миля», a noun that follows the count: «3 МОР. МИЛІ», «12 МОР. МИЛЬ», «0,75 МОР. МИЛІ». MW is МВт in any case. `°` and `%` stay. Decimal comma in coordinates written as text: 28,2710° пн. ш.
- Coordinates: пн. ш. / пд. ш. / сх. д. / зх. д.; the HUD hemisphere letters are Пн, Пд, Сх, Зх.
## Plurals
+17 -30
View File
@@ -1,33 +1,20 @@
# Bundled 3D Models
# Bundled 3D Model Attribution
Every 3D model shipped in this directory is one of the project's procedural
fleet models under [`fleet/`](fleet/): aircraft, helicopters, ships, buoys,
transit and rail vehicles, and a few other airborne and ground objects. They
are generated from code by the project maintainers, contain no third-party
artwork, and are covered by the repository's [MIT license](../../LICENSE)
like the source code.
The model files in this directory are third-party visual assets. They are not
covered by the repository's MIT source-code license; each remains available
under the license listed below.
| Path | What it holds |
|---|---|
| `fleet/catalog.json` | Every model by name: its file, category, built length, beam and bounds (metres, in Cesium's Z-up model frame: x along the length with the nose toward −X, y across the beam, z up), the clearance below its origin, and its 2D icon class. |
| `fleet/types.json` | Which model draws which vehicle, and at what length: ICAO aircraft and helicopter type codes, ADS-B emitter categories, AIS ship-type and length ranges, GTFS route types, transit modes and rail categories, with the defaults. |
| `fleet/aircraft/`, `fleet/helicopters/`, `fleet/ships/`, `fleet/buoys/`, `fleet/transit/`, `fleet/other/` | The models, one GLB each (EXT_meshopt_compression and KHR_mesh_quantization, vertex colours, no textures). |
| File | Original work and creator | Source | License | Project modifications |
|---|---|---|---|---|
| `airplane.glb` | “boeing 747” by [zairiq-123](https://sketchfab.com/zairiq-123) | [Sketchfab model](https://sketchfab.com/3d-models/boeing-747-9b16672038ba48f98e6d80a159044ed9) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Substantially modified and optimized for God's Eye View, including geometry/material simplification and coordinate/orientation preparation. The former 24× runtime calibration is baked into the mesh; location, rotation, and scale are applied; the bounding-box centre is at the origin; and the model uses glTF +Y-up with its nose toward local −X. Geometry remains uncompressed so the aircraft asset does not compete with photogrammetry for Draco worker capacity. |
| `jet.glb` | “Private Jet” by [Nick the Name](https://sketchfab.com/Nick_The_Name) | [Sketchfab model](https://sketchfab.com/3d-models/private-jet-cbdd1de6ced9461e950eafaa302cc82b) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Repackaged as a glTF binary for the project's military-flight visualization. Imported hierarchy transforms are baked into the meshes; location, rotation, and scale are applied; the bounding-box centre is at the origin; and the model uses meter scale, glTF +Y-up, and the shared nose −X convention. Existing materials are preserved. |
| `bell206.glb` | “Bell 206 JetRanger” by [terran4627](https://sketchfab.com/terran4627) | [Sketchfab model](https://sketchfab.com/3d-models/bell-206-jetranger-d2f7ba1d671549d4b26aaf834139a1dd) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures resized to 256 px WebP, orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
| `c172.glb` | “Cessna 172” by [e737](https://sketchfab.com/e0057537) | [Sketchfab model](https://sketchfab.com/3d-models/cessna-172-64cddaee5aff470682659a8c08525046) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures resized to 256 px WebP, orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
| `citation2.glb` | “1990 Cessna Citation, Texture Detailed, Exterior” by [BlenderCommunityHead](https://sketchfab.com/aboodgoudagad) | [Sketchfab model](https://sketchfab.com/3d-models/1990-cessna-citation-texture-detailed-exterior-a78839624fe64900a8352cb23462350a) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures resized to 256 px WebP, orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
| `mq9.glb` | “MQ-9” by [IProZenoN](https://sketchfab.com/IProZenoN) | [Sketchfab model](https://sketchfab.com/3d-models/mq-9-fabe963feb354c5584b51f9c470c3f7e) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures resized to 256 px WebP, orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
| `b789.glb` | “Boeing 787-9” by [Nobilis 2](https://sketchfab.com/nobilishornet2) | [Sketchfab model](https://sketchfab.com/3d-models/boeing-787-9-b6711e2e698e4e469675c1154a50b7a3) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures resized to 256 px WebP, orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
| `atr72.glb` | “ATR 72 - 600” by [Oyan3D](https://sketchfab.com/oyan3D) | [Sketchfab model](https://sketchfab.com/3d-models/atr-72-600-1e1a7186f7444d288675262fcee44744) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures removed with dominant material colors baked into PBR factors (flat “abstracted” style), orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
How the layers use them:
- Each layer draws a vehicle with the model its type selects, scaled to the
type's published length (a vessel to its reported AIS length and beam), so
every model is drawn life size. Ground objects, balloons and obstacles in
the `other` category are drawn at the size they are built.
- An aircraft model's origin is its axis; it stands that model's scaled
clearance above the ground. A ship's origin is its waterline, and a transit
or rail vehicle's the road or rail top (a monorail or gondola is raised by
its `transit.elevation` entry, for a source that names those modes).
- Transit and rail models carry a `_TINT` vertex attribute that marks where
the route or category colour is painted.
- The whole set loads once, up front, when a layer that draws it starts; no
model is fetched while a session runs.
`src/data/fleetModels.js` reads the set and chooses each vehicle's model;
`src/data/fleetModels.test.mjs` checks that every model `types.json` names is
in the catalog and on disk, and that no GLB exceeds 3 MB.
CC BY 4.0 permits sharing and adaptation, including commercial use, provided
appropriate credit is retained, the license is linked, and modifications are
identified. These credits do not imply endorsement by the original creators.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large. Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loaded 100 of 245 files, more files were not shown because too many files have changed in this diff. Show more