Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Facilitate for globe transition expression refactoring #5139

Merged
merged 20 commits into from
Dec 12, 2024

Conversation

HarelM
Copy link
Collaborator

@HarelM HarelM commented Dec 1, 2024

Launch Checklist

This is a draft PR at this point to see what still need to be fixed and for others to see.
CC: @birkskyum @ibesora @kubapelc

The idea behind this refactoring:

  1. Move all logic that is common for vertical-perspective and mercator to the transform helper.
  2. Create a new class to hold all the logic of transitioning while relaying on the two transforms to do their part when called.
  3. Remove the events and define the default expression for globe
  • Confirm your changes do not include backports from Mapbox projects (unless with compliant license) - if you are not sure about this, please ask!

Copy link

codecov bot commented Dec 1, 2024

Codecov Report

Attention: Patch coverage is 85.88020% with 231 lines in your changes missing coverage. Please review.

Project coverage is 91.82%. Comparing base (9ca3f20) to head (1703870).
Report is 4 commits behind head on main.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...c/geo/projection/vertical_perspective_transform.ts 85.41% 104 Missing ⚠️
...o/projection/vertical_perspective_camera_helper.ts 73.63% 82 Missing ⚠️
src/geo/projection/globe_projection.ts 89.38% 12 Missing ⚠️
src/geo/projection/projection_factory.ts 71.87% 9 Missing ⚠️
src/geo/projection/globe_transform.ts 93.69% 7 Missing ⚠️
src/geo/transform_helper.ts 94.54% 6 Missing ⚠️
src/geo/projection/camera_helper.ts 94.00% 3 Missing ⚠️
src/geo/projection/globe_camera_helper.ts 86.36% 3 Missing ⚠️
.../geo/projection/vertical_perspective_projection.ts 88.46% 3 Missing ⚠️
src/geo/projection/mercator_transform.ts 97.56% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5139      +/-   ##
==========================================
- Coverage   91.84%   91.82%   -0.03%     
==========================================
  Files         278      281       +3     
  Lines       38336    38776     +440     
  Branches     6714     6756      +42     
==========================================
+ Hits        35211    35605     +394     
- Misses       2996     3043      +47     
+ Partials      129      128       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@birkskyum
Copy link
Member

birkskyum commented Dec 1, 2024

I think this looks like the right direction, with the globe transform (being a mercator<->verticalPerspective lerp) to contain a mercatorTransform and now also a verticalPerspectiveTransform, and call into those, instead of having too much logic of it's own.

@HarelM

This comment was marked as outdated.

@HarelM HarelM mentioned this pull request Dec 1, 2024
8 tasks
@HarelM
Copy link
Collaborator Author

HarelM commented Dec 1, 2024

Surprisingly I think I managed to find what created the issues in the branch after trying to recreate it in another branch...
I'll see if I can fix the remaining failing unit test, but otherwise this might be ready for review.
@kubapelc I found strange behavior in the getProjectionData and getProjectionDataForCustomLayer - both methods don't really follow the "if globe do that otherwise do what we did in mercator".
Last two commits are basically reverting the logic there, but I still find it odd.
Any chance you can take a look and let me know if there are improvements that can be done?

@kubapelc
Copy link
Collaborator

kubapelc commented Dec 2, 2024

The new getProjectionData on globe transform look good to me! As for getProjectionDataForCustomLayer it is somewhat broken in main right now, I'm fixing it to resolve #5117. But I have some render tests failing after the fix, and I haven't figured it out yet.

@HarelM
Copy link
Collaborator Author

HarelM commented Dec 2, 2024

I think you can simply fix it by opening a PR to this branch, it would be better to avoid the need for me to resolve conflicts.
Is it possible to get a fallbackMatrix without the code from mercator transform? Or should I move part of the code from mercator transfrom to the helper to calculate the fallbackMatrix in case of globe/vertical-perspective?
There is also the same question for prefetchTiles and a few more other places where I couldn't find a proper solution.
If you could take a look at those it would be great.
I'm also thinking about splitting the camera helper the same way I did for the globe transform, it creates a clear separation of code and is very easy to see where issues exists this way.

@kubapelc
Copy link
Collaborator

kubapelc commented Dec 2, 2024

Is it possible to get a fallbackMatrix without the code from mercator transform?

I think it makes sense to query mercator transfrom to get the fallback matrix. since it is the exact matrix which is used when mercator is active. Globe mostly needs it to do the projection transition.

There is also the same question for prefetchTiles and a few more other places where I couldn't find a proper solution.

I think precacheTiles is ok in its current state, since there is no equivalent for globe transform. Mercator needs to compute a separate matrix for each tile, globe does not. (But I'm honestly not sure this precaching step even helps performance, I think maplibre did do it originally, but it was a side effect of some other function which was obsoleted and removed by the globe changes, iirc., and so I left it in.)

I'll go over all the mercator transform usages.

I'm also thinking about splitting the camera helper the same way I did for the globe transform

Sounds good!

@kubapelc
Copy link
Collaborator

kubapelc commented Dec 2, 2024

I went over all mercator transform usages in the current globe_transform.ts, everything looks good, I only added a comment about the removed double interpolation.

Copy link
Collaborator

@ibesora ibesora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like where this is going, nice work!
Added some comments but feel free to ignore them (except for the typo ones!)

src/geo/projection/globe_transform.ts Outdated Show resolved Hide resolved
src/geo/projection/globe_transform.ts Outdated Show resolved Hide resolved
src/geo/projection/globe_transform.ts Outdated Show resolved Hide resolved
src/geo/projection/globe_transform.ts Outdated Show resolved Hide resolved
src/geo/projection/vertical_perspective_transform.ts Outdated Show resolved Hide resolved
@HarelM
Copy link
Collaborator Author

HarelM commented Dec 2, 2024

@kubapelc I'm looking into leveraging the following code to calculate the current globeness:

type ProjectionProps = {
    type: DataConstantProperty<ProjectionDefinition>;
}

type ProjectionPossiblyEvaluated = {
    type: ProjectionDefinitionSpecification;
}

const properties: Properties<ProjectionProps> = new Properties({
    'type': new DataConstantProperty(styleSpec.projection.type as StylePropertySpecification)
});

export class ProjectionTransition extends Evented {
    properties: PossiblyEvaluated<ProjectionProps, ProjectionPossiblyEvaluated>;

    _transitionable: Transitionable<ProjectionProps>;
    _transitioning: Transitioning<ProjectionProps>;

    constructor(projection?: ProjectionSpecification) {
        super();
        this._transitionable = new Transitionable(properties);
        this.setProjection(projection);
        this._transitioning = this._transitionable.untransitioned();
        this.recalculate(new EvaluationParameters(0));
    }

    setProjection(projection?: ProjectionSpecification) {
        this._transitionable.setValue('type', projection.type);
    }

    updateTransitions(parameters: TransitionParameters) {
        this._transitioning = this._transitionable.transitioned(parameters, this._transitioning);
    }

    hasTransition() {
        return this._transitioning.hasTransition();
    }

    recalculate(parameters: EvaluationParameters) {
        this.properties = this._transitioning.possiblyEvaluate(parameters);
    }
}

//... usage:
new ProjectionTransition({
    type: ["interpolate", ["linear"], ["zoom"],
    10, "vertical-perspective", 12, "mercator"]
});

This leverages maplibre's expression evaluation capabilities and it looks like it is working as expected, and also removes the code related to animation and time tracking. I do see code related to updating the zoom and center when the globeness is not equal, can you elaborate on what it does?

@kubapelc
Copy link
Collaborator

kubapelc commented Dec 3, 2024

I do see code related to updating the zoom and center when the globeness is not equal, can you elaborate on what it does?

See #5139 (comment)

We need to somehow smoothly move globe's map center to match mercator, it is not clear how now that the transition is controlled by an arbitrary expression.

Maybe we can interpolate the center towards mercator every time that globeness decresases compared to the last update, and do nothing if it increases? This would make zooming in smoothly interpolate the center, and zooming out would not affect it.

@HarelM
Copy link
Collaborator Author

HarelM commented Dec 3, 2024

I'll create a PR against this branch with the changes related to the globeness calculations outside the transform class so we can discuss the changes.
@ibesora @kubapelc I've left the comments above unresolved, let me know if you want me to close them as resolved or if you prefer to do it so I'd know which comments I still need to address.

* This refactors the projection class only, without touching other parts of the code.

* remove mercator from the code, revert more changes
…d mercator (#5162)

* Refactor camera helper

* Use the helper in the factory.

* Fix build test

* Fix according to code review
@HarelM HarelM mentioned this pull request Dec 9, 2024
15 tasks
HarelM and others added 2 commits December 11, 2024 11:54
#5164)

* Remove duplicate code

* Fix lint, add some methods for original branch

* Add projection definition in factory

* Add has transition to projection

* Fix transition value

* Remove isRenderingDirty and use hasTransition when needed

* Remove the last part of the animation handling in the transform class

* More clean-up

* Remove some "TODO"s.

* Remove reference to globe projection in globe transform

* Rename newFrame with recalculateCache

* Remove unneeded ifs

* Add support for arbitrary projection definitions

* Uses mercator matrix when globe is using mercator transform

* Improve handling of fog martix in globe transform

---------

Co-authored-by: Isaac Besora Vilardaga <[email protected]>
@HarelM HarelM marked this pull request as ready for review December 11, 2024 09:55
@HarelM
Copy link
Collaborator Author

HarelM commented Dec 11, 2024

This is now ready for review and afterwards merged to main branch.
This is almost the last change related to version 5, so after this is merged we can release version 5 (there will be other bug fixes afterwards, but no breaking changes).

kubapelc and others added 2 commits December 11, 2024 16:53
* Simplify custom layer ProjectionData code in mercator transform

* Fix globe tiles example

* Fix globe projection shader

* Add custom layer 3D model after globe->mercator transition render test

* Fix custom layer 3D models not rendering when globe transitions to mercator

* Move camera to center distance to helper

# Conflicts:
#	src/geo/projection/globe_transform.ts
#	src/geo/projection/mercator_transform.ts
#	src/geo/transform_helper.ts
#	src/geo/transform_interface.ts

* Synchronize globe+mercator near and far Z to prevent 3D model disappearing during projection transition

* Expose getProjectionData and getMatrixForModel for custom layers, don't use internal API in examples

* VerticalPerspectiveTransform should have a valid getProjectionDataForCustomLayer implementation

* Add changelog entry

* Fix missing docs

* Fix docs again

* Review feedback

* Move nearZfarZoverride to transform helper

* Update build size

* Review feedback

* Change near/far Z override API

* Custom layers use internal API

* Fix globe custom tiles example

* Update build size

* Fix typo

---------

Co-authored-by: HarelM <[email protected]>
@HarelM
Copy link
Collaborator Author

HarelM commented Dec 12, 2024

@Pessimistress I was about to completely remove the event of projection change here as the only place after these code change that this event is fired is when setting the projection, which is a programmatic operation, and raising an event for something you called seems weird to me...
Please let me know what event would help and when to raise it.
I'll be merging this branch shortly.

@HarelM HarelM enabled auto-merge (squash) December 12, 2024 09:51
@HarelM HarelM merged commit 551ba95 into main Dec 12, 2024
15 of 17 checks passed
@HarelM HarelM deleted the projection-expression branch December 12, 2024 10:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants