refactor(street-level): drop FOLLOW and Google 3D ground casting

FOLLOW is gone: no setFollow, follow state, map-stack availability or
handoff listener. Opening a photo still frames it with one flight through
the application's deferred navigation (begin/reassert), so a slow photo
never overrides newer navigation and tracking is released as before.

Ground casting is gone: groundCast.js, meshSampler.js, the surface mode,
the draped-to-cast swap and remesh. Coverage lines are always draped
GroundPolylinePrimitives (ClassificationType.BOTH); cones and the marker
clamp to the ground and keep the horizon cull. The terrain/meshFloor/ground
services and meshFloor.visibleTilesetLoaded are no longer needed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
German KhokhlovandClaude Opus 5.5 committed 2026-10-07 21:59:15 +04:00
1 parent 7dec7883aa
commit 0f41fb04cd
37 files changed
+430 -3323

No files matched your search

+4 -48
View File
@@ -1,15 +1,13 @@
import * as Cesium from 'cesium';
import { positionMarkerGlyph } from './glyphs.js';
import { COLORS, POSITION_PICK_ID } from './policy.js';
import { refineHeights } from './groundCast.js';
import { createHorizonCull } from './view.js';
const SPRITE_ID = 'street-level:marker';
/** On-globe marker for the open image; in terrain mode it stands on bare earth. */
export function createMarker({ state, parts }) {
/** On-globe marker for the open image, clamped to the ground. */
export function createMarker({ state }) {
const { render, sprites } = state.services;
let last = null;
function requestRender() {
render?.governorRequestRender?.('street-level-marker');
@@ -31,36 +29,10 @@ export function createMarker({ state, parts }) {
sprites?.registerSpriteCollection?.(SPRITE_ID, state.marker.collection);
}
/**
* Terrain-mode height (bare earth refined by mesh samples), or null to
* clamp. Requests a missing terrain cell or mesh sample as a side effect.
*/
function castHeight(position) {
const ground = parts?.groundCaster;
if (state.surface !== 'terrain' || !ground) return null;
const { lon, lat } = position;
const dem = ground.groundAt(lon, lat);
if (dem === null) {
ground.prepare([[lon, lat]]).then((ready) => {
if (ready && last?.position === position) set(position, last.bearing);
});
return null;
}
const mesh = parts.meshSampler?.meshAt(lon, lat);
if (mesh === undefined) parts.meshSampler?.request([[lon, lat]]);
return refineHeights([{ dem, mesh }])[0];
}
// A new mesh sample may move the marker onto (or off) the road surface.
parts?.meshSampler?.onSampled(() => {
if (last && state.surface === 'terrain') set(last.position, last.bearing);
});
/** Move (or create) the marker; a null position removes it. */
function set(position, bearing) {
const collection = state.marker.collection;
if (!collection) return;
last = position ? { position, bearing } : null;
if (!position) {
collection.removeAll();
state.marker.billboard = null;
@@ -68,16 +40,7 @@ export function createMarker({ state, parts }) {
requestRender();
return;
}
const height = castHeight(position);
const cartesian = Cesium.Cartesian3.fromDegrees(
position.lon,
position.lat,
height ?? 0,
);
const heightReference =
height === null
? Cesium.HeightReference.CLAMP_TO_GROUND
: Cesium.HeightReference.NONE;
const cartesian = Cesium.Cartesian3.fromDegrees(position.lon, position.lat);
if (!state.marker.billboard) {
state.marker.billboard = collection.add({
id: POSITION_PICK_ID,
@@ -87,12 +50,11 @@ export function createMarker({ state, parts }) {
width: 40,
height: 40,
alignedAxis: Cesium.Cartesian3.UNIT_Z,
heightReference,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
verticalOrigin: Cesium.VerticalOrigin.CENTER,
});
} else {
state.marker.billboard.heightReference = heightReference;
state.marker.billboard.position = cartesian;
}
state.marker.billboard.rotation = -Cesium.Math.toRadians(bearing || 0);
@@ -115,17 +77,11 @@ export function createMarker({ state, parts }) {
state.marker.billboard = null;
}
/** Re-place the marker after the surface mode changes. */
function setSurface() {
if (last) set(last.position, last.bearing);
}
return {
ensure,
set,
clear: () => set(null),
setVisible,
setSurface,
destroy,
};
}