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

Error in splitLongitudeTriangles for FrustumGeometry #6187

Open
davidbuzz opened this issue Feb 5, 2018 · 11 comments
Open

Error in splitLongitudeTriangles for FrustumGeometry #6187

davidbuzz opened this issue Feb 5, 2018 · 11 comments

Comments

@davidbuzz
Copy link

error text from sandcastle:

An error occurred while rendering. Rendering has stopped.
undefined
DeveloperError: normalized result is not a number
Error
at new DeveloperError (https://cesiumjs.org/Cesium/Source/Core/DeveloperError.js:43:19)
at Function.Cartesian3.normalize (https://cesiumjs.org/Cesium/Source/Core/Cartesian3.js:421:19)
at computeTriangleAttributes (https://cesiumjs.org/Cesium/Source/Core/GeometryPipeline.js:1948:24)
at splitLongitudeTriangles (https://cesiumjs.org/Cesium/Source/Core/GeometryPipeline.js:2129:17)
at Object.GeometryPipeline.splitLongitude (https://cesiumjs.org/Cesium/Source/Core/GeometryPipeline.js:2553:17)
at geometryPipeline (https://cesiumjs.org/Cesium/Source/Scene/PrimitivePipeline.js:134:38)
at Object.PrimitivePipeline.combineGeometry (https://cesiumjs.org/Cesium/Source/Scene/PrimitivePipeline.js:278:26)
at loadSynchronous (https://cesiumjs.org/Cesium/Source/Scene/Primitive.js:1216:40)
at Primitive.update (https://cesiumjs.org/Cesium/Source/Scene/Primitive.js:1772:17)
at DebugCameraPrimitive.update (https://cesiumjs.org/Cesium/Source/Scene/DebugCameraPrimitive.js:221:33)

javascript code from sandcastle to demonstrate the issue:

var viewer = new Cesium.Viewer('cesiumContainer');

//var heading = Cesium.Math.toRadians(-1); // works
//var heading = Cesium.Math.toRadians(0); // fails
//var heading = Cesium.Math.toRadians(1); // fails
//var heading = Cesium.Math.toRadians(2); // works
//var heading = Cesium.Math.toRadians(3); // fails
//var heading = Cesium.Math.toRadians(4); // works
var heading = Cesium.Math.toRadians(5); // fails
//var heading = Cesium.Math.toRadians(6); // works

var pitch = 0;
var roll = 0;

//var camera = viewer.camera;
var scene = viewer.scene;

var camera = new Cesium.Camera(scene);

 camera.setView({
    destination : Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706,30),
    orientation: {
        heading : heading,
        pitch : pitch,
        roll : roll
    }
}); 

scene.primitives.add(new Cesium.DebugCameraPrimitive({
camera : camera,
color : Cesium.Color.AQUA
}));

@davidbuzz
Copy link
Author

given that changing .toRadians(6) to .toRadians(5) is all it takes to trigger this error, I consider it pretty serious.

@ggetz
Copy link
Contributor

ggetz commented Feb 5, 2018

I don't think this is being caused by Cesium.MathtoRadians`, as removing this block does not throw the error.

scene.primitives.add(new Cesium.DebugCameraPrimitive({
camera : camera,
color : Cesium.Color.AQUA
}));

This probably has to do with the DebugCameraPrimitve.

@mramato
Copy link
Contributor

mramato commented Feb 5, 2018

This may be a dupe (or same root cause) as #4801.

@hpinkos
Copy link
Contributor

hpinkos commented Feb 5, 2018

Nope, the problem with this one is the numbers are too big. barycentricCoordinates is loosing precision because the dot products of the coordinates are too big, so all these dot products are resolving to the same value (~344 quadrillion).

Then, since all those values are equal, there's a divide by zero on line 76, resulting in NaNs

@hpinkos hpinkos changed the title Cesium.Math.toRadians(X) may or may not trigger this error Error in splitLongitudeTriangles for FrustumGeometry Feb 5, 2018
@hpinkos
Copy link
Contributor

hpinkos commented Feb 5, 2018

@davidbuzz like @ggetz suspected, the problem is with the DebugCameraPrimitive, not with toRadians

@davidbuzz
Copy link
Author

Yes, I'm aware that without the 'DebugCameraPrimitive' the problem doesn't seem to manifest, which is why I included it in the code needed to demonstrate the issue. :-)

@phazor
Copy link

phazor commented Feb 21, 2018

I'm also encountering this issue for the same reason that you described @hpinkos.

I can replicate it by calling 'barycentricCoordinates' with the following args:

  var point = new Cartesian3(-5718037.772328699, -2653008.3876569583, -975992.1249051815);

  var p0 = new Cartesian3(-5718037.772328699, -2653008.3876569583, -975992.1249051815);
  var p1 = new Cartesian3(-5728822.056425484, -2631410.230366517, -971241.7183699571);
  var p2 = new Cartesian3(-5728822.055062331, -2631410.233096925, -971241.7190085766);

  barycentricCoordinates(point, p0, p1, p2, new Cartesian3());

due to dot00 * dot11 and dot01 * dot01 equalling 366445556247163500.

This occurs for me intermittently when trying to draw corridors, which I'm using to display satellite swaths.

@hpinkos do you have any suggested workarounds? I had some ideas but since I don't understand the rendering pipeline I'm not sure which (if any) are feasible:

  • Find and cull the culprit points before they are given to the cesium renderer. I wouldn't know the right check to execute, except to effectively replicate barycentricCoordinates with an NaN check at the end.
  • Set q on line 76 to 1 / Number.EPSILON when dividing by 0.
  • Have a check inside the render loop (e.g. in computeTriangleAttributes) that checks for this condition and skips rendering such a polygon.
  • Give the pipeline an option to not use splitLongitudeTriangles.
  • Catch the DeveloperError and continue rendering. (is this possible?)

As far as I can tell I'm not using DebugCameraPrimitive.

Having some control on the result would be nice - I'd rather skip rendering and have a gap instead of getting an error that blocks the entire UI.

@hpinkos
Copy link
Contributor

hpinkos commented Feb 21, 2018

As far as I can tell I'm not using DebugCameraPrimitive.

@phazor if you're not using DebugCameaPrimitive, can you paste a code example with the geometry you are using that reproduces this issue? I'm not sure of a workaround for this right now

@phazor
Copy link

phazor commented Feb 21, 2018

Unfortunately the geometries are time-dependent + generated, and it can be hours before the error manifests. Next time I catch it I'll try to extract the geometry and use it to provide some better reproduction steps.

In the meantime, I have a rather ugly workaround that at least allows the cesium viewer to jump past an 'expected' DeveloperError:
https://cesiumjs.org/Cesium/Apps/Sandcastle/?src=Hello%20World.html&label=Showcases&gist=15bca861811d7c2115af2285e57f0322

This is the crux of it:

var viewer = new Cesium.Viewer('cesiumContainer', {showRenderLoopErrors: false});

viewer.scene.renderError.addEventListener(() => {
    // Retry every 10 milliseconds. Progress the clock accordingly in case it's an issue with the current frame.
    setTimeout(() => {
        viewer.clock.currentTime = Cesium.JulianDate.addSeconds(viewer.clock.currentTime, 0.01, new Cesium.JulianDate()); // skip forward 10ms
        viewer.timeline.updateFromClock();
        viewer.useDefaultRenderLoop = true; // restart rendering        
    }, 10);
});

@hpinkos
Copy link
Contributor

hpinkos commented Feb 21, 2018

Gotcha. Yeah, let me know when you have an update. Thanks @phazor!

@mramato
Copy link
Contributor

mramato commented Feb 21, 2018

If you're only working in 3D, then there may be a workaround. Geometries are only split for 2D and CV scenes, so can pass scene3DOnly: true to the Viewer constructor and the problematic code shouldn't execute at all (unless the bug is a very different issue than I think it is): https://cesiumjs.org/Cesium/Build/Documentation/Viewer.html#Viewer Setting this flag is good practice either way if you are only using 3D.

If you are using 2D/CV, then @hpinkos is right and there is no good workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants