Skip to content

Commit

Permalink
Merge pull request #7196 from AnalyticalGraphicsInc/availability-from…
Browse files Browse the repository at this point in the history
…-bvh

Availability from bvh
  • Loading branch information
mramato authored Nov 19, 2018
2 parents 1ce4134 + a169f54 commit f862c55
Show file tree
Hide file tree
Showing 10 changed files with 449 additions and 66 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ Change Log

### 1.52 - 2018-12-03

##### Breaking Changes :mega:
* `TerrainProviders` that implement `availability` must now also implement the `loadTileDataAvailability` method.

##### Additions :tada:
* Added functions to get the most detailed height of 3D Tiles on-screen or off-screen. [#7115](https://github.com/AnalyticalGraphicsInc/cesium/pull/7115)
* Added `Scene.sampleHeightMostDetailed`, an asynchronous version of `Scene.sampleHeight` that uses the maximum level of detail for 3D Tiles.
* Added `Scene.clampToHeightMostDetailed`, an asynchronous version of `Scene.clampToHeight` that uses the maximum level of detail for 3D Tiles.
* Added support for high dynamic range rendering. It is enabled by default when supported, but can be disabled with `Scene.highDynamicRange`. [#7017](https://github.com/AnalyticalGraphicsInc/cesium/pull/7017)
* Added `Scene.invertClassificationSupported` for checking if invert classification is supported.
* Added `computeLineSegmentLineSegmentIntersection` to `Intersections2D`. [#7228](https://github.com/AnalyticalGraphicsInc/Cesium/pull/7228)
* Added ability to load availability progressively from a quantized mesh extension instead of upfront. This will speed up load time and reduce memory usage. [#7196](https://github.com/AnalyticalGraphicsInc/cesium/pull/7196)
* Added the ability to apply styles to 3D Tilesets that don't contain features. [#7255](https://github.com/AnalyticalGraphicsInc/Cesium/pull/7255)

##### Fixes :wrench:
Expand Down
326 changes: 283 additions & 43 deletions Source/Core/CesiumTerrainProvider.js

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions Source/Core/EllipsoidTerrainProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,5 +189,17 @@ define([
return undefined;
};

/**
* Makes sure we load availability data for a tile
*
* @param {Number} x The X coordinate of the tile for which to request geometry.
* @param {Number} y The Y coordinate of the tile for which to request geometry.
* @param {Number} level The level of the tile for which to request geometry.
* @returns {undefined|Promise} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded
*/
EllipsoidTerrainProvider.prototype.loadTileDataAvailability = function(x, y, level) {
return undefined;
};

return EllipsoidTerrainProvider;
});
12 changes: 12 additions & 0 deletions Source/Core/GoogleEarthEnterpriseTerrainProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,18 @@ define([
return false;
};

/**
* Makes sure we load availability data for a tile
*
* @param {Number} x The X coordinate of the tile for which to request geometry.
* @param {Number} y The Y coordinate of the tile for which to request geometry.
* @param {Number} level The level of the tile for which to request geometry.
* @returns {undefined|Promise} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded
*/
GoogleEarthEnterpriseTerrainProvider.prototype.loadTileDataAvailability = function(x, y, level) {
return undefined;
};

//
// Functions to handle imagery packets
//
Expand Down
10 changes: 10 additions & 0 deletions Source/Core/TerrainProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,5 +227,15 @@ define([
*/
TerrainProvider.prototype.getTileDataAvailable = DeveloperError.throwInstantiationError;

/**
* Makes sure we load availability data for a tile
*
* @param {Number} x The X coordinate of the tile for which to request geometry.
* @param {Number} y The Y coordinate of the tile for which to request geometry.
* @param {Number} level The level of the tile for which to request geometry.
* @returns {undefined|Promise} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded
*/
TerrainProvider.prototype.loadTileDataAvailability = DeveloperError.throwInstantiationError;

return TerrainProvider;
});
12 changes: 12 additions & 0 deletions Source/Core/VRTheWorldTerrainProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,5 +355,17 @@ define([
return undefined;
};

/**
* Makes sure we load availability data for a tile
*
* @param {Number} x The X coordinate of the tile for which to request geometry.
* @param {Number} y The Y coordinate of the tile for which to request geometry.
* @param {Number} level The level of the tile for which to request geometry.
* @returns {undefined|Promise} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded
*/
VRTheWorldTerrainProvider.prototype.loadTileDataAvailability = function(x, y, level) {
return undefined;
};

return VRTheWorldTerrainProvider;
});
84 changes: 61 additions & 23 deletions Source/Core/sampleTerrainMostDetailed.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
define([
'../ThirdParty/when',
'./Cartesian2',
'./defined',
'./DeveloperError',
'./sampleTerrain'
], function(
when,
Cartesian2,
defined,
DeveloperError,
sampleTerrain) {
'use strict';

var scratchCartesian2 = new Cartesian2();

/**
* Initiates a sampleTerrain() request at the maximum available tile level for a terrain dataset.
*
Expand Down Expand Up @@ -43,36 +47,70 @@ define([
}
//>>includeEnd('debug');

return terrainProvider.readyPromise.then(function() {
var byLevel = [];
return terrainProvider.readyPromise
.then(function() {
var byLevel = [];
var maxLevels = [];

var availability = terrainProvider.availability;
var availability = terrainProvider.availability;

//>>includeStart('debug', pragmas.debug);
if (!defined(availability)) {
throw new DeveloperError('sampleTerrainMostDetailed requires a terrain provider that has tile availability.');
}
//>>includeEnd('debug');
//>>includeStart('debug', pragmas.debug);
if (!defined(availability)) {
throw new DeveloperError('sampleTerrainMostDetailed requires a terrain provider that has tile availability.');
}
//>>includeEnd('debug');

for (var i = 0; i < positions.length; ++i) {
var position = positions[i];
var maxLevel = availability.computeMaximumLevelAtPosition(position);
var promises = [];
for (var i = 0; i < positions.length; ++i) {
var position = positions[i];
var maxLevel = availability.computeMaximumLevelAtPosition(position);
maxLevels[i] = maxLevel;
if (maxLevel === 0) {
// This is a special case where we have a parent terrain and we are requesting
// heights from an area that isn't covered by the top level terrain at all.
// This will essentially trigger the loading of the parent terrains root tile
terrainProvider.tilingScheme.positionToTileXY(position, 1, scratchCartesian2);
var promise = terrainProvider.loadTileDataAvailability(scratchCartesian2.x, scratchCartesian2.y, 1);
if (defined(promise)) {
promises.push(promise);
}
}

var atLevel = byLevel[maxLevel];
if (!defined(atLevel)) {
byLevel[maxLevel] = atLevel = [];
var atLevel = byLevel[maxLevel];
if (!defined(atLevel)) {
byLevel[maxLevel] = atLevel = [];
}
atLevel.push(position);
}
atLevel.push(position);
}

return when.all(byLevel.map(function(positionsAtLevel, index) {
if (defined(positionsAtLevel)) {
return sampleTerrain(terrainProvider, index, positionsAtLevel);
}
})).then(function() {
return positions;
return when.all(promises)
.then(function() {
return when.all(byLevel.map(function(positionsAtLevel, index) {
if (defined(positionsAtLevel)) {
return sampleTerrain(terrainProvider, index, positionsAtLevel);
}
}));
})
.then(function() {
var changedPositions = [];
for (var i = 0; i < positions.length; ++i) {
var position = positions[i];
var maxLevel = availability.computeMaximumLevelAtPosition(position);

if (maxLevel !== maxLevels[i]) {
// Now that we loaded the max availability, a higher level has become available
changedPositions.push(position);
}
}

if (changedPositions.length > 0) {
return sampleTerrainMostDetailed(terrainProvider, changedPositions);
}
})
.then(function() {
return positions;
});
});
});
}

return sampleTerrainMostDetailed;
Expand Down
54 changes: 54 additions & 0 deletions Specs/Core/CesiumTerrainProviderSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ defineSuite([
};
}

function returnMetadataAvailabilityTileJson() {
return returnTileJson('Data/CesiumTerrainTileJson/MetadataAvailability.tile.json');
}

function waitForTile(level, x, y, requestNormals, requestWaterMask, f) {
var terrainProvider = new CesiumTerrainProvider({
url : 'made/up/url',
Expand Down Expand Up @@ -652,6 +656,33 @@ defineSuite([
});
});

it('provides QuantizedMeshTerrainData with Metadata availability', 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);
};

returnMetadataAvailabilityTileJson();

var terrainProvider = new CesiumTerrainProvider({
url : 'made/up/url'
});

return pollToPromise(function() {
return terrainProvider.ready;
}).then(function() {
expect(terrainProvider.hasMetadata).toBe(true);
expect(terrainProvider._layers[0].availabilityLevels).toBe(10);
expect(terrainProvider.availability.isTileAvailable(0,0,0)).toBe(true);
expect(terrainProvider.availability.isTileAvailable(0,1,0)).toBe(true);
expect(terrainProvider.availability.isTileAvailable(1,0,0)).toBe(false);

return terrainProvider.requestTileGeometry(0, 0, 0);
}).then(function(loadedData) {
expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData);
expect(terrainProvider.availability.isTileAvailable(1,0,0)).toBe(true);
});
});

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

Expand Down Expand Up @@ -726,6 +757,29 @@ defineSuite([
});
});

it('getTileDataAvailable() with Metadata availability', 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);
};

returnMetadataAvailabilityTileJson();

var terrainProvider = new CesiumTerrainProvider({
url : 'made/up/url'
});

return pollToPromise(function() {
return terrainProvider.ready;
}).then(function() {
expect(terrainProvider.getTileDataAvailable(0,0,0)).toBe(true);
expect(terrainProvider.getTileDataAvailable(0,0,1)).toBeUndefined();

return terrainProvider.requestTileGeometry(0, 0, 0);
}).then(function() {
expect(terrainProvider.getTileDataAvailable(0,0,1)).toBe(true);
});
});

it('supports a query string in the base URL', function() {
Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) {
// Just return any old file, as long as its big enough
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"attribution":"","bounds":[-180,-90,180,90],"bvhlevels":6,"description":"","extensions":["bvh","metadata","octvertexnormals"],"format":"quantized-mesh-1.0","maxzoom":8,"metadataAvailability":10,"minzoom":0,"name":"","projection":"EPSG:4326","scheme":"tms","tiles":["{z}/{x}/{y}.terrain?v={version}"],"version":"1.33.0"}
Binary file not shown.

0 comments on commit f862c55

Please sign in to comment.