diff --git a/CHANGES.md b/CHANGES.md index 995290f24245..0fee949a304e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ - Fixed several artifcats on mobile devices caused by using insufficient precision. [#9064](https://github.com/CesiumGS/cesium/pull/9064) - Fixed handling of `data:` scheme for the Cesium ion logo URL. [#9085](https://github.com/CesiumGS/cesium/pull/9085) +- Fixed an issue where the boundary rectangles in `TileAvailability` are not sorted correctly, causing terrain to sometimes fail to achieve its maximum detail. [#9098](https://github.com/CesiumGS/cesium/pull/9098) ### 1.72 - 2020-08-03 diff --git a/Source/Core/TileAvailability.js b/Source/Core/TileAvailability.js index 64e72d48a81c..f5381886c0b2 100644 --- a/Source/Core/TileAvailability.js +++ b/Source/Core/TileAvailability.js @@ -361,7 +361,7 @@ function putRectangleInQuadtree(maxDepth, node, rectangle) { rectangle.level, rectangleLevelComparator ); - if (index <= 0) { + if (index < 0) { index = ~index; } node.rectangles.splice(index, 0, rectangle); diff --git a/Specs/Core/TileAvailabilitySpec.js b/Specs/Core/TileAvailabilitySpec.js index 1280f8825210..5ba02b18b0d3 100644 --- a/Specs/Core/TileAvailabilitySpec.js +++ b/Specs/Core/TileAvailabilitySpec.js @@ -3,6 +3,7 @@ import { GeographicTilingScheme } from "../../Source/Cesium.js"; import { Rectangle } from "../../Source/Cesium.js"; import { TileAvailability } from "../../Source/Cesium.js"; import { WebMercatorTilingScheme } from "../../Source/Cesium.js"; +import { defined } from "../../Source/Cesium.js"; describe("Core/TileAvailability", function () { var webMercator = new WebMercatorTilingScheme(); @@ -190,6 +191,26 @@ describe("Core/TileAvailability", function () { }); describe("addAvailableTileRange", function () { + function checkNodeRectanglesSorted(node) { + if (!defined(node)) { + return; + } + + var levelRectangles = node.rectangles; + for (var i = 0; i < levelRectangles.length; ++i) { + for (var j = i; j < levelRectangles.length; ++j) { + expect(levelRectangles[i].level <= levelRectangles[j].level).toBe( + true + ); + } + } + + checkNodeRectanglesSorted(node._ne); + checkNodeRectanglesSorted(node._se); + checkNodeRectanglesSorted(node._nw); + checkNodeRectanglesSorted(node._sw); + } + it("keeps availability ranges sorted by rectangle", function () { var availability = createAvailability(geographic, 15); availability.addAvailableTileRange(0, 0, 0, 1, 0); @@ -210,5 +231,19 @@ describe("Core/TileAvailability", function () { ) ).toBe(1); }); + + it("ensure the boundary rectangles are sorted properly", function () { + var availability = new TileAvailability(geographic, 6); + availability.addAvailableTileRange(0, 0, 0, 1, 0); + availability.addAvailableTileRange(1, 0, 0, 2, 0); + availability.addAvailableTileRange(2, 0, 0, 4, 0); + availability.addAvailableTileRange(3, 0, 0, 8, 0); + availability.addAvailableTileRange(0, 0, 0, 1, 0); + + for (var i = 0; i < availability._rootNodes.length; ++i) { + var node = availability._rootNodes[i]; + checkNodeRectanglesSorted(node); + } + }); }); });