OSMeta icon indicating copy to clipboard operation
OSMeta copied to clipboard

Functions to calculate between Geo- and GPU coordinates

Open DerKarlos opened this issue 2 years ago • 2 comments

If and as we now use an Earth sphere, we can't just use the GPU coordinates or the camera Transform to for orientation relative to the map. For our development and for future users we should add some helper functions.

Examples:

  • The camera speed should depend on the height above the ground (the Earth-Sphere surface). How to get the height?
  • A tile should be loaded first if it is in the same direction as the camera (player) looks. How to get the direction?
  • A new "thing" should be added at a lat/lon/elevate place on the map. How to get the GPU Transform?

We may have functions like camera.get_local_transform / .get_earth_rotation / .get_map_position (names to be discussed) The position in meter relativ to the start position of the scene or the center of the first loaded tile. (Terrain rendering is to be considered if implemented) The functions may get added to our existing "classes" like GeoPos.

DerKarlos avatar Nov 30 '23 19:11 DerKarlos

The camera speed should depend on the height above the ground (the Earth-Sphere surface). How to get the height?

a bevy system for changing the speed depending on the height:

fn update_camera_speed(
    mut movement_settings: ResMut<MovementSettings>,
    fly_cam: Query<&Transform, (With<FlyCam>, Without<TileMap>)>,
    tilemap: Query<&Transform, (With<TileMap>, Without<FlyCam>)>,
) {
    movement_settings.speed =
        3.5 * (fly_cam.single().translation.distance(tilemap.single().translation) - EARTH_RADIUS) + 100.0
}

You can change the 3.5 to change how much the height affects the speed (or even switch to something entirely different like an exponential formula

A tile should be loaded first if it is in the same direction as the camera (player) looks. How to get the direction?

in load_next_tile you can use flycam_pos.single().forward() to get a vector in the direction the camera is looking.

A new "thing" should be added at a lat/lon/elevate place on the map. How to get the GPU Transform?

GeoPos { lat: 49.0, lon: 9.0 }.to_cartesian() gives you the coordinates on the surface of the earth. We can change to_cartesian to accept any elevation.

In order for the thing to actually show up in the right place, it needs to be made a child of the TileMap. I will fix this soon, so that we can just use global world coordinates by making the earth sphere be centered at 0,0,0

oli-obk avatar Dec 01 '23 01:12 oli-obk

update_camera_speed works great. The calculation is understandable, if you know the concept of the Earth sphere. In the flat solution, one could just use the camera position. We should offer functions, so the user must not consider the sphere math. A way to get the camera translation relative to Earth and the start point.

The direction the camera I get is a "space direction", relative to the GPU coordinates. But for a compass, We need a code to get it relative to the ... see above.

To handle things on Earth, the user should not need to think in GPU coordinates but relative ... see above. In the placing case, the user has lat/lon and elevation on the surface (already relative to ... ground) and needs to transform to get the Translation in the GPU coordinates. Again a function should be provided.


You somewhere mentioned, if the camera/player moves to far form the GPU zero point, we may need to move the map, to avoid fuzzy GPU calculations. When you startet with the Earth, I assumed, you place the Earth "below" the player and instead of shifting the map we would rotate the Earth. In this case, the user scene nearby would have the same coordinates for programming as the GPU coordinates. Now you intent do place the Earth center to GPU zero. Will that work with the large numbers? If yes, we get different coordinate systems and should provide functions transform/calculate between both.

DerKarlos avatar Dec 01 '23 18:12 DerKarlos