Main's camera, voice, Cockpit and layer work now runs on the globe
contract where this branch draws through it:
- The voice tilt to an angle, its pivot about the place under the
crosshair and the frame limit from orbit run through the camera rig;
src/globeInView.js measures a camera pose with src/geo instead of a
Cesium camera. The free-look height limit and the globe-in-view
recovery stay Cesium-only for now.
- Cockpit takes main's own-layer entry rule. Double-clicking the
followed track goes through cockpitHost.routeDoubleClick, so it works
on both engines.
- Space Missions' failed-entry rollback and GhostMaps' age filter run
in the engine-neutral layer code. On Cesium an expired report is
dropped in place; on Navara its product is redrawn.
- Wildlife Sightings joins the catalog Cesium-only: Navara leaves it
out, and the shell builds its card only for the real layer, so a
Navara page no longer fails to start on its stand-in.
- One instruction sentence is shorter, which keeps the Realtime prompt
within its 55,500-character budget with the Sentinel-2 basemap.
The held-pointer guard was one flag, so with two fingers down, lifting one cleared it and the recovery turned the view down under the other (pitch -42° to -90°). It now tracks each pressed pointer by id and defers until the last is released.
A release outside the window that the page never sees could leave the recovery deferred for good. A lost window focus, a hidden page or a lost pointer capture now releases every held pointer, and a pointer that moves with no button down is released.
Holding a drag still for half a second on a view that already showed no surface looked like a camera at rest, so the recovery turned the view down under the user's hand. The recovery now defers while a pointer pressed on the canvas is held, and runs once it is released, as for a flight or a playing scene.
A Director hold longer than the settle check's five-minute bound used
to expire the deferred check, so a run that ended on a stars-only shot
after a long hold stayed there until the next move. While a flight or a
playing scene defers the check, its bound no longer counts down; the
flight or scene bounds the deferral itself.
Also correct the trackball note in CURRENT-STATE: Cesium's tilt tests
the screen centre, so any tilt (drag or touch) with the centre on the
stars between 1,000 and 7,500 km now tilts about the planet's edge or
does nothing, wherever it starts. Rotation drags that start on the
planet are unchanged.
A check skipped because a flight or a playing Director scene was in
progress used to be dropped, so a run that ended or held on a stars-only
shot stayed there until the next camera move. Keep watching instead:
the settle check retries once the flight or scene ends, within its
existing five-minute bound, and a moveEnd that arrives while it is
deferred keeps the check armed rather than stopping it.
Also test that the free-look limit never raises Cesium's trackball
height and that dispose keeps a value set after install, note in its
JSDoc the enableLook case it cannot tell apart, and document the
trackball change and the retry in CURRENT-STATE and the changelog.
Below Cesium's trackball height (7,500 km by default) a drag that starts
on the stars turns the camera in place, whatever enableLook says, which
was the drag path to a view with no planet in it. Lower that height to
the free-look height with the free-look limit, never raising it, and
restore it on dispose. Above 1,000 km such a drag now orbits the globe,
as it already did above 7,500 km, at a similar rate, and a tilt drag
from the stars there tilts about the planet's edge or does nothing
instead of turning the camera. Drags that start on the planet are
unchanged.
Review follow-ups for the globe-in-view recovery and voice limits.
- Leave a camera flight in progress and a playing Director scene, holds
included, to their own framing. The recovery is now installed with the
scene tools, which own the Director, and reads its running state.
- Reuse a voice turn's half-degree proof only from the position and
direction it was proven at, so a release that moves the camera checks
the turn again.
- Share one free-globe-camera check between the recovery, the voice
turn limit and the globe rotation.
- Keep an enableLook setting other code makes after the free-look limit
is installed, instead of writing back the install-time value.
- Name the nudging test for what it asserts, the 1% floor, and document
that a view losing its surface without a camera move waits for the
next one.
From the whole-globe view the camera could end up facing empty space with
only stars on screen. Cesium's free look (Shift+drag) turns the camera in
place, and from 18,000 km the planet's edge is only about 15 degrees from
nadir, so a few drags turned it out of frame. The rolled pose was then
saved into the share hash, so a reload or shared link opened on stars too.
- Allow free look only below 1,000 km. Orbit, tilt and zoom are unchanged.
- Measure how much of the frame shows the planet's surface by casting a
32x18 grid of view rays at the WGS84 ellipsoid. While the scope mask is
on (the default) only the rays inside its keyhole count, since the mask
hides or dims the rest of the frame.
- When a camera move ends above 1,000 km with no ray on the surface, turn
straight down at the same position and heading. Limb glow and a sliver
up to about one grid cell thick can count as out of view. The end of a
move comes from Cesium's moveEnd and from a check of its own that
samples the pose every 250 ms after moveStart and acts once it has held
for half a second: at some of these poses the camera drifts by a
rounding error every frame, so Cesium never sees it stop and never
raises moveEnd. The zoom-out guard from #1522 keeps wheel and pinch
zoom-outs in view; this catches the other ways a move can end looking
away, such as a saved or shared view that did, or a
drag that Cesium turns into an in-place look below its 7,500 km
trackball height (one that starts on the stars, or a tilt drag with the
screen centre off the planet). Views with more surface, tracked or
locked cameras and the 2D and Columbus modes are left alone.
- Voice tilt and in-place turns of a free 3D globe camera above 1,000 km
stop when about a tenth of the frame still shows the planet (or about as
much as it showed when it started, two grid cells of sampling noise
allowed), never below about 1% of the visible frame; a view that already
shows less only keeps or gains what it has. A turn that cannot go half a
degree further without crossing that limit is refused with a reason
instead of reported as done, and a turn it accepts turns at least that
half degree. A turn that keeps or gains surface is not refused, even
after the window has been resized, except that near the limit, where the
planet's edge crosses the sample grid, sampling wobble can occasionally
refuse one (most often above about 15,000 km and on phone or ultrawide
frames); nothing then turns away from the planet. A turn that starts
where the last voice turn left the camera keeps that turn's limit, or a
higher one if the planet now fills more, so repeating the request does
not take any more; once anything else has moved or turned the camera, a
turn is measured from what is on screen. A request made while the camera
is tracked is judged by the pose voice's release of the follow camera
will leave, before that release, so a refused turn keeps the tracking.
The frame measure and the look-step limit live in src/globeInView.js,
shared by the viewer and the voice camera verbs.
Preserve the camera, map source and layer selection across engine sessions. Restore the previous engine if startup fails and retain local history navigation.
The scene chrome, cockpit, Display controls, command dock, layer panels,
Context rail, welcome card and Provider Settings move verbatim into
src/ui/views and mount into their hosts before the page is translated and
wired. Each view renders the same elements, attributes and text as its
template; Vue keeps whitespace between elements as one space, and no view
markup sits under a white-space: pre rule.
Template asset URLs stay literal, view files are left out of Prettier so
the markup is not reflowed, and the Node component loader moves to build/
and is exported as build/register-vue for host test runners. Hosts that do
not initialize Core's locale pass localePicker: false instead of editing
the markup.
Scene reads skyBox._cubeMap as the environment map that lights models, in
the TEME, flipY layout of Cesium's own sky box; the ICRF Milky Way would
light them rotated. Rename the field so models keep Cesium's default.
Test the anime fade on a real StarrySky and that the viewer gets the sky
as an option (skyBox: false would drop the Sun and Moon). Correct three
comments on the star limit and the Milky Way levels.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The scene builds the page's Cesium engine right after the viewer
(src/app/globeEngine.js), names the startup Google tileset to it once
loaded, returns it beside the viewer and destroys it before the viewer.
The debug handle exposes it as window.__godsEyeView.engine. Nothing
consumes it yet; render holds taken before the governor is installed
apply at install.
qa-globe-contract now runs on the app's engine (self-built only when the
app has none); a throwaway engine checks creation and destroy leave the
scene untouched.