diff --git a/Apps/Sandcastle/gallery/Profile Half Dome.html b/Apps/Sandcastle/gallery/Profile Half Dome.html new file mode 100644 index 000000000000..309bb6630c69 --- /dev/null +++ b/Apps/Sandcastle/gallery/Profile Half Dome.html @@ -0,0 +1,59 @@ + + + + + + + + + Cesium Demo + + + + + + +
+

Loading...

+
+ + + diff --git a/CHANGES.md b/CHANGES.md index 73be74ff0477..2a33288d87e0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,11 +3,14 @@ Change Log ### 1.2 - 2014-10-01 +* Deprecated + * Types implementing the `TerrainProvider` interface should now include the new `getTileDataAvailable` function. The function will be required starting in Cesium 1.04. * Added a constructor option to `Scene`, `CesiumWidget`, and `Viewer` to disable order independent translucency. * Eliminated imagery artifacts at some zoom levels due to Mercator reprojection. * Fixed a bug in `Model` where the wrong animations could be used when the model was created from glTF JSON instead of a url to a glTF file. [#2078](https://github.com/AnalyticalGraphicsInc/cesium/issues/2078) * Added support for WKID 102113 (equivalent to 102100) to `ArcGisMapServerImageryProvider`. +* Added `TerrainProvider.getTileDataAvailable` to improve tile loading performance when camera starts near globe. ### 1.1 - 2014-09-02 diff --git a/Source/Core/ArcGisImageServerTerrainProvider.js b/Source/Core/ArcGisImageServerTerrainProvider.js index 296355dc1a3c..9a702c36b633 100644 --- a/Source/Core/ArcGisImageServerTerrainProvider.js +++ b/Source/Core/ArcGisImageServerTerrainProvider.js @@ -244,5 +244,17 @@ define([ return this._levelZeroMaximumGeometricError / (1 << level); }; + /** + * Determines whether data for a tile is available to be loaded. + * + * @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 {Boolean} Undefined if not supported, otherwise true or false. + */ + ArcGisImageServerTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { + return undefined; + }; + return ArcGisImageServerTerrainProvider; }); \ No newline at end of file diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index 8e70b6003d94..dc518d0b11ca 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -635,5 +635,27 @@ define([ return false; } + /** + * Determines whether data for a tile is available to be loaded. + * + * @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 {Boolean} Undefined if not supported, otherwise true or false. + */ + CesiumTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { + var available = this._availableTiles; + + if (!available || available.length === 0) { + return undefined; + } else { + if (level >= available.length) { + return false; + } + var levelAvailable = available[level]; + return isTileInRange(levelAvailable, x, y); + } + }; + return CesiumTerrainProvider; }); \ No newline at end of file diff --git a/Source/Core/EllipsoidTerrainProvider.js b/Source/Core/EllipsoidTerrainProvider.js index 9d1242998011..810072e0bae8 100644 --- a/Source/Core/EllipsoidTerrainProvider.js +++ b/Source/Core/EllipsoidTerrainProvider.js @@ -166,5 +166,17 @@ define([ return this._levelZeroMaximumGeometricError / (1 << level); }; + /** + * Determines whether data for a tile is available to be loaded. + * + * @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 {Boolean} Undefined if not supported, otherwise true or false. + */ + EllipsoidTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { + return undefined; + }; + return EllipsoidTerrainProvider; }); \ No newline at end of file diff --git a/Source/Core/TerrainProvider.js b/Source/Core/TerrainProvider.js index 825a97d5fbe4..5843595715c8 100644 --- a/Source/Core/TerrainProvider.js +++ b/Source/Core/TerrainProvider.js @@ -192,5 +192,16 @@ define([ */ TerrainProvider.prototype.getLevelMaximumGeometricError = DeveloperError.throwInstantiationError; + /** + * Determines whether data for a tile is available to be loaded. + * @function + * + * @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 {Boolean} Undefined if not supported by the terrain provider, otherwise true or false. + */ + TerrainProvider.prototype.getTileDataAvailable = DeveloperError.throwInstantiationError; + return TerrainProvider; }); \ No newline at end of file diff --git a/Source/Core/VRTheWorldTerrainProvider.js b/Source/Core/VRTheWorldTerrainProvider.js index c6cef39f7d28..e27b416bd03d 100644 --- a/Source/Core/VRTheWorldTerrainProvider.js +++ b/Source/Core/VRTheWorldTerrainProvider.js @@ -335,5 +335,17 @@ define([ return !Rectangle.isEmpty(Rectangle.intersectWith(tileRectangle, rectangle, rectangleScratch)); } + /** + * Determines whether data for a tile is available to be loaded. + * + * @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 {Boolean} Undefined if not supported, otherwise true or false. + */ + VRTheWorldTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { + return undefined; + }; + return VRTheWorldTerrainProvider; }); \ No newline at end of file diff --git a/Source/Scene/GlobeSurfaceTile.js b/Source/Scene/GlobeSurfaceTile.js index 6906e0a621f4..a9b78624001b 100644 --- a/Source/Scene/GlobeSurfaceTile.js +++ b/Source/Scene/GlobeSurfaceTile.js @@ -7,6 +7,7 @@ define([ '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/deprecationWarning', '../Core/IntersectionTests', '../Core/PixelFormat', '../Core/Rectangle', @@ -27,6 +28,7 @@ define([ defaultValue, defined, defineProperties, + deprecationWarning, IntersectionTests, PixelFormat, Rectangle, @@ -378,7 +380,7 @@ define([ surfaceTile.upsampledTerrain = new TileTerrain(upsampleTileDetails); } - if (isDataAvailable(tile)) { + if (isDataAvailable(tile, terrainProvider)) { surfaceTile.loadedTerrain = new TileTerrain(); } @@ -618,7 +620,17 @@ define([ } } - function isDataAvailable(tile) { + function isDataAvailable(tile, terrainProvider) { + + if (defined(terrainProvider.getTileDataAvailable)) { + var tileDataAvailable = terrainProvider.getTileDataAvailable(tile.x, tile.y, tile.level); + if (defined(tileDataAvailable)) { + return tileDataAvailable; + } + } else { + deprecationWarning('TerrainProvider.getTileDataAvailable', 'TerrainProviders must now implement the getTileDataAvailable function.'); + } + var parent = tile.parent; if (!defined(parent)) { // Data is assumed to be available for root tiles. diff --git a/Specs/Core/CesiumTerrainProviderSpec.js b/Specs/Core/CesiumTerrainProviderSpec.js index 22f6abf8d2cf..0c0538f0377b 100644 --- a/Specs/Core/CesiumTerrainProviderSpec.js +++ b/Specs/Core/CesiumTerrainProviderSpec.js @@ -596,5 +596,42 @@ defineSuite([ } }); }); + + it('supports getTileDataAvailable()', function() { + var baseUrl = 'made/up/url'; + + loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + return loadWithXhr.defaultLoad('Data/CesiumTerrainTileJson/tile.terrain', responseType, method, data, headers, deferred); + }; + + returnQuantizedMeshTileJson(); + + var terrainProvider = new CesiumTerrainProvider({ + url : baseUrl + }); + + waitsFor(function() { + return terrainProvider.ready; + }); + + var loadedData; + + runs(function() { + var promise = terrainProvider.requestTileGeometry(0, 0, 0); + + when(promise, function(terrainData) { + loadedData = terrainData; + }); + }); + + waitsFor(function() { + return defined(loadedData); + }, 'request to complete'); + + runs(function() { + expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); + expect(terrainProvider.getTileDataAvailable(0, 0, 2)).toBe(false); + }); + }); }); }); diff --git a/Specs/Core/EllipsoidTerrainProviderSpec.js b/Specs/Core/EllipsoidTerrainProviderSpec.js index af62c2f5dfdd..d94002916ae8 100644 --- a/Specs/Core/EllipsoidTerrainProviderSpec.js +++ b/Specs/Core/EllipsoidTerrainProviderSpec.js @@ -1,10 +1,12 @@ /*global defineSuite*/ defineSuite([ 'Core/EllipsoidTerrainProvider', + 'Core/TerrainProvider', 'Specs/createContext', 'Specs/destroyContext' ], function( EllipsoidTerrainProvider, + TerrainProvider, createContext, destroyContext) { "use strict"; @@ -20,6 +22,10 @@ defineSuite([ destroyContext(context); }); + it('conforms to TerrainProvider interface', function() { + expect(EllipsoidTerrainProvider).toConformToInterface(TerrainProvider); + }); + it('requestTileGeometry creates terrain data.', function() { var terrain = new EllipsoidTerrainProvider(); var terrainData = terrain.requestTileGeometry(0, 0, 0); @@ -31,4 +37,9 @@ defineSuite([ expect(provider.errorEvent).toBeDefined(); expect(provider.errorEvent).toBe(provider.errorEvent); }); + + it('returns undefined on getTileDataAvailable()', function() { + var provider = new EllipsoidTerrainProvider(); + expect(provider.getTileDataAvailable()).toBeUndefined(); + }); }, 'WebGL'); \ No newline at end of file