Skip to content

Commit

Permalink
Camera Roll (#4780)
Browse files Browse the repository at this point in the history
* 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

* Add basic roll capability

* code hygiene

* update sky shader to use roll angle

* fix horizon /sky display when rolled

* reduce repeat calls to potentially expensive functions

* use slerp instread of euler angle interpolation for mercator easeTo(). Also reverses definition of roll.

* safe roll pitch bearing near singularity

* add option to use slerp or old linear interpolation of Euler angles

* code hygiene

* code hygiene

* fix unit tests

* add roll unit tests

* change euler angle behavior at the end of easeTo() to use the representation specified by the caller. This only matters at the singularity (pitch = 0)

* unit tests fro R2D and D2R

* add euler angle unit tests

* add roll to transform unit tests

* add roll to transform helper test

* code hygiene

* add sky and fog render tests

* code hygiene

* this rotates labels as I intended it to when pitchWithMap = true, rotateWithMap= false, but I don't think that's what we want

* Revert "this rotates labels as I intended it to when pitchWithMap = true, rotateWithMap= false, but I don't think that's what we want"

This reverts commit 01845a9.

* extend rotateWithMap to include the effects of camera roll

* Add roll icon render tests

* getPitchedLabelPlaneMatrix unit tests

* add getPitchedLabelPlaneMatrix unit test

* add getGlCoordMatrix unit tests

* remove console.log

* code hygiene

* add roll text alignment render tests

* fix lint

* add text upright with roll render test

* add combined rotation text upright render test

* add text-pitch-scaling render test with roll

* fix collision box when camera is rolled

* add skew matrix tests at horizon.

* faster getTileSkewMatrix

* update changelog

* updated expected build size

* remove "useSlerp" flag from mercator transform, and use slerp in globe transform as well.

* fix merge error

* increase test coverage

* switch from _underscore fields to getters

* add render text for different text alignments with rolled horizon present.

* change private angle names in transform to include prefix "InRadians", and add getters directly in radians. Remove ambiguous member "angle", which was negative bearingInRadians.

* updated library size

* use *InRadians where possible

* combine duplicate interpolation code from mercator and globe

* add roll to root style spec

* change getTileSkewMatrix to return vectors instead of mat2

* fix lint

* Add roll visualization to Navigation Control, and add mouse control of roll using Ctrl + right click.

* Update style spec and remove "as any" in jumpTo()

* rearrrange if-else

* add roll and pitch control and visualization to navigation example

* update build size

* fix bad changelog merge

* add mouseRollHandler and DragRotateHandler unit tests

---------

Co-authored-by: Jakub Pelc <[email protected]>
Co-authored-by: HarelM <[email protected]>
Co-authored-by: Larrieu Vivian <[email protected]>
Co-authored-by: Jakub Pelc <[email protected]>
  • Loading branch information
5 people authored Oct 17, 2024
1 parent 9c62b8b commit 86ed382
Show file tree
Hide file tree
Showing 84 changed files with 2,096 additions and 189 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## main

### ✨ Features and improvements
- Add support for camera roll angle ([#4717](https://github.com/maplibre/maplibre-gl-js/issues/4717))
- _...Add new stuff here..._

### 🐞 Bug fixes
Expand Down
34 changes: 32 additions & 2 deletions src/geo/projection/camera_helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import {LngLat, LngLatLike} from '../lng_lat';
import {CameraForBoundsOptions, PointLike} from '../../ui/camera';
import {PaddingOptions} from '../edge_insets';
import {LngLatBounds} from '../lng_lat_bounds';
import {warnOnce} from '../../util/util';
import {getRollPitchBearing, RollPitchBearing, warnOnce} from '../../util/util';
import {quat} from 'gl-matrix';

export type MapControlsDeltas = {
panDelta: Point;
zoomDelta: number;
bearingDelta: number;
pitchDelta: number;
rollDelta: number;
around: Point;
}

Expand All @@ -23,6 +25,7 @@ export type CameraForBoxAndBearingHandlerResult = {
export type EaseToHandlerOptions = {
bearing: number;
pitch: number;
roll: number;
padding: PaddingOptions;
offsetAsPoint: Point;
around?: LngLat;
Expand All @@ -41,6 +44,7 @@ export type EaseToHandlerResult = {
export type FlyToHandlerOptions = {
bearing: number;
pitch: number;
roll: number;
padding: PaddingOptions;
offsetAsPoint: Point;
center?: LngLatLike;
Expand Down Expand Up @@ -78,7 +82,7 @@ export interface ICameraHelper {
easingOffset: Point;
};

handleMapControlsPitchBearingZoom(deltas: MapControlsDeltas, tr: ITransform): void;
handleMapControlsRollPitchBearingZoom(deltas: MapControlsDeltas, tr: ITransform): void;

handleMapControlsPan(deltas: MapControlsDeltas, tr: ITransform, preZoomAroundLoc: LngLat): void;

Expand All @@ -90,3 +94,29 @@ export interface ICameraHelper {

handleFlyTo(tr: ITransform, options: FlyToHandlerOptions): FlyToHandlerResult;
}

/**
* @internal
* Set a transform's rotation to a value interpolated between startRotation and endRotation
* @param startRotation - the starting rotation (rotation when k = 0)
* @param endRotation - the end rotation (rotation when k = 1)
* @param endEulerAngles - the end Euler angles. This is needed in case `endRotation` has an ambiguous Euler angle representation.
* @param tr - the transform to be updated
* @param k - the interpolation fraction, between 0 and 1.
*/
export function updateRotation(startRotation: quat, endRotation: quat, endEulerAngles: RollPitchBearing, tr: ITransform, k: number) {
// At pitch ==0, the Euler angle representation is ambiguous. In this case, set the Euler angles
// to the representation requested by the caller
if (k < 1) {
const rotation: quat = new Float64Array(4) as any;
quat.slerp(rotation, startRotation, endRotation, k);
const eulerAngles = getRollPitchBearing(rotation);
tr.setRoll(eulerAngles.roll);
tr.setPitch(eulerAngles.pitch);
tr.setBearing(eulerAngles.bearing);
} else {
tr.setRoll(endEulerAngles.roll);
tr.setPitch(endEulerAngles.pitch);
tr.setBearing(endEulerAngles.bearing);
}
}
26 changes: 14 additions & 12 deletions src/geo/projection/globe_camera_helper.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import Point from '@mapbox/point-geometry';
import {IReadonlyTransform, ITransform} from '../transform_interface';
import {cameraBoundsWarning, CameraForBoxAndBearingHandlerResult, EaseToHandlerResult, EaseToHandlerOptions, FlyToHandlerResult, FlyToHandlerOptions, ICameraHelper, MapControlsDeltas} from './camera_helper';
import {cameraBoundsWarning, CameraForBoxAndBearingHandlerResult, EaseToHandlerResult, EaseToHandlerOptions, FlyToHandlerResult, FlyToHandlerOptions, ICameraHelper, MapControlsDeltas, updateRotation} from './camera_helper';
import {GlobeProjection} from './globe';
import {LngLat, LngLatLike} from '../lng_lat';
import {MercatorCameraHelper} from './mercator_camera_helper';
import {angularCoordinatesToSurfaceVector, computeGlobePanCenter, getGlobeRadiusPixels, getZoomAdjustment, globeDistanceOfLocationsPixels, interpolateLngLatForGlobe} from './globe_utils';
import {clamp, createVec3f64, differenceOfAnglesDegrees, remapSaturate, warnOnce} from '../../util/util';
import {mat4, vec3} from 'gl-matrix';
import {clamp, createVec3f64, differenceOfAnglesDegrees, remapSaturate, rollPitchBearingToQuat, warnOnce} from '../../util/util';
import {mat4, quat, vec3} from 'gl-matrix';
import {MAX_VALID_LATITUDE, normalizeCenter, scaleZoom, zoomScale} from '../transform_helper';
import {CameraForBoundsOptions} from '../../ui/camera';
import {LngLatBounds} from '../lng_lat_bounds';
Expand Down Expand Up @@ -48,9 +48,9 @@ export class GlobeCameraHelper implements ICameraHelper {
};
}

handleMapControlsPitchBearingZoom(deltas: MapControlsDeltas, tr: ITransform): void {
handleMapControlsRollPitchBearingZoom(deltas: MapControlsDeltas, tr: ITransform): void {
if (!this.useGlobeControls) {
this._mercatorCameraHelper.handleMapControlsPitchBearingZoom(deltas, tr);
this._mercatorCameraHelper.handleMapControlsRollPitchBearingZoom(deltas, tr);
return;
}

Expand All @@ -59,6 +59,7 @@ export class GlobeCameraHelper implements ICameraHelper {

if (deltas.bearingDelta) tr.setBearing(tr.bearing + deltas.bearingDelta);
if (deltas.pitchDelta) tr.setPitch(tr.pitch + deltas.pitchDelta);
if (deltas.rollDelta) tr.setRoll(tr.roll + deltas.rollDelta);
const oldZoomPreZoomDelta = tr.zoom;
if (deltas.zoomDelta) tr.setZoom(tr.zoom + deltas.zoomDelta);
const actualZoomDelta = tr.zoom - oldZoomPreZoomDelta;
Expand Down Expand Up @@ -191,6 +192,7 @@ export class GlobeCameraHelper implements ICameraHelper {
clonedTr.setCenter(result.center);
clonedTr.setBearing(result.bearing);
clonedTr.setPitch(0);
clonedTr.setRoll(0);
clonedTr.setZoom(result.zoom);
const matrix = clonedTr.modelViewProjectionMatrix;

Expand Down Expand Up @@ -259,9 +261,12 @@ export class GlobeCameraHelper implements ICameraHelper {
}

const startZoom = tr.zoom;
const startBearing = tr.bearing;
const startPitch = tr.pitch;
const startCenter = tr.center;
const startRotation = rollPitchBearingToQuat(tr.roll, tr.pitch, tr.bearing);
const endRoll = options.roll === undefined ? tr.roll : options.roll;
const endPitch = options.pitch === undefined ? tr.pitch : options.pitch;
const endBearing = options.bearing === undefined ? tr.bearing : options.bearing;
const endRotation = rollPitchBearingToQuat(endRoll, endPitch, endBearing);

const optionsZoom = typeof options.zoom !== 'undefined';

Expand Down Expand Up @@ -312,11 +317,8 @@ export class GlobeCameraHelper implements ICameraHelper {
isZooming = (endZoomWithShift !== startZoom);

const easeFunc = (k: number) => {
if (startBearing !== options.bearing) {
tr.setBearing(interpolates.number(startBearing, options.bearing, k));
}
if (startPitch !== options.pitch) {
tr.setPitch(interpolates.number(startPitch, options.pitch, k));
if (!quat.equals(startRotation, endRotation)) {
updateRotation(startRotation, endRotation, {roll: endRoll, pitch: endPitch, bearing: endBearing}, tr, k);
}

if (options.around) {
Expand Down
10 changes: 10 additions & 0 deletions src/geo/projection/globe_transform.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ describe('GlobeTransform', () => {
globeTransform.setBearing(70);
expectToBeCloseToArray(globeTransform.cameraPosition as Array<number>, [-0.7098603286961542, 2.002400604307631, 0.6154310261827212], precisionDigits);

globeTransform.setPitch(35);
globeTransform.setBearing(70);
globeTransform.setRoll(40);
expectToBeCloseToArray(globeTransform.cameraPosition as Array<number>, [-0.7098603286961542, 2.002400604307631, 0.6154310261827212], precisionDigits);

globeTransform.setPitch(35);
globeTransform.setBearing(70);
globeTransform.setRoll(180);
expectToBeCloseToArray(globeTransform.cameraPosition as Array<number>, [-0.7098603286961542, 2.002400604307631, 0.6154310261827212], precisionDigits);

globeTransform.setCenter(new LngLat(-10, 42));
expectToBeCloseToArray(globeTransform.cameraPosition as Array<number>, [-3.8450970996236364, 2.9368285470351516, 4.311953269048194], precisionDigits);
});
Expand Down
39 changes: 28 additions & 11 deletions src/geo/projection/globe_transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ export class GlobeTransform implements ITransform {
setPitch(pitch: number): void {
this._helper.setPitch(pitch);
}
setRoll(roll: number): void {
this._helper.setRoll(roll);
}
setFov(fov: number): void {
this._helper.setFov(fov);
}
Expand Down Expand Up @@ -151,9 +154,6 @@ export class GlobeTransform implements ITransform {
get height(): number {
return this._helper.height;
}
get angle(): number {
return this._helper.angle;
}
get lngRange(): [number, number] {
return this._helper.lngRange;
}
Expand Down Expand Up @@ -181,12 +181,27 @@ export class GlobeTransform implements ITransform {
get pitch(): number {
return this._helper.pitch;
}
get pitchInRadians(): number {
return this._helper.pitchInRadians;
}
get roll(): number {
return this._helper.roll;
}
get rollInRadians(): number {
return this._helper.rollInRadians;
}
get bearing(): number {
return this._helper.bearing;
}
get bearingInRadians(): number {
return this._helper.bearingInRadians;
}
get fov(): number {
return this._helper.fov;
}
get fovInRadians(): number {
return this._helper.fovInRadians;
}
get elevation(): number {
return this._helper.elevation;
}
Expand Down Expand Up @@ -472,13 +487,13 @@ export class GlobeTransform implements ITransform {
// - "cam" is camera origin
// - "C" is globe center
// - "B" is the point on "top" of the globe - camera is looking at B - "B" is the intersection between the camera center ray and the globe
// - this._pitch is the angle at B between points cam,B,A
// - this._pitchInRadians is the angle at B between points cam,B,A
// - this.cameraToCenterDistance is the distance from camera to "B"
// - globe radius is (0.5 * this.worldSize)
// - "T" is any point where a tangent line from "cam" touches the globe surface
// - elevation is assumed to be zero - globe rendering must be separate from terrain rendering anyway

const pitch = this.pitch * Math.PI / 180.0;
const pitch = this.pitchInRadians;
// scale things so that the globe radius is 1
const distanceCameraToB = this.cameraToCenterDistance / globeRadiusPixels;
const radius = 1;
Expand All @@ -504,7 +519,7 @@ export class GlobeTransform implements ITransform {
// Note the swizzled components
const planeVector: vec3 = [0, vectorCtoCamX, vectorCtoCamY];
// Apply transforms - lat, lng and angle (NOT pitch - already accounted for, as it affects the tangent plane)
vec3.rotateZ(planeVector, planeVector, [0, 0, 0], this.angle);
vec3.rotateZ(planeVector, planeVector, [0, 0, 0], -this.bearingInRadians);
vec3.rotateX(planeVector, planeVector, [0, 0, 0], -1 * this.center.lat * Math.PI / 180.0);
vec3.rotateY(planeVector, planeVector, [0, 0, 0], this.center.lng * Math.PI / 180.0);
// Scale the plane vector up
Expand Down Expand Up @@ -609,7 +624,7 @@ export class GlobeTransform implements ITransform {
const globeMatrixUncorrected = createMat4f64();
this._nearZ = 0.5;
this._farZ = this.cameraToCenterDistance + globeRadiusPixels * 2.0; // just set the far plane far enough - we will calculate our own z in the vertex shader anyway
mat4.perspective(globeMatrix, this.fov * Math.PI / 180, this.width / this.height, this._nearZ, this._farZ);
mat4.perspective(globeMatrix, this.fovInRadians, this.width / this.height, this._nearZ, this._farZ);

// Apply center of perspective offset
const offset = this.centerOffset;
Expand All @@ -620,8 +635,9 @@ export class GlobeTransform implements ITransform {
this._globeProjMatrixInverted = createMat4f64();
mat4.invert(this._globeProjMatrixInverted, globeMatrix);
mat4.translate(globeMatrix, globeMatrix, [0, 0, -this.cameraToCenterDistance]);
mat4.rotateX(globeMatrix, globeMatrix, -this.pitch * Math.PI / 180);
mat4.rotateZ(globeMatrix, globeMatrix, -this.angle);
mat4.rotateZ(globeMatrix, globeMatrix, this.rollInRadians);
mat4.rotateX(globeMatrix, globeMatrix, -this.pitchInRadians);
mat4.rotateZ(globeMatrix, globeMatrix, this.bearingInRadians);
mat4.translate(globeMatrix, globeMatrix, [0.0, 0, -globeRadiusPixels]);
// Rotate the sphere to center it on viewed coordinates

Expand All @@ -647,8 +663,9 @@ export class GlobeTransform implements ITransform {
const zero = createVec3f64();
this._cameraPosition = createVec3f64();
this._cameraPosition[2] = this.cameraToCenterDistance / globeRadiusPixels;
vec3.rotateX(this._cameraPosition, this._cameraPosition, zero, this.pitch * Math.PI / 180);
vec3.rotateZ(this._cameraPosition, this._cameraPosition, zero, this.angle);
vec3.rotateZ(this._cameraPosition, this._cameraPosition, zero, -this.rollInRadians);
vec3.rotateX(this._cameraPosition, this._cameraPosition, zero, this.pitchInRadians);
vec3.rotateZ(this._cameraPosition, this._cameraPosition, zero, -this.bearingInRadians);
vec3.add(this._cameraPosition, this._cameraPosition, [0, 0, 1]);
vec3.rotateX(this._cameraPosition, this._cameraPosition, zero, -this.center.lat * Math.PI / 180.0);
vec3.rotateY(this._cameraPosition, this._cameraPosition, zero, this.center.lng * Math.PI / 180.0);
Expand Down
4 changes: 2 additions & 2 deletions src/geo/projection/globe_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,13 @@ export function getDegreesPerPixel(worldSize: number, lat: number): number {
* @returns New center location to set to the map's transform to apply the specified panning.
*/
export function computeGlobePanCenter(panDelta: Point, tr: {
readonly angle: number;
readonly bearingInRadians: number;
readonly worldSize: number;
readonly center: LngLat;
readonly zoom: number;
}): LngLat {
// Apply map bearing to the panning vector
const rotatedPanDelta = panDelta.rotate(-tr.angle);
const rotatedPanDelta = panDelta.rotate(tr.bearingInRadians);
// Compute what the current zoom would be if the transform center would be moved to latitude 0.
const normalizedGlobeZoom = tr.zoom + getZoomAdjustment(tr.center.lat, 0);
// Note: we divide longitude speed by planet width at the given latitude. But we diminish this effect when the globe is zoomed out a lot.
Expand Down
22 changes: 12 additions & 10 deletions src/geo/projection/mercator_camera_helper.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import Point from '@mapbox/point-geometry';
import {LngLat, LngLatLike} from '../lng_lat';
import {IReadonlyTransform, ITransform} from '../transform_interface';
import {cameraBoundsWarning, CameraForBoxAndBearingHandlerResult, EaseToHandlerResult, EaseToHandlerOptions, FlyToHandlerResult, FlyToHandlerOptions, ICameraHelper, MapControlsDeltas} from './camera_helper';
import {cameraBoundsWarning, CameraForBoxAndBearingHandlerResult, EaseToHandlerResult, EaseToHandlerOptions, FlyToHandlerResult, FlyToHandlerOptions, ICameraHelper, MapControlsDeltas, updateRotation} from './camera_helper';
import {CameraForBoundsOptions} from '../../ui/camera';
import {PaddingOptions} from '../edge_insets';
import {LngLatBounds} from '../lng_lat_bounds';
import {normalizeCenter, scaleZoom, zoomScale} from '../transform_helper';
import {degreesToRadians} from '../../util/util';
import {degreesToRadians, rollPitchBearingToQuat} from '../../util/util';
import {projectToWorldCoordinates, unprojectFromWorldCoordinates} from './mercator_utils';
import {interpolates} from '@maplibre/maplibre-gl-style-spec';
import {quat} from 'gl-matrix';

/**
* @internal
Expand All @@ -26,9 +27,10 @@ export class MercatorCameraHelper implements ICameraHelper {
};
}

handleMapControlsPitchBearingZoom(deltas: MapControlsDeltas, tr: ITransform): void {
handleMapControlsRollPitchBearingZoom(deltas: MapControlsDeltas, tr: ITransform): void {
if (deltas.bearingDelta) tr.setBearing(tr.bearing + deltas.bearingDelta);
if (deltas.pitchDelta) tr.setPitch(tr.pitch + deltas.pitchDelta);
if (deltas.rollDelta) tr.setRoll(tr.roll + deltas.rollDelta);
if (deltas.zoomDelta) tr.setZoom(tr.zoom + deltas.zoomDelta);
}

Expand Down Expand Up @@ -119,9 +121,12 @@ export class MercatorCameraHelper implements ICameraHelper {

handleEaseTo(tr: ITransform, options: EaseToHandlerOptions): EaseToHandlerResult {
const startZoom = tr.zoom;
const startBearing = tr.bearing;
const startPitch = tr.pitch;
const startPadding = tr.padding;
const startRotation = rollPitchBearingToQuat(tr.roll, tr.pitch, tr.bearing);
const endRoll = options.roll === undefined ? tr.roll : options.roll;
const endPitch = options.pitch === undefined ? tr.pitch : options.pitch;
const endBearing = options.bearing === undefined ? tr.bearing : options.bearing;
const endRotation = rollPitchBearingToQuat(endRoll, endPitch, endBearing);

const optionsZoom = typeof options.zoom !== 'undefined';

Expand Down Expand Up @@ -149,11 +154,8 @@ export class MercatorCameraHelper implements ICameraHelper {
if (isZooming) {
tr.setZoom(interpolates.number(startZoom, endZoom, k));
}
if (startBearing !== options.bearing) {
tr.setBearing(interpolates.number(startBearing, options.bearing, k));
}
if (startPitch !== options.pitch) {
tr.setPitch(interpolates.number(startPitch, options.pitch, k));
if (!quat.equals(startRotation, endRotation)) {
updateRotation(startRotation, endRotation, {roll: endRoll, pitch: endPitch, bearing: endBearing}, tr, k);
}
if (doPadding) {
tr.interpolatePadding(startPadding, options.padding, k);
Expand Down
13 changes: 12 additions & 1 deletion src/geo/projection/mercator_transform.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('transform', () => {
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1], 6);
expect([...transform.modelViewProjectionMatrix.values()]).toEqual([3, 0, 0, 0, 0, -2.954423259036624, -0.1780177690666898, -0.17364817766693033, 0, 0.006822967915294533, -0.013222891287479163, -0.012898324631281611, -786432, 774484.3308168967, 47414.91102496082, 46270.827886319785]);
expect([...transform.modelViewProjectionMatrix.values()]).toEqual([3, 0, 0, 0, 0, -2.954423259036624, -0.1780177690666898, -0.17364817766693033, -0, 0.006822967915294533, -0.013222891287479163, -0.012898324631281611, -786432, 774484.3308168967, 47414.91102496082, 46270.827886319785]);
expect(fixedLngLat(transform.screenPointToLocation(new Point(250, 250)))).toEqual({lng: 0, lat: 0});
expect(fixedCoord(transform.screenPointToMercatorCoordinate(new Point(250, 250)))).toEqual({x: 0.5, y: 0.5, z: 0});
expect(transform.locationToScreenPoint(new LngLat(0, 0))).toEqual({x: 250, y: 250});
Expand Down Expand Up @@ -83,6 +83,17 @@ describe('transform', () => {
expect(fixedLngLat(transform.screenPointToLocation(new Point(15, 45)))).toEqual({lng: 13, lat: 10});
});

test('setLocationAt tilted rolled', () => {
const transform = new MercatorTransform(0, 22, 0, 60, true);
transform.resize(500, 500);
transform.setZoom(4);
transform.setPitch(50);
transform.setRoll(50);
expect(transform.center).toEqual({lng: 0, lat: 0});
transform.setLocationAtPoint(new LngLat(13, 10), new Point(15, 45));
expect(fixedLngLat(transform.screenPointToLocation(new Point(15, 45)))).toEqual({lng: 13, lat: 10});
});

test('has a default zoom', () => {
const transform = new MercatorTransform(0, 22, 0, 60, true);
transform.resize(500, 500);
Expand Down
Loading

0 comments on commit 86ed382

Please sign in to comment.