cesium-native icon indicating copy to clipboard operation
cesium-native copied to clipboard

Exception creating culling volume when camera is very far from the globe

Open kring opened this issue 2 years ago • 0 comments

When the camera is very far away from the globe, cesium-native throws an exception while attempting to construct a Plane because the normal is NaN.

I ran into this while testing globe scaling in Unity. If we zoom out so that we can see the whole globe, and then scale the globe down until it's very tiny (e.g. scale factor of 1e-12), that's equivalent to the camera being extraordinarily far away from the globe. In my testing, I was seeing the camera-to-globe distance be about 1e18 meters at the time of the crash. At that distance, the globe is much too small to see, but we shouldn't crash.

The problem is in the createCullingVolume function in CullingVolume.cpp. For tile selection, cesium-native doesn't use the near and far planes for culling. In fact, they're not even provided to the selection algorithm. But this createCullingVolume function, which was ported from CesiumJS, uses the near plane distance as part of the computation of the top, bottom, left, and right planes of the frustum. Since the overall goal here is just to form a direction, I thought the actual near plane value wouldn't matter and just hard-coded it to 1.0.

This is mostly a fine assumption, except if the position value is so huge that adding 1.0 to it results in the same value. When that happens, our normal vector has zero magnitude and we throw an exception while trying to create a Plane for it.

I'm not sure if there's a smarter way to compute these planes, but a simple way to fix this bug is to use the same algorithm but simply to choose the "near plane" distance more carefully. Something like "half the distance to the globe" would probably work fine. Maybe put a minimum on it so that a camera at the center of the Earth won't cause a different sort of problem.

kring avatar May 08 '23 05:05 kring