DSDSWeb/static/js/Cesium-1.53/Specs/Scene/GlobeSurfaceTileProviderSpe...

1019 lines
39 KiB
JavaScript
Raw Normal View History

2024-07-11 18:02:47 +08:00
defineSuite([
'Scene/GlobeSurfaceTileProvider',
'Core/Cartesian3',
'Core/CesiumTerrainProvider',
'Core/Color',
'Core/Credit',
'Core/defined',
'Core/Ellipsoid',
'Core/EllipsoidTerrainProvider',
'Core/GeographicProjection',
'Core/Rectangle',
'Core/WebMercatorProjection',
'Renderer/ContextLimits',
'Renderer/RenderState',
'Scene/BlendingState',
'Scene/ClippingPlane',
'Scene/ClippingPlaneCollection',
'Scene/Fog',
'Scene/Globe',
'Scene/GlobeSurfaceShaderSet',
'Scene/ImageryLayerCollection',
'Scene/ImagerySplitDirection',
'Scene/Model',
'Scene/QuadtreeTile',
'Scene/QuadtreeTileProvider',
'Scene/SceneMode',
'Scene/SingleTileImageryProvider',
'Scene/WebMapServiceImageryProvider',
'Specs/createScene',
'Specs/pollToPromise'
], function(
GlobeSurfaceTileProvider,
Cartesian3,
CesiumTerrainProvider,
Color,
Credit,
defined,
Ellipsoid,
EllipsoidTerrainProvider,
GeographicProjection,
Rectangle,
WebMercatorProjection,
ContextLimits,
RenderState,
BlendingState,
ClippingPlane,
ClippingPlaneCollection,
Fog,
Globe,
GlobeSurfaceShaderSet,
ImageryLayerCollection,
ImagerySplitDirection,
Model,
QuadtreeTile,
QuadtreeTileProvider,
SceneMode,
SingleTileImageryProvider,
WebMapServiceImageryProvider,
createScene,
pollToPromise) {
'use strict';
var scene;
function forEachRenderedTile(quadtreePrimitive, minimumTiles, maximumTiles, callback) {
var tileCount = 0;
quadtreePrimitive.forEachRenderedTile(function(tile) {
++tileCount;
callback(tile);
});
if (defined(minimumTiles)) {
expect(tileCount).not.toBeLessThan(minimumTiles);
}
if (defined(maximumTiles)) {
expect(tileCount).not.toBeGreaterThan(maximumTiles);
}
}
/**
* Repeatedly calls update until the load queue is empty. You must wrap any code to follow
* this in a "runs" function.
*/
function updateUntilDone(globe) {
// update until the load queue is empty.
return pollToPromise(function() {
scene.renderForSpecs();
return globe._surface.tileProvider.ready && globe._surface._tileLoadQueueHigh.length === 0 && globe._surface._tileLoadQueueMedium.length === 0 && globe._surface._tileLoadQueueLow.length === 0 && globe._surface._debug.tilesWaitingForChildren === 0;
});
}
var cameraDestination = new Rectangle(0.0001, 0.0001, 0.0030, 0.0030);
function switchViewMode(mode, projection) {
scene.mode = mode;
scene.frameState.mapProjection = projection;
scene.camera.update(scene.mode);
scene.camera.setView({
destination : cameraDestination
});
}
beforeAll(function() {
scene = createScene();
scene.frameState.scene3DOnly = false;
});
afterAll(function() {
scene.destroyForSpecs();
});
beforeEach(function() {
scene.globe = new Globe();
});
afterEach(function() {
scene.imageryLayers.removeAll();
scene.primitives.removeAll();
});
it('conforms to QuadtreeTileProvider interface', function() {
expect(GlobeSurfaceTileProvider).toConformToInterface(QuadtreeTileProvider);
});
describe('construction', function() {
it('throws if a terrainProvider is not provided', function() {
function constructWithoutTerrainProvider() {
return new GlobeSurfaceTileProvider({
imageryLayers : new ImageryLayerCollection(),
surfaceShaderSet : new GlobeSurfaceShaderSet()
});
}
expect(constructWithoutTerrainProvider).toThrowDeveloperError();
});
it('throws if a imageryLayers is not provided', function() {
function constructWithoutImageryLayerCollection() {
return new GlobeSurfaceTileProvider({
terrainProvider : new EllipsoidTerrainProvider(),
surfaceShaderSet : new GlobeSurfaceShaderSet()
});
}
expect(constructWithoutImageryLayerCollection).toThrowDeveloperError();
});
it('throws if a surfaceShaderSet is not provided', function() {
function constructWithoutImageryLayerCollection() {
return new GlobeSurfaceTileProvider({
terrainProvider : new EllipsoidTerrainProvider(),
imageryLayers : new ImageryLayerCollection()
});
}
expect(constructWithoutImageryLayerCollection).toThrowDeveloperError();
});
}, 'WebGL');
describe('layer updating', function() {
it('removing a layer removes it from all tiles', function() {
var layer = scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
return updateUntilDone(scene.globe).then(function() {
// All tiles should have one or more associated images.
forEachRenderedTile(scene.globe._surface, 1, undefined, function(tile) {
expect(tile.data.imagery.length).toBeGreaterThan(0);
for (var i = 0; i < tile.data.imagery.length; ++i) {
expect(tile.data.imagery[i].readyImagery.imageryLayer).toEqual(layer);
}
});
scene.imageryLayers.remove(layer);
// All associated images should be gone.
forEachRenderedTile(scene.globe._surface, 1, undefined, function(tile) {
expect(tile.data.imagery.length).toEqual(0);
});
});
});
it('adding a layer adds it to all tiles after update', function() {
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
return updateUntilDone(scene.globe).then(function() {
// Add another layer
var layer2 = scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Green4x4.png'
}));
return updateUntilDone(scene.globe).then(function() {
// All tiles should have one or more associated images.
forEachRenderedTile(scene.globe._surface, 1, undefined, function(tile) {
expect(tile.data.imagery.length).toBeGreaterThan(0);
var hasImageFromLayer2 = false;
for (var i = 0; i < tile.data.imagery.length; ++i) {
var imageryTile = tile.data.imagery[i].readyImagery;
if (!defined(imageryTile)) {
imageryTile = tile.data.imagery[i].loadingImagery;
}
if (imageryTile.imageryLayer === layer2) {
hasImageFromLayer2 = true;
}
}
expect(hasImageFromLayer2).toEqual(true);
});
});
});
});
it('moving a layer moves the corresponding TileImagery instances on every tile', function() {
var layer1 = scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
var layer2 = scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Green4x4.png'
}));
return updateUntilDone(scene.globe).then(function() {
forEachRenderedTile(scene.globe._surface, 1, undefined, function(tile) {
expect(tile.data.imagery.length).toBeGreaterThan(0);
var indexOfFirstLayer1 = tile.data.imagery.length;
var indexOfLastLayer1 = -1;
var indexOfFirstLayer2 = tile.data.imagery.length;
for (var i = 0; i < tile.data.imagery.length; ++i) {
if (tile.data.imagery[i].readyImagery.imageryLayer === layer1) {
indexOfFirstLayer1 = Math.min(indexOfFirstLayer1, i);
indexOfLastLayer1 = i;
} else {
expect(tile.data.imagery[i].readyImagery.imageryLayer).toEqual(layer2);
indexOfFirstLayer2 = Math.min(indexOfFirstLayer2, i);
}
}
expect(indexOfFirstLayer1).toBeLessThan(indexOfFirstLayer2);
expect(indexOfLastLayer1).toBeLessThan(indexOfFirstLayer2);
});
scene.imageryLayers.raiseToTop(layer1);
return updateUntilDone(scene.globe).then(function() {
forEachRenderedTile(scene.globe._surface, 1, undefined, function(tile) {
expect(tile.data.imagery.length).toBeGreaterThan(0);
var indexOfFirstLayer2 = tile.data.imagery.length;
var indexOfLastLayer2 = -1;
var indexOfFirstLayer1 = tile.data.imagery.length;
for (var i = 0; i < tile.data.imagery.length; ++i) {
if (tile.data.imagery[i].readyImagery.imageryLayer === layer2) {
indexOfFirstLayer2 = Math.min(indexOfFirstLayer2, i);
indexOfLastLayer2 = i;
} else {
expect(tile.data.imagery[i].readyImagery.imageryLayer).toEqual(layer1);
indexOfFirstLayer1 = Math.min(indexOfFirstLayer1, i);
}
}
expect(indexOfFirstLayer2).toBeLessThan(indexOfFirstLayer1);
expect(indexOfLastLayer2).toBeLessThan(indexOfFirstLayer1);
});
});
});
});
it('adding a layer creates its skeletons only once', function() {
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
return updateUntilDone(scene.globe).then(function() {
// Add another layer
var layer2 = scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Green4x4.png'
}));
return updateUntilDone(scene.globe).then(function() {
// All tiles should have one or more associated images.
forEachRenderedTile(scene.globe._surface, 1, undefined, function(tile) {
expect(tile.data.imagery.length).toBeGreaterThan(0);
var tilesFromLayer2 = 0;
for (var i = 0; i < tile.data.imagery.length; ++i) {
var imageryTile = tile.data.imagery[i].readyImagery;
if (!defined(imageryTile)) {
imageryTile = tile.data.imagery[i].loadingImagery;
}
if (imageryTile.imageryLayer === layer2) {
++tilesFromLayer2;
}
}
expect(tilesFromLayer2).toBe(1);
});
});
});
});
it('calling _reload adds a callback per layer per tile', function() {
var layer1 = scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
var layer2 = scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Green4x4.png'
}));
return updateUntilDone(scene.globe).then(function() {
// Verify that each tile has 2 imagery objects and no loaded callbacks
forEachRenderedTile(scene.globe._surface, 1, undefined, function(tile) {
expect(tile.data.imagery.length).toBe(2);
expect(Object.keys(tile._loadedCallbacks).length).toBe(1);
});
// Reload each layer
layer1._imageryProvider._reload();
layer2._imageryProvider._reload();
// These should be ignored
layer1._imageryProvider._reload();
layer2._imageryProvider._reload();
// Verify that each tile has 4 imagery objects (the old imagery and the reloaded imagery for each layer)
// and also has 2 callbacks so the old imagery will be removed once loaded.
forEachRenderedTile(scene.globe._surface, 1, undefined, function(tile) {
expect(tile.data.imagery.length).toBe(4);
expect(Object.keys(tile._loadedCallbacks).length).toBe(3);
});
return updateUntilDone(scene.globe).then(function() {
// Verify the old imagery was removed and the callbacks are no longer there
forEachRenderedTile(scene.globe._surface, 1, undefined, function(tile) {
expect(tile.data.imagery.length).toBe(2);
expect(Object.keys(tile._loadedCallbacks).length).toBe(1);
});
});
});
});
}, 'WebGL');
it('renders in 2D geographic', function() {
expect(scene).toRender([0, 0, 0, 255]);
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
switchViewMode(SceneMode.SCENE2D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
});
});
it('renders in 2D web mercator', function() {
expect(scene).toRender([0, 0, 0, 255]);
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
switchViewMode(SceneMode.SCENE2D, new WebMercatorProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
});
});
it('renders in Columbus View geographic', function() {
expect(scene).toRender([0, 0, 0, 255]);
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
switchViewMode(SceneMode.COLUMBUS_VIEW, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
});
});
it('renders in Columbus View web mercator', function() {
expect(scene).toRender([0, 0, 0, 255]);
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
switchViewMode(SceneMode.COLUMBUS_VIEW, new WebMercatorProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 128, 255]);
});
});
it('renders in 3D', function() {
expect(scene).toRender([0, 0, 0, 255]);
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
});
});
it('renders in 3D (2)', function() {
expect(scene).toRender([0, 0, 0, 255]);
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
});
});
describe('fog', function() {
it('culls tiles in full fog', function() {
expect(scene).toRender([0, 0, 0, 255]);
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
var oldFog = scene.fog;
scene.fog = new Fog();
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
scene.camera.lookUp(1.2); // Horizon-view
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
scene.fog.enabled = true;
scene.fog.density = 1.0;
scene.fog.screenSpaceErrorFactor = 0.0;
expect(scene).toRender([0, 0, 0, 255]);
scene.fog = oldFog;
});
});
it('culls tiles because of increased SSE', function() {
expect(scene).toRender([0, 0, 0, 255]);
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
var oldFog = scene.fog;
scene.fog = new Fog();
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
scene.camera.lookUp(1.2); // Horizon-view
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
scene.fog.enabled = true;
scene.fog.density = 0.001;
scene.fog.screenSpaceErrorFactor = 0.0;
var result;
expect(scene).toRenderAndCall(function(rgba) {
result = rgba;
expect(rgba).not.toEqual([0, 0, 0, 255]);
});
scene.fog.screenSpaceErrorFactor = 10000.0;
expect(scene).notToRender(result);
scene.fog = oldFog;
});
});
});
it('can change baseColor', function() {
expect(scene).toRender([0, 0, 0, 255]);
scene.globe.baseColor = Color.RED;
scene.fog.enabled = false;
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).toRender([255, 0, 0, 255]);
});
});
it('renders in 3D and then Columbus View', function() {
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
switchViewMode(SceneMode.COLUMBUS_VIEW, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
});
});
});
it('renders even if imagery root tiles fail to load', function() {
expect(scene).toRender([0, 0, 0, 255]);
var providerWithInvalidRootTiles = new WebMapServiceImageryProvider({
url : '/invalid',
layers : 'invalid'
});
scene.imageryLayers.addImageryProvider(providerWithInvalidRootTiles);
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
});
});
it('passes layer adjustment values as uniforms', function() {
expect(scene).toRender([0, 0, 0, 255]);
var layer = scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
layer.alpha = 0.123;
layer.brightness = 0.456;
layer.contrast = 0.654;
layer.gamma = 0.321;
layer.saturation = 0.123;
layer.hue = 0.456;
layer.splitDirection = ImagerySplitDirection.LEFT;
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
var tileCommandCount = 0;
var commandList = scene.frameState.commandList;
for (var i = 0; i < commandList.length; ++i) {
var command = commandList[i];
var uniforms = command.uniformMap;
if (!defined(uniforms) || !defined(uniforms.u_dayTextureAlpha)) {
continue;
}
++tileCommandCount;
expect(uniforms.u_dayTextureAlpha()).toEqual([0.123]);
expect(uniforms.u_dayTextureBrightness()).toEqual([0.456]);
expect(uniforms.u_dayTextureContrast()).toEqual([0.654]);
expect(uniforms.u_dayTextureOneOverGamma()).toEqual([1.0 / 0.321]);
expect(uniforms.u_dayTextureSaturation()).toEqual([0.123]);
expect(uniforms.u_dayTextureHue()).toEqual([0.456]);
expect(uniforms.u_dayTextureSplit()).toEqual([ImagerySplitDirection.LEFT]);
}
expect(tileCommandCount).toBeGreaterThan(0);
});
});
it('renders imagery cutout', function() {
expect(scene).toRender([0, 0, 0, 255]);
var layer = scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
layer.cutoutRectangle = cameraDestination;
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
var baseColor;
return updateUntilDone(scene.globe).then(function() {
expect(scene).toRenderAndCall(function(rgba) {
baseColor = rgba;
expect(rgba).not.toEqual([0, 0, 0, 255]);
});
layer.cutoutRectangle = undefined;
return updateUntilDone(scene.globe);
})
.then(function() {
expect(scene).toRenderAndCall(function(rgba) {
expect(rgba).not.toEqual(baseColor);
expect(rgba).not.toEqual([0, 0, 0, 255]);
});
});
});
it('skips layer with uniform alpha value of zero', function() {
var layer = scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
layer.alpha = 0.0;
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
var tileCommandCount = 0;
var commandList = scene.frameState.commandList;
for (var i = 0; i < commandList.length; ++i) {
var command = commandList[i];
var uniforms = command.uniformMap;
if (!defined(uniforms) || !defined(uniforms.u_dayTextureAlpha)) {
continue;
}
++tileCommandCount;
expect(uniforms.u_dayTextureAlpha()).toEqual([]);
}
expect(tileCommandCount).toBeGreaterThan(0);
});
});
it('can render more imagery layers than the available texture units', function() {
for (var i = 0; i < ContextLimits.maximumTextureImageUnits + 1; ++i) {
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png'
}));
}
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
var renderStateWithAlphaBlending = RenderState.fromCache({
blending : BlendingState.ALPHA_BLEND
});
var drawCommandsPerTile = {};
var commandList = scene.frameState.commandList;
for (var i = 0; i < commandList.length; ++i) {
var command = commandList[i];
if (command.owner instanceof QuadtreeTile) {
var tile = command.owner;
var key = 'L' + tile.level + 'X' + tile.x + 'Y' + tile.y;
if (!defined(drawCommandsPerTile[key])) {
drawCommandsPerTile[key] = 0;
// The first draw command for each tile should use a non-alpha-blending render state.
expect(command.renderState.blending).not.toEqual(renderStateWithAlphaBlending.blending);
} else {
// Successive draw commands per tile should alpha blend.
expect(command.renderState.blending).toEqual(renderStateWithAlphaBlending.blending);
expect(command.uniformMap.u_initialColor().w).toEqual(0.0);
}
++drawCommandsPerTile[key];
}
}
var tileCount = 0;
for ( var tileID in drawCommandsPerTile) {
if (drawCommandsPerTile.hasOwnProperty(tileID)) {
++tileCount;
expect(drawCommandsPerTile[tileID]).toBeGreaterThanOrEqualTo(2);
}
}
expect(tileCount).toBeGreaterThanOrEqualTo(1);
});
});
it('adds terrain and imagery credits to the CreditDisplay', function() {
var imageryCredit = new Credit('imagery credit');
scene.imageryLayers.addImageryProvider(new SingleTileImageryProvider({
url : 'Data/Images/Red16x16.png',
credit : imageryCredit
}));
var terrainCredit = new Credit('terrain credit');
scene.terrainProvider = new CesiumTerrainProvider({
url : 'https://s3.amazonaws.com/cesiumjs/smallTerrain',
credit : terrainCredit
});
return updateUntilDone(scene.globe).then(function() {
var creditDisplay = scene.frameState.creditDisplay;
creditDisplay.showLightbox();
expect(creditDisplay._currentFrameCredits.lightboxCredits.values).toContain(imageryCredit);
expect(creditDisplay._currentFrameCredits.lightboxCredits.values).toContain(terrainCredit);
creditDisplay.hideLightbox();
});
});
describe('switching terrain providers', function() {
it('clears the replacement queue', function() {
return updateUntilDone(scene.globe).then(function() {
var surface = scene.globe._surface;
var replacementQueue = surface._tileReplacementQueue;
expect(replacementQueue.count).toBeGreaterThan(0);
var oldTile = replacementQueue.head;
surface.tileProvider.terrainProvider = new EllipsoidTerrainProvider();
scene.renderForSpecs();
expect(replacementQueue.count).toBeGreaterThan(0);
expect(replacementQueue.head).not.toBe(oldTile);
});
});
it('recreates the level zero tiles', function() {
var surface = scene.globe._surface;
scene.renderForSpecs();
var levelZeroTiles = surface._levelZeroTiles;
expect(levelZeroTiles.length).toBe(2);
var levelZero0 = levelZeroTiles[0];
var levelZero1 = levelZeroTiles[1];
surface.tileProvider.terrainProvider = new EllipsoidTerrainProvider();
scene.renderForSpecs();
scene.renderForSpecs();
levelZeroTiles = surface._levelZeroTiles;
expect(levelZeroTiles[0]).not.toBe(levelZero0);
expect(levelZeroTiles[1]).not.toBe(levelZero1);
});
it('does nothing if the new provider is the same as the old', function() {
var surface = scene.globe._surface;
var provider = surface.tileProvider.terrainProvider;
scene.renderForSpecs();
var levelZeroTiles = surface._levelZeroTiles;
expect(levelZeroTiles.length).toBe(2);
var levelZero0 = levelZeroTiles[0];
var levelZero1 = levelZeroTiles[1];
surface.tileProvider.terrainProvider = provider;
scene.renderForSpecs();
levelZeroTiles = surface._levelZeroTiles;
expect(levelZeroTiles[0]).toBe(levelZero0);
expect(levelZeroTiles[1]).toBe(levelZero1);
});
}, 'WebGL');
it('renders back side of globe when camera is near the poles', function() {
var camera = scene.camera;
camera.position = new Cartesian3(2909078.1077849553, -38935053.40234136, -63252400.94628872);
camera.direction = new Cartesian3(-0.03928753135806185, 0.44884096070717633, 0.8927476025569903);
camera.up = new Cartesian3(0.00002847975895320034, -0.8934368803055558, 0.4491887577613425);
camera.right = new Cartesian3(0.99922794650124, 0.017672942642764363, 0.03508814656908402);
scene.cullingVolume = camera.frustum.computeCullingVolume(camera.position, camera.direction, camera.up);
return updateUntilDone(scene.globe).then(function() {
// Both level zero tiles should be rendered.
forEachRenderedTile(scene.globe._surface, 2, 2, function(tile) {
});
});
});
it('throws if baseColor is assigned undefined', function() {
expect(function() {
scene.globe._surface.tileProvider.baseColor = undefined;
}).toThrowDeveloperError();
});
it('clipping planes selectively disable rendering globe surface', function() {
expect(scene).toRender([0, 0, 0, 255]);
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
var result;
expect(scene).toRenderAndCall(function(rgba) {
result = rgba;
expect(rgba).not.toEqual([0, 0, 0, 255]);
});
var clipPlane = new ClippingPlane(Cartesian3.UNIT_Z, -10000.0);
scene.globe.clippingPlanes = new ClippingPlaneCollection ({
planes : [
clipPlane
]
});
expect(scene).notToRender(result);
clipPlane.distance = 0.0;
expect(scene).toRender(result);
scene.globe.clippingPlanes = undefined;
});
});
it('renders with clipping planes edge styling on globe surface', function() {
expect(scene).toRender([0, 0, 0, 255]);
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
var result;
expect(scene).toRenderAndCall(function(rgba) {
result = rgba;
expect(rgba).not.toEqual([0, 0, 0, 255]);
});
var clipPlane = new ClippingPlane(Cartesian3.UNIT_Z, -1000.0);
scene.globe.clippingPlanes = new ClippingPlaneCollection ({
planes : [
clipPlane
],
edgeWidth : 20.0,
edgeColor : Color.RED
});
expect(scene).notToRender(result);
clipPlane.distance = 0.0;
expect(scene).toRender([255, 0, 0, 255]);
scene.globe.clippingPlanes = undefined;
});
});
it('renders with multiple clipping planes clipping regions according to the value of unionClippingPlane', function() {
expect(scene).toRender([0, 0, 0, 255]);
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
var result;
expect(scene).toRenderAndCall(function(rgba) {
result = rgba;
expect(rgba).not.toEqual([0, 0, 0, 255]);
});
scene.globe.clippingPlanes = new ClippingPlaneCollection ({
planes : [
new ClippingPlane(Cartesian3.UNIT_Z, -10000.0),
new ClippingPlane(Cartesian3.UNIT_X, -1000.0)
],
unionClippingRegions: true
});
expect(scene).notToRender(result);
scene.globe.clippingPlanes.unionClippingRegions = false;
expect(scene).toRender(result);
scene.globe.clippingPlanes = undefined;
});
});
it('No extra tiles culled with no clipping planes', function() {
var globe = scene.globe;
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(globe).then(function() {
expect(scene.frameState.commandList.length).toBe(4);
});
});
it('Culls tiles when completely inside clipping region', function() {
var globe = scene.globe;
globe.clippingPlanes = new ClippingPlaneCollection ({
planes : [
new ClippingPlane(Cartesian3.UNIT_Z, -1000000.0)
]
});
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(globe).then(function() {
var surface = globe._surface;
var tile = surface._levelZeroTiles[0];
expect(tile.isClipped).toBe(true);
expect(scene.frameState.commandList.length).toBe(2);
});
});
it('Doesn\'t cull, but clips tiles when intersecting clipping plane', function() {
var globe = scene.globe;
globe.clippingPlanes = new ClippingPlaneCollection ({
planes : [
new ClippingPlane(Cartesian3.UNIT_Z, 0.0)
]
});
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(globe).then(function() {
var surface = globe._surface;
var tile = surface._levelZeroTiles[0];
expect(tile.isClipped).toBe(true);
expect(scene.frameState.commandList.length).toBe(4);
});
});
it('Doesn\'t cull or clip tiles when completely outside clipping region', function() {
var globe = scene.globe;
globe.clippingPlanes = new ClippingPlaneCollection ({
planes : [
new ClippingPlane(Cartesian3.UNIT_Z, 10000000.0)
]
});
switchViewMode(SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84));
return updateUntilDone(globe).then(function() {
var surface = globe._surface;
var tile = surface._levelZeroTiles[0];
expect(tile.isClipped).toBe(false);
expect(scene.frameState.commandList.length).toBe(4);
});
});
it('destroys attached ClippingPlaneCollections that have been detached', function() {
var clippingPlanes = new ClippingPlaneCollection ({
planes : [
new ClippingPlane(Cartesian3.UNIT_Z, 10000000.0)
]
});
var globe = scene.globe;
globe.clippingPlanes = clippingPlanes;
expect(clippingPlanes.isDestroyed()).toBe(false);
globe.clippingPlanes = undefined;
expect(clippingPlanes.isDestroyed()).toBe(true);
});
it('throws a DeveloperError when given a ClippingPlaneCollection attached to a Model', function() {
var clippingPlanes = new ClippingPlaneCollection ({
planes : [
new ClippingPlane(Cartesian3.UNIT_Z, 10000000.0)
]
});
var model = scene.primitives.add(Model.fromGltf({
url : './Data/Models/Box/CesiumBoxTest.gltf'
}));
model.clippingPlanes = clippingPlanes;
var globe = scene.globe;
expect(function() {
globe.clippingPlanes = clippingPlanes;
}).toThrowDeveloperError();
});
it('cartographicLimitRectangle selectively enables rendering globe surface', function() {
expect(scene).toRender([0, 0, 0, 255]);
switchViewMode(SceneMode.COLUMBUS_VIEW, new GeographicProjection(Ellipsoid.WGS84));
var result;
return updateUntilDone(scene.globe).then(function() {
expect(scene).notToRender([0, 0, 0, 255]);
expect(scene).toRenderAndCall(function(rgba) {
result = rgba;
expect(rgba).not.toEqual([0, 0, 0, 255]);
});
scene.globe.cartographicLimitRectangle = Rectangle.fromDegrees(-2, -2, -1, -1);
expect(scene).notToRender(result);
scene.camera.setView({
destination : scene.globe.cartographicLimitRectangle
});
return updateUntilDone(scene.globe);
})
.then(function() {
expect(scene).toRender(result);
});
});
it('cartographicLimitRectangle culls tiles outside the region', function() {
switchViewMode(SceneMode.COLUMBUS_VIEW, new GeographicProjection(Ellipsoid.WGS84));
var unculledCommandCount;
return updateUntilDone(scene.globe).then(function() {
unculledCommandCount = scene.frameState.commandList.length;
scene.globe.cartographicLimitRectangle = Rectangle.fromDegrees(-2, -2, -1, -1);
return updateUntilDone(scene.globe);
})
.then(function() {
expect(unculledCommandCount).toBeGreaterThan(scene.frameState.commandList.length);
});
});
it('cartographicLimitRectangle may cross the antimeridian', function() {
switchViewMode(SceneMode.SCENE2D, new GeographicProjection(Ellipsoid.WGS84));
var unculledCommandCount;
return updateUntilDone(scene.globe).then(function() {
unculledCommandCount = scene.frameState.commandList.length;
scene.globe.cartographicLimitRectangle = Rectangle.fromDegrees(179, -2, -179, -1);
return updateUntilDone(scene.globe);
})
.then(function() {
expect(unculledCommandCount).toBeGreaterThan(scene.frameState.commandList.length);
});
});
}, 'WebGL');