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

Throw DeveloperError if normalize fails #3605

Merged
merged 17 commits into from
Oct 20, 2016
Merged

Throw DeveloperError if normalize fails #3605

merged 17 commits into from
Oct 20, 2016

Conversation

hpinkos
Copy link
Contributor

@hpinkos hpinkos commented Feb 18, 2016

Fixes issue raised in #3433

A DeveloperError is raised when any of the values of normalize are NaN
(For example, when you try Cartesian3.normalize(Cartesian3.ZERO))

Blocked By:

@bagnell
Copy link
Contributor

bagnell commented Feb 19, 2016

I get 16 test failures:
image

@hpinkos
Copy link
Contributor Author

hpinkos commented Feb 19, 2016

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.
I did push some changes to a few other places to handle a zero vector. I'm not sure if they're the best fix.

@mramato
Copy link
Contributor

mramato commented Feb 19, 2016

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.

@shunter
Copy link
Contributor

shunter commented Feb 19, 2016

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.

@mramato
Copy link
Contributor

mramato commented Feb 19, 2016

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).

@pjcozzi
Copy link
Contributor

pjcozzi commented Feb 19, 2016

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?

@hpinkos
Copy link
Contributor Author

hpinkos commented Feb 19, 2016

@shunter I created an issue here: #3613

@mramato
Copy link
Contributor

mramato commented Feb 19, 2016

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 Source directory. It has to be done during their apps own compile step (unless we wanted to ship two copies of the source tree). I believe Webpack might have some dead-code elimination features, but I don't think they support the same pragma format out of the box. I'm guessing if someone cared enough they could make it work; but as we see on the forum most of our users just use the minified Cesium.js from the start and don't even bother with the developer build that has error checking. Ultimately that's an education issue we should eventually fix with improved documentation.

@pjcozzi
Copy link
Contributor

pjcozzi commented Feb 19, 2016

Ah, I see.

@mramato
Copy link
Contributor

mramato commented Aug 30, 2016

@hpinkos would it be possible to work around Incorrect PolylineVolumeGeometry binormals separately at the geometry level and merge this with NaN checks are the Cartesian3 level? It would be really nice to get these checks into master.

@hpinkos
Copy link
Contributor Author

hpinkos commented Aug 30, 2016

@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.

@mramato
Copy link
Contributor

mramato commented Aug 30, 2016

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

@mramato
Copy link
Contributor

mramato commented Oct 6, 2016

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.

hpinkos added 2 commits October 19, 2016 10:28
# Conflicts:
#	Specs/Scene/SkyAtmosphereSpec.js
#	Specs/Scene/SkyBoxSpec.js
#	Specs/Scene/SunSpec.js
@hpinkos
Copy link
Contributor Author

hpinkos commented Oct 19, 2016

@lilleyse I'm getting a whole bunch of ShadowMap test failures. I'm not sure if the tests are bad or if it's a problem with the code.

It looks like at some point sceneCamera.frustum.projectionMatrix has -Infinity in it, which then makes a bunch of things later on in fitShadowMapToScene got to NaN

@lilleyse
Copy link
Contributor

Ok I'll take a look now.

@hpinkos
Copy link
Contributor Author

hpinkos commented Oct 19, 2016

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.

@hpinkos
Copy link
Contributor Author

hpinkos commented Oct 19, 2016

@hpinkos
Copy link
Contributor Author

hpinkos commented Oct 19, 2016

Alright, all the test except the ShadowMap test are failing.
#3609 (PolylineVolumeGeometry tangets/binormals) is not fixed, but I worked around it for the specs

@lilleyse let me know when you have the ShadowMap tests fixed. Getting this change in master will be hugely beneficial for preventing future bugs.

@mramato
Copy link
Contributor

mramato commented Oct 19, 2016

Thanks @hpinkos huge 👍 from me! @lilleyse if you could get to this as part of the bash, that would be a huge help in tracking down some of the other issues (which are better exposed by these fixes).

try {
geometry = GeometryPipeline.computeBinormalAndTangent(geometry);
} catch (e) {
console.log('Unable to compute tangents and binormals for polyline volume geometry');
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor

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.

@lilleyse
Copy link
Contributor

I figured out the ShadowMap NaN issues, but there is something else going on with terrain shadows so I'm going to open a separate shadows fix PR rather than add to this one.

@@ -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);
Copy link
Contributor

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);

@lilleyse lilleyse mentioned this pull request Oct 20, 2016
@hpinkos
Copy link
Contributor Author

hpinkos commented Oct 20, 2016

@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.');
Copy link
Contributor

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');
Copy link
Contributor

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)) {
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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();
});


Copy link
Contributor

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
Copy link
Contributor

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;
Copy link
Contributor

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.

Copy link
Contributor

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.

@mramato
Copy link
Contributor

mramato commented Oct 20, 2016

I'm way more excited about this than I probably should be. Just those comments and this is good to go.

@hpinkos
Copy link
Contributor Author

hpinkos commented Oct 20, 2016

@mramato anything else?

@mramato mramato merged commit bcd4503 into master Oct 20, 2016
@mramato mramato deleted the normalizeZeroVector branch October 20, 2016 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants