Skip to content

Commit

Permalink
Merge pull request #11296 from CesiumGS/terrain-availability
Browse files Browse the repository at this point in the history
Terrain availability race condition
  • Loading branch information
mramato authored May 19, 2023
2 parents c60dd09 + fa78047 commit 2cbe296
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 0 deletions.
8 changes: 8 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Change Log

### 1.106 - 2023-06-01

#### @cesium/engine

##### Fixes :wrench:

- Fixed a race condition when loading cut-out terrain. [#11296](https://github.com/CesiumGS/cesium/pull/11296)

### 1.105.2 - 2023-05-15

- This is an npm-only release to fix a dependency issue published in 1.105.1.
Expand Down
36 changes: 36 additions & 0 deletions Specs/Data/CesiumTerrainTileJson/ParentAvailability.tile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"tilejson": "2.1.0",
"format" : "quantized-mesh-1.0",
"version" : "1.0.0",
"scheme" : "tms",
"attribution" : "This amazing data is courtesy The Amazing Data Source!",
"tiles" : [
"{z}/{x}/{y}.terrain?v={version}"
],
"extensions": [
"watermask",
"metadata",
"octvertexnormals"
],
"metadataAvailability": 10,
"minzoom": 0,
"maxzoom": 13,
"available" : [
[
{
"startX" : 0,
"startY" : 0,
"endX" : 1,
"endY" : 0
}
],
[
{
"startX" : 0,
"startY" : 0,
"endX" : 3,
"endY" : 1
}
]
]
}
38 changes: 38 additions & 0 deletions Specs/Data/CesiumTerrainTileJson/ParentUrlAvailability.tile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"tilejson": "2.1.0",
"format" : "quantized-mesh-1.0",
"version" : "1.0.0",
"scheme" : "tms",
"attribution" : "This is a child tileset!",
"tiles" : [
"{z}/{x}/{y}.terrain?v={version}"
],
"extensions" : [
"watermask",
"metadata",
"octvertexnormals"
],
"metadataAvailability": 10,
"minzoom": 0,
"maxzoom": 13,
"available" : [
[
{
"startX" : 0,
"startY" : 0,
"endX" : 1,
"endY" : 0
}
],
[
{
"startX" : 0,
"startY" : 0,
"endX" : 2,
"endY" : 1
}
]
],
"parentUrl": "./"
}

25 changes: 25 additions & 0 deletions packages/engine/Source/Core/CesiumTerrainProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,8 @@ CesiumTerrainProvider.prototype.requestTileGeometry = function (
const layers = this._layers;
let layerToUse;
const layerCount = layers.length;
let unknownAvailability = false;
let availabilityPromise = Promise.resolve();

if (layerCount === 1) {
// Optimized path for single layers
Expand All @@ -915,9 +917,32 @@ CesiumTerrainProvider.prototype.requestTileGeometry = function (
layerToUse = layer;
break;
}

const availabilityUnloaded = checkLayer(
this,
x,
y,
level,
layer,
i === 0
);
if (availabilityUnloaded.result) {
// We can't know yet since the availability is not yet loaded
unknownAvailability = true;
availabilityPromise = availabilityPromise.then(
() => availabilityUnloaded.promise
);
}
}
}

if (!defined(layerToUse) && unknownAvailability) {
// Try again when availability data is ready– Otherwise the tile will be marked as failed and never re-requested
return availabilityPromise.then(() =>
this.requestTileGeometry(x, y, level, request)
);
}

return requestTileGeometry(this, x, y, level, layerToUse, request);
};

Expand Down
76 changes: 76 additions & 0 deletions packages/engine/Specs/Core/CesiumTerrainProviderSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,45 @@ describe("Core/CesiumTerrainProvider", function () {
);
}

function returnParentUrlTileJsonWithMetadataAvailability() {
const paths = [
"Data/CesiumTerrainTileJson/ParentUrlAvailability.tile.json",
"Data/CesiumTerrainTileJson/ParentAvailability.tile.json",
];
let i = 0;
const oldLoad = Resource._Implementations.loadWithXhr;
Resource._Implementations.loadWithXhr = function (
url,
responseType,
method,
data,
headers,
deferred,
overrideMimeType
) {
if (url.indexOf("layer.json") >= 0) {
Resource._DefaultImplementations.loadWithXhr(
paths[i++],
responseType,
method,
data,
headers,
deferred
);
} else {
return oldLoad(
url,
responseType,
method,
data,
headers,
deferred,
overrideMimeType
);
}
};
}

async function waitForTile(level, x, y, requestNormals, requestWaterMask, f) {
const terrainProvider = await CesiumTerrainProvider.fromUrl("made/up/url", {
requestVertexNormals: requestNormals,
Expand Down Expand Up @@ -899,6 +938,43 @@ describe("Core/CesiumTerrainProvider", function () {
expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe(true);
});

it("provides QuantizedMeshTerrainData with multiple layers and with Metadata availability ", async function () {
Resource._Implementations.loadWithXhr = function (
url,
responseType,
method,
data,
headers,
deferred,
overrideMimeType
) {
Resource._DefaultImplementations.loadWithXhr(
"Data/CesiumTerrainTileJson/tile.metadataavailability.terrain",
responseType,
method,
data,
headers,
deferred
);
};

returnParentUrlTileJsonWithMetadataAvailability();

const terrainProvider = await CesiumTerrainProvider.fromUrl(
"made/up/url"
);

expect(terrainProvider.hasMetadata).toBe(true);
const layers = terrainProvider._layers;
expect(layers.length).toBe(2);

expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe(false);

const loadedData = await terrainProvider.requestTileGeometry(0, 0, 1);
expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData);
expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe(true);
});

it("returns undefined if too many requests are already in progress", async function () {
const baseUrl = "made/up/url";

Expand Down

0 comments on commit 2cbe296

Please sign in to comment.