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