Skip to content

Commit a283af1

Browse files
HarelMkubapelcPheonor
authored
Globe final PR (#3963)
* Globe - basic infrastructure, raster layer adaptation for globe (#3783) * Port changes from main globe branch - basics Fix minor issues so that it compiles. * Fix PI redefinitions * Fix stencil shader * Port adaptation of raster layer for globe from main globe branch * Add globe.html example from pheonor's repo Minor changes (remove terrain, set initial zoom 0, change title and description) * Better map projection parameter doc comment, warn when using unknown projection * Mercator projectionData handles negative zoom correctly * Comment clarification * Fix spelling of "granularity" * Add missing docs * Convert ProjectionBase to an interface * Do not leak GL object in globe projection error measurement, add a destroy method to projection * Fix chrome performance warning, refactor error measurement Warning fixed by changing ring buffer size to 1, making ring buffer pointless, so I removed it. * Fix granularity capitalization * Fix capitalization * Fix typo * Fix stencil mask triangle index order (this was causing failing render tests) * Cleanup vertex shader projection interface * Move projection creation function into its own file * Remove getProjectionName * Added comment for deduplicateWrapped * Remove unused vertex-buffer-related code from image source * Add globe raster layer render test * More render tests - test transition to mercator * Remove pointless test, add test descriptions * Render test for rendering poles on globe * SubdivisionGranularitySetting constructor takes an object * Remove "defines" parameter from useProgram * Refactor useProgram and Program constructor * Properly format translatePosMatrix comment * Refactor globe-specific code outside projection classes, remove stencil-specific granularity settings * Refactor granularity settings to be more readable * Minor refactor of ProjectionErrorMeasurement * Refactor draw_raster.ts * Move globe utility functions to utils.ts, use easeCubicInOut instead of smoothStep * Simplify imports in globe.ts * globe.ts refactor * Move ProjectionErrorMeasurement to a separate file * Refactor ProjectionErrorMeasurement Change parseRGBA8float to a private static function, use isWebGL2 function instead of instanceof * Refactor draw_raster.ts * Refactor globe projection error measurement to not use Painter * Painter.clearStencil creates custom ProjectionData instead of calling getProjectionData(null, null) * Remove "deduplicateWrapped" functionality from source_cache.ts * Globe projection no longer requires a map instance * Painter doesn't pass `this` to `updateGPUdependent` * isRenderingDirty is now a function * Rename ProjectionBase to Projection * Replace globeView property with setGlobeViewAllowed * Add mercator and globe projection unit tests * Remove tests that test for exact clipping planes * Update build test with new bundle size * isRenderingDirty is now a function * Globe - fill layer (#3882) * Port changes from main globe branch - basics Fix minor issues so that it compiles. * Fix PI redefinitions * Fix stencil shader * Port adaptation of raster layer for globe from main globe branch * Add globe.html example from pheonor's repo Minor changes (remove terrain, set initial zoom 0, change title and description) * Better map projection parameter doc comment, warn when using unknown projection * Mercator projectionData handles negative zoom correctly * Comment clarification * Fix spelling of "granularity" * Add missing docs * Convert ProjectionBase to an interface * Do not leak GL object in globe projection error measurement, add a destroy method to projection * Fix chrome performance warning, refactor error measurement Warning fixed by changing ring buffer size to 1, making ring buffer pointless, so I removed it. * Fix granularity capitalization * Fix capitalization * Fix typo * Fix stencil mask triangle index order (this was causing failing render tests) * Cleanup vertex shader projection interface * Move projection creation function into its own file * Remove getProjectionName * Added comment for deduplicateWrapped * Remove unused vertex-buffer-related code from image source * Add globe raster layer render test * More render tests - test transition to mercator * Remove pointless test, add test descriptions * Render test for rendering poles on globe * SubdivisionGranularitySetting constructor takes an object * Remove "defines" parameter from useProgram * Refactor useProgram and Program constructor * Properly format translatePosMatrix comment * Refactor globe-specific code outside projection classes, remove stencil-specific granularity settings * Refactor granularity settings to be more readable * Minor refactor of ProjectionErrorMeasurement * Refactor draw_raster.ts * Move globe utility functions to utils.ts, use easeCubicInOut instead of smoothStep * Simplify imports in globe.ts * globe.ts refactor * Move ProjectionErrorMeasurement to a separate file * Refactor ProjectionErrorMeasurement Change parseRGBA8float to a private static function, use isWebGL2 function instead of instanceof * Refactor draw_raster.ts * Refactor globe projection error measurement to not use Painter * Painter.clearStencil creates custom ProjectionData instead of calling getProjectionData(null, null) * Remove "deduplicateWrapped" functionality from source_cache.ts * Globe projection no longer requires a map instance * Painter doesn't pass `this` to `updateGPUdependent` * isRenderingDirty is now a function * Rename ProjectionBase to Projection * Replace globeView property with setGlobeViewAllowed * Add mercator and globe projection unit tests * Remove tests that test for exact clipping planes * Update build test with new bundle size * isRenderingDirty is now a function * Fill, fill-extrusion, line layers, subdivision: Import changes from kubapelc/globe-vector branch * Fix unit tests * Subdivision: ensure consistent triangle winding order, fix unit tests * Fix terrain * Fix fill extrusion not working with terrain * Fix typos * Fix line gradient bug * Subdivision: fix line ring handling * Subdivision: fix unit test expecting an invalid line segment * Fix fill-extrusion ring handling * Fill-extrusion refactor and fix failing test * Update terrain fill extrusion test expected image * Render tests for fill, line and fill-extrusion for globe * Move fillArrays function into a separate file * Add vector globe example * Remove changes for line and fill-extrusion layers to make the PR smaller * Add unit tests for fillArrays() * fillArrays unit test has better segment size limits * Update build test build size * Fix html example description * Fix missing docs for granularity settings * Rename globe fill render test tile source layer to "vector_tiles" * Fix classifyRings comment format * Move subdivisionGranularitySettingsNoSubdivision constant to a static readonly field, shorten the name * Use `import type` for SubdivisionGranularitySetting where possible * Fix typo * Revert fill_attributes back to default exports * Improve comment for scanline subdivision * Subdivision: break up scanline subdivision function into more functions * Move SubdivisionGranularitySetting into its own file * Unit tests: use mock of MercatorProjection instead of the full class * Add SegmentVector unit tests * Subdivision: unit tests for poles, ring triangulation, fix bug in ring triangulation * Subdivision: more pole unit tests * Subdivision: fix wireframe generation, add unit test for wireframe * Rename subdivisionGranularitySettings.ts to subdivision_granularity_settings.ts * Move granularity settings registration to subdivision * Update build size * Rename `fillArrays` to `fillLargeMeshArrays` * Move virtual buffers to a test util file * Better warning for segments.ts vertex overflow * Better comment for projection subdivision granularity * Clarify mesh comparison in fill_large_mesh_arrays.test.ts * Move mesh creating functions into a separate file, add tests for mesh comparison and grid creation * Refactor and add better doc comment for `fillLargeMeshArrays` * Refactor fill_large_mesh_arrays by removing duplicated code * Move debug functions to mesh_utils.ts * Unit tests: use StructArrays instead of VirtualVertexBuffer, etc. * Subdivision: refactor * Subdivision: rename subdivideFill to subdividePolygon, remove wireframe function * Subdivision: throw when a vertex is outside int16 range * Subdivision: refactor generatePoleQuad into a proper function * Subdivision: add subdivision benchmark * Subdivision: split scanline subdivision into smaller functions * Remove wireframe generation function * Subdivision: better doc comments for scanline subdivision * Fix 'as any' in segment.ts * Reuse condition in fill_large_arrays * Deduplicate code in fill_large_arrays * Subdivision: remove redundant function in tests * Subdivision: improve scanline subdivision comments * Subdivision: benchmark is not async * Rename SegmentVector's invalidateLast to forceNewSegmentOnTextPrepare * More tests for segment.ts * Fix typo in forceNewSegmentOnNextPrepare * Subdivision: more tests for fillLargeMeshArrays * Subdivision: better comment in fillLargeMeshArrays * Fix build due to bad merge. * Globe - line layer (#3961) * Fix merge * Import line layer changes from kubapelc/globe-vector * Lines: shorten line_bucket.test.ts subdivision settings * Lines: minor refactor * Lines: update build size * Lines: minor refactor * Globe - fill extrusion layer (#3968) * Import changes for fill-extrusion from main vector globe branch * Fill extrusion: refactor * Fill extrusion: indent shader ifdefs * Fill extrusion: add example * Fill extrusion: update build size * Move globe specific projection methods to projection interface * Fix failing unit test * Use vec3.clone() instead of manually copying vector components * Kubapelc/globe pr hillshade (#3979) * Import background layer changes from main vector globe branch * Import hillshade layer changes from main vector globe branch * Subdivision: explicit types * Fix single-pixel seams in the oceans * Add render test for background pattern on globe * Refactor drawBackground * Refactor drawHillshade * Update build size * Update globe background-pattern render test with results from CI * Hillshade: refactor prepareHillshade * Add a render test for fill layer seams fix * Globe - circle and heatmap layers (#4015) * Import changes for circle and heatmap layers from the main vector globe branch * Minor refactors * Update build size * Use "/ 8.0" in shader instead of "* 0.125" * Update shader comments * Use a thin type instead of full Transform in projection * Only import types in projection.ts * getPixelScale and getCircleRadiusCorrection only need map center as argument * Only import types where possible in projection classes * Smaller refactors * Fix failing unit test * Add heatmap render test * More explicit types in projection interface * Globe plane equation is a vec4 * Fix wrong args in projection functions * Improve readibility of build test and fix it. * Globe - symbols & symbol bugfixes (#4067) * Import changes from main vector globe branch * Fix import * Remove unused code * Remove unused imports * Update build size test * Remove unused function * Add render test results for Debian * Add another Debian render test variant * Add more render test variants * Hide collision boxes on the backfacing side of the globe * Fix pitch-aligned texts getting hidden when their anchor is beyond horizon * Update build size * Fix merge * Better comment in draw_collision_debug * Update build size The 10 kb size increase seems to come from the main branch * Minor refactor * Use explicit types, even for unused parameters * Refactor screenspace path projection * Refactor imports for projection.ts and collision_index.ts * Fix import in collision_index.ts * Globe - example images (#4140) * Add example images * Add "-" into example name * Remove basic globe example * Globe - clipping fix (#4146) * HiSilicon fix: enable face culling whereever possible (cherry picked from commit fe439a5) * Improve circle layer performance by discarding empty pixels (cherry picked from commit 266897d) * HiSilicon fix: software clipping of polygon outlines (cherry picked from commit 98167ba) * HiSilicon fix: software clipping for line layer (cherry picked from commit d521e95) * HiSilicon fix: circle software clipping (cherry picked from commit f2ed744) * HiSilicon fix: enable backface culling for symbols (cherry picked from commit 54e3632) * Update build test * Fix terrain using a mirrored projection matrix * Fix typos * Fix terrain coord textures being flipped vertically * Update build size * Fix rendering of images with face culling, fix image rendering near pole regions * Add render test for images on a globe * Update comment in circle.vertex.glsl * Fix bad merge * Fix lint * Fix location of old vertex count * replace expected file for terrain changes * Fix rename in main merge branch * Fix build test * Move projection to style class (#4267) * Move projection to style class * Fix lint * Fix unit tests * Increase build size * Update docs, fix test * Fix lint * Add test to cover projection change * Added more tests * Add an Atmosphere layer for Globe (#3888) (#4020) * Port of PoC atmosphere layer. * Fix resize for draw_atmosphere * Add some options. * Allow to change sun date and time * Fix import warning * Render atmosphere only when a Globe projection is selected * Add some comments * Add some comments * Change key * Update changelog * Fix merge with globe branch * Fix documentation and default background color. * Use black clear color only when atmosphere is on * Use atmosphere uniform for globe position, raidus in camera frame and inv projection matrix. * Remove unused project method * Update maplibre-gl-style-spec to 20.3.0 and use sky atmosphere parameter * Fix globe tests and use light position as Sun position. * Avoid type name collisions. * Add atmosphere test for globe projection. * Update expectedBytes for build test. * Fix PR comments. * Update Style test. * Remove unused method on projection * Add Sky Test. * Fix style test and add sky unit test. * Move getSunPos method * Fix mercator updateProjection * Remove isGlobe method and fix merge. * Fix globe atmosphere tests with new projection style. * Clean-up some projection and light. Fix setSky and add tests. * Remove sky test during update. * Clean-up * missing fix from merge * Fix lint * Terrain fix (#4343) * Fix missing image for globe example * Update atmosphere (#4345) * Merge Sky and Atmosphere code. * Update changelog * Fix generate-struct-arrays * Globe - transform+projection changes (#4341) * Delete unused file * Rename projection.name to projection.projectionName Since this interface will be implemented by the transfrom class soon * Symbols: displayed collision circles now exactly match their computed positions * Globe: use mercator projection for symbol placement when globe rendering is disabled * Group all getters/setters in the transform class * Transform: move transform-related stuff from the projection interface to transform class (WIP) * Transform: finish moving parts of projection into mercator_transform.ts * Transform: remove posMatrix usage from line symbol placement (WIP) * Transform: temporarily remove globe stuff (WIP, compilable) * Transform: fix line symbols * Symbols: fix wrong function names * Fix line point projections * Fix line rendering Some things are still broken * Fix line symbols sometimes being incorrectly oriented * Fix some failing unit tests * Fix single glyph orientation * Add another image to render test No idea why it is shifted by a few pixels but I assume that the new expected image is also correct * Add another expected image to textFit-grid-long test It was only failing on my machine, works fine in github CI windows tests * Fix some failing unit tests * Simplify getProjectionData interface and terrain matrix passing * Change comment at calculatePosMatrix * Fix symbols not rendering, remove unused shader parameters * Bring back globe src files * globe.test.ts is now globe_transform.test.ts * Move stuff from globe.ts to globe_transform.ts * Fix showTileBoundaries not working Fix the three render tests related to showTileBoundaries timing out. * Remove irrelevant test * Fix failing unit test * Transform: move more stuff from globe to globe_transform * Transform: better comments * Transfrom: isRenderingDirty cleanup * Transform: no more errors in globe_transform.ts * Transform: remove `get point()` from transform class * Transform: globe_transform.ts is compilable * Re-enable globe projection * Fix source_cache.ts sometimes crashing * Fix globe.ts - globe_transform.ts circular dependency * Fix and refactor getProjectionData interface Now it is actually compilable, with many bugs * Transform: fix failing unit tests * Transform: fix symbols not rendering on globe * Transform: minor fixes * Transform: update globe symbol render tests * Transform: unify how symbol/projection.ts exports stuff * Transform: improve comments * Remove unused function in painter * Transform: cleanup unneeded abstract functions * Transform: replace abstract getHorizon function with more generic isPointOnMapSurface function * Fix useGlobeRendering not being set properly * Transform: proper implementation of isPointOnMapSurface and screen pixel unprojection for globe * Transform: adapt more functions for globe * Transform: fix locationPoint implementation * Controls: globe panning experiments * Controls: reasonable globe panning * Controls: centering zoom for globe experiment * Transform: fix globe unit tests * Transform: fix remaining unit tests * Move mercator_transform.test to src/geo/projection * Transform: globe bugfixes and more unit tests * Transform: bugfix globe setLocationAtPoint * Transform: isolate accesses to globe projection to avoid unintentional transform's state changes * Transform: move related tests so they are near each other * Transform: improve globe unprojection accuracy * Transform: fix globe bugs * Transform: move globe unit tests * Transform: another globe setLocationAtPoint implementation * Transform: fix globe zoom adjustment not working * Transform: fix setLocationAtPoint * Transform: setLocationAtPoint and zoom WIP * Transform: adjust unit test to accept positive longitudes * Transform: improve globe math precision (fp64) * Transform: precision improvement, better camera position * Transform: another test WIP * Transform: fix setLocationAtPoint condition * Transform: more reasonable zoom for globe Still has bugs though * Transform: globe zoom works well when cursor is outside the globe * Transform: globe more consistent zoom logic * Transform: experimental pole edge clamp for globe * Transform: fix maxLatitudeForZoomLevel math * Transform: globe constrain experiment * Transform: minor improvements * Transform: globe panning 2.0 * Transform: globe panning 2.1 Adjust more constants! * Transform: some math for globe zoom * Transform: globe: working zoom controls without glitches * Transform: globe zoom: fix some more glitching * Transform: globe zoom: reduce panning when zoom pixel is far from the planet * Transform: zoom globe: simplify, better behaviour around poles * Transform: globe zoom: exact zooming * Transform: globe zoom: better comments * Transform: temporarily disable camera easeTo and flyTo * Transform: calling project/unproject on a globe should fail, rename project/unproject to be more descriptive * Transform: fitBounds: initial implementation for globe_transform Not working * Transform: fitBounds: zoom is now correct * Transform: fitBounds: padding works for north/south * Transform: fitBounds: just build on top of mercator code * Transform: fitBounds: the original way * Transform: fitBounds: back to mercator-buildon + done * Transform: tighter bounds for zoom heuristic transition * Transform: easeTo: probably works * Transform: attempt to handle camera options apparent zoom for globe * Transform: easeTo fixes WIP * Transform: easeTo: mostly working implementation (still WIP) * Transform: easeTo: small fixes * Transform: easeTo: intertia works for panning * Transform: globe zoom: add globe radius based slowing factor * Transform: globe zoom adjustments * Transform: jumpTo adapted for globe * Transform: camera flyTo works for globe * Make (un)projectToWorldCoordinates into standalone functions * Fix inertia sometimes rotating in the wrong direction * Fix transform center sometimes not getting wrapped, leading to visual artifacts * Transform: easeTo: slerp experiment * Transform: easeTo: revert slerp, add note on why it is not used * Transform: improve center animation for easeTo and flyTo * Minor refactor & remove some outdated TODOs * More refactor and TODOs * Transform: globe remembers its globeness state after clone, fixes improper collision box when globe gets soft-disabled * Terrain matrix refactor WIP * Terrain fixes * Transform: better comments, rename angularCoordinatesToVector to angularCoordinatesToSurfaceVector, some functions for globe WIP * Transform: getBounds for globe works * Transform: remove some comments * Fix merge * Remove globe.test.ts (it is now globe_transform.test.ts) * Rename Transform.updateProjection to newFrameUpdate * Revert globe.ts to pre-merge state * Revert mercator.ts to pre-merge state * New mechanism for creating specialized transforms, more merge fixes * Rename projectionMatrix to modelViewProjectionMatrix, refactor mercator_transform.ts a bit * More merge fixes, minor refactor of transforms * Add transform getters for atmosphere * Fix forgotten useGlobeControls uses * Fix cyclical dependency * Fix tests * Fix crashes * Fix manually triggered globe transition animation * Fix collision boxes not respecting mercator transition * Blend out atmosphere when transitioning to mercator * Fix globe transitions when mercator should be constrained * Reload all tiles upon projection change * Fix failing style tests * Fix terrain source cache tests * Fix map zoom&center being applied in wrong order, causing zoom to be wrongly constrained under globe * Update globe pole render tests with correct zoom * Update globe unit test zooms * Fix more unit tests * Fix transform.apply not copying everything, fix globe controls not wrapping longitudes * Fix some globe tests * Fix globe setLocationAtPoint * Fix docs & lint * Increase globe setLocationAtPoint test desired precision * Some camera tests for globe * Fix easeTo test suite name and placing * Add rotated setLocationAtPoint test for globe, fix failing test * Fix globe easeTo & flyTo with bearing to follow spec, add tests * easeTo globe tests * All relevant camera tests for globe implemented * Update build size test * Fix symbols not respecting mercator * Update build size again * Terrain fix * Fix merge * Fix terrain shaders * Fix merge * Revert controls changes * Fix reverted files * Fix reverted camera tests * Revert forgotten file, fix lint * Update build size * Feedback comments for unit tests * Convert setters to functions: runtime code * Convert setters to functions: test code * Convert last setter to function * Fix some tests * Transform is now an interface * Rename Transform to ITransform * Remove abstract functions from transform base class * TransformHelper wip * Rename transform files * Finish transform rewrite * Fix mercator transform tests * Fix mercator_transform constructor * Fix symbol bucket test * Fix source cache tests * Fix transform clone bug & tests * Improve comments * More comments * Fix import * Move helper functions in tests to beginning of file * Fix collision index test accessing a private field * Remove unneeded null check * New utils tests + quadratic solve fix * Add remapSaturate tests * Add explicit types to line glyph placement * Refactor placeGlyphsAlongLine args into an object * Fix merge, cleanup draw_custom.test, fix missing perspective offset in globe transform * Fix draw_custom test * Update build test * Fix crashes * Fix transform_helper apply function not setting bearing correctly * Add test for TransformHelper * Fix TransformHelper.apply * Fix flipped text placement * Add new expected image to render test * Fix marker tests * Update build size * Move functions from mercator_transform.ts to mercator_utils.ts * Refactor un/projectToWorldCoordinates function args * Make zoomScale and scaleZoom standalone functions * Fix unprojectFromWorldCoordinates arg type * Move globe functions to separate file * Fix private member access in source_cache.test.ts * Fix deck.gl missing dot * Fix missing globe_utils.ts * Better `angleToRotateBetweenVectors2D` doccomment * Remove unneeded `protected` * Cleanup transform interface and remove duplicate comments * Split mercator_utils tests into a separate file * Fix tests * Split globe locationPoint tests a bit * Add more mercator tests * More globe tests * Fix globe getBounds and add tests for it * Remove unneeded function, update build size * projectTileCoordinates for globe now covered by test * Add globe_utils tests * Split up globe tests more * Fix missing doccomment * Rename transform's projection/unprojection functions * Better ray intersection comment and type * Reduce indentation * Improve unproject math readability * Add point-plane distance util function * Move tileCoordinatesToMercatorCoordinates to mercator_utils * Better name for location to mercator coordinate functions * Move angleToRotateBetweenVectors2D to utils * Refactor _globeness usage * Remove _initialized from GlobeTransform * Remove translatePosition from transform interface * Add IReadonlyTransform interface * Update build size * Remove unneeded comment * Fix painter test * Fix lint * Update test/build/min.test.ts * Update changelog * Globe - camera controls (#4408) * Camera controls changes from dev branch * Move stuff from globe_control_utils to globe_utils * Better globe_utils comments * Fix markers not being updated when globe is toggled * Fix globe tests * Update build size * Better comments for camera helper functions * Move camera helper functions to beginning of file * Camera: more and better comments * Update build size * Fix globe transform error correction handling * Better comments for _last* fields in globe transform * Refactor newFrameUpdate * Better comments for CoveringTilesOptions type members. * Refactor globe camera tests to use more describe statements * Remove isTilePositionOccluded function from transform interface * Fix camera tests * Add more mercator_utils test * Add more globe_transform tests * Fix failing render tests * Make camera helper functions static * Remove `around` from flyTo options. * Update build size * CameraHelper: initial implementation, inertia handling * Move createVec* functions to util.ts * CameraHelper: panning and zooming * CameraHelpers: implement cameraForBounds * CameraHelpers: handle jumpTo * CameraHelper: easeTo * CameraHelper: flyTo * Projection event contains new projection name and is fired by changing style's projection * Fix lint * Fix test camera/map not having proper CameraHelper * Fix easeTo not emitting zoom events * Fix cameraForBoxAndBearing globe not returning anything, rename camera helter types * Fix globe easeTo ignoring offset * Fix one flyTo test not creating camera properly * Update build size * Add projection transition event tests * Add example on how to compensate for how globe size changes with latitude * Revert scrollzoom delete removal * Remove apparentZoom parameter * CameraHelper is set in camera constuctor * Use spy for projection event unit tests * Remove unnecessary done() in tests * Update build size * Remove more unneeded done() calls * Do not use map.once callback in projection events tests * Better zoom delta example title and description * Rename globe zoom delta and planet size function example * Add zoom planet size function example image * Reduce size of some globe example images using compresspng * Globe: bugfixes: raster layer & projection change (#4546) * Port bugfix changes * Update build size * Fix render tests * Add render test result for debian * Increase raster tile granularity some more * Adjust warped raster tile render test * Add missing tsdoc param * Use single checkerboard image for render test * Globe examples now use setProjection * Add new raster-pole render test image * Add another raster-warped expected image * Use "style.load" event on map instead of on style * Adapt new heatmap code for globe, update build size * Fix render tests Most tests had subpixel shifts * Globe - custom layers API and examples, globe dev guide (#4577) * Port custom layer changes and globe docs * Port transform changes * Fix custom layer unit test * Fix failing render tests * Update build size * Update globe custom layer example descritions, remove forgotten code * Remove unused util function * Incorporate globe docs feedback * Refactor and expose tile mesh generation * Refactor custom layers to get smaller args object and access map transform directly * Simplify more of the custom layer API * Clean up and adapt more examples * Fix mercator matrix precision * Fix 3D model on terrain example * Rename projectionDataForMercatorCoords to defaultProjectionData * Document ProjectionData type * Update build size * Update developer-guides/globe.md Co-authored-by: Harel M <[email protected]> * Decouple ProjectionData from rendering code Rename fields to camelCase, move it to a separate file * Rename ProjectionData members * Fix mercator transform unit tests * Add an example to createTileMesh * Rename CustomRenderMethodInput.shader to shaderData * Add shaderData examples * Document TileMesh and CreateTileMeshOptions types * Fix custom layers in render tests * Update render tests Fails other than raster-warped were caused by increasing pos matrix precision in mercator_transform to 64 bit floats * Add render test result from linux * Update build size * Update src/render/program/projection_program.ts Co-authored-by: Harel M <[email protected]> * Rename createTileMeshInternal to createTileMeshWithBuffers * Update build size * Improve doc comments --------- Co-authored-by: Harel M <[email protected]> * Globe - Covering tiles (#4615) * Import coveringTiles changes from dev branch * Remove duplicated tiles used in render tests * Remove unused function * Fix typo * Properly handle tile wraps and LOD across antimeridian * Discard previous changes and use custom wrap values instead * Update build size * Add render test for LOD at antimeridian * Convert visibility numbers to enum * Refactor globe covering tiles into a separate file * Add yet another raster-warped expected image * Add unit tests for globe covering tiles * Refactor globe coveringTiles math to assume worldSize=1 instead of tileSize=1 * Split globe coveringTiles into more functions * Explain radiusOfMaxLvlLodInTiles value * Explain why checking 4 tile corners is (mostly) enough to construct an AABB. * Move mercator coveringTiles into a separate file * Yet another raster-warped expected image * Remove ITileVisibilityProvider interface * Use explicit types * PR feedback * Rename coveringTiles stack types * fix typo * Remove sky disabling in examples as this is no longer needed. * Fix spelling * Fix spelling - unencode * Fix more spelling * Fix lint * Update CHANGELOG.md --------- Co-authored-by: Jakub Pelc <[email protected]> Co-authored-by: Larrieu Vivian <[email protected]> Co-authored-by: Jakub Pelc <[email protected]>
1 parent 2a17350 commit a283af1

File tree

385 files changed

+24019
-3240
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

385 files changed

+24019
-3240
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
## main
22

33
### ✨ Features and improvements
4+
- Support globe mode ([#3963](https://github.com/maplibre/maplibre-gl-js/issues/3963))
5+
- Merge atmosphere an sky implementation ([#3888](https://github.com/maplibre/maplibre-gl-js/issues/3888))
6+
- Add option to display a realistic atmosphere when using a Globe projection ([#3888](https://github.com/maplibre/maplibre-gl-js/issues/3888))
47
- _...Add new stuff here..._
58

69
### 🐞 Bug fixes

build/generate-doc-images.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ async function createImage(exampleName) {
3131
try {
3232
await page.waitForFunction('map.loaded()');
3333
// Wait for 5 seconds on 3d model examples, since this takes longer to load.
34-
const waitTime = exampleName.includes('3d-model') ? 5000 : 1500;
34+
const waitTime = (exampleName.includes('3d-model') || exampleName.includes('globe')) ? 5000 : 1500;
3535
console.log(`waiting for ${waitTime} ms`);
3636
await new Promise(resolve => setTimeout(resolve, waitTime));
3737
} catch (err) {

developer-guides/assets/floats.png

566 KB
Loading
517 KB
Loading
708 KB
Loading

developer-guides/globe.md

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Globe projection
2+
3+
This guide describes the inner workings of globe projection.
4+
Globe draws the same vector polygons and lines as mercator projection,
5+
ensuring a clear, unstretched image at all view angles and support for dynamic layers and geometry.
6+
7+
The actual projection is done in three steps:
8+
9+
- compute angular spherical coordinates from source web mercator tile data
10+
- convert spherical coordinates to a 3D vector - a point on the surface of a unit sphere
11+
- project the 3D vector using a common perspective projection matrix
12+
13+
So the globe is a unit sphere from the point of view of projection.
14+
This also simplifies a lot of math, and is used extensively in the globe transform class.
15+
16+
Geometry is projected to the sphere in the vertex shader.
17+
18+
## Zoom behavior
19+
20+
To stay consistent with web mercator maps, globe is automatically enlarged when map center is nearing the poles.
21+
This keeps the map center visually similar to a mercator map with the same x,y and zoom.
22+
However, when panning the globe or performing camera animations,
23+
we do not want the planet to get larger or smaller when changing latitudes.
24+
Map movement thus compensates for the planet size change by also
25+
changing zoom level along with latitude changes.
26+
27+
This behavior is completely automatic and transparent to the user.
28+
The only case when the user needs to be aware of this is when
29+
programmatically triggering animations such as `flyTo` and `easeTo`
30+
and using them to both change the map center's latitude and *at the same time*
31+
changing the map's zoom to an amount based on the map's starting zoom.
32+
The example [globe-zoom-planet-size-function](https://maplibre.org/maplibre-gl-js/docs/examples/globe-zoom-planet-size-function/) demonstrates how to
33+
compensate for planet size changes in this case.
34+
All other camera animations (that either specify target zoom
35+
that is not based on current zoom or do not specify zoom at all) will work as expected.
36+
37+
## Shaders
38+
39+
Most vertex shaders use the `projectTile` function, which
40+
accepts a 2D vector of coordinates inside the currently drawn tile,
41+
in range 0..EXTENT (8192), and returns its final projection that can
42+
be directly passed to `gl_Position`.
43+
When drawing a tile, proper uniforms must be set to convert from
44+
these tile-local coordinates to web mercator.
45+
46+
The implementation of `projectTile` is automatically injected into the shader source code.
47+
Different implementations can be injected, depending on the currently active projection.
48+
Thanks to this many shaders use the exact same code for both mercator and globe,
49+
although there are shaders that use `#ifdef GLOBE` for globe-specific code.
50+
51+
## Subdivision
52+
53+
If we were to draw mercator tiles with globe shaders directly, we would end up with a deformed sphere.
54+
This is due to how polygons and lines are triangulated in MapLibre - the earcut algorithm
55+
creates as few triangles as possible, which can sometimes result in huge triangles, for example in the oceans.
56+
This behavior is desirable in mercator maps, but if we were to project the vertices of such large triangles to globe directly,
57+
we would not get curved horizons, lines, etc.
58+
For this reason, before a tile is finished loading, its geometry (both polygons and lines) is further subdivided.
59+
60+
The figure below demonstrates how globe would look without subdivision.
61+
Note the deformed oceans, and the USA-Canada border that is not properly curved.
62+
63+
![](assets/no_subdivision.png)
64+
65+
It is critical that subdivision is as fast as possible, otherwise it would significantly slow down tile loading.
66+
Currently the fastest approach seems to be taking the output geometry from `earcut` and subdividing that further.
67+
68+
When modifying subdivision, beware that it is very prone to subtle errors, resulting in single-pixel seams.
69+
Subdivision should also split the geometry in consistent places,
70+
so that polygons and lines match up correctly when projected.
71+
72+
We use subdivision that results in a square grid, visible in the figure below.
73+
74+
![](assets/wireframe.png)
75+
76+
Subdivision is configured in the Projection object.
77+
Subdivision granularity is defined by the base tile granularity and minimal allowed granularity.
78+
The tile for zoom level 0 will have base granularity, tile for zoom 1 will have half that, etc.,
79+
but never less than minimal granularity.
80+
81+
The maximal subdivision granularity of 128 for fill layers is enough to get nicely curved horizons,
82+
while also not generating too much new geometry and not overflowing the 16 bit vertex indices used throughout MapLibre.
83+
84+
Raster tiles in particular need a relative high base granularity, as otherwise they would exhibit
85+
visible warping and deformations when changing zoom levels.
86+
87+
## Floating point precision & transitioning to mercator
88+
89+
Shaders work with 32 bit floating point numbers (64 bit are possible on some platforms, but very slow).
90+
The 23 bits of mantissa and 1 sign bit can represent at most around 16 million values,
91+
but the circumference of the earth is roughly 40 000 km, which works out to
92+
about one float32 value per 2.5 meters, which is insufficient for a map.
93+
Thus if we were to use globe projection at all zoom levels, we would unsurprisingly encounter precision issues.
94+
95+
![](assets/floats.png)
96+
97+
To combat this, globe projection automatically switches to mercator projection around zoom level 12.
98+
This transition is smooth, animated and can only be noticed if you look very closely,
99+
because globe and mercator projections converge at high zoom levels, and around level 12
100+
they are already very close.
101+
102+
The transition animation is implemented in the shader's projection function,
103+
and is controlled by a "globeness" parameter passed from the transform.
104+
105+
## GPU "atan" error correction
106+
107+
When implementing globe, we noticed that globe projection did not match mercator projection
108+
after the automatic transition described in previous section.
109+
This mismatch was very visible at certain latitudes, the globe map was shifted north/south by hundreds of meters,
110+
but at other latitudes the shift was much smaller. This behavior was also inconsistent - one would
111+
expect the shift to gradually increase or decrease with distance from equator, but that was not the case.
112+
113+
Eventually, we tracked this down to an issue in the projection shader, specifically the `atan` function.
114+
On some GPU vendors, the function is inaccurate in a way that matches the observed projection shifts.
115+
116+
To combat this, every second we draw a 1x1 pixel framebuffer and store the `atan` value
117+
for the current latitude, asynchronously download the pixel's value, compare it with `Math.atan`
118+
reference, and shift the globe projection matrix to compensate.
119+
This approach works, because the error is continuous and doesn't change too quickly with latitude.
120+
121+
This approach also has the advantage that it works regardless of the actual error of the `atan`,
122+
so MapLibre should work fine even if it runs on some new GPU in the future with different
123+
`atan` inaccuracies.
124+
125+
## Clipping
126+
127+
When drawing a planet, we need to somehow clip the geometry that is on its backfacing side.
128+
Since MapLibre uses the Z-buffer for optimizing transparency drawing, filling it with custom
129+
values, we cannot use it for this purpose.
130+
131+
Instead, we compute a plane that intersects the horizons, and for each vertex
132+
we compute the distance from this plane and store it in `gl_Position.z`.
133+
This forces the GPU's clipping hardware to clip geometry beyond the planet's horizon.
134+
This does not affect MapLibre's custom Z values, since they are set later using
135+
`glDepthRange`.
136+
137+
However this approach does not work on some phones due to what is likely a driver bug,
138+
which applies `glDepthRange` and clipping in the wrong order.
139+
So additionally, face culling is used for fill and raster layers
140+
(earcut does not result in consistent winding order, this is ensured during subdivision)
141+
and line layers (which have inconsistent winding order) discard beyond-horizon
142+
pixels in the fragment shader.
143+
144+
## Raster tiles
145+
146+
Drawing raster tiles under globe is somewhat more complex than under mercator,
147+
since under globe they are much more prone to having slight seams between tiles.
148+
Tile are drawn as subdivided meshes instead of simple quads, and the curvature
149+
near the edges can cause seams, especially in cases when two tiles of different
150+
zoom levels are next to each other.
151+
152+
To make sure that there are both no seams and that every pixel is covered by
153+
valid tile texture (as opposed to a stretched border of a neighboring tile),
154+
we first draw all tiles *without* border, marking all drawn pixels in stencil.
155+
Then, we draw all tiles *with* borders, but set stencil to discard all pixels
156+
that were drawn in the first pass.
157+
158+
This ensures that no pixel is drawn twice, and that the stretched borders
159+
are only drawn in regions between tiles.
160+
161+
## Symbols
162+
163+
Symbol rendering also had to be adapted for globe, as well as collision detection and placement.
164+
MapLibre computed well-fitting bounding boxes even for curved symbols under globe projection
165+
by computing the AABB from a projection of the symbol's box' corners and box edge midpoints.
166+
This is an approximation, but works well in practice.
167+
168+
## Transformations and unproject
169+
170+
Most projection and unproject functions from the transform interface are adapted for globe,
171+
with some caveats.
172+
The `setLocationAtPoint`function may sometimes not find a valid solution
173+
for the given parameters.
174+
Globe transform currently does not support constraining the map's center.
175+
176+
## Controls
177+
178+
Globe uses slightly different controls than mercator map.
179+
Panning, zooming, etc. is aware of the sphere and should work intuitively,
180+
as well as camera animations such as `flyTo` and `easeTo`.
181+
182+
Specifically, when zooming, the location under the cursor stays under the cursor,
183+
just like it does on a mercator map.
184+
However this behavior has some limitations on the globe.
185+
In some scenarios, such as zooming to the edge of the planet,
186+
this way of zooming would result in rapid and unpleasant map panning.
187+
Thus this behavior is slowly faded out at low zooms and replaced with an approximation.
188+
189+
There are also other edge cases, such as when looking at the planet's poles
190+
and trying to zoom in to a location that is on the other hemisphere ("behind the pole").
191+
MapLibre does not support moving the camera across poles, so instead we need to rotate around.
192+
In this case, an approximation instead of exact zooming is used as well.
193+
194+
Globe controls also use panning inertia, just like mercator.
195+
Special care was taken to keep the movement speed of inertia consistent.
52.8 KB
Loading
163 KB
Loading
92.2 KB
Loading
139 KB
Loading

0 commit comments

Comments
 (0)