Preserve camera orientation when flying to bouding sphere

1. A concise explanation of the problem you're experiencing.

When using the camera flyToBoundingSphere method, it seems that the camera pitch is slightly updated even if it was provided as is in the offset argument.

2. A minimal code example. If you've found a bug, this helps us reproduce and repair it.

An example can be found here : https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/#c=fVNRb9owEP4rJ14IkufAWmlVStFU2mmTNq0q1Z7yYpILWDM+ZDt0bOK/z44NhE5annx3/u6+78t5JwzsJL6igTvQ+ApztLLd8B9dLhtWXTgn7YTUaIaj21KXeudRW7LSSdITD0yguTDOn4S+4o2hzQOuDKLN3jO4vmEwGfvvjEftpNsHdJzPu4REy0VdZ39KDf7bktSugBR1GfkL1UL+xgImN+ycr0iRKU5MQsSfHx/ihQM7toucizP7Uh/OnCqxQSPOlGLsy/HALbpgzJFdjdZJLWLH/3tw5T34kDwYjxIdMtKLTviexjWKWupVAWPWF+6qdQHv4Jtwa/70BXK47pUNKVUkATwESflJX9PqKkyCRu1f6LFzPxsdx1akLSnkilZZatINDNhQD+4sqdWB12K7RoOX+3J/UctO9jIY91sYoVcBGX1IhTSv4/Wmz+VI1jepbk1yru8SNY3/SUWf2ufo5lOQ8xzmHwUmmxn0BbPIcZTsC+QPwb6F0HUlrPMe+f18IVJLYe5b50hnw09qD47SSg9Z3+LR7YANptbtFc5iz49ysyXjoDUq4zx3uNkq4XcmX7bVT3S8sjZMneZH0LSWO5D1XTl48xrLAVRKWOsrTau6V1EOZtPc37+AKeqEft+hUWIfrqwns68xyTmf5j78F+Wixl7Hvw

Clicking on "Fly to entity" multiple times will move the camera. Only camera pitch is modified, camera heading remains exactly the same.

3. Context. Why do you need to do this? We might know a better way to accomplish your goal.

I would like to fly to a target (given its coordinates), without modifying the current camera orientation and altitude. We assume that target altitude is less than camera altitude.

4. The Cesium version you're using, your operating system and browser.

Reproduced with Cesium 1.51, on Windows/Fedora/MacOS, Chrome/Safari.

Thanks for providing a Sandcastle example for this. I think it might be a numerical imprecision error. You can work around it might saving camera.pitch and sending that in, instead of using camera.pitch directly which will always change slightly every time you call it.

This is strange, because there is no numerical imprecision error with the flyTo camera method.
Do you think there is an issue with the camera flyToBoundingSphere method ?

I just updated the Sandcastle example to highlight the difference: https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/#c=lZRdb9owFIb/ipUbguQ5sFZalVE0lW7apE1DpdpVbkxyAtaMjWyHjk3899mxAw6l+8hVju33nPc8PsmOKrRj8AQK3SIBT2gGmjUb8q1dSwdlG86kMJQJUIPh20IUYmdVW6mZYVKMrTCIZlQZ+0bFFamV3NzDSgHo9DVG1zcYjUf2OelBGGb2Tu3rk3aBgSa0qtJfhUD22UomTI5C1K6wH8AX7CfkaHyDT+ul5FLlRycuIg/v7/2BA+7Sec/5yX0hDidPJd2AoidLPrbb/oVoMA5M564CbZigPuOfGVxZBm8Cg9Ew2JGK2aaDPupxDbRiYpWjEY4bN+U6R6/QF2rWZP4JZeg62laS8zw0QFwQOj/2VzeidJVQzfeP8k42wtVYbNegIB125UsptORAuFylIVlb2OVw+47Ssqftz81Z3iNmjEZxCkXFyik9j7AR6l3y1y+JY1hVowLBmJasa3tZeWzto6c6d+08uPpdgwE3RnHD2HscBozO/OE5xnno7/8ARnNjGRwZXcCQxo3G0xYF+K8sXhiz3qidseifCrPX49M/8cL4hRHsI1xQUZVUG0vJfuqPUvIlVXeNMZbj4APfIyOPM4Z0e+MDfGlsXcZ/SdYR7rJ0t+Y/jAQnE232HKbe6Du22UplUKN4SkhmYLPl1H7T2bIpv4MhpdZOOMk60aRiO8Sq2yI5+1sWCSo51dru1A1v/1pFMp1k9nxPxmUL/esOFKd7d2Q9nn72i4SQSWbD5yrje40y/gY

Yeah, this is quite interesting. If you look in Source/Scene/Camera.js, in the flyToBoundingSphere function, you’ll see that it makes a lot of extra computations before calling flyTo, including creating a quaternion, converting to a matrix, and multiplying that matrix by the vector.

This is a really good Sandcastle example showing this issue. Feel free to open up a GitHub issue (https://github.com/AnalyticalGraphicsInc/cesium/issues) and link back to this thread (or better yet, if you can investigate and contribute towards a fix that’d be awesome!)

I created a GitHub as you suggested, but it seems that flyToBoundingSphere is working as expected.
camera flyTo method uses the globe pitch. camera flyToBoundingSphere method uses a pitch relative to the location of the bounding sphere.
Link to the issue : https://github.com/AnalyticalGraphicsInc/cesium/issues/7384

I saw this on the docs before opening this thread, but I was not sure if there was really a difference or not.

That said, would you know if there is a way to calculate the pitch relative to the bounding sphere location from the pitch relative to globe, and vice versa ?

Thank you.

Instead of using flyToBoundingSphere, I think you’re going to have to use flyTo and compute the position you need to fly to based on the current camera pitch and altitude. There isn’t anything built into Cesium that will do this calculation for you.

-Hannah

Thank you for your help Hannah.

I am sorry for the issue I made on the github, I did not understand well the difference between the frames.

Now it is more clear to me. I succeeded in calculating the good pitch in the target reference frame from the pitch in camera reference frame. Now, I have the desired orientation.

I just have one last problem. I would like to preserve the camera altitude from the old camera position to the new position. I have:
- a direction vector, that provides me the direction of the camera that is necessary to look the target with right orientation.
- the altitude the camera is and should be after the flight.
And I would like to calculate the new coordinates of the camera new position.

I thought about using Intersectiontests class. I could determine the intersection of a ray with target as origin and the negate of camera direction as direction, with an ellipsoid corresponding to the camera altitude.
Do you think this solution would be a good idea? Would you see another way to achieve what I am trying to do?

I’m not sure I follow your solution completely, but if you’re concerned about the height of the terrain at a particular point, you can get that with the sampleTerrain and sampleTerrainMostDetailed functions:

https://cesiumjs.org/Cesium/Build/Documentation/sampleTerrainMostDetailed.html?classFilter=sample

My message was not very clear, sorry.

Let's say camera is initially at a position (longitudei, latitudei, altitudei), and has an orientation (headingi, pitchi, rolli).

I would like the camera to fly to a target (look a it). I would like the camera to keep the same orientation (headingi, pitchi, rolli), and the same altitude. Thus, new camera position must be (longituden, latituden, altitudei) where longituden and latituden must be determined.

Using eastNorthUpToFixedFrame, I am able to calculate a direction vector starting from the target with right direction to preserve the camera orientation. That means that the camera must be on this axis to preserve its initial orientation (headingi, pitchi, rolli).

However, I cannot find the right position (longituden, latituden) on this axis to preserve camera altitude too.

Hope it's clear. I'll try to do another simple sandcastle to illustrate my problem.

Yeah that seems like a specially constrained problem. I don’t think the camera’s built in flyTo mechanics were written for this sort of use case. It wonder if it would be easier for you to modify those original functions or write your own.

A Sandcastle might help to think about this, and perhaps other community members might chime in. But I’m not sure that I know the right way to compute it off the top of my head.