You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The GeoMap 3D terrain surface can currently show holes and cliffs that appear and later fill in: flat-zero patches rendered beside real-height neighbors (cliff at the shared edge), pending patches suppressed or covered by retiring predecessors (holes when that hiding has a gap), and failed fetches degrading to flat ground next to lifted terrain. This is wrong as a product experience — partial data should never look broken.
The root cause is architectural: heights are per-patch independent facts. Each patch renders whatever it personally received (or flat zero), and continuity between neighbors is nobody's responsibility. The covered/retiring/degraded machinery exists to hide the discontinuities that model inevitably produces, and every gap in the hiding is visible as a cliff or hole.
Design principle
The map is always a continuous drape, regardless of what data is or isn't available.
The surface starts fully draped at zero height.
As terrain data becomes available, the carpet lifts up in that region.
Where data is missing (not yet fetched, fetch failed, coarser LOD), the surface renders the best available estimate, and edges always match the surrounding heights — never a cliff, never a hole.
Architecture: one heightfield, patches are views
Invert the data model: there is one continuous heightfield; patch meshes are views into it, never owners of private height data.
HeightField (new)
Owns the current best estimate of terrain height everywhere: real data where delivered, ancestor-interpolated estimates where only coarser data exists, zero where nothing is known.
Continuous by construction — there is no "missing" region, only coarser-estimate regions.
Patches sample the field at their vertex world positions. Two patches sharing an edge sample identical positions → identical heights → edges match structurally, not via suppression logic.
Cross-LOD edges use the standard stitching rule: fine-edge vertices adjacent to a coarser neighbor are constrained to the coarse edge's interpolation (eliminates T-junction cracks).
Data arrival
A delivery updates a region of the field → affected patches (plus edge-adjacent neighbors) re-sample and re-mesh.
The field eases toward new data (~300 ms) so the carpet visibly lifts; because the animation lives in the field, adjacent patches lift coherently — no transient edge mismatch.
Failure handling
"Degraded" ceases to exist as a state: a failed fetch simply means the region keeps its current estimate (ancestor data or zero). A later retry improves it. No flat-zero cliff is possible.
What this eliminates
The covered/z-fight suppression for pending patches (they render the field estimate, which matches any cover)
Most retiring-cover height semantics (imagery fallback remains a separate, existing mechanism)
The degraded-patch special case and its retry-ladder visual consequences
The entire bug class "hole/cliff that fills in later"
Replaced by one invariant, testable in one line: adjacent rendered edge vertices are always equal.
The blend band in TerrainHeightSource (kMinTerrainZoom..kFullTerrainZoom height scaling) was a stopgap for the same continuity problem and can likely be retired once estimates are continuous.
Design doc: field data structure (pyramid-tile sampling + interpolation rules), cross-LOD edge stitching rule, dirty-region → re-mesh flow, easing model, migration path from the current per-patch delivery.
Field + re-sampling: introduce HeightField over the existing height sources; patches sample it; delete covered/degraded height logic. Invariant test: edge-vertex equality across all resident patch pairs, under churn and failure injection.
Easing: temporal blend on field updates ("carpet lift").
Problem
The GeoMap 3D terrain surface can currently show holes and cliffs that appear and later fill in: flat-zero patches rendered beside real-height neighbors (cliff at the shared edge), pending patches suppressed or covered by retiring predecessors (holes when that hiding has a gap), and failed fetches degrading to flat ground next to lifted terrain. This is wrong as a product experience — partial data should never look broken.
The root cause is architectural: heights are per-patch independent facts. Each patch renders whatever it personally received (or flat zero), and continuity between neighbors is nobody's responsibility. The covered/retiring/degraded machinery exists to hide the discontinuities that model inevitably produces, and every gap in the hiding is visible as a cliff or hole.
Design principle
The map is always a continuous drape, regardless of what data is or isn't available.
Architecture: one heightfield, patches are views
Invert the data model: there is one continuous heightfield; patch meshes are views into it, never owners of private height data.
HeightField (new)
Patch meshing
Data arrival
Failure handling
What this eliminates
Replaced by one invariant, testable in one line: adjacent rendered edge vertices are always equal.
Relationship to existing work
Suggested phases
Acceptance criteria