Skip to content

Commit f862c55

Browse files
authoredNov 19, 2018
Merge pull request #7196 from AnalyticalGraphicsInc/availability-from-bvh
Availability from bvh
2 parents 1ce4134 + a169f54 commit f862c55

10 files changed

+449
-66
lines changed
 

‎CHANGES.md

+4
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ Change Log
33

44
### 1.52 - 2018-12-03
55

6+
##### Breaking Changes :mega:
7+
* `TerrainProviders` that implement `availability` must now also implement the `loadTileDataAvailability` method.
8+
69
##### Additions :tada:
710
* Added functions to get the most detailed height of 3D Tiles on-screen or off-screen. [#7115](https://github.com/AnalyticalGraphicsInc/cesium/pull/7115)
811
* Added `Scene.sampleHeightMostDetailed`, an asynchronous version of `Scene.sampleHeight` that uses the maximum level of detail for 3D Tiles.
912
* Added `Scene.clampToHeightMostDetailed`, an asynchronous version of `Scene.clampToHeight` that uses the maximum level of detail for 3D Tiles.
1013
* 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)
1114
* Added `Scene.invertClassificationSupported` for checking if invert classification is supported.
1215
* Added `computeLineSegmentLineSegmentIntersection` to `Intersections2D`. [#7228](https://github.com/AnalyticalGraphicsInc/Cesium/pull/7228)
16+
* 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)
1317
* Added the ability to apply styles to 3D Tilesets that don't contain features. [#7255](https://github.com/AnalyticalGraphicsInc/Cesium/pull/7255)
1418

1519
##### Fixes :wrench:

‎Source/Core/CesiumTerrainProvider.js

+283-43
Large diffs are not rendered by default.

‎Source/Core/EllipsoidTerrainProvider.js

+12
Original file line numberDiff line numberDiff line change
@@ -189,5 +189,17 @@ define([
189189
return undefined;
190190
};
191191

192+
/**
193+
* Makes sure we load availability data for a tile
194+
*
195+
* @param {Number} x The X coordinate of the tile for which to request geometry.
196+
* @param {Number} y The Y coordinate of the tile for which to request geometry.
197+
* @param {Number} level The level of the tile for which to request geometry.
198+
* @returns {undefined|Promise} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded
199+
*/
200+
EllipsoidTerrainProvider.prototype.loadTileDataAvailability = function(x, y, level) {
201+
return undefined;
202+
};
203+
192204
return EllipsoidTerrainProvider;
193205
});

‎Source/Core/GoogleEarthEnterpriseTerrainProvider.js

+12
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,18 @@ define([
580580
return false;
581581
};
582582

583+
/**
584+
* Makes sure we load availability data for a tile
585+
*
586+
* @param {Number} x The X coordinate of the tile for which to request geometry.
587+
* @param {Number} y The Y coordinate of the tile for which to request geometry.
588+
* @param {Number} level The level of the tile for which to request geometry.
589+
* @returns {undefined|Promise} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded
590+
*/
591+
GoogleEarthEnterpriseTerrainProvider.prototype.loadTileDataAvailability = function(x, y, level) {
592+
return undefined;
593+
};
594+
583595
//
584596
// Functions to handle imagery packets
585597
//

‎Source/Core/TerrainProvider.js

+10
Original file line numberDiff line numberDiff line change
@@ -227,5 +227,15 @@ define([
227227
*/
228228
TerrainProvider.prototype.getTileDataAvailable = DeveloperError.throwInstantiationError;
229229

230+
/**
231+
* Makes sure we load availability data for a tile
232+
*
233+
* @param {Number} x The X coordinate of the tile for which to request geometry.
234+
* @param {Number} y The Y coordinate of the tile for which to request geometry.
235+
* @param {Number} level The level of the tile for which to request geometry.
236+
* @returns {undefined|Promise} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded
237+
*/
238+
TerrainProvider.prototype.loadTileDataAvailability = DeveloperError.throwInstantiationError;
239+
230240
return TerrainProvider;
231241
});

‎Source/Core/VRTheWorldTerrainProvider.js

+12
Original file line numberDiff line numberDiff line change
@@ -355,5 +355,17 @@ define([
355355
return undefined;
356356
};
357357

358+
/**
359+
* Makes sure we load availability data for a tile
360+
*
361+
* @param {Number} x The X coordinate of the tile for which to request geometry.
362+
* @param {Number} y The Y coordinate of the tile for which to request geometry.
363+
* @param {Number} level The level of the tile for which to request geometry.
364+
* @returns {undefined|Promise} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded
365+
*/
366+
VRTheWorldTerrainProvider.prototype.loadTileDataAvailability = function(x, y, level) {
367+
return undefined;
368+
};
369+
358370
return VRTheWorldTerrainProvider;
359371
});

‎Source/Core/sampleTerrainMostDetailed.js

+61-23
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
define([
22
'../ThirdParty/when',
3+
'./Cartesian2',
34
'./defined',
45
'./DeveloperError',
56
'./sampleTerrain'
67
], function(
78
when,
9+
Cartesian2,
810
defined,
911
DeveloperError,
1012
sampleTerrain) {
1113
'use strict';
1214

15+
var scratchCartesian2 = new Cartesian2();
16+
1317
/**
1418
* Initiates a sampleTerrain() request at the maximum available tile level for a terrain dataset.
1519
*
@@ -43,36 +47,70 @@ define([
4347
}
4448
//>>includeEnd('debug');
4549

46-
return terrainProvider.readyPromise.then(function() {
47-
var byLevel = [];
50+
return terrainProvider.readyPromise
51+
.then(function() {
52+
var byLevel = [];
53+
var maxLevels = [];
4854

49-
var availability = terrainProvider.availability;
55+
var availability = terrainProvider.availability;
5056

51-
//>>includeStart('debug', pragmas.debug);
52-
if (!defined(availability)) {
53-
throw new DeveloperError('sampleTerrainMostDetailed requires a terrain provider that has tile availability.');
54-
}
55-
//>>includeEnd('debug');
57+
//>>includeStart('debug', pragmas.debug);
58+
if (!defined(availability)) {
59+
throw new DeveloperError('sampleTerrainMostDetailed requires a terrain provider that has tile availability.');
60+
}
61+
//>>includeEnd('debug');
5662

57-
for (var i = 0; i < positions.length; ++i) {
58-
var position = positions[i];
59-
var maxLevel = availability.computeMaximumLevelAtPosition(position);
63+
var promises = [];
64+
for (var i = 0; i < positions.length; ++i) {
65+
var position = positions[i];
66+
var maxLevel = availability.computeMaximumLevelAtPosition(position);
67+
maxLevels[i] = maxLevel;
68+
if (maxLevel === 0) {
69+
// This is a special case where we have a parent terrain and we are requesting
70+
// heights from an area that isn't covered by the top level terrain at all.
71+
// This will essentially trigger the loading of the parent terrains root tile
72+
terrainProvider.tilingScheme.positionToTileXY(position, 1, scratchCartesian2);
73+
var promise = terrainProvider.loadTileDataAvailability(scratchCartesian2.x, scratchCartesian2.y, 1);
74+
if (defined(promise)) {
75+
promises.push(promise);
76+
}
77+
}
6078

61-
var atLevel = byLevel[maxLevel];
62-
if (!defined(atLevel)) {
63-
byLevel[maxLevel] = atLevel = [];
79+
var atLevel = byLevel[maxLevel];
80+
if (!defined(atLevel)) {
81+
byLevel[maxLevel] = atLevel = [];
82+
}
83+
atLevel.push(position);
6484
}
65-
atLevel.push(position);
66-
}
6785

68-
return when.all(byLevel.map(function(positionsAtLevel, index) {
69-
if (defined(positionsAtLevel)) {
70-
return sampleTerrain(terrainProvider, index, positionsAtLevel);
71-
}
72-
})).then(function() {
73-
return positions;
86+
return when.all(promises)
87+
.then(function() {
88+
return when.all(byLevel.map(function(positionsAtLevel, index) {
89+
if (defined(positionsAtLevel)) {
90+
return sampleTerrain(terrainProvider, index, positionsAtLevel);
91+
}
92+
}));
93+
})
94+
.then(function() {
95+
var changedPositions = [];
96+
for (var i = 0; i < positions.length; ++i) {
97+
var position = positions[i];
98+
var maxLevel = availability.computeMaximumLevelAtPosition(position);
99+
100+
if (maxLevel !== maxLevels[i]) {
101+
// Now that we loaded the max availability, a higher level has become available
102+
changedPositions.push(position);
103+
}
104+
}
105+
106+
if (changedPositions.length > 0) {
107+
return sampleTerrainMostDetailed(terrainProvider, changedPositions);
108+
}
109+
})
110+
.then(function() {
111+
return positions;
112+
});
74113
});
75-
});
76114
}
77115

78116
return sampleTerrainMostDetailed;

‎Specs/Core/CesiumTerrainProviderSpec.js

+54
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ defineSuite([
8989
};
9090
}
9191

92+
function returnMetadataAvailabilityTileJson() {
93+
return returnTileJson('Data/CesiumTerrainTileJson/MetadataAvailability.tile.json');
94+
}
95+
9296
function waitForTile(level, x, y, requestNormals, requestWaterMask, f) {
9397
var terrainProvider = new CesiumTerrainProvider({
9498
url : 'made/up/url',
@@ -652,6 +656,33 @@ defineSuite([
652656
});
653657
});
654658

659+
it('provides QuantizedMeshTerrainData with Metadata availability', function() {
660+
Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) {
661+
Resource._DefaultImplementations.loadWithXhr('Data/CesiumTerrainTileJson/tile.metadataavailability.terrain', responseType, method, data, headers, deferred);
662+
};
663+
664+
returnMetadataAvailabilityTileJson();
665+
666+
var terrainProvider = new CesiumTerrainProvider({
667+
url : 'made/up/url'
668+
});
669+
670+
return pollToPromise(function() {
671+
return terrainProvider.ready;
672+
}).then(function() {
673+
expect(terrainProvider.hasMetadata).toBe(true);
674+
expect(terrainProvider._layers[0].availabilityLevels).toBe(10);
675+
expect(terrainProvider.availability.isTileAvailable(0,0,0)).toBe(true);
676+
expect(terrainProvider.availability.isTileAvailable(0,1,0)).toBe(true);
677+
expect(terrainProvider.availability.isTileAvailable(1,0,0)).toBe(false);
678+
679+
return terrainProvider.requestTileGeometry(0, 0, 0);
680+
}).then(function(loadedData) {
681+
expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData);
682+
expect(terrainProvider.availability.isTileAvailable(1,0,0)).toBe(true);
683+
});
684+
});
685+
655686
it('returns undefined if too many requests are already in progress', function() {
656687
var baseUrl = 'made/up/url';
657688

@@ -726,6 +757,29 @@ defineSuite([
726757
});
727758
});
728759

760+
it('getTileDataAvailable() with Metadata availability', function() {
761+
Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) {
762+
Resource._DefaultImplementations.loadWithXhr('Data/CesiumTerrainTileJson/tile.metadataavailability.terrain', responseType, method, data, headers, deferred);
763+
};
764+
765+
returnMetadataAvailabilityTileJson();
766+
767+
var terrainProvider = new CesiumTerrainProvider({
768+
url : 'made/up/url'
769+
});
770+
771+
return pollToPromise(function() {
772+
return terrainProvider.ready;
773+
}).then(function() {
774+
expect(terrainProvider.getTileDataAvailable(0,0,0)).toBe(true);
775+
expect(terrainProvider.getTileDataAvailable(0,0,1)).toBeUndefined();
776+
777+
return terrainProvider.requestTileGeometry(0, 0, 0);
778+
}).then(function() {
779+
expect(terrainProvider.getTileDataAvailable(0,0,1)).toBe(true);
780+
});
781+
});
782+
729783
it('supports a query string in the base URL', function() {
730784
Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) {
731785
// Just return any old file, as long as its big enough
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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 commit comments

Comments
 (0)
Please sign in to comment.