import createTileKey from "./createTileKey.js"; import runLater from "./runLater.js"; import { defined } from "../Source/Cesium.js"; import { GeographicTilingScheme } from "../Source/Cesium.js"; import { HeightmapTerrainData } from "../Source/Cesium.js"; import { RuntimeError } from "../Source/Cesium.js"; import { TerrainProvider } from "../Source/Cesium.js"; import { when } from "../Source/Cesium.js"; function MockTerrainProvider() { this.tilingScheme = new GeographicTilingScheme(); this.heightmapWidth = 65; this.levelZeroMaximumGeometricError = TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap( this.tilingScheme.ellipsoid, this.heightmapWidth, this.tilingScheme.getNumberOfXTilesAtLevel(0) ); this.ready = true; this.readyPromise = when.resolve(); this.hasWaterMask = true; this._tileDataAvailable = {}; this._requestTileGeometryWillSucceed = {}; this._requestTileGeometryWillSucceedWith = {}; this._willHaveWaterMask = {}; this._createMeshWillSucceed = {}; this._upsampleWillSucceed = {}; } MockTerrainProvider.prototype.requestTileGeometry = function ( x, y, level, request ) { var willSucceed = this._requestTileGeometryWillSucceed[ createTileKey(x, y, level) ]; if (willSucceed === undefined) { return undefined; // defer by default } var that = this; return runLater(function () { if (willSucceed === true) { return createTerrainData(that, x, y, level, false); } else if (willSucceed === false) { throw new RuntimeError("requestTileGeometry failed as requested."); } return when(willSucceed).then(function () { return createTerrainData(that, x, y, level, false); }); }); }; MockTerrainProvider.prototype.getTileDataAvailable = function ( xOrTile, y, level ) { return this._tileDataAvailable[createTileKey(xOrTile, y, level)]; }; MockTerrainProvider.prototype.getLevelMaximumGeometricError = function (level) { return this.levelZeroMaximumGeometricError / (1 << level); }; MockTerrainProvider.prototype.requestTileGeometryWillSucceed = function ( xOrTile, y, level ) { this._requestTileGeometryWillSucceed[createTileKey(xOrTile, y, level)] = true; return this; }; MockTerrainProvider.prototype.requestTileGeometryWillSucceedWith = function ( terrainData, xOrTile, y, level ) { this._requestTileGeometryWillSucceed[createTileKey(xOrTile, y, level)] = true; this._requestTileGeometryWillSucceedWith[ createTileKey(xOrTile, y, level) ] = terrainData; return this; }; MockTerrainProvider.prototype.requestTileGeometryWillFail = function ( xOrTile, y, level ) { this._requestTileGeometryWillSucceed[ createTileKey(xOrTile, y, level) ] = false; return this; }; MockTerrainProvider.prototype.requestTileGeometryWillDefer = function ( xOrTile, y, level ) { this._requestTileGeometryWillSucceed[ createTileKey(xOrTile, y, level) ] = undefined; return this; }; MockTerrainProvider.prototype.requestTileGeometryWillWaitOn = function ( promise, xOrTile, y, level ) { this._requestTileGeometryWillSucceed[ createTileKey(xOrTile, y, level) ] = promise; return this; }; MockTerrainProvider.prototype.willHaveWaterMask = function ( includeLand, includeWater, xOrTile, y, level ) { this._willHaveWaterMask[createTileKey(xOrTile, y, level)] = includeLand || includeWater ? { includeLand: includeLand, includeWater: includeWater, } : undefined; return this; }; MockTerrainProvider.prototype.createMeshWillSucceed = function ( xOrTile, y, level ) { this._createMeshWillSucceed[createTileKey(xOrTile, y, level)] = true; return this; }; MockTerrainProvider.prototype.createMeshWillFail = function ( xOrTile, y, level ) { this._createMeshWillSucceed[createTileKey(xOrTile, y, level)] = false; return this; }; MockTerrainProvider.prototype.createMeshWillDefer = function ( xOrTile, y, level ) { this._createMeshWillSucceed[createTileKey(xOrTile, y, level)] = undefined; return this; }; MockTerrainProvider.prototype.createMeshWillWaitOn = function ( promise, xOrTile, y, level ) { this._createMeshWillSucceed[createTileKey(xOrTile, y, level)] = promise; return this; }; MockTerrainProvider.prototype.upsampleWillSucceed = function ( xOrTile, y, level ) { this._upsampleWillSucceed[createTileKey(xOrTile, y, level)] = true; return this; }; MockTerrainProvider.prototype.upsampleWillFail = function (xOrTile, y, level) { this._upsampleWillSucceed[createTileKey(xOrTile, y, level)] = false; return this; }; MockTerrainProvider.prototype.upsampleWillDefer = function (xOrTile, y, level) { this._upsampleWillSucceed[createTileKey(xOrTile, y, level)] = undefined; return this; }; MockTerrainProvider.prototype.willBeAvailable = function (xOrTile, y, level) { this._tileDataAvailable[createTileKey(xOrTile, y, level)] = true; return this; }; MockTerrainProvider.prototype.willBeUnavailable = function (xOrTile, y, level) { this._tileDataAvailable[createTileKey(xOrTile, y, level)] = false; return this; }; MockTerrainProvider.prototype.willBeUnknownAvailability = function ( xOrTile, y, level ) { this._tileDataAvailable[createTileKey(xOrTile, y, level)] = undefined; return this; }; function createTerrainData(terrainProvider, x, y, level, upsampled) { var terrainData = terrainProvider._requestTileGeometryWillSucceedWith[ createTileKey(x, y, level) ]; if (!defined(terrainData)) { var options = { width: 5, height: 5, buffer: new Float32Array(25), createdByUpsampling: upsampled, }; var willHaveWaterMask = terrainProvider._willHaveWaterMask[createTileKey(x, y, level)]; if (defined(willHaveWaterMask)) { if (willHaveWaterMask.includeLand && willHaveWaterMask.includeWater) { options.waterMask = new Uint8Array(4); options.waterMask[0] = 1; options.waterMask[1] = 1; options.waterMask[2] = 0; options.waterMask[3] = 0; } else if (willHaveWaterMask.includeLand) { options.waterMask = new Uint8Array(1); options.waterMask[0] = 0; } else if (willHaveWaterMask.includeWater) { options.waterMask = new Uint8Array(1); options.waterMask[0] = 1; } } terrainData = new HeightmapTerrainData(options); } var originalUpsample = terrainData.upsample; terrainData.upsample = function ( tilingScheme, thisX, thisY, thisLevel, descendantX, descendantY ) { var willSucceed = terrainProvider._upsampleWillSucceed[ createTileKey(descendantX, descendantY, thisLevel + 1) ]; if (willSucceed === undefined) { return undefined; // defer by default } if (willSucceed) { return originalUpsample.apply(terrainData, arguments); } return runLater(function () { throw new RuntimeError("upsample failed as requested."); }); }; var originalCreateMesh = terrainData.createMesh; 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) { return undefined; // defer by default } if (willSucceed === true) { return originalCreateMesh.apply(terrainData, arguments); } else if (willSucceed === false) { return runLater(function () { throw new RuntimeError("createMesh failed as requested."); }); } var args = arguments; return runLater(function () { return when(willSucceed).then(function () { return originalCreateMesh.apply(terrainData, args); }); }); }; return terrainData; } export default MockTerrainProvider;