CesiumGS / cesium-unity

Bringing the 3D geospatial ecosystem to Unity
https://cesium.com/platform/cesium-for-unity/
Apache License 2.0
347 stars 83 forks source link

CesiumFlyToComponent "jumps" at the end due to spherical math that doesn't quite work on an ellipsoid #390

Closed kring closed 7 months ago

kring commented 8 months ago

Copied from CesiumGS/cesium-unreal#1332.

Here's a diagram to try to illustrate the problem:

image

The blue oval is a highly exaggerated ellipsoidal model of the Earth. To do a flight between the start and end points marked, CesiumFlyToController first computes a rotation axis and angle between those two points. At each step, it interpolates the angle and rotates the initial direction by that angle to produce the direction of the path at this step. It then scales this direction to the ellipsoid surface and adds a separately-computed height to it to get the actual position for the flight.

The problem, as shown in the diagram, is that scaling the final direction to the ellipsoid and then adding the final position's height does not actually result in the final position. It would on a sphere, but not on an ellipsoid. It's our old friend geocentric versus geodetic angles.

As a result, flights often appear to jump to a new position just as they complete, because the final position along the curve is quite different from the real final position. I originally wrote this issue for Cesium for Unreal, which has the same bug. In Unreal, this can be seen quite obviously by opening the Google Photorealistic 3D Tiles level in Cesium for Unreal Samples, hitting Play-In-Editor, pressing 3 to fly to Tokyo, then moving the camera a good distance up and away from Tokyo before pressing 3 to fly toward it again. When the intial position of the camera is fairly high, the jump at the end should be very obvious. It may be less obvious in Unity because we generate keypoints and then interpolate over them. So the "jump" will happen between the second-to-last and last keypoints rather than very suddenly at the end.

j9liu commented 8 months ago

Note the fix for this issue in the Unreal plugin: https://github.com/CesiumGS/cesium-unreal/pull/1333. Would be nice to eventually move CesiumFlyToComponent logic to cesium-native to avoid the duplication :)