Hide street vehicles behind low walls and trees seen from above

In a dense downtown view from about 400 m up, the occlusion margin of
max(3 m, 2% of the range) came to 14 to 20 m, so a wall, awning, tree or
lower facade standing 10 to 20 m in front of a street was read as the
road itself: the vehicle's dot was hidden by the scene, but its bracket and
callout were still drawn. Checked against scene.pickPosition in one such
view, 18 of 470 vehicles in frame fell in that band.

The margin now depends on how steeply the camera looks down on the
contact. A point on the line of sight s metres in front of a vehicle
stands s * sin(elevation) above it, so a surface there hides the vehicle
once that rise passes 2 m. The margin stays at least 3 m and at most 2%
of the range, so grazing and street-level views are unchanged. In the
same views no vehicle with the drawn surface within 3 m in front of it
(its own road) is newly hidden.

From the review of the first change:

- A contact back in view after longer than a retest interval is held back
  and retested like a new one, instead of being drawn from an answer
  given before it left the view. It gets a fresh record, so a test still
  in flight from before cannot end the hold-back either.
- The hold-back for a contact's first answer stretches with the retest
  pace when a crowded view slows it.
- A batch whose control point failed no longer counts as a first answer.
- An unknown log-depth flag reads as "no depth" rather than as standard
  depth, which would have put every surface in front of every contact.
- A shader that fails to build leaves no shader behind and is not built
  again on the same context.
This commit is contained in:
Sameh Khamis committed 2026-11-10 15:08:26 -08:00
1 parent 630e1b1998
commit 076d264982
6 files changed
+388 -31

No files matched your search

+14 -5
View File
@@ -3609,8 +3609,13 @@ isCurrent })` gates BOTH halves of the map-stack switch, which is its only
> (2026-11-09):** a contact a layer marks `depthTested: true` (only Street
> Traffic does) is tested against the depth the scene drew, and is left out
> of the overlay while a building, 3D tile, terrain or any other drawn
> surface stands in front of it by more than max(3 m, 2% of its range). That
> includes vehicles the road data routes through tunnels. Every other layer
> surface stands in front of it by more than a margin: 3 m, or what a 2 m
> rise above the vehicle on its line of sight takes when the camera looks
> down on it, and above 3 m never more than 2% of its range (2% applies
> outright at grazing angles or when the camera looks up). A flat
> 2% let walls, awnings and trees 10 to 20 m in front of a street 1 km away
> pass as the road. That includes vehicles the road data routes through
> tunnels. Every other layer
> is untouched: aircraft, vessels and satellites draw their markers over the
> scene on purpose and keep their labels over it. The test runs on the GPU
> (`src/data/sceneOcclusionProbe.js`): one occlusion query per contact,
@@ -3619,9 +3624,13 @@ isCurrent })` gates BOTH halves of the map-stack switch, which is its only
> "hidden" answer arrives and returns 600 ms after its last one, which keeps
> a contact on a silhouette edge from blinking; a callout whose contact goes
> behind something is dropped at once rather than faded out on the facade.
> A contact new to the view is held back until its first answer (at most
> 400 ms), so orbiting a city does not flash a bracket for each vehicle that
> swings into frame behind a building. These times run on painted frames,
> A contact new to the view, or back in it after longer than a retest
> interval, is held back until its first answer (at most 400 ms, longer
> when a crowded view stretches the retest pace), so orbiting a city does
> not flash a bracket for each vehicle that swings into frame behind a
> building. A callout placed beside a visible vehicle can still overlap a
> facade; that is where the callout was placed, not the vehicle being
> behind it. These times run on painted frames,
> so a hidden tab or an idle scene does not expire them.
> Do not swap this for `scene.pickPosition` per contact or for a depth
> read-back: both wait on the GPU process (measured 0.2 to 1.4 ms per pick,