diff --git a/CHANGES.md b/CHANGES.md index 590bea8b480e..821cd55bcd1a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ # Change Log +### 1.72 - 2020-08-03 + +##### Fixes :wrench: + +- Fixed 3D Tileset replacement refinement when leaf is empty. [#8996](https://github.com/CesiumGS/cesium/8996) + ### 1.71 - 2020-07-01 ##### Breaking Changes :mega: diff --git a/Source/Scene/Cesium3DTilesetTraversal.js b/Source/Scene/Cesium3DTilesetTraversal.js index 4e022ba775d5..0fb54521e77f 100644 --- a/Source/Scene/Cesium3DTilesetTraversal.js +++ b/Source/Scene/Cesium3DTilesetTraversal.js @@ -652,11 +652,14 @@ function executeEmptyTraversal(tileset, root, frameState) { var childrenLength = children.length; // Only traverse if the tile is empty - traversal stop at descendants with content - var traverse = hasEmptyContent(tile) && canTraverse(tileset, tile); - - // Traversal stops but the tile does not have content yet. - // There will be holes if the parent tries to refine to its children, so don't refine. - if (!traverse && !tile.contentAvailable) { + var emptyContent = hasEmptyContent(tile); + var traverse = emptyContent && canTraverse(tileset, tile); + var emptyLeaf = emptyContent && tile.children.length === 0; + + // Traversal stops but the tile does not have content yet + // There will be holes if the parent tries to refine to its children, so don't refine + // One exception: a parent may refine even if one of its descendants is an empty leaf + if (!traverse && !tile.contentAvailable && !emptyLeaf) { allDescendantsLoaded = false; } diff --git a/Specs/Scene/Cesium3DTilesetSpec.js b/Specs/Scene/Cesium3DTilesetSpec.js index 19af1f790c85..9586e39c8165 100644 --- a/Specs/Scene/Cesium3DTilesetSpec.js +++ b/Specs/Scene/Cesium3DTilesetSpec.js @@ -1411,6 +1411,32 @@ describe( }); }); + it("replacement refinement - refines if descendant is empty leaf tile", function () { + // Check that the root is refinable once its children with content are loaded + // + // C + // C C C E + // + viewAllTiles(); + var originalLoadJson = Cesium3DTileset.loadJson; + spyOn(Cesium3DTileset, "loadJson").and.callFake(function (tilesetUrl) { + return originalLoadJson(tilesetUrl).then(function (tilesetJson) { + tilesetJson.root.refine = "REPLACE"; + tilesetJson.root.children[3].content = undefined; + return tilesetJson; + }); + }); + + return Cesium3DTilesTester.loadTileset(scene, tilesetUrl).then(function ( + tileset + ) { + tileset.skipLevelOfDetail = false; + var statistics = tileset._statistics; + scene.renderForSpecs(); + expect(statistics.numberOfCommands).toEqual(3); + }); + }); + it("replacement and additive refinement", function () { // A // A R (not rendered)