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

Add API support for adjusting camera roll angle, extend pitch angle range #4717

Open
ssokol opened this issue Sep 17, 2024 · 7 comments
Open
Labels
enhancement New feature or request PR is more than welcomed Extra attention is needed

Comments

@ssokol
Copy link

ssokol commented Sep 17, 2024

User Story

As a developer I can programmatically adjust the roll angle of the camera from 0 (level) to +/- 180° and I can programmatically adjust the pitch angle from 0° (looking down) to 180° (looking directly up) so that I can accurately represent the spatial orientation of the observer when displaying maps with 3D terrain.

Rationale

I am looking to use MapLibre in an aviation application to implement what is commonly know as "Synthetic Vision" - a feature which provides a virtual "view from the cockpit". To be able to accurately represent the this view, I need to be able to adjust the roll angle of the camera to match the roll angle of the airplane. You can see a similar system at a distinct roll angle here:

https://blog.foreflight.com/wp-content/uploads/2014/12/800x600-refined-terrain.png

From what I can find, the transformCameraUpdate callback currently allows programmatic control of bearing, center, elevation, pitch, and zoom (with pitch limited to 0° - 60°). Perhaps this could be extended to include the roll parameter and to accept pitch values from 0 (straight down) to 180 (straight up).

It might also be useful to allow for all of these parameter to be incorporated into the parameter objects for map.flyTo() and map.easeTo(). The way the Synthetic Vision app works, a server feeds situation data (location, altitude, track, speed, etc.) over a WebSocket at between 10-20 Hz. The handler for the WebSocket moves the camera using a string of very short duration flyTo or easeTo operations. Adding the ability to update situational parameters directly would simplify the process.

Impact

This won't have any real impact on users who only need a basic down-and-forward level view, but it will go a long way towards making MapLibre more useful for certain simulations, games, and situational awareness applications.

@HarelM
Copy link
Collaborator

HarelM commented Sep 17, 2024

Thanks for taking the time to open this issue.
In general, I think this can be a nice (although niche) addition to this lib.
The main caveat I can think of is which tile to fetch and show.
But feel free to push this forward.

@HarelM HarelM added enhancement New feature or request PR is more than welcomed Extra attention is needed labels Sep 17, 2024
@ssokol
Copy link
Author

ssokol commented Sep 18, 2024

Thanks!

I'm slowly making my way through the library - long time Javascript user, first time Typescript user. I hope to be able to submit a PR, but it will probably need some help from those more fluent in the language. One question for you...

I haven't been able to find a way to manually set the camera altitude in feet or meters above median sea level. I kind of expected the easeTo and flyTo functions to have an altitude parameter, indicating the camera altitude at the end of the move.

Is there an API call to set the camera altitude independent of the zoom level? I see references to altitude in the camera.ts and map.ts files, but the altitude seems to be an output based on the current zoom level rather than something that can be preset programmatically.

@HarelM
Copy link
Collaborator

HarelM commented Sep 18, 2024

Zoom level is highly tide to altitude, it has deep historic roots and causes a lot of grief with terrain related stuff.
You can use cameraFromTo I believe to calculate some stuff, IIRC.

@ssokol
Copy link
Author

ssokol commented Sep 18, 2024

Thanks. I'll look into that. I was just reading over the discussion of deterministic values on #4688 and it seems like the camera controls and associated motion methods may have come from the purely 2D world, where 'zoom' makes far more sense than 'altitude', and where pitch simply isn't a concept.

In testing some ideas I've discovered that the "center" parameter has very different meanings depending on if there is a pitch angle set. With a zero pitch (essentially a 2D map), center places the camera exactly where I expect it to. With a pitch value set, the lib appears to set the "gaze" or "focal point" of the camera at the "center" location, rather than the camera itself. Probably useful for some things, but challenging to use for a PoV application.

I wonder if 3D / terrain apps might be better off with a different camera control model. This would make center, altitude, bearing, pitch, and roll fixed and deterministic - these position the camera. The "gaze" or "focal point" is then determined by the zoom level (and optionally some additional parameters if needed). For my app, zoom will be constant throughout since it emulates what a human would see looking out the front window of an airplane.

Do you think there might be interest in a large bounty (perhaps funded by several participants) for a project that builds out a more 3D-centric "mode" or set of APIs?

@HarelM
Copy link
Collaborator

HarelM commented Sep 19, 2024

I don't have a good answer to the question about if there is an interest, and if someone would like to pay for it.
One thing to note is that one can switch from 2D to 3D and the expectation is to be at the same "position", so a concept where center means different things in respect to terrain may be problematic.
API-wise, I think Cesium has implemented something with unreal engine that allows looking from the ground up, might be interesting to look at what they did.
The concept of zoom is very much coupled to level of details (vector rendering) so that needs to be taken into account as well...

@ssokol
Copy link
Author

ssokol commented Sep 19, 2024

My company would be willing to pay a bounty for a set of enhancements that make the 3D behavior meet my our case. I can see if anyone else in my industry is interested in participating.

On the center issue.... Is the current behavior (that center = focal point) intentional, inadvertent but accepted, or erroneous?

From what I can tell, giving the map a pitch angle and a center value positions the camera such that it is "looking at" the center rather than being positioned directly on the center. The actual camera position appears to be determined by some combination of the zoom value and the pitch angle.

If that's a behavior other users rely on, I wouldn't want to break it but would suggest creating a new cameraPoint parameter which is deterministic. If you set the cameraPoint, the lib calculates the focal point based on pitch and zoom. If you set the center, the lib uses the current behavior and determines the camera placement based on the center, pitch, and zoom.

Does that sound reasonable, or would it be better to change center control camera placement?

@HarelM
Copy link
Collaborator

HarelM commented Sep 20, 2024

Regarding the bounty, I would suggest to advertise it in our slack channel, as not many people follow the github issues.
In order to avoid breaking changes a parameter can be added to the map initialization to define a different camera behavior, something like immersive: true or something similar, once this is set thing will behave differently.
I think @cigone-openindoor had similar requirements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request PR is more than welcomed Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants