Skip to content

Commit

Permalink
Async event handler for terrain providers
Browse files Browse the repository at this point in the history
  • Loading branch information
ggetz committed Feb 8, 2023
1 parent b5233df commit b6b0663
Show file tree
Hide file tree
Showing 12 changed files with 469 additions and 108 deletions.
18 changes: 9 additions & 9 deletions Apps/CesiumViewer/CesiumViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ if (window.CESIUM_BASE_URL === undefined) {

import {
Cartesian3,
createWorldTerrainAsync,
defined,
formatError,
Math as CesiumMath,
Expand All @@ -14,6 +13,7 @@ import {
GeoJsonDataSource,
KmlDataSource,
GpxDataSource,
Terrain,
TileMapServiceImageryProvider,
Viewer,
viewerCesiumInspectorMixin,
Expand Down Expand Up @@ -50,21 +50,21 @@ async function main() {
}

const loadingIndicator = document.getElementById("loadingIndicator");
let viewer;
try {
const hasBaseLayerPicker = !defined(imageryProvider);
const hasBaseLayerPicker = !defined(imageryProvider);

const terrainProvider = await createWorldTerrainAsync({
requestWaterMask: true,
requestVertexNormals: true,
});
const terrain = Terrain.fromWorldTerrain({
requestWaterMask: true,
requestVertexNormals: true,
});

let viewer;
try {
viewer = new Viewer("cesiumContainer", {
imageryProvider: imageryProvider,
baseLayerPicker: hasBaseLayerPicker,
scene3DOnly: endUserOptions.scene3DOnly,
requestRenderMode: true,
terrainProvider: terrainProvider,
terrain: terrain,
});

if (hasBaseLayerPicker) {
Expand Down
83 changes: 44 additions & 39 deletions Apps/Sandcastle/gallery/Terrain.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,12 @@
window.startup = function (Cesium) {
"use strict";
//Sandcastle_Begin
const viewer = new Cesium.Viewer("cesiumContainer");

(async () => {
try {
viewer.terrainProvider = await Cesium.createWorldTerrainAsync({
requestWaterMask: true,
requestVertexNormals: true,
});
} catch (error) {
console.log(error);
}
})();
const viewer = new Cesium.Viewer("cesiumContainer", {
terrain: Cesium.Terrain.fromWorldTerrain({
requestWaterMask: true,
requestVertexNormals: true,
}),
});

// set lighting to true
viewer.scene.globe.enableLighting = true;
Expand Down Expand Up @@ -91,36 +85,41 @@
[
{
text: "CesiumTerrainProvider - Cesium World Terrain",
onselect: async function () {
const provider = await Cesium.createWorldTerrainAsync({
requestWaterMask: true,
requestVertexNormals: true,
});
viewer.terrainProvider = provider;
onselect: function () {
viewer.scene.setTerrain(
Cesium.Terrain.fromWorldTerrain({
requestWaterMask: true,
requestVertexNormals: true,
})
);
viewer.scene.globe.enableLighting = true;
},
},
{
text: "CesiumTerrainProvider - Cesium World Terrain - no effects",
onselect: async function () {
viewer.terrainProvider = await Cesium.createWorldTerrainAsync();
onselect: function () {
viewer.scene.setTerrain(Cesium.Terrain.fromWorldTerrain());
},
},
{
text: "CesiumTerrainProvider - Cesium World Terrain w/ Lighting",
onselect: async function () {
viewer.terrainProvider = await Cesium.createWorldTerrainAsync({
requestVertexNormals: true,
});
onselect: function () {
viewer.scene.setTerrain(
Cesium.Terrain.fromWorldTerrain({
requestVertexNormals: true,
})
);
viewer.scene.globe.enableLighting = true;
},
},
{
text: "CesiumTerrainProvider - Cesium World Terrain w/ Water",
onselect: async function () {
viewer.terrainProvider = await Cesium.createWorldTerrainAsync({
requestWaterMask: true,
});
onselect: function () {
viewer.scene.setTerrain(
Cesium.Terrain.fromWorldTerrain({
requestWaterMask: true,
})
);
},
},
{
Expand All @@ -137,23 +136,29 @@
},
{
text: "VRTheWorldTerrainProvider",
onselect: async function () {
const provider = await Cesium.VRTheWorldTerrainProvider.fromUrl(
"http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/",
{
credit: "Terrain data courtesy VT MÄK",
}
onselect: function () {
viewer.scene.setTerrain(
new Cesium.Terrain(
Cesium.VRTheWorldTerrainProvider.fromUrl(
"http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/",
{
credit: "Terrain data courtesy VT MÄK",
}
)
)
);
viewer.terrainProvider = provider;
},
},
{
text: "ArcGISTerrainProvider",
onselect: async function () {
const provider = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl(
"https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer"
onselect: function () {
viewer.scene.setTerrain(
new Cesium.Terrain(
Cesium.ArcGISTiledElevationTerrainProvider.fromUrl(
"https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer"
)
)
);
viewer.terrainProvider = provider;
},
},
],
Expand Down
1 change: 1 addition & 0 deletions packages/engine/Source/Scene/Globe.js
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,7 @@ Globe.prototype.beginFrame = function (frameState) {
const terrainProvider = this.terrainProvider;
const hasWaterMask =
this.showWaterEffect &&
defined(terrainProvider) &&
terrainProvider.hasWaterMask &&
// ready is deprecated; This is here for backwards compatibility
terrainProvider._ready;
Expand Down
13 changes: 7 additions & 6 deletions packages/engine/Source/Scene/GlobeSurfaceTileProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ Object.defineProperties(GlobeSurfaceTileProvider.prototype, {
ready: {
get: function () {
return (
defined(this._terrainProvider) &&
// ready is deprecated; This is here for backwards compatibility
this._terrainProvider._ready &&
(this._imageryLayers.length === 0 ||
Expand Down Expand Up @@ -295,12 +296,6 @@ Object.defineProperties(GlobeSurfaceTileProvider.prototype, {
return;
}

//>>includeStart('debug', pragmas.debug);
if (!defined(terrainProvider)) {
throw new DeveloperError("terrainProvider is required.");
}
//>>includeEnd('debug');

this._terrainProvider = terrainProvider;

if (defined(this._quadtree)) {
Expand Down Expand Up @@ -350,6 +345,7 @@ GlobeSurfaceTileProvider.prototype.update = function (frameState) {
function updateCredits(surface, frameState) {
const creditDisplay = frameState.creditDisplay;
if (
defined(surface._terrainProvider) &&
// ready is deprecated; This is here for backwards compatibility
surface._terrainProvider._ready &&
defined(surface._terrainProvider.credit)
Expand Down Expand Up @@ -573,6 +569,10 @@ GlobeSurfaceTileProvider.prototype.cancelReprojections = function () {
GlobeSurfaceTileProvider.prototype.getLevelMaximumGeometricError = function (
level
) {
if (!defined(this._terrainProvider)) {
return 0;
}

return this._terrainProvider.getLevelMaximumGeometricError(level);
};

Expand Down Expand Up @@ -2126,6 +2126,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
const oceanNormalMap = tileProvider.oceanNormalMap;
const showOceanWaves = showReflectiveOcean && defined(oceanNormalMap);
const hasVertexNormals =
defined(tileProvider.terrainProvider) &&
// ready is deprecated; This is here for backwards compatibility
tileProvider.terrainProvider._ready &&
tileProvider.terrainProvider.hasVertexNormals;
Expand Down
7 changes: 4 additions & 3 deletions packages/engine/Source/Scene/ImageryLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ ImageryLayer.prototype.getViewableRectangle = function () {
* @private
*
* @param {Tile} tile The terrain tile.
* @param {TerrainProvider} terrainProvider The terrain provider associated with the terrain tile.
* @param {TerrainProvider|undefined} terrainProvider The terrain provider associated with the terrain tile.
* @param {Number} insertionPoint The position to insert new skeletons before in the tile's imagery list.
* @returns {Boolean} true if this layer overlaps any portion of the terrain tile; otherwise, false.
*/
Expand All @@ -523,8 +523,9 @@ ImageryLayer.prototype._createTileImagerySkeletons = function (
const surfaceTile = tile.data;

if (
defined(this._minimumTerrainLevel) &&
tile.level < this._minimumTerrainLevel
!defined(terrainProvider) ||
(defined(this._minimumTerrainLevel) &&
tile.level < this._minimumTerrainLevel)
) {
return false;
}
Expand Down
59 changes: 59 additions & 0 deletions packages/engine/Source/Scene/Scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import BoundingSphere from "../Core/BoundingSphere.js";
import BoxGeometry from "../Core/BoxGeometry.js";
import Cartesian3 from "../Core/Cartesian3.js";
import Cartographic from "../Core/Cartographic.js";
import Check from "../Core/Check.js";
import clone from "../Core/clone.js";
import Color from "../Core/Color.js";
import ColorGeometryInstanceAttribute from "../Core/ColorGeometryInstanceAttribute.js";
Expand Down Expand Up @@ -638,6 +639,7 @@ function Scene(options) {
requestRenderAfterFrame(this)
);
this._removeGlobeCallbacks = [];
this._removeTerrainProviderReadyListener = undefined;

const viewport = new BoundingRectangle(
0,
Expand Down Expand Up @@ -1104,6 +1106,11 @@ Object.defineProperties(Scene.prototype, {
return this.globe.terrainProvider;
},
set: function (terrainProvider) {
// Cancel any in-progress terrain update
this._removeTerrainProviderReadyListener =
this._removeTerrainProviderReadyListener &&
this._removeTerrainProviderReadyListener();

if (defined(this.globe)) {
this.globe.terrainProvider = terrainProvider;
}
Expand Down Expand Up @@ -4377,6 +4384,55 @@ Scene.prototype.morphTo3D = function (duration) {
this._transitioner.morphTo3D(duration, ellipsoid);
};

function setTerrain(scene, terrain) {
// Cancel any in-progress terrain update
scene._removeTerrainProviderReadyListener =
scene._removeTerrainProviderReadyListener &&
scene._removeTerrainProviderReadyListener();

// Set a placeholder
scene.globe.terrainProvider = undefined;

scene._removeTerrainProviderReadyListener = terrain.readyEvent.addEventListener(
(provider) => {
if (defined(scene) && defined(scene.globe)) {
scene.globe.terrainProvider = provider;
}

scene._removeTerrainProviderReadyListener();
}
);
}

/**
* Update the terrain providing surface geometry for the globe.
*
* @param {Terrain} terrain The terrain provider async helper
* @returns {Terrain} terrain The terrain provider async helper
*
* @example
* // Use Cesium World Terrain
* scene.setTerrain(Cesium.Terrain.fromWorldTerrain());
*
* @example
* // Use a custom terrain provider
* const terrain = new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl("https://myTestTerrain.com"));
* scene.setTerrain(terrain);
*
* terrain.errorEvent.addEventListener(error => {
* alert(`Encountered an error while creating terrain! ${error}`);
* });
*/
Scene.prototype.setTerrain = function (terrain) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("terrain", terrain);
//>>includeEnd('debug');

setTerrain(this, terrain);

return terrain;
};

/**
* Returns true if this object was destroyed; otherwise, false.
* <br /><br />
Expand Down Expand Up @@ -4421,6 +4477,9 @@ Scene.prototype.destroy = function () {
this._groundPrimitives =
this._groundPrimitives && this._groundPrimitives.destroy();
this._globe = this._globe && this._globe.destroy();
this._removeTerrainProviderReadyListener =
this._removeTerrainProviderReadyListener &&
this._removeTerrainProviderReadyListener();
this.skyBox = this.skyBox && this.skyBox.destroy();
this.skyAtmosphere = this.skyAtmosphere && this.skyAtmosphere.destroy();
this._debugSphere = this._debugSphere && this._debugSphere.destroy();
Expand Down
Loading

0 comments on commit b6b0663

Please sign in to comment.