-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[core] Asymmetric viewport when edge insets are specified #14664
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
core LGTM
@fabian-guerra @d-prukop would you mind looking at this from the SDKs' POV please? |
@fabian-guerra , @d-prukop, @frederoni The issue #14362 explains the problem well; user specify camera parameters, but because there is content inset, camera values that user reads back are not the same as specified (inset moves center). I put focus on honouring existing SDK documentation and contracts and find that the code is in line with it. Render tests pass :) However, I "might" have stretched the interpretation of the documentation. Please comment:
It doesn't say center of screen and edge insets documentation further confirms it:
This is how I interpreted terms map, map view and map view's frame: I wouldn't use both camera |
Right, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for fixing this. I added some nits and a question. Also could you please add an entry in the changelogs.
@tobrun, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a minor blurb change. LGTM.
4e6cd24
to
7a9ce6c
Compare
re #14664 (comment), looks great @astojilj! |
The change is implemented in TransformState::getProjMatrix, the rest of the code is making sure that existing API contracts stay and there are tests verifyingrendering and render query processing only items within screen and given tolerance around screen edges. MapView: don't bake edge insets into relalculated camera center. Keep edge insets as property of camera in TransformState (similar to pitch, zoom, bearing) independent from specified camera center. Interpolate edge insets in animation. iOS Demo app: "Turn On/Off Content Insets" pitch the camera and navigate to convenient location in Denver, where streets are parallel to cardinal directions, to illustrate viewport center offset when edge insets are set. Tests: ViewFrustumCulling: although Annotations are deprecated, queryRenderedFeatures related tests in Annotations would need to get ported and decided to add the edge insets related query tests next to them. Verify frustum culling (render+queryRenderedFeatures) With different camera and edge insets setups. TODO: port Annotations tests. Transform.Padding: Verify that coordinates take proper place on screen after applying edge insets. LocalGlyphRasterizer: verify text rendering when applying padding. Related to #11882: both use projection matrix elements [8] and [9]. Alternative approach to this was to increase and offset map origin so that the screen would be a sub-rectangle in larger map viewport. This approach has a drawback of unecessary processing the items that are outside screen area. Fixes #12107, #12728, navigation-sdks/issues/120
Check edge insets difference, in addition to isEqualToMapCamera in all the places in MGLMapView before map.easeTo/map.flyTo.
f3145c1
to
85f6649
Compare
Allows changing camera when user duplicates content insets. Related to previous patch and comment: #14664 (review) Thanks @1ec5
To changelog: Fixed incorrect center coordinate after pinch regression caused by edge insets fix (#14664). While working on #14664, missed to understand the logic used in ``` CLLocationCoordinate2D centerCoordinate = _previousPinchCenterCoordinate; mbgl::EdgeInsets padding { centerPoint.y, centerPoint.x, self.size.height - centerPoint.y, self.size.width - centerPoint.x }; self.mbglMap.jumpTo(mbgl::CameraOptions() .withCenter(MGLLatLngFromLocationCoordinate2D(centerCoordinate)) .withPadding(padding)); ``` Replacing this code by moveBy achieves the required translation. Fixes: #14977, #15082
To changelog: Fixed incorrect center coordinate after pinch regression caused by edge insets fix (#14664). While working on #14664, missed to understand the logic used in ``` CLLocationCoordinate2D centerCoordinate = _previousPinchCenterCoordinate; mbgl::EdgeInsets padding { centerPoint.y, centerPoint.x, self.size.height - centerPoint.y, self.size.width - centerPoint.x }; self.mbglMap.jumpTo(mbgl::CameraOptions() .withCenter(MGLLatLngFromLocationCoordinate2D(centerCoordinate)) .withPadding(padding)); ``` Replacing this code by moveBy achieves the required translation. Fixes: #14977, #15082
To changelog: Fixed incorrect center coordinate after pinch regression caused by edge insets fix (#14664). While working on #14664, missed to understand the logic used in ``` CLLocationCoordinate2D centerCoordinate = _previousPinchCenterCoordinate; mbgl::EdgeInsets padding { centerPoint.y, centerPoint.x, self.size.height - centerPoint.y, self.size.width - centerPoint.x }; self.mbglMap.jumpTo(mbgl::CameraOptions() .withCenter(MGLLatLngFromLocationCoordinate2D(centerCoordinate)) .withPadding(padding)); ``` Replacing this code by moveBy achieves the required translation. Fixes: #14977, #15082
Viewport center offset usage was wrongly submitted in #14664. It was part of alternative approach that used enlarged viewport. Existing and added tests were not sufficient to spot the regression, since the collision check padding is usually larger than the center offset x and y. Annotation picking has tolerance of only 10 pixels but no annotation integration test was using content insets. Usage of offset is not needed because `posMatrix` in e.g. `CollisionIndex::projectPoint(const mat4& posMatrix, const Point<float>& point)` already incorporates center offset (projection matrix) and the code in current master was just offsetting all by the value. Modified [ios] MGLAnnotationViewIntegrationTests.testSelectingAnnotationWithCenterOffset to use different insets. It verifies the fix. Fixes [iOS] Annotations are not selectable (added via iosapp menu) #15106: In case of #15106, view's original content insets is {top:88, bottom:34}, causing that center offset is {x:0, y:27} and selection with tolerance of 10 wouldn't select annotation. After tapping the view, so that the header gets removed, view's content insets get changed to {top:44, bottom:34}, center offset is {x:0, y:5} and annotation selection would work, as described in #15106. Fixes: #15106
Viewport center offset usage was wrongly submitted in #14664. It was part of alternative approach that used enlarged viewport. Existing and added tests were not sufficient to spot the regression, since the collision check padding is usually larger than the center offset x and y. Annotation picking has tolerance of only 10 pixels but no annotation integration test was using content insets. Usage of offset is not needed because `posMatrix` in e.g. `CollisionIndex::projectPoint(const mat4& posMatrix, const Point<float>& point)` already incorporates center offset (projection matrix) and the code in current master was just offsetting all by the value. Modified [ios] MGLAnnotationViewIntegrationTests.testSelectingAnnotationWithCenterOffset to use different insets. It verifies the fix. Fixes [iOS] Annotations are not selectable (added via iosapp menu) #15106: In case of #15106, view's original content insets is {top:88, bottom:34}, causing that center offset is {x:0, y:27} and selection with tolerance of 10 wouldn't select annotation. After tapping the view, so that the header gets removed, view's content insets get changed to {top:44, bottom:34}, center offset is {x:0, y:5} and annotation selection would work, as described in #15106. Fixes: #15106
To changelog: Fixed incorrect center coordinate after pinch regression caused by edge insets fix (#14664). While working on #14664, missed to understand the logic used in ``` CLLocationCoordinate2D centerCoordinate = _previousPinchCenterCoordinate; mbgl::EdgeInsets padding { centerPoint.y, centerPoint.x, self.size.height - centerPoint.y, self.size.width - centerPoint.x }; self.mbglMap.jumpTo(mbgl::CameraOptions() .withCenter(MGLLatLngFromLocationCoordinate2D(centerCoordinate)) .withPadding(padding)); ``` Replacing this code by moveBy achieves the required translation. Fixes: #14977, #15082
Viewport center offset usage was wrongly submitted in #14664. It was part of alternative approach that used enlarged viewport. Existing and added tests were not sufficient to spot the regression, since the collision check padding is usually larger than the center offset x and y. Annotation picking has tolerance of only 10 pixels but no annotation integration test was using content insets. Usage of offset is not needed because `posMatrix` in e.g. `CollisionIndex::projectPoint(const mat4& posMatrix, const Point<float>& point)` already incorporates center offset (projection matrix) and the code in current master was just offsetting all by the value. Modified [ios] MGLAnnotationViewIntegrationTests.testSelectingAnnotationWithCenterOffset to use different insets. It verifies the fix. Fixes [iOS] Annotations are not selectable (added via iosapp menu) #15106: In case of #15106, view's original content insets is {top:88, bottom:34}, causing that center offset is {x:0, y:27} and selection with tolerance of 10 wouldn't select annotation. After tapping the view, so that the header gets removed, view's content insets get changed to {top:44, bottom:34}, center offset is {x:0, y:5} and annotation selection would work, as described in #15106. Fixes: #15106
To changelog: Fixed incorrect center coordinate after pinch regression caused by edge insets fix (#14664). While working on #14664, missed to understand the logic used in ``` CLLocationCoordinate2D centerCoordinate = _previousPinchCenterCoordinate; mbgl::EdgeInsets padding { centerPoint.y, centerPoint.x, self.size.height - centerPoint.y, self.size.width - centerPoint.x }; self.mbglMap.jumpTo(mbgl::CameraOptions() .withCenter(MGLLatLngFromLocationCoordinate2D(centerCoordinate)) .withPadding(padding)); ``` Replacing this code by moveBy achieves the required translation. Fixes: #14977, #15082
Viewport center offset usage was wrongly submitted in #14664. It was part of alternative approach that used enlarged viewport. Existing and added tests were not sufficient to spot the regression, since the collision check padding is usually larger than the center offset x and y. Annotation picking has tolerance of only 10 pixels but no annotation integration test was using content insets. Usage of offset is not needed because `posMatrix` in e.g. `CollisionIndex::projectPoint(const mat4& posMatrix, const Point<float>& point)` already incorporates center offset (projection matrix) and the code in current master was just offsetting all by the value. Modified [ios] MGLAnnotationViewIntegrationTests.testSelectingAnnotationWithCenterOffset to use different insets. It verifies the fix. Fixes [iOS] Annotations are not selectable (added via iosapp menu) #15106: In case of #15106, view's original content insets is {top:88, bottom:34}, causing that center offset is {x:0, y:27} and selection with tolerance of 10 wouldn't select annotation. After tapping the view, so that the header gets removed, view's content insets get changed to {top:44, bottom:34}, center offset is {x:0, y:5} and annotation selection would work, as described in #15106. Fixes: #15106
Decouple dependency content insets -> anchor point -> padding/content insets broken after mapbox/mapbox-gl-native#14664 introduced animated interpolation for padding change. Remove the need to specify center for puck view - use the approach where content inset is keeping it centered. Take safeArea into account when calculating contentInsets. Addresses: mapbox/mapbox-gl-native#15232, mapbox/mapbox-gl-native#15233 Related to: #2165, Fixes: #2145
Decouple dependency content insets -> anchor point -> padding/content insets broken after mapbox/mapbox-gl-native#14664 introduced animated interpolation for padding change. Remove the need to specify center for puck view - use the approach where content inset is keeping it centered. Take safeArea into account when calculating contentInsets. Addresses: mapbox/mapbox-gl-native#15232, mapbox/mapbox-gl-native#15233 Related to: #2165, Fixes: #2145
Decouple dependency content insets -> anchor point -> padding/content insets broken after mapbox/mapbox-gl-native#14664 introduced animated interpolation for padding change. Remove the need to specify center for puck view - use the approach where content inset is keeping it centered. Take safeArea into account when calculating contentInsets. Addresses: mapbox/mapbox-gl-native#15232, mapbox/mapbox-gl-native#15233 Related to: #2165, Fixes: #2145
The change is implemented in TransformState::getProjMatrix, the rest of the code is making sure that existing API contracts stay and there are tests verifyingrendering and render query processing only items within screen and given tolerance around screen edges.
MapView: don't bake edge insets into relalculated camera center. Keep edge insets as property of camera in TransformState (similar to pitch, zoom, bearing) independent from specified camera center. Interpolate edge insets in animation.
iOS Demo app: "Turn On/Off Content Insets" pitch the camera and navigate to convenient location in Denver, where streets are parallel to cardinal directions, to illustrate viewport center offset when edge insets are set.
Tests:
ViewFrustumCulling: although Annotations are deprecated, queryRenderedFeatures related tests in Annotations would need to get ported and decided to add the edge insets related query tests next to them. Verify frustum culling (render+queryRenderedFeatures) With different camera and edge insets setups. TODO: port Annotations tests.
Transform.Padding: Verify that coordinates take proper place on screen after applying edge insets.
LocalGlyphRasterizer: verify text rendering when applying padding.
Related to #11882: both use projection matrix elements [8] and [9].
Alternative approach to this was to increase and offset map origin so that the screen would be a sub-rectangle in larger map viewport. This approach has a drawback of unecessary processing the items that are outside screen area.
Addreses: mapbox/mapbox-navigation-ios#1845
Fixes: #12728, #12107, https://github.com/mapbox/navigation-sdks/issues/120, #14362
Example1: Turn on/off content half-width left edge inset in horizontal mode. Two finger rotate at the end.
![Image](https://user-images.githubusercontent.com/549216/57699623-cffe5380-7660-11e9-8df3-7f0481a5ee91.gif)
Example2: quarter-height top and quarter width right edge insets.
![Image](https://user-images.githubusercontent.com/549216/57699648-e0163300-7660-11e9-9221-7bc79ced9082.gif)