-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Throw DeveloperError if normalize fails #3605
Conversation
Welp, I found a handful of geometry errors this change exposed. They'll have to be fixed before this goes in:
So I'm going to put this issue on hold until I have time fix those things. |
The fact that this exposed 4 bugs already proves it's the right change to make. Thanks @kalmykov for bringing this to our attention! Hopefully we can get these fixed soon since some of them were user reported. Also, 👍 for use of welp. |
As a side comment, we should start adding validation like this (within debug pragmas) in many more places. Basically, throw as soon as any calculation anywhere produces a NaN. This would help to work to finally track down the dreaded "invalid array length" in the frustum code, which is where all NaNs eventually end up crashing currently. I know I've discussed this before, but I couldn't find any existing issues by searching. |
I couldn't agree more. The only potential downside are module users who don't probably perform dead-code elimination and website Sandcastle demos will get a performance hit (but they are already getting that hit now because we have tons of pragmas). |
Do we have a build step to remove pragmas for these users? Or do you think they just ignore it? |
Pragma specifically is a requirejs thing, so anyone using modules with requirejs should be covered. We can't do it as part of the build because modules are just the |
Ah, I see. |
@hpinkos would it be possible to work around |
@mramato I might be able to do something... I mean the binormals are already incorrect, I guess making them incorrect in a different way to work around this wouldn't be the worst thing. I probably won't have a chance to really fix the geometry in the near future. |
Yep, that's why I was hoping for a workaround because these nan checks would go a long way to finding other unrelated bugs |
We really need to get these changes into master sooner rather than later so I marked this for the bug bash. I don't care if we have to hack around PolylineVolumeGeometry to do it; there are several other bugs that would have been caught sooner if these checks were in place in master. |
# Conflicts: # Specs/Scene/SkyAtmosphereSpec.js # Specs/Scene/SkyBoxSpec.js # Specs/Scene/SunSpec.js
@lilleyse I'm getting a whole bunch of It looks like at some point sceneCamera.frustum.projectionMatrix has |
Ok I'll take a look now. |
Thanks! Don't have to worry about the other failing tests, I'm trying to fix those. I just have no idea what's going on with those shadow map test. |
@bagnell this is the one test I was looking into: DataSources/KmlDataSource NetworkLink: Heading and pitch can be undefined if the camera is in morphing mode |
Alright, all the test except the @lilleyse let me know when you have the |
try { | ||
geometry = GeometryPipeline.computeBinormalAndTangent(geometry); | ||
} catch (e) { | ||
console.log('Unable to compute tangents and binormals for polyline volume geometry'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure about this change? It is atypical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's definitely atypical, but I don't have a better solution that won't take a ton of time. This geometry type really needs a major rewrite, but I don't think it's worth spending the time to do that right now. I think the benefits of getting this PR merged outweigh the downside of this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this to workaround tests? Would it be better to put this in the tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It prevents the geometry from failing if you request the tangents and binormals, both in and out of the tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, OK. Leave it, but maybe remove the console.log
or use something like deprecationWarning
to avoid flooding the console.
Also use a debug pragma.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could use oneTimeWarning
and log out the url to the GitHub issue, so if people run into it (doubtful) they can comment or +1 it.
I figured out the |
@@ -678,8 +678,9 @@ define([ | |||
var scratchCartographicMax = new Cartographic(); | |||
|
|||
function computeRectangle(positions, ellipsoid, width, cornerType) { | |||
var length = positions.length - 1; | |||
if (length === 0) { | |||
var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something weird is going on with this change. Run the below code in this branch and it will crash, however remove the first point (which is a duplicate) and everything works. So many we need to re-use the deduplicated version in other places in this file?
var viewer = new Cesium.Viewer('cesiumContainer');
var redCorridor = viewer.entities.add({
name : 'Red corridor on surface with rounded corners and outline',
corridor : {
positions : Cesium.Cartesian3.fromDegreesArray([
-16.41549000000001,28.44423000000001,
-16.41549000000001,28.44423000000001,
-16.41505000000001,28.44430000000001,
-16.41507000000001,28.44430000000001,
-16.41473000000001,28.44460000000001,
-16.41429000000001,28.44452000000001,
-16.41430000000001,28.44453000000001,
-16.41428000000001,28.44452000000001,
-16.41416000000001,28.44434000000001,
-16.41415000000001,28.44434000000001,
-16.41397000000001,28.44408000000001
]),
width : 1,
height:0,
material : Cesium.Color.RED.withAlpha(0.5),
outline : true,
outlineColor : Cesium.Color.RED
}
});
viewer.zoomTo(viewer.entities);
@mramato anything else? I think this is ready to go now. I also tested all the sandcastle examples and everything worked there. |
@@ -219,6 +219,15 @@ define([ | |||
if (!defined(v1)) { | |||
throw new DeveloperError('v1 is required.'); | |||
} | |||
if (!defined(p0)) { | |||
throw new DeveloperError('v1 is required.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error messages are incorrect.
try { | ||
geometry = GeometryPipeline.computeBinormalAndTangent(geometry); | ||
} catch (e) { | ||
deprecationWarning('polyline-volume-tangent-binormal', 'Unable to compute tangents and binormals for polyline volume geometry'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use oneTimeWarning
here instead. It's the same thing but it's confusing to refer to this as deprecated.
var nUnit = Cartesian3.normalize(Cartesian3.cross(qUnit, eUnit, scratchCartesian3_4), scratchCartesian3_4); | ||
var eUnit; | ||
var nUnit; | ||
if (Cartesian3.equalsEpsilon(qUnit, Cartesian3.UNIT_Z, CesiumMath.EPSILON10)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since random epsilon values have bitten us in the past, is there any ryhme or reason for 10 over other values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
10 seems sufficiently small? We picked 10 in other places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"We use it in other places" is fine for now.
}).toThrowDeveloperError(); | ||
}); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whitespace
@@ -181,18 +181,21 @@ defineSuite([ | |||
}); | |||
|
|||
it('lineSegmentTriangle throws without p0', function() { | |||
//TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
@@ -338,6 +338,9 @@ defineSuite([ | |||
Matrix3.multiplyByVector(axes, tang, tang); | |||
Matrix3.multiplyByVector(axes, binorm, binorm); | |||
Cartesian3.cross(tang, binorm, n); | |||
if (Cartesian3.magnitude(n) === 0) { | |||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use return undefined;
here for consistency with the rest of the function.
The rule we tend to use (but doubt we've ever codified) is that we use return undefined;
in cases where the function returns actual values sometimes as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add it to the Coding Guide to keep our flurry of non-code PRs.
I'm way more excited about this than I probably should be. Just those comments and this is good to go. |
@mramato anything else? |
Fixes issue raised in #3433
A
DeveloperError
is raised when any of the values of normalize areNaN
(For example, when you try
Cartesian3.normalize(Cartesian3.ZERO)
)Blocked By: