cesium/Specs/MockTerrainProvider.js

307 lines
7.6 KiB
JavaScript

import createTileKey from "./createTileKey.js";
import runLater from "./runLater.js";
import {
defined,
Event,
GeographicTilingScheme,
HeightmapTerrainData,
RuntimeError,
TerrainProvider,
} from "@cesium/engine";
function MockTerrainProvider() {
this.tilingScheme = new GeographicTilingScheme();
this.heightmapWidth = 65;
this.levelZeroMaximumGeometricError =
TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap(
this.tilingScheme.ellipsoid,
this.heightmapWidth,
this.tilingScheme.getNumberOfXTilesAtLevel(0),
);
this.hasWaterMask = true;
this.errorEvent = new Event();
this._tileDataAvailable = {};
this._requestTileGeometryWillSucceed = {};
this._requestTileGeometryWillSucceedWith = {};
this._willHaveWaterMask = {};
this._createMeshWillSucceed = {};
this._upsampleWillSucceed = {};
}
MockTerrainProvider.prototype.requestTileGeometry = function (
x,
y,
level,
request,
) {
const willSucceed =
this._requestTileGeometryWillSucceed[createTileKey(x, y, level)];
if (willSucceed === undefined) {
return undefined; // defer by default
}
const 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 Promise.resolve(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) {
let terrainData =
terrainProvider._requestTileGeometryWillSucceedWith[
createTileKey(x, y, level)
];
if (!defined(terrainData)) {
const options = {
width: 5,
height: 5,
buffer: new Float32Array(25),
createdByUpsampling: upsampled,
};
const 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);
}
const originalUpsample = terrainData.upsample;
terrainData.upsample = function (
tilingScheme,
thisX,
thisY,
thisLevel,
descendantX,
descendantY,
) {
const 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.");
});
};
const originalCreateMesh = terrainData.createMesh;
terrainData.createMesh = function (options) {
const x = options.x;
const y = options.y;
const level = options.level;
const 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.");
});
}
const args = arguments;
return runLater(function () {
return Promise.resolve(willSucceed).then(function () {
return originalCreateMesh.apply(terrainData, args);
});
});
};
return terrainData;
}
export default MockTerrainProvider;