From 487b5f8f46b76e75ca89bc991164ff69893f16c9 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Mon, 11 Jan 2021 14:46:53 -0500 Subject: [PATCH 1/4] changed TaskProcessor.maximumActiveTasks to infinity by default, added a throttle option to TerrainData.createMesh, and using options object for TerrainData.createMesh --- CHANGES.md | 10 ++ Source/Core/GoogleEarthEnterpriseMetadata.js | 5 +- .../Core/GoogleEarthEnterpriseTerrainData.js | 57 ++++--- .../GoogleEarthEnterpriseTerrainProvider.js | 5 +- Source/Core/HeightmapTerrainData.js | 99 ++++++------ Source/Core/QuantizedMeshTerrainData.js | 64 ++++---- Source/Core/TaskProcessor.js | 7 +- Source/Core/TerrainData.js | 20 ++- Source/Core/loadCRN.js | 5 +- Source/Scene/GlobeSurfaceTile.js | 23 ++- Source/Scene/Primitive.js | 10 +- Source/Scene/TerrainFillMesh.js | 23 ++- Source/Scene/Vector3DTileGeometry.js | 3 +- Source/Scene/Vector3DTilePoints.js | 5 +- Source/Scene/Vector3DTilePolygons.js | 5 +- Source/Scene/Vector3DTilePolylines.js | 3 +- .../GoogleEarthEnterpriseTerrainDataSpec.js | 148 +++++++++++------- Specs/Core/HeightmapTerrainDataSpec.js | 89 +++++++++-- Specs/Core/QuantizedMeshTerrainDataSpec.js | 147 +++++++++++++---- Specs/MockTerrainProvider.js | 6 +- 20 files changed, 494 insertions(+), 240 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4e4bc83d553e..a3f56981e7d2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,15 @@ # Change Log +### 1.78 - 2021-02-01 + +##### Additions :tada: + +- Added `Cartesian2.cross`. [#9305](https://github.com/CesiumGS/cesium/pull/9305) + +##### Breaking Changes :mega: + +- Changed the `TaskProcessor.maximumActiveTasks` constructor option to be infinity by default. + ### 1.77 - 2021-01-04 ##### Additions :tada: diff --git a/Source/Core/GoogleEarthEnterpriseMetadata.js b/Source/Core/GoogleEarthEnterpriseMetadata.js index da939555ae1c..feff17a4497f 100644 --- a/Source/Core/GoogleEarthEnterpriseMetadata.js +++ b/Source/Core/GoogleEarthEnterpriseMetadata.js @@ -291,10 +291,7 @@ GoogleEarthEnterpriseMetadata.prototype.isValid = function (quadKey) { return valid; }; -var taskProcessor = new TaskProcessor( - "decodeGoogleEarthEnterprisePacket", - Number.POSITIVE_INFINITY -); +var taskProcessor = new TaskProcessor("decodeGoogleEarthEnterprisePacket"); /** * Retrieves a Google Earth Enterprise quadtree packet. diff --git a/Source/Core/GoogleEarthEnterpriseTerrainData.js b/Source/Core/GoogleEarthEnterpriseTerrainData.js index f8137464e24f..aa375d6d6d2c 100644 --- a/Source/Core/GoogleEarthEnterpriseTerrainData.js +++ b/Source/Core/GoogleEarthEnterpriseTerrainData.js @@ -13,6 +13,7 @@ import QuantizedMeshTerrainData from "./QuantizedMeshTerrainData.js"; import Rectangle from "./Rectangle.js"; import TaskProcessor from "./TaskProcessor.js"; import TerrainEncoding from "./TerrainEncoding.js"; +import TerrainData from "./TerrainData.js"; import TerrainMesh from "./TerrainMesh.js"; /** @@ -116,8 +117,11 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainData.prototype, { }, }); -var taskProcessor = new TaskProcessor( - "createVerticesFromGoogleEarthEnterpriseBuffer" +var createMeshTaskName = "createVerticesFromGoogleEarthEnterpriseBuffer"; +var createMeshTaskProcessorNoThrottle = new TaskProcessor(createMeshTaskName); +var createMeshTaskProcessorThrottle = new TaskProcessor( + createMeshTaskName, + TerrainData.maximumAsynchronousTasks ); var nativeRectangleScratch = new Rectangle(); @@ -128,33 +132,37 @@ var rectangleScratch = new Rectangle(); * * @private * - * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} x The X coordinate of the tile for which to create the terrain data. - * @param {Number} y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} level The level of the tile for which to create the terrain data. - * @param {Number} [exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {Object} options Object with the following properties: + * @param {TilingScheme} options.tilingScheme The tiling scheme to which this tile belongs. + * @param {Number} options.x The X coordinate of the tile for which to create the terrain data. + * @param {Number} options.y The Y coordinate of the tile for which to create the terrain data. + * @param {Number} options.level The level of the tile for which to create the terrain data. + * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {Boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. * @returns {Promise.|undefined} A promise for the terrain mesh, or undefined if too many * asynchronous mesh creations are already in progress and the operation should * be retried later. */ -GoogleEarthEnterpriseTerrainData.prototype.createMesh = function ( - tilingScheme, - x, - y, - level, - exaggeration -) { +GoogleEarthEnterpriseTerrainData.prototype.createMesh = function (options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + //>>includeStart('debug', pragmas.debug); - Check.typeOf.object("tilingScheme", tilingScheme); - Check.typeOf.number("x", x); - Check.typeOf.number("y", y); - Check.typeOf.number("level", level); + Check.typeOf.object("options.tilingScheme", options.tilingScheme); + Check.typeOf.number("options.x", options.x); + Check.typeOf.number("options.y", options.y); + Check.typeOf.number("options.level", options.level); //>>includeEnd('debug'); + var tilingScheme = options.tilingScheme; + var x = options.x; + var y = options.y; + var level = options.level; + var exaggeration = defaultValue(options.exaggeration, 1.0); + var throttle = defaultValue(options.throttle, true); + var ellipsoid = tilingScheme.ellipsoid; tilingScheme.tileXYToNativeRectangle(x, y, level, nativeRectangleScratch); tilingScheme.tileXYToRectangle(x, y, level, rectangleScratch); - exaggeration = defaultValue(exaggeration, 1.0); // Compute the center of the tile for RTC rendering. var center = ellipsoid.cartographicToCartesian( @@ -165,7 +173,11 @@ GoogleEarthEnterpriseTerrainData.prototype.createMesh = function ( var thisLevelMaxError = levelZeroMaxError / (1 << level); this._skirtHeight = Math.min(thisLevelMaxError * 8.0, 1000.0); - var verticesPromise = taskProcessor.scheduleTask({ + var createMeshTaskProcessor = throttle + ? createMeshTaskProcessorThrottle + : createMeshTaskProcessorNoThrottle; + + var verticesPromise = createMeshTaskProcessor.scheduleTask({ buffer: this._buffer, nativeRectangle: nativeRectangleScratch, rectangle: rectangleScratch, @@ -249,7 +261,10 @@ GoogleEarthEnterpriseTerrainData.prototype.interpolateHeight = function ( return interpolateMeshHeight(this, u, v); }; -var upsampleTaskProcessor = new TaskProcessor("upsampleQuantizedTerrainMesh"); +var upsampleTaskProcessor = new TaskProcessor( + "upsampleQuantizedTerrainMesh", + TerrainData.maximumAsynchronousTasks +); /** * Upsamples this terrain data for use by a descendant tile. The resulting instance will contain a subset of the diff --git a/Source/Core/GoogleEarthEnterpriseTerrainProvider.js b/Source/Core/GoogleEarthEnterpriseTerrainProvider.js index d69cbfec5fdd..9d3e14079199 100644 --- a/Source/Core/GoogleEarthEnterpriseTerrainProvider.js +++ b/Source/Core/GoogleEarthEnterpriseTerrainProvider.js @@ -314,10 +314,7 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { }, }); -var taskProcessor = new TaskProcessor( - "decodeGoogleEarthEnterprisePacket", - Number.POSITIVE_INFINITY -); +var taskProcessor = new TaskProcessor("decodeGoogleEarthEnterprisePacket"); // If the tile has its own terrain, then you can just use its child bitmask. If it was requested using it's parent // then you need to check all of its children to see if they have terrain. diff --git a/Source/Core/HeightmapTerrainData.js b/Source/Core/HeightmapTerrainData.js index 949ce5c1b6d7..e83d22cb208e 100644 --- a/Source/Core/HeightmapTerrainData.js +++ b/Source/Core/HeightmapTerrainData.js @@ -1,6 +1,7 @@ import when from "../ThirdParty/when.js"; import BoundingSphere from "./BoundingSphere.js"; import Cartesian3 from "./Cartesian3.js"; +import Check from "./Check.js"; import defaultValue from "./defaultValue.js"; import defined from "./defined.js"; import DeveloperError from "./DeveloperError.js"; @@ -12,6 +13,7 @@ import OrientedBoundingBox from "./OrientedBoundingBox.js"; import Rectangle from "./Rectangle.js"; import TaskProcessor from "./TaskProcessor.js"; import TerrainEncoding from "./TerrainEncoding.js"; +import TerrainData from "./TerrainData.js"; import TerrainMesh from "./TerrainMesh.js"; import TerrainProvider from "./TerrainProvider.js"; @@ -182,48 +184,49 @@ Object.defineProperties(HeightmapTerrainData.prototype, { }, }); -var taskProcessor = new TaskProcessor("createVerticesFromHeightmap"); +var createMeshTaskName = "createVerticesFromHeightmap"; +var createMeshTaskProcessorNoThrottle = new TaskProcessor(createMeshTaskName); +var createMeshTaskProcessorThrottle = new TaskProcessor( + createMeshTaskName, + TerrainData.maximumAsynchronousTasks +); /** * Creates a {@link TerrainMesh} from this terrain data. * * @private * - * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} x The X coordinate of the tile for which to create the terrain data. - * @param {Number} y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} level The level of the tile for which to create the terrain data. - * @param {Number} [exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {Object} options Object with the following properties: + * @param {TilingScheme} options.tilingScheme The tiling scheme to which this tile belongs. + * @param {Number} options.x The X coordinate of the tile for which to create the terrain data. + * @param {Number} options.y The Y coordinate of the tile for which to create the terrain data. + * @param {Number} options.level The level of the tile for which to create the terrain data. + * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {Boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. * @returns {Promise.|undefined} A promise for the terrain mesh, or undefined if too many * asynchronous mesh creations are already in progress and the operation should * be retried later. */ -HeightmapTerrainData.prototype.createMesh = function ( - tilingScheme, - x, - y, - level, - exaggeration -) { +HeightmapTerrainData.prototype.createMesh = function (options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + //>>includeStart('debug', pragmas.debug); - if (!defined(tilingScheme)) { - throw new DeveloperError("tilingScheme is required."); - } - if (!defined(x)) { - throw new DeveloperError("x is required."); - } - if (!defined(y)) { - throw new DeveloperError("y is required."); - } - if (!defined(level)) { - throw new DeveloperError("level is required."); - } + Check.typeOf.object("options.tilingScheme", options.tilingScheme); + Check.typeOf.number("options.x", options.x); + Check.typeOf.number("options.y", options.y); + Check.typeOf.number("options.level", options.level); //>>includeEnd('debug'); + var tilingScheme = options.tilingScheme; + var x = options.x; + var y = options.y; + var level = options.level; + var exaggeration = defaultValue(options.exaggeration, 1.0); + var throttle = defaultValue(options.throttle, true); + var ellipsoid = tilingScheme.ellipsoid; var nativeRectangle = tilingScheme.tileXYToNativeRectangle(x, y, level); var rectangle = tilingScheme.tileXYToRectangle(x, y, level); - exaggeration = defaultValue(exaggeration, 1.0); // Compute the center of the tile for RTC rendering. var center = ellipsoid.cartographicToCartesian(Rectangle.center(rectangle)); @@ -238,7 +241,11 @@ HeightmapTerrainData.prototype.createMesh = function ( var thisLevelMaxError = levelZeroMaxError / (1 << level); this._skirtHeight = Math.min(thisLevelMaxError * 4.0, 1000.0); - var verticesPromise = taskProcessor.scheduleTask({ + var createMeshTaskProcessor = throttle + ? createMeshTaskProcessorThrottle + : createMeshTaskProcessorNoThrottle; + + var verticesPromise = createMeshTaskProcessor.scheduleTask({ heightmap: this._buffer, structure: structure, includeWebMercatorT: true, @@ -305,34 +312,32 @@ HeightmapTerrainData.prototype.createMesh = function ( }; /** + * @param {Object} options Object with the following properties: + * @param {TilingScheme} options.tilingScheme The tiling scheme to which this tile belongs. + * @param {Number} options.x The X coordinate of the tile for which to create the terrain data. + * @param {Number} options.y The Y coordinate of the tile for which to create the terrain data. + * @param {Number} options.level The level of the tile for which to create the terrain data. + * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * * @private */ -HeightmapTerrainData.prototype._createMeshSync = function ( - tilingScheme, - x, - y, - level, - exaggeration -) { +HeightmapTerrainData.prototype._createMeshSync = function (options) { //>>includeStart('debug', pragmas.debug); - if (!defined(tilingScheme)) { - throw new DeveloperError("tilingScheme is required."); - } - if (!defined(x)) { - throw new DeveloperError("x is required."); - } - if (!defined(y)) { - throw new DeveloperError("y is required."); - } - if (!defined(level)) { - throw new DeveloperError("level is required."); - } + Check.typeOf.object("options.tilingScheme", options.tilingScheme); + Check.typeOf.number("options.x", options.x); + Check.typeOf.number("options.y", options.y); + Check.typeOf.number("options.level", options.level); //>>includeEnd('debug'); + var tilingScheme = options.tilingScheme; + var x = options.x; + var y = options.y; + var level = options.level; + var exaggeration = defaultValue(options.exaggeration, 1.0); + var ellipsoid = tilingScheme.ellipsoid; var nativeRectangle = tilingScheme.tileXYToNativeRectangle(x, y, level); var rectangle = tilingScheme.tileXYToRectangle(x, y, level); - exaggeration = defaultValue(exaggeration, 1.0); // Compute the center of the tile for RTC rendering. var center = ellipsoid.cartographicToCartesian(Rectangle.center(rectangle)); diff --git a/Source/Core/QuantizedMeshTerrainData.js b/Source/Core/QuantizedMeshTerrainData.js index 8bd031b9174b..ebf65f8cfa14 100644 --- a/Source/Core/QuantizedMeshTerrainData.js +++ b/Source/Core/QuantizedMeshTerrainData.js @@ -2,6 +2,7 @@ import when from "../ThirdParty/when.js"; import BoundingSphere from "./BoundingSphere.js"; import Cartesian2 from "./Cartesian2.js"; import Cartesian3 from "./Cartesian3.js"; +import Check from "./Check.js"; import defaultValue from "./defaultValue.js"; import defined from "./defined.js"; import DeveloperError from "./DeveloperError.js"; @@ -10,6 +11,7 @@ import Intersections2D from "./Intersections2D.js"; import CesiumMath from "./Math.js"; import OrientedBoundingBox from "./OrientedBoundingBox.js"; import TaskProcessor from "./TaskProcessor.js"; +import TerrainData from "./TerrainData.js"; import TerrainEncoding from "./TerrainEncoding.js"; import TerrainMesh from "./TerrainMesh.js"; @@ -262,8 +264,11 @@ function sortIndicesIfNecessary(indices, sortFunction, vertexCount) { return indices; } -var createMeshTaskProcessor = new TaskProcessor( - "createVerticesFromQuantizedTerrainMesh" +var createMeshTaskName = "createVerticesFromQuantizedTerrainMesh"; +var createMeshTaskProcessorNoThrottle = new TaskProcessor(createMeshTaskName); +var createMeshTaskProcessorThrottle = new TaskProcessor( + createMeshTaskName, + TerrainData.maximumAsynchronousTasks ); /** @@ -271,40 +276,40 @@ var createMeshTaskProcessor = new TaskProcessor( * * @private * - * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} x The X coordinate of the tile for which to create the terrain data. - * @param {Number} y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} level The level of the tile for which to create the terrain data. - * @param {Number} [exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {Object} options Object with the following properties: + * @param {TilingScheme} options.tilingScheme The tiling scheme to which this tile belongs. + * @param {Number} options.x The X coordinate of the tile for which to create the terrain data. + * @param {Number} options.y The Y coordinate of the tile for which to create the terrain data. + * @param {Number} options.level The level of the tile for which to create the terrain data. + * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {Boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. * @returns {Promise.|undefined} A promise for the terrain mesh, or undefined if too many * asynchronous mesh creations are already in progress and the operation should * be retried later. */ -QuantizedMeshTerrainData.prototype.createMesh = function ( - tilingScheme, - x, - y, - level, - exaggeration -) { +QuantizedMeshTerrainData.prototype.createMesh = function (options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + //>>includeStart('debug', pragmas.debug); - if (!defined(tilingScheme)) { - throw new DeveloperError("tilingScheme is required."); - } - if (!defined(x)) { - throw new DeveloperError("x is required."); - } - if (!defined(y)) { - throw new DeveloperError("y is required."); - } - if (!defined(level)) { - throw new DeveloperError("level is required."); - } + Check.typeOf.object("options.tilingScheme", options.tilingScheme); + Check.typeOf.number("options.x", options.x); + Check.typeOf.number("options.y", options.y); + Check.typeOf.number("options.level", options.level); //>>includeEnd('debug'); + var tilingScheme = options.tilingScheme; + var x = options.x; + var y = options.y; + var level = options.level; + var exaggeration = defaultValue(options.exaggeration, 1.0); + var throttle = defaultValue(options.throttle, true); + var ellipsoid = tilingScheme.ellipsoid; var rectangle = tilingScheme.tileXYToRectangle(x, y, level); - exaggeration = defaultValue(exaggeration, 1.0); + + var createMeshTaskProcessor = throttle + ? createMeshTaskProcessorThrottle + : createMeshTaskProcessorNoThrottle; var verticesPromise = createMeshTaskProcessor.scheduleTask({ minimumHeight: this._minimumHeight, @@ -405,7 +410,10 @@ QuantizedMeshTerrainData.prototype.createMesh = function ( }); }; -var upsampleTaskProcessor = new TaskProcessor("upsampleQuantizedTerrainMesh"); +var upsampleTaskProcessor = new TaskProcessor( + "upsampleQuantizedTerrainMesh", + TerrainData.maximumAsynchronousTasks +); /** * Upsamples this terrain data for use by a descendant tile. The resulting instance will contain a subset of the diff --git a/Source/Core/TaskProcessor.js b/Source/Core/TaskProcessor.js index 140474748767..af35138b4cc7 100644 --- a/Source/Core/TaskProcessor.js +++ b/Source/Core/TaskProcessor.js @@ -195,13 +195,16 @@ function getWebAssemblyLoaderConfig(processor, wasmOptions) { * * @param {String} workerName The name of the worker. This is expected to be a script * in the Workers folder. - * @param {Number} [maximumActiveTasks=5] The maximum number of active tasks. Once exceeded, + * @param {Number} [maximumActiveTasks=Number.POSITIVE_INFINITY] The maximum number of active tasks. Once exceeded, * scheduleTask will not queue any more tasks, allowing * work to be rescheduled in future frames. */ function TaskProcessor(workerName, maximumActiveTasks) { this._workerName = workerName; - this._maximumActiveTasks = defaultValue(maximumActiveTasks, 5); + this._maximumActiveTasks = defaultValue( + maximumActiveTasks, + Number.POSITIVE_INFINITY + ); this._activeTasks = 0; this._deferreds = {}; this._nextID = 0; diff --git a/Source/Core/TerrainData.js b/Source/Core/TerrainData.js index a76e95e998f4..9376ead48370 100644 --- a/Source/Core/TerrainData.js +++ b/Source/Core/TerrainData.js @@ -71,10 +71,13 @@ TerrainData.prototype.isChildAvailable = DeveloperError.throwInstantiationError; * * @private * - * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} x The X coordinate of the tile for which to create the terrain data. - * @param {Number} y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} level The level of the tile for which to create the terrain data. + * @param {Object} options Object with the following properties: + * @param {TilingScheme} options.tilingScheme The tiling scheme to which this tile belongs. + * @param {Number} options.x The X coordinate of the tile for which to create the terrain data. + * @param {Number} options.y The Y coordinate of the tile for which to create the terrain data. + * @param {Number} options.level The level of the tile for which to create the terrain data. + * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {Boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. * @returns {Promise.|undefined} A promise for the terrain mesh, or undefined if too many * asynchronous mesh creations are already in progress and the operation should * be retried later. @@ -109,4 +112,13 @@ TerrainData.prototype.upsample = DeveloperError.throwInstantiationError; */ TerrainData.prototype.wasCreatedByUpsampling = DeveloperError.throwInstantiationError; + +/** + * The maximum number of asynchronous tasks used for terrain processing. + * + * @type {Number} + * @private + */ +TerrainData.maximumAsynchronousTasks = 5; + export default TerrainData; diff --git a/Source/Core/loadCRN.js b/Source/Core/loadCRN.js index c7676364cc13..c1583f3a7a67 100644 --- a/Source/Core/loadCRN.js +++ b/Source/Core/loadCRN.js @@ -5,10 +5,7 @@ import DeveloperError from "./DeveloperError.js"; import Resource from "./Resource.js"; import TaskProcessor from "./TaskProcessor.js"; -var transcodeTaskProcessor = new TaskProcessor( - "transcodeCRNToDXT", - Number.POSITIVE_INFINITY -); +var transcodeTaskProcessor = new TaskProcessor("transcodeCRNToDXT"); /** * Asynchronously loads and parses the given URL to a CRN file or parses the raw binary data of a CRN file. diff --git a/Source/Scene/GlobeSurfaceTile.js b/Source/Scene/GlobeSurfaceTile.js index 1034d7706bc9..330430c472e4 100644 --- a/Source/Scene/GlobeSurfaceTile.js +++ b/Source/Scene/GlobeSurfaceTile.js @@ -627,17 +627,26 @@ function requestTileGeometry(surfaceTile, terrainProvider, x, y, level) { doRequest(); } +var scratchCreateMeshOptions = { + tilingScheme: undefined, + x: 0, + y: 0, + level: 0, + exaggeration: 1.0, +}; + function transform(surfaceTile, frameState, terrainProvider, x, y, level) { var tilingScheme = terrainProvider.tilingScheme; + var createMeshOptions = scratchCreateMeshOptions; + createMeshOptions.tilingScheme = tilingScheme; + createMeshOptions.x = x; + createMeshOptions.y = y; + createMeshOptions.level = level; + createMeshOptions.exaggeration = frameState.exaggeration; + var terrainData = surfaceTile.terrainData; - var meshPromise = terrainData.createMesh( - tilingScheme, - x, - y, - level, - frameState.terrainExaggeration - ); + var meshPromise = terrainData.createMesh(createMeshOptions); if (!defined(meshPromise)) { // Postponed. diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 465362ea8836..909ab72da3ec 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -1202,10 +1202,7 @@ var numberOfCreationWorkers = Math.max( 1 ); var createGeometryTaskProcessors; -var combineGeometryTaskProcessor = new TaskProcessor( - "combineGeometry", - Number.POSITIVE_INFINITY -); +var combineGeometryTaskProcessor = new TaskProcessor("combineGeometry"); function loadAsynchronous(primitive, frameState) { var instances; @@ -1244,10 +1241,7 @@ function loadAsynchronous(primitive, frameState) { if (!defined(createGeometryTaskProcessors)) { createGeometryTaskProcessors = new Array(numberOfCreationWorkers); for (i = 0; i < numberOfCreationWorkers; i++) { - createGeometryTaskProcessors[i] = new TaskProcessor( - "createGeometry", - Number.POSITIVE_INFINITY - ); + createGeometryTaskProcessors[i] = new TaskProcessor("createGeometry"); } } diff --git a/Source/Scene/TerrainFillMesh.js b/Source/Scene/TerrainFillMesh.js index 5b1ed66a82e1..80b2b0b1d62a 100644 --- a/Source/Scene/TerrainFillMesh.js +++ b/Source/Scene/TerrainFillMesh.js @@ -807,6 +807,13 @@ var neVertexScratch = new HeightAndNormal(); var heightmapBuffer = typeof Uint8Array !== "undefined" ? new Uint8Array(9 * 9) : undefined; +var scratchCreateMeshOptions = { + tilingScheme: undefined, + x: 0, + y: 0, + level: 0, + exaggeration: 1.0, +}; function createFillMesh(tileProvider, frameState, tile, vertexArraysToDestroy) { GlobeSurfaceTile.initialize( tile, @@ -973,13 +980,15 @@ function createFillMesh(tileProvider, frameState, tile, vertexArraysToDestroy) { heightOffset: maximumHeight, }, }); - fill.mesh = terrainData._createMeshSync( - tile.tilingScheme, - tile.x, - tile.y, - tile.level, - 1.0 - ); + + var createMeshOptions = scratchCreateMeshOptions; + createMeshOptions.tilingScheme = tile.tilingScheme; + createMeshOptions.x = tile.x; + createMeshOptions.y = tile.y; + createMeshOptions.level = tile.level; + createMeshOptions.exaggeration = 1.0; + + fill.mesh = terrainData._createMeshSync(createMeshOptions); } else { var encoding = new TerrainEncoding( undefined, diff --git a/Source/Scene/Vector3DTileGeometry.js b/Source/Scene/Vector3DTileGeometry.js index 63e8ca8b74b3..dedaef7aa996 100644 --- a/Source/Scene/Vector3DTileGeometry.js +++ b/Source/Scene/Vector3DTileGeometry.js @@ -210,7 +210,8 @@ function unpackBuffer(geometries, packedBuffer) { } var createVerticesTaskProcessor = new TaskProcessor( - "createVectorTileGeometries" + "createVectorTileGeometries", + 5 ); var scratchColor = new Color(); diff --git a/Source/Scene/Vector3DTilePoints.js b/Source/Scene/Vector3DTilePoints.js index b6cd9346dc90..d4d12de11cd7 100644 --- a/Source/Scene/Vector3DTilePoints.js +++ b/Source/Scene/Vector3DTilePoints.js @@ -122,7 +122,10 @@ function packBuffer(points, ellipsoid) { return packedBuffer; } -var createVerticesTaskProcessor = new TaskProcessor("createVectorTilePoints"); +var createVerticesTaskProcessor = new TaskProcessor( + "createVectorTilePoints", + 5 +); var scratchPosition = new Cartesian3(); function createPoints(points, ellipsoid) { diff --git a/Source/Scene/Vector3DTilePolygons.js b/Source/Scene/Vector3DTilePolygons.js index afe4f440b18e..bdbcf35eec49 100644 --- a/Source/Scene/Vector3DTilePolygons.js +++ b/Source/Scene/Vector3DTilePolygons.js @@ -215,7 +215,10 @@ function unpackBuffer(polygons, packedBuffer) { } } -var createVerticesTaskProcessor = new TaskProcessor("createVectorTilePolygons"); +var createVerticesTaskProcessor = new TaskProcessor( + "createVectorTilePolygons", + 5 +); var scratchColor = new Color(); function createPrimitive(polygons) { diff --git a/Source/Scene/Vector3DTilePolylines.js b/Source/Scene/Vector3DTilePolylines.js index 6f4f31bed62d..3473c5ba2c8d 100644 --- a/Source/Scene/Vector3DTilePolylines.js +++ b/Source/Scene/Vector3DTilePolylines.js @@ -161,7 +161,8 @@ function packBuffer(polylines) { } var createVerticesTaskProcessor = new TaskProcessor( - "createVectorTilePolylines" + "createVectorTilePolylines", + 5 ); var attributeLocations = { previousPosition: 0, diff --git a/Specs/Core/GoogleEarthEnterpriseTerrainDataSpec.js b/Specs/Core/GoogleEarthEnterpriseTerrainDataSpec.js index d74dfd3de467..814267b5a0a7 100644 --- a/Specs/Core/GoogleEarthEnterpriseTerrainDataSpec.js +++ b/Specs/Core/GoogleEarthEnterpriseTerrainDataSpec.js @@ -146,7 +146,14 @@ describe("Core/GoogleEarthEnterpriseTerrainData", function () { tilingScheme.tileXYToRectangle(1, 1, 1), ]; - return when(data.createMesh(tilingScheme, 0, 0, 0, 1)) + return when( + data.createMesh({ + tilingScheme: tilingScheme, + x: 0, + y: 0, + level: 0, + }) + ) .then(function () { var swPromise = data.upsample(tilingScheme, 0, 0, 0, 0, 0, 1); var sePromise = data.upsample(tilingScheme, 0, 0, 0, 1, 0, 1); @@ -247,25 +254,45 @@ describe("Core/GoogleEarthEnterpriseTerrainData", function () { it("requires tilingScheme", function () { expect(function () { - data.createMesh(undefined, 0, 0, 0); + data.createMesh({ + tilingScheme: undefined, + x: 0, + y: 0, + level: 0, + }); }).toThrowDeveloperError(); }); it("requires x", function () { expect(function () { - data.createMesh(tilingScheme, undefined, 0, 0); + data.createMesh({ + tilingScheme: tilingScheme, + x: undefined, + y: 0, + level: 0, + }); }).toThrowDeveloperError(); }); it("requires y", function () { expect(function () { - data.createMesh(tilingScheme, 0, undefined, 0); + data.createMesh({ + tilingScheme: tilingScheme, + x: 0, + y: undefined, + level: 0, + }); }).toThrowDeveloperError(); }); it("requires level", function () { expect(function () { - data.createMesh(tilingScheme, 0, 0, undefined); + data.createMesh({ + tilingScheme: tilingScheme, + x: 0, + y: 0, + level: undefined, + }); }).toThrowDeveloperError(); }); @@ -273,59 +300,74 @@ describe("Core/GoogleEarthEnterpriseTerrainData", function () { var rectangle = tilingScheme.tileXYToRectangle(0, 0, 0); var wgs84 = Ellipsoid.WGS84; - return data.createMesh(tilingScheme, 0, 0, 0).then(function (mesh) { - expect(mesh).toBeInstanceOf(TerrainMesh); - expect(mesh.vertices.length).toBe(17 * mesh.encoding.getStride()); // 9 regular + 8 skirt vertices - expect(mesh.indices.length).toBe(4 * 6 * 3); // 2 regular + 4 skirt triangles per quad - expect(mesh.minimumHeight).toBe(0); - expect(mesh.maximumHeight).toBeCloseTo(20, 5); - - var encoding = mesh.encoding; - var cartesian = new Cartesian3(); - var cartographic = new Cartographic(); - var count = mesh.vertices.length / mesh.encoding.getStride(); - for (var i = 0; i < count; ++i) { - var height = encoding.decodeHeight(mesh.vertices, i); - if (i < 9) { - // Original vertices - expect(height).toBeBetween(0, 20); - - // Only test on original positions as the skirts angle outward - encoding.decodePosition(mesh.vertices, i, cartesian); - wgs84.cartesianToCartographic(cartesian, cartographic); - cartographic.longitude = CesiumMath.convertLongitudeRange( - cartographic.longitude - ); - expect(Rectangle.contains(rectangle, cartographic)).toBe(true); - } else { - // Skirts - expect(height).toBeBetween(-1000, -980); + return data + .createMesh({ + tilingScheme: tilingScheme, + x: 0, + y: 0, + level: 0, + }) + .then(function (mesh) { + expect(mesh).toBeInstanceOf(TerrainMesh); + expect(mesh.vertices.length).toBe(17 * mesh.encoding.getStride()); // 9 regular + 8 skirt vertices + expect(mesh.indices.length).toBe(4 * 6 * 3); // 2 regular + 4 skirt triangles per quad + expect(mesh.minimumHeight).toBe(0); + expect(mesh.maximumHeight).toBeCloseTo(20, 5); + + var encoding = mesh.encoding; + var cartesian = new Cartesian3(); + var cartographic = new Cartographic(); + var count = mesh.vertices.length / mesh.encoding.getStride(); + for (var i = 0; i < count; ++i) { + var height = encoding.decodeHeight(mesh.vertices, i); + if (i < 9) { + // Original vertices + expect(height).toBeBetween(0, 20); + + // Only test on original positions as the skirts angle outward + encoding.decodePosition(mesh.vertices, i, cartesian); + wgs84.cartesianToCartographic(cartesian, cartographic); + cartographic.longitude = CesiumMath.convertLongitudeRange( + cartographic.longitude + ); + expect(Rectangle.contains(rectangle, cartographic)).toBe(true); + } else { + // Skirts + expect(height).toBeBetween(-1000, -980); + } } - } - }); + }); }); it("exaggerates mesh", function () { - return data.createMesh(tilingScheme, 0, 0, 0, 2).then(function (mesh) { - expect(mesh).toBeInstanceOf(TerrainMesh); - expect(mesh.vertices.length).toBe(17 * mesh.encoding.getStride()); // 9 regular + 8 skirt vertices - expect(mesh.indices.length).toBe(4 * 6 * 3); // 2 regular + 4 skirt triangles per quad - expect(mesh.minimumHeight).toBe(0); - expect(mesh.maximumHeight).toBeCloseTo(40, 5); - - var encoding = mesh.encoding; - var count = mesh.vertices.length / mesh.encoding.getStride(); - for (var i = 0; i < count; ++i) { - var height = encoding.decodeHeight(mesh.vertices, i); - if (i < 9) { - // Original vertices - expect(height).toBeBetween(0, 40); - } else { - // Skirts - expect(height).toBeBetween(-1000, -960); + return data + .createMesh({ + tilingScheme: tilingScheme, + x: 0, + y: 0, + level: 0, + exaggeration: 2, + }) + .then(function (mesh) { + expect(mesh).toBeInstanceOf(TerrainMesh); + expect(mesh.vertices.length).toBe(17 * mesh.encoding.getStride()); // 9 regular + 8 skirt vertices + expect(mesh.indices.length).toBe(4 * 6 * 3); // 2 regular + 4 skirt triangles per quad + expect(mesh.minimumHeight).toBe(0); + expect(mesh.maximumHeight).toBeCloseTo(40, 5); + + var encoding = mesh.encoding; + var count = mesh.vertices.length / mesh.encoding.getStride(); + for (var i = 0; i < count; ++i) { + var height = encoding.decodeHeight(mesh.vertices, i); + if (i < 9) { + // Original vertices + expect(height).toBeBetween(0, 40); + } else { + // Skirts + expect(height).toBeBetween(-1000, -960); + } } - } - }); + }); }); }); diff --git a/Specs/Core/HeightmapTerrainDataSpec.js b/Specs/Core/HeightmapTerrainDataSpec.js index 7581407fe40d..8c17248a5064 100644 --- a/Specs/Core/HeightmapTerrainDataSpec.js +++ b/Specs/Core/HeightmapTerrainDataSpec.js @@ -1,7 +1,9 @@ +import { defined } from "../../Source/Cesium.js"; import { GeographicTilingScheme } from "../../Source/Cesium.js"; import { HeightmapEncoding } from "../../Source/Cesium.js"; import { HeightmapTerrainData } from "../../Source/Cesium.js"; import { TerrainData } from "../../Source/Cesium.js"; +import { when } from "../../Source/Cesium.js"; describe("Core/HeightmapTerrainData", function () { it("conforms to TerrainData interface", function () { @@ -68,38 +70,99 @@ describe("Core/HeightmapTerrainData", function () { var data; var tilingScheme; - beforeEach(function () { - tilingScheme = new GeographicTilingScheme(); - data = new HeightmapTerrainData({ + function createSampleTerrainData() { + return new HeightmapTerrainData({ buffer: new Float32Array(25), width: 5, height: 5, }); + } + + beforeEach(function () { + tilingScheme = new GeographicTilingScheme(); + data = createSampleTerrainData(); }); it("requires tilingScheme", function () { expect(function () { - data.createMesh(undefined, 0, 0, 0); + data.createMesh({ tilingScheme: undefined, x: 0, y: 0, level: 0 }); }).toThrowDeveloperError(); }); it("requires x", function () { expect(function () { - data.createMesh(tilingScheme, undefined, 0, 0); + data.createMesh({ + tilingScheme: tilingScheme, + x: undefined, + y: 0, + level: 0, + }); }).toThrowDeveloperError(); }); it("requires y", function () { expect(function () { - data.createMesh(tilingScheme, 0, undefined, 0); + data.createMesh({ + tilingScheme: tilingScheme, + x: 0, + y: undefined, + level: 0, + }); }).toThrowDeveloperError(); }); it("requires level", function () { expect(function () { - data.createMesh(tilingScheme, 0, 0, undefined); + data.createMesh({ + tilingScheme: tilingScheme, + x: 0, + y: 0, + level: undefined, + }); }).toThrowDeveloperError(); }); + + it("enables throttling for asynchronous tasks", function () { + var options = { + tilingScheme: tilingScheme, + x: 0, + y: 0, + level: 0, + throttle: true, + }; + var taskCount = TerrainData.maximumAsynchronousTasks + 1; + var promises = new Array(); + for (var i = 0; i < taskCount; i++) { + var tempData = createSampleTerrainData(); + var promise = tempData.createMesh(options); + if (defined(promise)) { + promises.push(promise); + } + } + expect(promises.length).toBe(TerrainData.maximumAsynchronousTasks); + return when.all(promises); + }); + + it("disables throttling for asynchronous tasks", function () { + var options = { + tilingScheme: tilingScheme, + x: 0, + y: 0, + level: 0, + throttle: false, + }; + var taskCount = TerrainData.maximumAsynchronousTasks + 1; + var promises = new Array(); + for (var i = 0; i < taskCount; i++) { + var tempData = createSampleTerrainData(); + var promise = tempData.createMesh(options); + if (defined(promise)) { + promises.push(promise); + } + } + expect(promises.length).toBe(taskCount); + return when.all(promises); + }); }); describe("upsample", function () { @@ -188,7 +251,7 @@ describe("Core/HeightmapTerrainData", function () { }); return data - .createMesh(tilingScheme, 0, 0, 0, 1) + .createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) .then(function () { return data.upsample(tilingScheme, 0, 0, 0, 0, 0, 1); }) @@ -278,7 +341,7 @@ describe("Core/HeightmapTerrainData", function () { }); return data - .createMesh(tilingScheme, 0, 0, 0, 1) + .createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) .then(function () { return data.upsample(tilingScheme, 0, 0, 0, 0, 0, 1); }) @@ -401,7 +464,7 @@ describe("Core/HeightmapTerrainData", function () { }); return data - .createMesh(tilingScheme, 0, 0, 0, 1) + .createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) .then(function () { return data.upsample(tilingScheme, 0, 0, 0, 0, 0, 1); }) @@ -487,7 +550,7 @@ describe("Core/HeightmapTerrainData", function () { }); return data - .createMesh(tilingScheme, 0, 0, 0, 1) + .createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) .then(function () { return data.upsample(tilingScheme, 0, 0, 0, 1, 0, 1); }) @@ -577,7 +640,7 @@ describe("Core/HeightmapTerrainData", function () { }); return data - .createMesh(tilingScheme, 0, 0, 0, 1) + .createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) .then(function () { return data.upsample(tilingScheme, 0, 0, 0, 1, 0, 1); }) @@ -669,7 +732,7 @@ describe("Core/HeightmapTerrainData", function () { }); return data - .createMesh(tilingScheme, 0, 0, 0, 1) + .createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) .then(function () { return data.upsample(tilingScheme, 0, 0, 0, 0, 0, 1); }) diff --git a/Specs/Core/QuantizedMeshTerrainDataSpec.js b/Specs/Core/QuantizedMeshTerrainDataSpec.js index 32a59822174a..41282a13885d 100644 --- a/Specs/Core/QuantizedMeshTerrainDataSpec.js +++ b/Specs/Core/QuantizedMeshTerrainDataSpec.js @@ -1,5 +1,6 @@ import { BoundingSphere } from "../../Source/Cesium.js"; import { Cartesian3 } from "../../Source/Cesium.js"; +import { defined } from "../../Source/Cesium.js"; import { GeographicTilingScheme } from "../../Source/Cesium.js"; import { Math as CesiumMath } from "../../Source/Cesium.js"; import { QuantizedMeshTerrainData } from "../../Source/Cesium.js"; @@ -100,7 +101,9 @@ describe("Core/QuantizedMeshTerrainData", function () { var tilingScheme = new GeographicTilingScheme(); - return when(data.createMesh(tilingScheme, 0, 0, 0, 1)) + return when( + data.createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) + ) .then(function () { var swPromise = data.upsample(tilingScheme, 0, 0, 0, 0, 0, 1); var sePromise = data.upsample(tilingScheme, 0, 0, 0, 1, 0, 1); @@ -194,7 +197,9 @@ describe("Core/QuantizedMeshTerrainData", function () { var tilingScheme = new GeographicTilingScheme(); - return when(data.createMesh(tilingScheme, 0, 0, 0, 1)) + return when( + data.createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) + ) .then(function () { var swPromise = data.upsample(tilingScheme, 0, 0, 0, 0, 0, 1); var sePromise = data.upsample(tilingScheme, 0, 0, 0, 1, 0, 1); @@ -261,7 +266,9 @@ describe("Core/QuantizedMeshTerrainData", function () { }); var tilingScheme = new GeographicTilingScheme(); - return when(data.createMesh(tilingScheme, 0, 0, 0, 1)) + return when( + data.createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) + ) .then(function () { return data.upsample(tilingScheme, 0, 0, 0, 0, 0, 1); }) @@ -370,7 +377,9 @@ describe("Core/QuantizedMeshTerrainData", function () { }); var tilingScheme = new GeographicTilingScheme(); - return when(data.createMesh(tilingScheme, 0, 0, 0, 1)) + return when( + data.createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) + ) .then(function () { var nwPromise = data.upsample(tilingScheme, 0, 0, 0, 0, 0, 1); var nePromise = data.upsample(tilingScheme, 0, 0, 0, 1, 0, 1); @@ -443,9 +452,8 @@ describe("Core/QuantizedMeshTerrainData", function () { var data; var tilingScheme; - beforeEach(function () { - tilingScheme = new GeographicTilingScheme(); - data = new QuantizedMeshTerrainData({ + function createSampleTerrainData() { + return new QuantizedMeshTerrainData({ minimumHeight: 0.0, maximumHeight: 4.0, quantizedVertices: new Uint16Array([ @@ -479,54 +487,83 @@ describe("Core/QuantizedMeshTerrainData", function () { northSkirtHeight: 1.0, childTileMask: 15, }); + } + beforeEach(function () { + tilingScheme = new GeographicTilingScheme(); + data = createSampleTerrainData(); }); it("requires tilingScheme", function () { expect(function () { - data.createMesh(undefined, 0, 0, 0); + data.createMesh({ tilingScheme: undefined, x: 0, y: 0, level: 0 }); }).toThrowDeveloperError(); }); it("requires x", function () { expect(function () { - data.createMesh(tilingScheme, undefined, 0, 0); + data.createMesh({ + tilingScheme: tilingScheme, + x: undefined, + y: 0, + level: 0, + }); }).toThrowDeveloperError(); }); it("requires y", function () { expect(function () { - data.createMesh(tilingScheme, 0, undefined, 0); + data.createMesh({ + tilingScheme: tilingScheme, + x: 0, + y: undefined, + level: 0, + }); }).toThrowDeveloperError(); }); it("requires level", function () { expect(function () { - data.createMesh(tilingScheme, 0, 0, undefined); + data.createMesh({ + tilingScheme: tilingScheme, + x: 0, + y: 0, + level: undefined, + }); }).toThrowDeveloperError(); }); it("creates specified vertices plus skirt vertices", function () { - return data.createMesh(tilingScheme, 0, 0, 0).then(function (mesh) { - expect(mesh).toBeInstanceOf(TerrainMesh); - expect(mesh.vertices.length).toBe(12 * mesh.encoding.getStride()); // 4 regular vertices, 8 skirt vertices. - expect(mesh.indices.length).toBe(10 * 3); // 2 regular triangles, 8 skirt triangles. - expect(mesh.minimumHeight).toBe(data._minimumHeight); - expect(mesh.maximumHeight).toBe(data._maximumHeight); - expect(mesh.boundingSphere3D).toEqual(data._boundingSphere); - }); + return data + .createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) + .then(function (mesh) { + expect(mesh).toBeInstanceOf(TerrainMesh); + expect(mesh.vertices.length).toBe(12 * mesh.encoding.getStride()); // 4 regular vertices, 8 skirt vertices. + expect(mesh.indices.length).toBe(10 * 3); // 2 regular triangles, 8 skirt triangles. + expect(mesh.minimumHeight).toBe(data._minimumHeight); + expect(mesh.maximumHeight).toBe(data._maximumHeight); + expect(mesh.boundingSphere3D).toEqual(data._boundingSphere); + }); }); it("exaggerates mesh", function () { - return data.createMesh(tilingScheme, 0, 0, 0, 2).then(function (mesh) { - expect(mesh).toBeInstanceOf(TerrainMesh); - expect(mesh.vertices.length).toBe(12 * mesh.encoding.getStride()); // 4 regular vertices, 8 skirt vertices. - expect(mesh.indices.length).toBe(10 * 3); // 2 regular triangles, 8 skirt triangles. - expect(mesh.minimumHeight).toBe(data._minimumHeight); - expect(mesh.maximumHeight).toBeGreaterThan(data._maximumHeight); - expect(mesh.boundingSphere3D.radius).toBeGreaterThan( - data._boundingSphere.radius - ); - }); + return data + .createMesh({ + tilingScheme: tilingScheme, + x: 0, + y: 0, + level: 0, + exaggeration: 2, + }) + .then(function (mesh) { + expect(mesh).toBeInstanceOf(TerrainMesh); + expect(mesh.vertices.length).toBe(12 * mesh.encoding.getStride()); // 4 regular vertices, 8 skirt vertices. + expect(mesh.indices.length).toBe(10 * 3); // 2 regular triangles, 8 skirt triangles. + expect(mesh.minimumHeight).toBe(data._minimumHeight); + expect(mesh.maximumHeight).toBeGreaterThan(data._maximumHeight); + expect(mesh.boundingSphere3D.radius).toBeGreaterThan( + data._boundingSphere.radius + ); + }); }); it("requires 32bit indices for large meshes", function () { @@ -560,10 +597,54 @@ describe("Core/QuantizedMeshTerrainData", function () { childTileMask: 15, }); - return data.createMesh(tilingScheme, 0, 0, 0).then(function (mesh) { - expect(mesh).toBeInstanceOf(TerrainMesh); - expect(mesh.indices.BYTES_PER_ELEMENT).toBe(4); - }); + return data + .createMesh({ tilingScheme: tilingScheme, x: 0, y: 0, level: 0 }) + .then(function (mesh) { + expect(mesh).toBeInstanceOf(TerrainMesh); + expect(mesh.indices.BYTES_PER_ELEMENT).toBe(4); + }); + }); + + it("enables throttling for asynchronous tasks", function () { + var options = { + tilingScheme: tilingScheme, + x: 0, + y: 0, + level: 0, + throttle: true, + }; + var taskCount = TerrainData.maximumAsynchronousTasks + 1; + var promises = new Array(); + for (var i = 0; i < taskCount; i++) { + var tempData = createSampleTerrainData(); + var promise = tempData.createMesh(options); + if (defined(promise)) { + promises.push(promise); + } + } + expect(promises.length).toBe(TerrainData.maximumAsynchronousTasks); + return when.all(promises); + }); + + it("disables throttling for asynchronous tasks", function () { + var options = { + tilingScheme: tilingScheme, + x: 0, + y: 0, + level: 0, + throttle: false, + }; + var taskCount = TerrainData.maximumAsynchronousTasks + 1; + var promises = new Array(); + for (var i = 0; i < taskCount; i++) { + var tempData = createSampleTerrainData(); + var promise = tempData.createMesh(options); + if (defined(promise)) { + promises.push(promise); + } + } + expect(promises.length).toBe(taskCount); + return when.all(promises); }); }); diff --git a/Specs/MockTerrainProvider.js b/Specs/MockTerrainProvider.js index 3688a8b39663..1e37cbfc8a09 100644 --- a/Specs/MockTerrainProvider.js +++ b/Specs/MockTerrainProvider.js @@ -276,7 +276,11 @@ function createTerrainData(terrainProvider, x, y, level, upsampled) { }; var originalCreateMesh = terrainData.createMesh; - terrainData.createMesh = function (tilingScheme, x, y, level) { + terrainData.createMesh = function (options) { + var x = options.x; + var y = options.y; + var level = options.level; + var willSucceed = terrainProvider._createMeshWillSucceed[createTileKey(x, y, level)]; if (willSucceed === undefined) { From 951cadac7693c97be2e073f19bfd445e6b22ea8f Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Mon, 11 Jan 2021 16:53:43 -0500 Subject: [PATCH 2/4] updated changes.md with PR number and other small tweaks --- CHANGES.md | 2 +- Source/Core/GoogleEarthEnterpriseTerrainData.js | 2 +- Source/Core/HeightmapTerrainData.js | 2 +- Source/Scene/GlobeSurfaceTile.js | 1 + Source/Scene/TerrainFillMesh.js | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a3f56981e7d2..59630b2a365c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,7 @@ ##### Breaking Changes :mega: -- Changed the `TaskProcessor.maximumActiveTasks` constructor option to be infinity by default. +- Changed the `TaskProcessor.maximumActiveTasks` constructor option to be infinity by default. [#9313](https://github.com/CesiumGS/cesium/pull/9313) ### 1.77 - 2021-01-04 diff --git a/Source/Core/GoogleEarthEnterpriseTerrainData.js b/Source/Core/GoogleEarthEnterpriseTerrainData.js index aa375d6d6d2c..c743ebf09e63 100644 --- a/Source/Core/GoogleEarthEnterpriseTerrainData.js +++ b/Source/Core/GoogleEarthEnterpriseTerrainData.js @@ -12,8 +12,8 @@ import OrientedBoundingBox from "./OrientedBoundingBox.js"; import QuantizedMeshTerrainData from "./QuantizedMeshTerrainData.js"; import Rectangle from "./Rectangle.js"; import TaskProcessor from "./TaskProcessor.js"; -import TerrainEncoding from "./TerrainEncoding.js"; import TerrainData from "./TerrainData.js"; +import TerrainEncoding from "./TerrainEncoding.js"; import TerrainMesh from "./TerrainMesh.js"; /** diff --git a/Source/Core/HeightmapTerrainData.js b/Source/Core/HeightmapTerrainData.js index e83d22cb208e..fd235a8a38d6 100644 --- a/Source/Core/HeightmapTerrainData.js +++ b/Source/Core/HeightmapTerrainData.js @@ -12,8 +12,8 @@ import CesiumMath from "./Math.js"; import OrientedBoundingBox from "./OrientedBoundingBox.js"; import Rectangle from "./Rectangle.js"; import TaskProcessor from "./TaskProcessor.js"; -import TerrainEncoding from "./TerrainEncoding.js"; import TerrainData from "./TerrainData.js"; +import TerrainEncoding from "./TerrainEncoding.js"; import TerrainMesh from "./TerrainMesh.js"; import TerrainProvider from "./TerrainProvider.js"; diff --git a/Source/Scene/GlobeSurfaceTile.js b/Source/Scene/GlobeSurfaceTile.js index 330430c472e4..77fb72521e9c 100644 --- a/Source/Scene/GlobeSurfaceTile.js +++ b/Source/Scene/GlobeSurfaceTile.js @@ -633,6 +633,7 @@ var scratchCreateMeshOptions = { y: 0, level: 0, exaggeration: 1.0, + throttle: true, }; function transform(surfaceTile, frameState, terrainProvider, x, y, level) { diff --git a/Source/Scene/TerrainFillMesh.js b/Source/Scene/TerrainFillMesh.js index 80b2b0b1d62a..469bcbc4b7b5 100644 --- a/Source/Scene/TerrainFillMesh.js +++ b/Source/Scene/TerrainFillMesh.js @@ -813,6 +813,7 @@ var scratchCreateMeshOptions = { y: 0, level: 0, exaggeration: 1.0, + throttle: true, }; function createFillMesh(tileProvider, frameState, tile, vertexArraysToDestroy) { GlobeSurfaceTile.initialize( @@ -986,7 +987,6 @@ function createFillMesh(tileProvider, frameState, tile, vertexArraysToDestroy) { createMeshOptions.x = tile.x; createMeshOptions.y = tile.y; createMeshOptions.level = tile.level; - createMeshOptions.exaggeration = 1.0; fill.mesh = terrainData._createMeshSync(createMeshOptions); } else { From 3cbc2c3ff38f4da5ade92f90b33c1a77f99eb157 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Tue, 12 Jan 2021 16:03:32 -0500 Subject: [PATCH 3/4] fixes order in changes.md --- CHANGES.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 59630b2a365c..9a72129158b5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,14 +2,14 @@ ### 1.78 - 2021-02-01 -##### Additions :tada: - -- Added `Cartesian2.cross`. [#9305](https://github.com/CesiumGS/cesium/pull/9305) - ##### Breaking Changes :mega: - Changed the `TaskProcessor.maximumActiveTasks` constructor option to be infinity by default. [#9313](https://github.com/CesiumGS/cesium/pull/9313) +##### Additions :tada: + +- Added `Cartesian2.cross`. [#9305](https://github.com/CesiumGS/cesium/pull/9305) + ### 1.77 - 2021-01-04 ##### Additions :tada: From c0c23e33362b49e30e8f4f7b446aea4d7f5b99c7 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Sun, 28 Feb 2021 13:38:53 -0500 Subject: [PATCH 4/4] changed some options names --- CHANGES.md | 2 +- Source/Scene/GlobeSurfaceTile.js | 1 + Source/Scene/TerrainFillMesh.js | 15 +++++++-------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 815b8d83a390..82a3345ca538 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,7 @@ - Removed `EasingFunction.QUADRACTIC_IN`, which was deprecated in CesiumJS 1.77. Use `EasingFunction.QUADRATIC_IN`. - Removed `EasingFunction.QUADRACTIC_OUT`, which was deprecated in CesiumJS 1.77. Use `EasingFunction.QUADRATIC_OUT`. - Removed `EasingFunction.QUADRACTIC_IN_OUT`, which was deprecated in CesiumJS 1.77. Use `EasingFunction.QUADRATIC_IN_OUT`. -- Changed the `TaskProcessor.maximumActiveTasks` constructor option to be infinity by default. [#9313](https://github.com/CesiumGS/cesium/pull/9313) +- Changed `TaskProcessor.maximumActiveTasks` constructor option to be infinity by default. [#9313](https://github.com/CesiumGS/cesium/pull/9313) ##### Fixes :wrench: diff --git a/Source/Scene/GlobeSurfaceTile.js b/Source/Scene/GlobeSurfaceTile.js index 77fb72521e9c..099f4077b290 100644 --- a/Source/Scene/GlobeSurfaceTile.js +++ b/Source/Scene/GlobeSurfaceTile.js @@ -645,6 +645,7 @@ function transform(surfaceTile, frameState, terrainProvider, x, y, level) { createMeshOptions.y = y; createMeshOptions.level = level; createMeshOptions.exaggeration = frameState.exaggeration; + createMeshOptions.throttle = true; var terrainData = surfaceTile.terrainData; var meshPromise = terrainData.createMesh(createMeshOptions); diff --git a/Source/Scene/TerrainFillMesh.js b/Source/Scene/TerrainFillMesh.js index 469bcbc4b7b5..ea95bcde43bd 100644 --- a/Source/Scene/TerrainFillMesh.js +++ b/Source/Scene/TerrainFillMesh.js @@ -807,13 +807,12 @@ var neVertexScratch = new HeightAndNormal(); var heightmapBuffer = typeof Uint8Array !== "undefined" ? new Uint8Array(9 * 9) : undefined; -var scratchCreateMeshOptions = { +var scratchCreateMeshSyncOptions = { tilingScheme: undefined, x: 0, y: 0, level: 0, exaggeration: 1.0, - throttle: true, }; function createFillMesh(tileProvider, frameState, tile, vertexArraysToDestroy) { GlobeSurfaceTile.initialize( @@ -982,13 +981,13 @@ function createFillMesh(tileProvider, frameState, tile, vertexArraysToDestroy) { }, }); - var createMeshOptions = scratchCreateMeshOptions; - createMeshOptions.tilingScheme = tile.tilingScheme; - createMeshOptions.x = tile.x; - createMeshOptions.y = tile.y; - createMeshOptions.level = tile.level; + var createMeshSyncOptions = scratchCreateMeshSyncOptions; + createMeshSyncOptions.tilingScheme = tile.tilingScheme; + createMeshSyncOptions.x = tile.x; + createMeshSyncOptions.y = tile.y; + createMeshSyncOptions.level = tile.level; - fill.mesh = terrainData._createMeshSync(createMeshOptions); + fill.mesh = terrainData._createMeshSync(createMeshSyncOptions); } else { var encoding = new TerrainEncoding( undefined,