-
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
Fixing refinement of mixed empty and non-empty tiles #11843
Conversation
@ggetz So, @lilleyse and I took a closer look at the test failures for Also, the main dataset for testing this is private. Anyone internal please just ask me for the data and I can provide a sandcastle with it. |
return ( | ||
root.hasEmptyContent || root.hasImplicitContent || allDescendantsLoaded | ||
); |
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.
I think this should be root.hasEmptyContent || allDescendantsLoaded
.
Which means that traversal is allowed to stop at empty tiles but is not allowed to stop at external tilesets and implicit subtrees since they are placeholder tiles that aren't really part of the tileset structure.
cesium-native accomplishes this by setting their geometric error to infinity.
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.
Yeah, that makes sense. I tested it out against the problem dataset and Google and everything works as expected. Pushing up the change now.
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.
If a placeholder tile has an empty child we're going to see the same problems that came up in #9356.
To fix that I think another line should be changed:
const traverse = (tile.hasTilesetContent || tile.hasImplicitContent) && canTraverse(tile);
In other words, stop traversal if an empty tile is hit, but continue if an external tileset or implicit subtree is hit.
Also, the emptyLeaf
code can be removed. It's no longer necessary.
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.
I think there could be a cleaner way to do this and scrap executeEmptyTraversal
, but I'm not exactly sure what that would look like.
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.
Maybe final version of the function? I made a couple other tweaks:
function executeEmptyTraversal(root, frameState) {
const {
canTraverse,
updateTile,
loadTile,
touchTile,
} = Cesium3DTilesetTraversal;
let allDescendantsLoaded = true;
const stack = emptyTraversal.stack;
stack.push(root);
while (stack.length > 0) {
emptyTraversal.stackMaximumLength = Math.max(
emptyTraversal.stackMaximumLength,
stack.length
);
const tile = stack.pop();
const children = tile.children;
const childrenLength = children.length;
// Only traverse if the tile is an external tileset or implicit subtree
const traverse = (tile.hasTilesetContent || tile.hasImplicitContent) && canTraverse(tile);
// Traversal stops but the external tileset or implicit subtree hasn't loaded yet
// There will be holes if the parent tries to refine to its children, so don't refine
if (!traverse && !tile.contentReady) {
allDescendantsLoaded = false;
}
updateTile(tile, frameState);
if (!tile.isVisible) {
// Load tiles that aren't visible since they are still needed for the parent to refine
loadTile(tile, frameState);
touchTile(tile, frameState);
}
if (traverse) {
for (let i = 0; i < childrenLength; ++i) {
const child = children[i];
stack.push(child);
}
}
}
return root.hasEmptyContent || allDescendantsLoaded;
}
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.
@lilleyse I'm seeing holes in the Google tileset with this approach.
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.
I'm seeing the same thing as Gabby. The problem is the change to the initialization of const traverse
.
I do think we can get rid of the emptyLeaf
exception. It doesn't appear that is needed any longer according to my testing. Let me run the unit tests locally to confirm and I'll push up that change in a few moments.
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.
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.
Sorry I haven't had a chance to get back to this.
I probably wont have a chance to debug what's wrong with my code, so I'd be ok with proceeding with @weegeekps's changes. Let's just watch out for bugs where the root tile of an external tileset or implicit subtree is empty since I don't think that's being properly handled.
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.
Thanks @lilleyse! We're happy to review any further changes here. Let's proceed given @weegeekps's changes are a noticeable improvement on the existing behavior.
@weegeekps @lilleyse I'm seeing good results in my testing with this version. Happy to merge assuming @lilleyse does not have any additional feedback. |
Thanks @weegeekps and @lilleyse ! |
Description
Adds a short circuit in
executeEmptyTraversal
for when descendants may not be loaded, but the tile may have empty or implicit content. This resolves some selection issues with implicit tilesets.We believe this is the root cause for several instances where the wrong tiles are being selected with implicit tilesets. With the release of the Reality Tiler, we're seeing this more and more often, with bugs similar to: https://github.com/CesiumGS/tilers/issues/1297
Issue number and link
Fixes #9356.
Testing plan
I tested a variety of scenarios and tilesets, including but not excluding:
Author checklist
CONTRIBUTORS.md
CHANGES.md
with a short summary of my change