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

2235 lines
85 KiB
JavaScript

defineSuite([
'Core/Cartesian3',
'Core/Cartographic',
'Core/Color',
'Core/Ellipsoid',
'Core/FeatureDetection',
'Core/GeometryInstance',
'Core/Math',
'Core/Matrix4',
'Core/OrthographicFrustum',
'Core/PerspectiveFrustum',
'Core/Ray',
'Core/Rectangle',
'Core/RectangleGeometry',
'Core/ShowGeometryInstanceAttribute',
'Core/Transforms',
'Scene/Cesium3DTileset',
'Scene/Cesium3DTileStyle',
'Scene/EllipsoidSurfaceAppearance',
'Scene/Globe',
'Scene/PointPrimitiveCollection',
'Scene/Primitive',
'Scene/Scene',
'Scene/SceneMode',
'Specs/Cesium3DTilesTester',
'Specs/createCanvas',
'Specs/createScene',
'Specs/pollToPromise'
], 'Scene/Pick', function(
Cartesian3,
Cartographic,
Color,
Ellipsoid,
FeatureDetection,
GeometryInstance,
CesiumMath,
Matrix4,
OrthographicFrustum,
PerspectiveFrustum,
Ray,
Rectangle,
RectangleGeometry,
ShowGeometryInstanceAttribute,
Transforms,
Cesium3DTileset,
Cesium3DTileStyle,
EllipsoidSurfaceAppearance,
Globe,
PointPrimitiveCollection,
Primitive,
Scene,
SceneMode,
Cesium3DTilesTester,
createCanvas,
createScene,
pollToPromise) {
'use strict';
// It's not easily possible to mock the asynchronous pick functions
// so don't run those tests when using the WebGL stub
var webglStub = !!window.webglStub;
var scene;
var primitives;
var camera;
var largeRectangle = Rectangle.fromDegrees(-1.0, -1.0, 1.0, 1.0);
var smallRectangle = Rectangle.fromDegrees(-0.0001, -0.0001, 0.0001, 0.0001);
var offscreenRectangle = Rectangle.fromDegrees(-45.0002, -1.0002, -45.0001, -1.0001);
var primitiveRay;
var offscreenRay;
beforeAll(function() {
scene = createScene({
canvas : createCanvas(10, 10)
});
primitives = scene.primitives;
camera = scene.camera;
camera.setView({
destination : largeRectangle
});
primitiveRay = new Ray(camera.positionWC, camera.directionWC);
camera.setView({
destination : offscreenRectangle
});
offscreenRay = new Ray(camera.positionWC, camera.directionWC);
});
afterAll(function() {
scene.destroyForSpecs();
});
beforeEach(function() {
scene.mode = SceneMode.SCENE3D;
scene.morphTime = SceneMode.getMorphTime(scene.mode);
camera.setView({
destination : largeRectangle
});
camera.frustum = new PerspectiveFrustum();
camera.frustum.fov = CesiumMath.toRadians(60.0);
camera.frustum.aspectRatio = 1.0;
});
afterEach(function() {
primitives.removeAll();
scene.globe = undefined;
});
function createRectangle(height, rectangle) {
var e = new Primitive({
geometryInstances: new GeometryInstance({
geometry: new RectangleGeometry({
rectangle: rectangle,
vertexFormat: EllipsoidSurfaceAppearance.VERTEX_FORMAT,
granularity: CesiumMath.toRadians(20.0),
height: height
})
}),
appearance: new EllipsoidSurfaceAppearance({
aboveGround: false
}),
asynchronous: false
});
primitives.add(e);
return e;
}
function createLargeRectangle(height) {
return createRectangle(height, largeRectangle);
}
function createSmallRectangle(height) {
return createRectangle(height, smallRectangle);
}
function createTileset() {
var url = 'Data/Cesium3DTiles/Batched/BatchedWithTransformBox/tileset.json';
var options = {
maximumScreenSpaceError : 0
};
return Cesium3DTilesTester.loadTileset(scene, url, options).then(function(tileset) {
var cartographic = Rectangle.center(largeRectangle);
var cartesian = Cartographic.toCartesian(cartographic);
tileset.root.transform = Matrix4.IDENTITY;
tileset.modelMatrix = Transforms.eastNorthUpToFixedFrame(cartesian);
return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset);
});
}
function createGlobe() {
var globe = new Globe();
scene.globe = globe;
globe.depthTestAgainstTerrain = true;
return pollToPromise(function() {
scene.render();
return globe.tilesLoaded;
});
}
describe('pick', function() {
it('does not pick undefined window positions', function() {
expect(function() {
scene.pick(undefined);
}).toThrowDeveloperError();
});
it('picks a primitive', function() {
if (FeatureDetection.isInternetExplorer()) {
// Workaround IE 11.0.9. This test fails when all tests are ran without a breakpoint here.
return;
}
var rectangle = createLargeRectangle(0.0);
expect(scene).toPickPrimitive(rectangle);
});
it('picks a primitive with a modified pick search area', function() {
if (FeatureDetection.isInternetExplorer()) {
// Workaround IE 11.0.9. This test fails when all tests are ran without a breakpoint here.
return;
}
camera.setView({
destination : Rectangle.fromDegrees(-10.0, -10.0, 10.0, 10.0)
});
var rectangle = createLargeRectangle(0.0);
expect(scene).toPickPrimitive(rectangle, 7, 7, 5);
expect(scene).notToPick(7, 7, 3);
});
it('does not pick primitives when show is false', function() {
var rectangle = createLargeRectangle(0.0);
rectangle.show = false;
expect(scene).notToPick();
});
it('does not pick primitives when alpha is zero', function() {
var rectangle = createLargeRectangle(0.0);
rectangle.appearance.material.uniforms.color.alpha = 0.0;
expect(scene).notToPick();
});
it('picks the top primitive', function() {
createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
expect(scene).toPickPrimitive(rectangle2);
});
it('picks in 2D', function() {
scene.morphTo2D(0.0);
camera.setView({ destination : largeRectangle });
var rectangle = createLargeRectangle(0.0);
scene.initializeFrame();
expect(scene).toPickPrimitive(rectangle);
});
it('picks in 3D with orthographic projection', function() {
var frustum = new OrthographicFrustum();
frustum.aspectRatio = 1.0;
frustum.width = 20.0;
camera.frustum = frustum;
// force off center update
expect(frustum.projectionMatrix).toBeDefined();
camera.setView({ destination : largeRectangle });
var rectangle = createLargeRectangle(0.0);
scene.initializeFrame();
expect(scene).toPickPrimitive(rectangle);
});
});
describe('drillPick', function() {
it('drill picks a primitive with a modified pick search area', function() {
if (FeatureDetection.isInternetExplorer()) {
// Workaround IE 11.0.9. This test fails when all tests are ran without a breakpoint here.
return;
}
camera.setView({
destination : Rectangle.fromDegrees(-10.0, -10.0, 10.0, 10.0)
});
var rectangle = createLargeRectangle(0.0);
expect(scene).toDrillPickPrimitive(rectangle, 7, 7, 5);
expect(scene).notToDrillPick(7, 7, 3);
});
it('does not drill pick undefined window positions', function() {
expect(function() {
scene.pick(undefined);
}).toThrowDeveloperError();
});
it('drill picks multiple objects', function() {
var rectangle1 = createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
expect(scene).toDrillPickAndCall(function(pickedObjects) {
expect(pickedObjects.length).toEqual(2);
expect(pickedObjects[0].primitive).toEqual(rectangle2);
expect(pickedObjects[1].primitive).toEqual(rectangle1);
});
});
it('does not drill pick when show is false', function() {
var rectangle1 = createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
rectangle2.show = false;
expect(scene).toDrillPickAndCall(function(pickedObjects) {
expect(pickedObjects.length).toEqual(1);
expect(pickedObjects[0].primitive).toEqual(rectangle1);
});
});
it('does not drill pick when alpha is zero', function() {
var rectangle1 = createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
rectangle2.appearance.material.uniforms.color.alpha = 0.0;
expect(scene).toDrillPickAndCall(function(pickedObjects) {
expect(pickedObjects.length).toEqual(1);
expect(pickedObjects[0].primitive).toEqual(rectangle1);
});
});
it('can drill pick batched Primitives with show attribute', function() {
var geometry = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 0.0
});
var geometryWithHeight = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 20.0
});
var instance1 = new GeometryInstance({
id : 1,
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var instance2 = new GeometryInstance({
id : 2,
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(false)
}
});
var instance3 = new GeometryInstance({
id : 3,
geometry : geometryWithHeight,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var primitive = primitives.add(new Primitive({
geometryInstances : [instance1, instance2, instance3],
asynchronous : false,
appearance : new EllipsoidSurfaceAppearance()
}));
expect(scene).toDrillPickAndCall(function(pickedObjects) {
expect(pickedObjects.length).toEqual(2);
expect(pickedObjects[0].primitive).toEqual(primitive);
expect(pickedObjects[0].id).toEqual(3);
expect(pickedObjects[1].primitive).toEqual(primitive);
expect(pickedObjects[1].id).toEqual(1);
});
});
it('can drill pick without ID', function() {
var geometry = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT
});
var instance1 = new GeometryInstance({
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var instance2 = new GeometryInstance({
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var primitive = primitives.add(new Primitive({
geometryInstances : [instance1, instance2],
asynchronous : false,
appearance : new EllipsoidSurfaceAppearance()
}));
expect(scene).toDrillPickAndCall(function(pickedObjects) {
expect(pickedObjects.length).toEqual(1);
expect(pickedObjects[0].primitive).toEqual(primitive);
});
});
it('can drill pick batched Primitives without show attribute', function() {
var geometry = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 0.0
});
var geometryWithHeight = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 20.0
});
var instance1 = new GeometryInstance({
id : 1,
geometry : geometry
});
var instance2 = new GeometryInstance({
id : 2,
geometry : geometry
});
var instance3 = new GeometryInstance({
id : 3,
geometry : geometryWithHeight
});
var primitive = primitives.add(new Primitive({
geometryInstances : [instance1, instance2, instance3],
asynchronous : false,
appearance : new EllipsoidSurfaceAppearance()
}));
expect(scene).toDrillPickAndCall(function(pickedObjects) {
expect(pickedObjects.length).toEqual(1);
expect(pickedObjects[0].primitive).toEqual(primitive);
expect(pickedObjects[0].id).toEqual(3);
});
});
it('stops drill picking when the limit is reached.', function() {
createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
var rectangle3 = createLargeRectangle(2.0);
var rectangle4 = createLargeRectangle(3.0);
expect(scene).toDrillPickAndCall(function(pickedObjects) {
expect(pickedObjects.length).toEqual(3);
expect(pickedObjects[0].primitive).toEqual(rectangle4);
expect(pickedObjects[1].primitive).toEqual(rectangle3);
expect(pickedObjects[2].primitive).toEqual(rectangle2);
}, 3);
});
});
function picksFromRayTileset(style) {
return createTileset().then(function(tileset) {
tileset.style = style;
expect(scene).toPickFromRayAndCall(function(result) {
var primitive = result.object.primitive;
var position = result.position;
expect(primitive).toBe(tileset);
if (scene.context.depthTexture) {
var minimumHeight = Cartesian3.fromRadians(0.0, 0.0).x;
var maximumHeight = minimumHeight + 20.0; // Rough height of tile
expect(position.x).toBeGreaterThan(minimumHeight);
expect(position.x).toBeLessThan(maximumHeight);
expect(position.y).toEqualEpsilon(0.0, CesiumMath.EPSILON5);
expect(position.z).toEqualEpsilon(0.0, CesiumMath.EPSILON5);
}
}, primitiveRay);
});
}
describe('pickFromRay', function() {
it('picks a tileset', function() {
return picksFromRayTileset();
});
it('picks a translucent tileset', function() {
var style = new Cesium3DTileStyle({
color : 'color("white", 0.5)'
});
return picksFromRayTileset(style);
});
it('picks the globe', function() {
if (!scene.context.depthTexture) {
return;
}
return createGlobe().then(function() {
expect(scene).toPickFromRayAndCall(function(result) {
expect(result.object).toBeUndefined();
expect(result.position).toBeDefined();
expect(result.position.x).toBeGreaterThan(Ellipsoid.WGS84.minimumRadius);
expect(result.position.y).toEqualEpsilon(0.0, CesiumMath.EPSILON5);
expect(result.position.z).toEqualEpsilon(0.0, CesiumMath.EPSILON5);
}, primitiveRay);
});
});
it('picks a primitive', function() {
var rectangle = createSmallRectangle(0.0);
expect(scene).toPickFromRayAndCall(function(result) {
var primitive = result.object.primitive;
var position = result.position;
expect(primitive).toBe(rectangle);
if (scene.context.depthTexture) {
var expectedPosition = Cartesian3.fromRadians(0.0, 0.0);
expect(position).toEqualEpsilon(expectedPosition, CesiumMath.EPSILON5);
}
}, primitiveRay);
});
it('returns undefined if no primitives are picked', function() {
createLargeRectangle(0.0);
expect(scene).toPickFromRayAndCall(function(result) {
expect(result).toBeUndefined();
}, offscreenRay);
});
it('does not pick primitives when show is false', function() {
var rectangle = createLargeRectangle(0.0);
rectangle.show = false;
expect(scene).toPickFromRayAndCall(function(result) {
expect(result).toBeUndefined();
}, primitiveRay);
});
it('does not pick primitives when alpha is zero', function() {
var rectangle = createLargeRectangle(0.0);
rectangle.appearance.material.uniforms.color.alpha = 0.0;
expect(scene).toPickFromRayAndCall(function(result) {
expect(result).toBeUndefined();
}, primitiveRay);
});
it('picks the top primitive', function() {
createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
expect(scene).toPickFromRayAndCall(function(result) {
expect(result.object.primitive).toBe(rectangle2);
}, primitiveRay);
});
it('excludes objects', function() {
var rectangle1 = createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
var rectangle3 = createLargeRectangle(2.0);
var rectangle4 = createLargeRectangle(3.0);
rectangle4.show = false;
expect(scene).toPickFromRayAndCall(function(result) {
expect(result.object.primitive).toBe(rectangle1);
}, primitiveRay, [rectangle2, rectangle3, rectangle4]);
// Tests that rectangle4 does not get un-hidden
expect(scene).toPickFromRayAndCall(function(result) {
expect(result.object.primitive).toBe(rectangle3);
}, primitiveRay);
});
it('picks primitive that doesn\'t write depth', function() {
var collection = scene.primitives.add(new PointPrimitiveCollection());
var point = collection.add({
position : Cartographic.fromRadians(0.0, 0.0, 100.0),
disableDepthTestDistance : Number.POSITIVE_INFINITY
});
expect(scene).toPickFromRayAndCall(function(result) {
expect(result.object.primitive).toBe(point);
expect(result.position).toBeUndefined();
}, primitiveRay);
});
it('throws if ray is undefined', function() {
expect(function() {
scene.pickFromRay(undefined);
}).toThrowDeveloperError();
});
it('throws if scene camera is in 2D', function() {
scene.morphTo2D(0.0);
expect(function() {
scene.pickFromRay(primitiveRay);
}).toThrowDeveloperError();
});
it('throws if scene camera is in CV', function() {
scene.morphToColumbusView(0.0);
expect(function() {
scene.pickFromRay(primitiveRay);
}).toThrowDeveloperError();
});
});
describe('drillPickFromRay', function() {
it('drill picks a primitive', function() {
var rectangle = createSmallRectangle(0.0);
expect(scene).toDrillPickFromRayAndCall(function(results) {
expect(results.length).toBe(1);
var primitive = results[0].object.primitive;
var position = results[0].position;
expect(primitive).toBe(rectangle);
if (scene.context.depthTexture) {
var expectedPosition = Cartesian3.fromRadians(0.0, 0.0);
expect(position).toEqualEpsilon(expectedPosition, CesiumMath.EPSILON5);
} else {
expect(position).toBeUndefined();
}
}, primitiveRay);
});
it('drill picks multiple primitives', function() {
var rectangle1 = createSmallRectangle(0.0);
var rectangle2 = createSmallRectangle(1.0);
expect(scene).toDrillPickFromRayAndCall(function(results) {
expect(results.length).toBe(2);
// rectangle2 is picked before rectangle1
expect(results[0].object.primitive).toBe(rectangle2);
expect(results[1].object.primitive).toBe(rectangle1);
if (scene.context.depthTexture) {
var rectangleCenter1 = Cartesian3.fromRadians(0.0, 0.0, 0.0);
var rectangleCenter2 = Cartesian3.fromRadians(0.0, 0.0, 1.0);
expect(results[0].position).toEqualEpsilon(rectangleCenter2, CesiumMath.EPSILON5);
expect(results[1].position).toEqualEpsilon(rectangleCenter1, CesiumMath.EPSILON5);
} else {
expect(results[0].position).toBeUndefined();
expect(results[1].position).toBeUndefined();
}
}, primitiveRay);
});
it('does not drill pick when show is false', function() {
var rectangle1 = createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
rectangle2.show = false;
expect(scene).toDrillPickFromRayAndCall(function(results) {
expect(results.length).toEqual(1);
expect(results[0].object.primitive).toEqual(rectangle1);
}, primitiveRay);
});
it('does not drill pick when alpha is zero', function() {
var rectangle1 = createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
rectangle2.appearance.material.uniforms.color.alpha = 0.0;
expect(scene).toDrillPickFromRayAndCall(function(results) {
expect(results.length).toEqual(1);
expect(results[0].object.primitive).toEqual(rectangle1);
}, primitiveRay);
});
it('returns empty array if no primitives are picked', function() {
createLargeRectangle(0.0);
createLargeRectangle(1.0);
expect(scene).toDrillPickFromRayAndCall(function(results) {
expect(results.length).toEqual(0);
}, offscreenRay);
});
it('can drill pick batched Primitives with show attribute', function() {
var geometry = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 0.0
});
var geometryWithHeight = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 1.0
});
var instance1 = new GeometryInstance({
id : 1,
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var instance2 = new GeometryInstance({
id : 2,
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(false)
}
});
var instance3 = new GeometryInstance({
id : 3,
geometry : geometryWithHeight,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var primitive = primitives.add(new Primitive({
geometryInstances : [instance1, instance2, instance3],
asynchronous : false,
appearance : new EllipsoidSurfaceAppearance()
}));
expect(scene).toDrillPickFromRayAndCall(function(results) {
expect(results.length).toEqual(2);
expect(results[0].object.primitive).toEqual(primitive);
expect(results[0].object.id).toEqual(3);
expect(results[1].object.primitive).toEqual(primitive);
expect(results[1].object.id).toEqual(1);
}, primitiveRay);
});
it('can drill pick without ID', function() {
var geometry = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT
});
var instance1 = new GeometryInstance({
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var instance2 = new GeometryInstance({
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var primitive = primitives.add(new Primitive({
geometryInstances : [instance1, instance2],
asynchronous : false,
appearance : new EllipsoidSurfaceAppearance()
}));
expect(scene).toDrillPickFromRayAndCall(function(results) {
expect(results.length).toEqual(1);
expect(results[0].object.primitive).toEqual(primitive);
}, primitiveRay);
});
it('can drill pick batched Primitives without show attribute', function() {
var geometry = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 0.0
});
var geometryWithHeight = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 1.0
});
var instance1 = new GeometryInstance({
id : 1,
geometry : geometry
});
var instance2 = new GeometryInstance({
id : 2,
geometry : geometry
});
var instance3 = new GeometryInstance({
id : 3,
geometry : geometryWithHeight
});
var primitive = primitives.add(new Primitive({
geometryInstances : [instance1, instance2, instance3],
asynchronous : false,
appearance : new EllipsoidSurfaceAppearance()
}));
expect(scene).toDrillPickFromRayAndCall(function(results) {
expect(results.length).toEqual(1);
expect(results[0].object.primitive).toEqual(primitive);
expect(results[0].object.id).toEqual(3);
}, primitiveRay);
});
it('stops drill picking when the limit is reached.', function() {
createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
var rectangle3 = createLargeRectangle(2.0);
var rectangle4 = createLargeRectangle(3.0);
expect(scene).toDrillPickFromRayAndCall(function(results) {
expect(results.length).toEqual(3);
expect(results[0].object.primitive).toEqual(rectangle4);
expect(results[1].object.primitive).toEqual(rectangle3);
expect(results[2].object.primitive).toEqual(rectangle2);
}, primitiveRay, 3);
});
it('excludes objects', function() {
createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
var rectangle3 = createLargeRectangle(2.0);
var rectangle4 = createLargeRectangle(3.0);
var rectangle5 = createLargeRectangle(4.0);
expect(scene).toDrillPickFromRayAndCall(function(results) {
expect(results.length).toBe(2);
expect(results[0].object.primitive).toBe(rectangle4);
expect(results[1].object.primitive).toBe(rectangle2);
}, primitiveRay, 2, [rectangle5, rectangle3]);
});
it('throws if ray is undefined', function() {
expect(function() {
scene.drillPickFromRay(undefined);
}).toThrowDeveloperError();
});
it('throws if scene camera is in 2D', function() {
scene.morphTo2D(0.0);
expect(function() {
scene.drillPickFromRay(primitiveRay);
}).toThrowDeveloperError();
});
it('throws if scene camera is in CV', function() {
scene.morphToColumbusView(0.0);
expect(function() {
scene.drillPickFromRay(primitiveRay);
}).toThrowDeveloperError();
});
});
describe('sampleHeight', function() {
it('samples height from tileset', function() {
if (!scene.sampleHeightSupported) {
return;
}
var cartographic = new Cartographic(0.0, 0.0);
return createTileset().then(function(tileset) {
expect(scene).toSampleHeightAndCall(function(height) {
expect(height).toBeGreaterThan(0.0);
expect(height).toBeLessThan(20.0); // Rough height of tile
}, cartographic);
});
});
it('samples height from the globe', function() {
if (!scene.sampleHeightSupported) {
return;
}
var cartographic = new Cartographic(0.0, 0.0);
return createGlobe().then(function() {
expect(scene).toSampleHeightAndCall(function(height) {
expect(height).toBeDefined();
}, cartographic);
});
});
it('samples height from primitive', function() {
if (!scene.sampleHeightSupported) {
return;
}
createSmallRectangle(0.0);
var cartographic = new Cartographic(0.0, 0.0);
expect(scene).toSampleHeightAndCall(function(height) {
expect(height).toEqualEpsilon(0.0, CesiumMath.EPSILON3);
}, cartographic);
});
it('samples height from the top primitive', function() {
if (!scene.sampleHeightSupported) {
return;
}
createSmallRectangle(0.0);
createSmallRectangle(1.0);
var cartographic = new Cartographic(0.0, 0.0);
expect(scene).toSampleHeightAndCall(function(height) {
expect(height).toEqualEpsilon(1.0, CesiumMath.EPSILON3);
}, cartographic);
});
it('returns undefined if no height is sampled', function() {
if (!scene.sampleHeightSupported) {
return;
}
createSmallRectangle(0.0);
var cartographic = new Cartographic(1.0, 0.0);
expect(scene).toSampleHeightAndCall(function(height) {
expect(height).toBeUndefined();
}, cartographic);
});
it('excludes objects', function() {
if (!scene.sampleHeightSupported) {
return;
}
createSmallRectangle(0.0);
var rectangle2 = createSmallRectangle(1.0);
var rectangle3 = createSmallRectangle(2.0);
var cartographic = new Cartographic(0.0, 0.0);
expect(scene).toSampleHeightAndCall(function(height) {
expect(height).toEqualEpsilon(0.0, CesiumMath.EPSILON3);
}, cartographic, [rectangle2, rectangle3]);
});
it('excludes primitive that doesn\'t write depth', function() {
if (!scene.sampleHeightSupported) {
return;
}
var rectangle = createSmallRectangle(0.0);
var height = 100.0;
var cartographic = new Cartographic(0.0, 0.0, height);
var collection = scene.primitives.add(new PointPrimitiveCollection());
var point = collection.add({
position : Cartographic.toCartesian(cartographic)
});
expect(scene).toSampleHeightAndCall(function(height) {
expect(height).toEqualEpsilon(height, CesiumMath.EPSILON3);
}, cartographic);
point.disableDepthTestDistance = Number.POSITIVE_INFINITY;
expect(scene).toSampleHeightAndCall(function(height) {
expect(height).toEqualEpsilon(0.0, CesiumMath.EPSILON3);
}, cartographic);
rectangle.show = false;
expect(scene).toSampleHeightAndCall(function(height) {
expect(height).toBeUndefined();
}, cartographic);
});
it('throws if position is undefined', function() {
if (!scene.sampleHeightSupported) {
return;
}
expect(function() {
scene.sampleHeight(undefined);
}).toThrowDeveloperError();
});
it('throws if scene camera is in 2D', function() {
if (!scene.sampleHeightSupported) {
return;
}
scene.morphTo2D(0.0);
var cartographic = new Cartographic(0.0, 0.0);
expect(function() {
scene.sampleHeight(cartographic);
}).toThrowDeveloperError();
});
it('throws if scene camera is in CV', function() {
if (!scene.sampleHeightSupported) {
return;
}
scene.morphToColumbusView(0.0);
var cartographic = new Cartographic(0.0, 0.0);
expect(function() {
scene.sampleHeight(cartographic);
}).toThrowDeveloperError();
});
it('throws if sampleHeight is not supported', function() {
if (!scene.sampleHeightSupported) {
return;
}
// Disable extension
var depthTexture = scene.context._depthTexture;
scene.context._depthTexture = false;
var cartographic = new Cartographic(0.0, 0.0);
expect(function() {
scene.sampleHeight(cartographic);
}).toThrowDeveloperError();
// Re-enable extension
scene.context._depthTexture = depthTexture;
});
});
describe('clampToHeight', function() {
it('clamps to tileset', function() {
if (!scene.clampToHeightSupported) {
return;
}
var cartesian = Cartesian3.fromRadians(0.0, 0.0, 100000.0);
return createTileset().then(function(tileset) {
expect(scene).toClampToHeightAndCall(function(position) {
var minimumHeight = Cartesian3.fromRadians(0.0, 0.0).x;
var maximumHeight = minimumHeight + 20.0; // Rough height of tile
expect(position.x).toBeGreaterThan(minimumHeight);
expect(position.x).toBeLessThan(maximumHeight);
expect(position.y).toEqualEpsilon(0.0, CesiumMath.EPSILON5);
expect(position.z).toEqualEpsilon(0.0, CesiumMath.EPSILON5);
}, cartesian);
});
});
it('clamps to the globe', function() {
if (!scene.clampToHeightSupported) {
return;
}
var cartesian = Cartesian3.fromRadians(0.0, 0.0, 100000.0);
return createGlobe().then(function() {
expect(scene).toClampToHeightAndCall(function(position) {
expect(position).toBeDefined();
}, cartesian);
});
});
it('clamps to primitive', function() {
if (!scene.clampToHeightSupported) {
return;
}
createSmallRectangle(0.0);
var cartesian = Cartesian3.fromRadians(0.0, 0.0, 100000.0);
expect(scene).toClampToHeightAndCall(function(cartesian) {
var expectedCartesian = Cartesian3.fromRadians(0.0, 0.0);
expect(cartesian).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON5);
}, cartesian);
});
it('clamps to top primitive', function() {
if (!scene.clampToHeightSupported) {
return;
}
createSmallRectangle(0.0);
createSmallRectangle(1.0);
var cartesian = Cartesian3.fromRadians(0.0, 0.0, 100000.0);
expect(scene).toClampToHeightAndCall(function(cartesian) {
var expectedCartesian = Cartesian3.fromRadians(0.0, 0.0, 1.0);
expect(cartesian).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON5);
}, cartesian);
});
it('returns undefined if there was nothing to clamp to', function() {
if (!scene.clampToHeightSupported) {
return;
}
createSmallRectangle(0.0);
var cartesian = Cartesian3.fromRadians(1.0, 0.0, 100000.0);
expect(scene).toClampToHeightAndCall(function(cartesian) {
expect(cartesian).toBeUndefined();
}, cartesian);
});
it('excludes objects', function() {
if (!scene.clampToHeightSupported) {
return;
}
createSmallRectangle(0.0);
var rectangle2 = createSmallRectangle(1.0);
var rectangle3 = createSmallRectangle(2.0);
var cartesian = Cartesian3.fromRadians(0.0, 0.0, 100000.0);
expect(scene).toClampToHeightAndCall(function(cartesian) {
var expectedCartesian = Cartesian3.fromRadians(0.0, 0.0);
expect(cartesian).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON5);
}, cartesian, [rectangle2, rectangle3]);
});
it('excludes primitive that doesn\'t write depth', function() {
if (!scene.clampToHeightSupported) {
return;
}
var rectangle = createSmallRectangle(0.0);
var cartesian = Cartesian3.fromRadians(0.0, 0.0, 100.0);
var collection = scene.primitives.add(new PointPrimitiveCollection());
var point = collection.add({
position : cartesian
});
expect(scene).toClampToHeightAndCall(function(clampedCartesian) {
expect(clampedCartesian).toEqualEpsilon(cartesian, CesiumMath.EPSILON3);
}, cartesian);
point.disableDepthTestDistance = Number.POSITIVE_INFINITY;
expect(scene).toClampToHeightAndCall(function(clampedCartesian) {
expect(clampedCartesian).toEqualEpsilon(cartesian, CesiumMath.EPSILON3);
}, cartesian);
rectangle.show = false;
expect(scene).toClampToHeightAndCall(function(clampedCartesian) {
expect(clampedCartesian).toBeUndefined();
}, cartesian);
});
it('throws if cartesian is undefined', function() {
if (!scene.clampToHeightSupported) {
return;
}
expect(function() {
scene.clampToHeight(undefined);
}).toThrowDeveloperError();
});
it('throws if scene camera is in 2D', function() {
if (!scene.clampToHeightSupported) {
return;
}
scene.morphTo2D(0.0);
var cartesian = Cartesian3.fromRadians(0.0, 0.0, 100000.0);
expect(function() {
scene.clampToHeight(cartesian);
}).toThrowDeveloperError();
});
it('throws if scene camera is in CV', function() {
if (!scene.clampToHeightSupported) {
return;
}
scene.morphToColumbusView(0.0);
var cartesian = Cartesian3.fromRadians(0.0, 0.0, 100000.0);
expect(function() {
scene.clampToHeight(cartesian);
}).toThrowDeveloperError();
});
it('throws if clampToHeight is not supported', function() {
if (!scene.clampToHeightSupported) {
return;
}
// Disable extension
var depthTexture = scene.context._depthTexture;
scene.context._depthTexture = false;
var cartesian = Cartesian3.fromRadians(0.0, 0.0, 100000.0);
expect(function() {
scene.clampToHeight(cartesian);
}).toThrowDeveloperError();
// Re-enable extension
scene.context._depthTexture = depthTexture;
});
});
function pickFromRayMostDetailed(ray, objectsToExclude) {
var result;
var completed = false;
scene.pickFromRayMostDetailed(ray, objectsToExclude).then(function(pickResult) {
result = pickResult;
completed = true;
});
return pollToPromise(function() {
// Scene requires manual updates in the tests to move along the promise
scene.render();
return completed;
}).then(function() {
return result;
});
}
function drillPickFromRayMostDetailed(ray, limit, objectsToExclude) {
var result;
var completed = false;
scene.drillPickFromRayMostDetailed(ray, limit, objectsToExclude).then(function(pickResult) {
result = pickResult;
completed = true;
});
return pollToPromise(function() {
// Scene requires manual updates in the tests to move along the promise
scene.render();
return completed;
}).then(function() {
return result;
});
}
function sampleHeightMostDetailed(cartographics, objectsToExclude) {
var result;
var completed = false;
scene.sampleHeightMostDetailed(cartographics, objectsToExclude).then(function(pickResult) {
result = pickResult;
completed = true;
});
return pollToPromise(function() {
// Scene requires manual updates in the tests to move along the promise
scene.render();
return completed;
}).then(function() {
return result;
});
}
function clampToHeightMostDetailed(cartesians, objectsToExclude) {
var result;
var completed = false;
scene.clampToHeightMostDetailed(cartesians, objectsToExclude).then(function(pickResult) {
result = pickResult;
completed = true;
});
return pollToPromise(function() {
// Scene requires manual updates in the tests to move along the promise
scene.render();
return completed;
}).then(function() {
return result;
});
}
describe('pickFromRayMostDetailed', function() {
it('picks a tileset', function() {
if (webglStub) {
return;
}
scene.camera.setView({ destination : offscreenRectangle });
return createTileset().then(function(tileset) {
return pickFromRayMostDetailed(primitiveRay).then(function(result) {
var primitive = result.object.primitive;
var position = result.position;
expect(primitive).toBe(tileset);
if (scene.context.depthTexture) {
var minimumHeight = Cartesian3.fromRadians(0.0, 0.0).x;
var maximumHeight = minimumHeight + 20.0; // Rough height of tile
expect(position.x).toBeGreaterThan(minimumHeight);
expect(position.x).toBeLessThan(maximumHeight);
expect(position.y).toEqualEpsilon(0.0, CesiumMath.EPSILON5);
expect(position.z).toEqualEpsilon(0.0, CesiumMath.EPSILON5);
}
});
});
});
it('excludes tileset in objectsToExclude list', function() {
if (webglStub) {
return;
}
scene.camera.setView({ destination : offscreenRectangle });
return createTileset().then(function(tileset) {
var objectsToExclude = [tileset];
return pickFromRayMostDetailed(primitiveRay, objectsToExclude).then(function(result) {
expect(result).toBeUndefined();
});
});
});
it('excludes tileset whose show is false', function() {
if (webglStub) {
return;
}
scene.camera.setView({ destination : offscreenRectangle });
return createTileset().then(function(tileset) {
tileset.show = false;
return pickFromRayMostDetailed(primitiveRay).then(function(result) {
expect(result).toBeUndefined();
});
});
});
it('picks a primitive', function() {
if (webglStub) {
return;
}
var rectangle = createSmallRectangle(0.0);
scene.camera.setView({ destination : offscreenRectangle });
return pickFromRayMostDetailed(primitiveRay).then(function(result) {
var primitive = result.object.primitive;
var position = result.position;
expect(primitive).toBe(rectangle);
if (scene.context.depthTexture) {
var expectedPosition = Cartesian3.fromRadians(0.0, 0.0);
expect(position).toEqualEpsilon(expectedPosition, CesiumMath.EPSILON5);
}
});
});
it('returns undefined if no primitives are picked', function() {
if (webglStub) {
return;
}
createLargeRectangle(0.0);
scene.camera.setView({ destination : offscreenRectangle });
return pickFromRayMostDetailed(offscreenRay).then(function(result) {
expect(result).toBeUndefined();
});
});
it('picks the top primitive', function() {
if (webglStub) {
return;
}
createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
scene.camera.setView({ destination : offscreenRectangle });
return pickFromRayMostDetailed(primitiveRay).then(function(result) {
expect(result.object.primitive).toBe(rectangle2);
});
});
it('excludes objects', function() {
if (webglStub) {
return;
}
var rectangle1 = createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
var rectangle3 = createLargeRectangle(2.0);
var rectangle4 = createLargeRectangle(3.0);
rectangle4.show = false;
scene.camera.setView({ destination : offscreenRectangle });
return pickFromRayMostDetailed(primitiveRay, [rectangle2, rectangle3, rectangle4]).then(function(result) {
expect(result.object.primitive).toBe(rectangle1);
}).then(function() {
return pickFromRayMostDetailed(primitiveRay).then(function(result) {
expect(result.object.primitive).toBe(rectangle3);
});
});
});
it('picks primitive that doesn\'t write depth', function() {
if (webglStub) {
return;
}
var collection = scene.primitives.add(new PointPrimitiveCollection());
var point = collection.add({
position : Cartographic.fromRadians(0.0, 0.0, 100.0),
disableDepthTestDistance : Number.POSITIVE_INFINITY
});
scene.camera.setView({ destination : offscreenRectangle });
return pickFromRayMostDetailed(primitiveRay).then(function(result) {
expect(result.object.primitive).toBe(point);
expect(result.position).toBeUndefined();
});
});
it('throws if ray is undefined', function() {
expect(function() {
scene.pickFromRayMostDetailed(undefined);
}).toThrowDeveloperError();
});
it('throws if scene camera is in 2D', function() {
scene.morphTo2D(0.0);
expect(function() {
scene.pickFromRayMostDetailed(undefined);
}).toThrowDeveloperError();
});
it('throws if scene camera is in CV', function() {
scene.morphToColumbusView(0.0);
expect(function() {
scene.pickFromRayMostDetailed(undefined);
}).toThrowDeveloperError();
});
});
describe('drillPickFromRayMostDetailed', function() {
it('drill picks a primitive', function() {
if (webglStub) {
return;
}
var rectangle = createSmallRectangle(0.0);
scene.camera.setView({ destination : offscreenRectangle });
return drillPickFromRayMostDetailed(primitiveRay).then(function(results) {
expect(results.length).toBe(1);
var primitive = results[0].object.primitive;
var position = results[0].position;
expect(primitive).toBe(rectangle);
if (scene.context.depthTexture) {
var expectedPosition = Cartesian3.fromRadians(0.0, 0.0);
expect(position).toEqualEpsilon(expectedPosition, CesiumMath.EPSILON5);
} else {
expect(position).toBeUndefined();
}
});
});
it('drill picks multiple primitives', function() {
if (webglStub) {
return;
}
var rectangle1 = createSmallRectangle(0.0);
var rectangle2 = createSmallRectangle(1.0);
scene.camera.setView({ destination : offscreenRectangle });
return drillPickFromRayMostDetailed(primitiveRay).then(function(results) {
expect(results.length).toBe(2);
// rectangle2 is picked before rectangle1
expect(results[0].object.primitive).toBe(rectangle2);
expect(results[1].object.primitive).toBe(rectangle1);
if (scene.context.depthTexture) {
var rectangleCenter1 = Cartesian3.fromRadians(0.0, 0.0, 0.0);
var rectangleCenter2 = Cartesian3.fromRadians(0.0, 0.0, 1.0);
expect(results[0].position).toEqualEpsilon(rectangleCenter2, CesiumMath.EPSILON5);
expect(results[1].position).toEqualEpsilon(rectangleCenter1, CesiumMath.EPSILON5);
} else {
expect(results[0].position).toBeUndefined();
expect(results[1].position).toBeUndefined();
}
});
});
it('does not drill pick when show is false', function() {
if (webglStub) {
return;
}
var rectangle1 = createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
rectangle2.show = false;
scene.camera.setView({ destination : offscreenRectangle });
return drillPickFromRayMostDetailed(primitiveRay).then(function(results) {
expect(results.length).toEqual(1);
expect(results[0].object.primitive).toEqual(rectangle1);
});
});
it('does not drill pick when alpha is zero', function() {
if (webglStub) {
return;
}
var rectangle1 = createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
rectangle2.appearance.material.uniforms.color.alpha = 0.0;
scene.camera.setView({ destination : offscreenRectangle });
return drillPickFromRayMostDetailed(primitiveRay).then(function(results) {
expect(results.length).toEqual(1);
expect(results[0].object.primitive).toEqual(rectangle1);
});
});
it('returns empty array if no primitives are picked', function() {
if (webglStub) {
return;
}
createLargeRectangle(0.0);
createLargeRectangle(1.0);
scene.camera.setView({ destination : offscreenRectangle });
return drillPickFromRayMostDetailed(offscreenRay).then(function(results) {
expect(results.length).toEqual(0);
});
});
it('can drill pick batched Primitives with show attribute', function() {
if (webglStub) {
return;
}
var geometry = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 0.0
});
var geometryWithHeight = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 1.0
});
var instance1 = new GeometryInstance({
id : 1,
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var instance2 = new GeometryInstance({
id : 2,
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(false)
}
});
var instance3 = new GeometryInstance({
id : 3,
geometry : geometryWithHeight,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var primitive = primitives.add(new Primitive({
geometryInstances : [instance1, instance2, instance3],
asynchronous : false,
appearance : new EllipsoidSurfaceAppearance()
}));
scene.camera.setView({ destination : offscreenRectangle });
return drillPickFromRayMostDetailed(primitiveRay).then(function(results) {
expect(results.length).toEqual(2);
expect(results[0].object.primitive).toEqual(primitive);
expect(results[0].object.id).toEqual(3);
expect(results[1].object.primitive).toEqual(primitive);
expect(results[1].object.id).toEqual(1);
});
});
it('can drill pick without ID', function() {
if (webglStub) {
return;
}
var geometry = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT
});
var instance1 = new GeometryInstance({
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var instance2 = new GeometryInstance({
geometry : geometry,
attributes : {
show : new ShowGeometryInstanceAttribute(true)
}
});
var primitive = primitives.add(new Primitive({
geometryInstances : [instance1, instance2],
asynchronous : false,
appearance : new EllipsoidSurfaceAppearance()
}));
scene.camera.setView({ destination : offscreenRectangle });
return drillPickFromRayMostDetailed(primitiveRay).then(function(results) {
expect(results.length).toEqual(1);
expect(results[0].object.primitive).toEqual(primitive);
});
});
it('can drill pick batched Primitives without show attribute', function() {
if (webglStub) {
return;
}
var geometry = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 0.0
});
var geometryWithHeight = new RectangleGeometry({
rectangle : Rectangle.fromDegrees(-50.0, -50.0, 50.0, 50.0),
granularity : CesiumMath.toRadians(20.0),
vertexFormat : EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height : 1.0
});
var instance1 = new GeometryInstance({
id : 1,
geometry : geometry
});
var instance2 = new GeometryInstance({
id : 2,
geometry : geometry
});
var instance3 = new GeometryInstance({
id : 3,
geometry : geometryWithHeight
});
var primitive = primitives.add(new Primitive({
geometryInstances : [instance1, instance2, instance3],
asynchronous : false,
appearance : new EllipsoidSurfaceAppearance()
}));
scene.camera.setView({ destination : offscreenRectangle });
return drillPickFromRayMostDetailed(primitiveRay).then(function(results) {
expect(results.length).toEqual(1);
expect(results[0].object.primitive).toEqual(primitive);
expect(results[0].object.id).toEqual(3);
});
});
it('stops drill picking when the limit is reached.', function() {
if (webglStub) {
return;
}
createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
var rectangle3 = createLargeRectangle(2.0);
var rectangle4 = createLargeRectangle(3.0);
scene.camera.setView({ destination : offscreenRectangle });
return drillPickFromRayMostDetailed(primitiveRay, 3).then(function(results) {
expect(results.length).toEqual(3);
expect(results[0].object.primitive).toEqual(rectangle4);
expect(results[1].object.primitive).toEqual(rectangle3);
expect(results[2].object.primitive).toEqual(rectangle2);
});
});
it('excludes objects', function() {
if (webglStub) {
return;
}
createLargeRectangle(0.0);
var rectangle2 = createLargeRectangle(1.0);
var rectangle3 = createLargeRectangle(2.0);
var rectangle4 = createLargeRectangle(3.0);
var rectangle5 = createLargeRectangle(4.0);
scene.camera.setView({ destination : offscreenRectangle });
return drillPickFromRayMostDetailed(primitiveRay, 2, [rectangle5, rectangle3]).then(function(results) {
expect(results.length).toBe(2);
expect(results[0].object.primitive).toBe(rectangle4);
expect(results[1].object.primitive).toBe(rectangle2);
});
});
it('throws if ray is undefined', function() {
expect(function() {
scene.drillPickFromRayMostDetailed(undefined);
}).toThrowDeveloperError();
});
it('throws if scene camera is in 2D', function() {
scene.morphTo2D(0.0);
expect(function() {
scene.drillPickFromRayMostDetailed(primitiveRay);
}).toThrowDeveloperError();
});
it('throws if scene camera is in CV', function() {
scene.morphToColumbusView(0.0);
expect(function() {
scene.drillPickFromRayMostDetailed(primitiveRay);
}).toThrowDeveloperError();
});
});
describe('sampleHeightMostDetailed', function() {
it('samples height from tileset', function() {
if (!scene.sampleHeightSupported) {
return;
}
var cartographics = [new Cartographic(0.0, 0.0)];
return createTileset().then(function() {
return sampleHeightMostDetailed(cartographics).then(function(updatedCartographics) {
var height = updatedCartographics[0].height;
expect(height).toBeGreaterThan(0.0);
expect(height).toBeLessThan(20.0); // Rough height of tile
});
});
});
it('samples height from the globe', function() {
if (!scene.sampleHeightSupported) {
return;
}
var cartographics = [
new Cartographic(0.0, 0.0),
new Cartographic(0.0001, 0.0001),
new Cartographic(0.0002, 0.0002)
];
var clonedCartographics = [new Cartographic(0.0, 0.0), new Cartographic(0.0001, 0.0001), new Cartographic(0.0002, 0.0002)];
return createGlobe().then(function() {
return sampleHeightMostDetailed(cartographics).then(function(updatedCartographics) {
expect(updatedCartographics).toBe(cartographics);
expect(updatedCartographics.length).toBe(3);
var previousHeight;
for (var i = 0; i < 3; ++i) {
var longitude = updatedCartographics[i].longitude;
var latitude = updatedCartographics[i].latitude;
var height = updatedCartographics[i].height;
expect(longitude).toBe(clonedCartographics[i].longitude);
expect(latitude).toBe(clonedCartographics[i].latitude);
expect(height).toBeDefined();
expect(height).not.toBe(previousHeight);
previousHeight = height;
}
});
});
});
it('does not sample offscreen globe tiles', function() {
if (!scene.sampleHeightSupported) {
return;
}
var cartographics = [new Cartographic(0.0, 0.0)];
scene.camera.setView({ destination : offscreenRectangle });
return createGlobe().then(function() {
return sampleHeightMostDetailed(cartographics).then(function(updatedCartographics) {
expect(updatedCartographics[0].height).toBeUndefined();
});
});
});
it('samples height from multiple primitives', function() {
if (!scene.sampleHeightSupported) {
return;
}
createRectangle(0.0, smallRectangle);
createRectangle(0.0, offscreenRectangle);
var cartographics = [
Rectangle.center(smallRectangle),
Rectangle.center(offscreenRectangle),
new Cartographic(-2.0, -2.0)
];
scene.camera.setView({ destination : offscreenRectangle });
return sampleHeightMostDetailed(cartographics).then(function(updatedCartographics) {
expect(updatedCartographics[0].height).toBeDefined();
expect(updatedCartographics[1].height).toBeDefined();
expect(updatedCartographics[2].height).toBeUndefined(); // No primitive occupies this space
});
});
it('samples multiple heights from primitive', function() {
if (!scene.sampleHeightSupported) {
return;
}
createSmallRectangle(0.0);
var cartographics = [
new Cartographic(0.0, 0.0),
new Cartographic(-0.000001, -0.000001),
new Cartographic(0.0000005, 0.0000005)
];
scene.camera.setView({ destination : offscreenRectangle });
return sampleHeightMostDetailed(cartographics).then(function(updatedCartographics) {
var previousHeight;
for (var i = 0; i < 3; ++i) {
var height = updatedCartographics[i].height;
expect(height).toEqualEpsilon(0.0, CesiumMath.EPSILON3);
expect(height).not.toBe(previousHeight);
previousHeight = height;
}
});
});
it('samples height from the top primitive', function() {
if (!scene.sampleHeightSupported) {
return;
}
createSmallRectangle(0.0);
createSmallRectangle(1.0);
var cartographics = [new Cartographic(0.0, 0.0)];
scene.camera.setView({ destination : offscreenRectangle });
return sampleHeightMostDetailed(cartographics).then(function(updatedCartographics) {
expect(updatedCartographics[0].height).toEqualEpsilon(1.0, CesiumMath.EPSILON3);
});
});
it('excludes objects', function() {
if (!scene.sampleHeightSupported) {
return;
}
var rectangle1 = createRectangle(0.0, smallRectangle);
createRectangle(0.0, offscreenRectangle);
var rectangle3 = createRectangle(1.0, offscreenRectangle);
var cartographics = [
Rectangle.center(smallRectangle),
Rectangle.center(offscreenRectangle),
new Cartographic(-2.0, -2.0)
];
scene.camera.setView({ destination : offscreenRectangle });
return sampleHeightMostDetailed(cartographics, [rectangle1, rectangle3]).then(function(updatedCartographics) {
expect(updatedCartographics[0].height).toBeUndefined(); // This rectangle was excluded
expect(updatedCartographics[1].height).toEqualEpsilon(0.0, CesiumMath.EPSILON2);
expect(updatedCartographics[2].height).toBeUndefined(); // No primitive occupies this space
});
});
it('excludes primitive that doesn\'t write depth', function() {
if (!scene.sampleHeightSupported) {
return;
}
var rectangle = createSmallRectangle(0.0);
var height = 100.0;
var cartographics = [new Cartographic(0.0, 0.0, height)];
var collection = scene.primitives.add(new PointPrimitiveCollection());
var point = collection.add({
position : Cartographic.toCartesian(cartographics[0])
});
scene.camera.setView({ destination : offscreenRectangle });
return sampleHeightMostDetailed(cartographics).then(function(updatedCartographics) {
expect(updatedCartographics[0].height).toEqualEpsilon(height, CesiumMath.EPSILON3);
}).then(function() {
point.disableDepthTestDistance = Number.POSITIVE_INFINITY;
return sampleHeightMostDetailed(cartographics).then(function(updatedCartographics) {
expect(updatedCartographics[0].height).toEqualEpsilon(0.0, CesiumMath.EPSILON3);
});
}).then(function() {
rectangle.show = false;
return sampleHeightMostDetailed(cartographics).then(function(updatedCartographics) {
expect(updatedCartographics[0].height).toBeUndefined();
});
});
});
it('handles empty array', function() {
if (!scene.sampleHeightSupported) {
return;
}
var cartographics = [];
return sampleHeightMostDetailed(cartographics).then(function(updatedCartographics) {
expect(updatedCartographics.length).toBe(0);
});
});
it('throws if positions is undefined', function() {
if (!scene.sampleHeightSupported) {
return;
}
expect(function() {
scene.sampleHeightMostDetailed(undefined);
}).toThrowDeveloperError();
});
it('throws if scene camera is in 2D', function() {
if (!scene.sampleHeightSupported) {
return;
}
scene.morphTo2D(0.0);
var cartographics = [new Cartographic(0.0, 0.0)];
expect(function() {
scene.sampleHeightMostDetailed(cartographics);
}).toThrowDeveloperError();
});
it('throws if scene camera is in CV', function() {
if (!scene.sampleHeightSupported) {
return;
}
scene.morphToColumbusView(0.0);
var cartographics = [new Cartographic(0.0, 0.0)];
expect(function() {
scene.sampleHeightMostDetailed(cartographics);
}).toThrowDeveloperError();
});
it('throws if sampleHeight is not supported', function() {
if (!scene.sampleHeightSupported) {
return;
}
// Disable extension
var depthTexture = scene.context._depthTexture;
scene.context._depthTexture = false;
var cartographics = [new Cartographic(0.0, 0.0)];
expect(function() {
scene.sampleHeightMostDetailed(cartographics);
}).toThrowDeveloperError();
// Re-enable extension
scene.context._depthTexture = depthTexture;
});
});
describe('clampToHeightMostDetailed', function() {
it('clamps to tileset', function() {
if (!scene.clampToHeightSupported) {
return;
}
var cartesians = [Cartesian3.fromRadians(0.0, 0.0, 100000.0)];
return createTileset().then(function() {
return clampToHeightMostDetailed(cartesians).then(function(updatedCartesians) {
var minimumHeight = Cartesian3.fromRadians(0.0, 0.0).x;
var maximumHeight = minimumHeight + 20.0; // Rough height of tile
var position = updatedCartesians[0];
expect(position.x).toBeGreaterThan(minimumHeight);
expect(position.x).toBeLessThan(maximumHeight);
expect(position.y).toEqualEpsilon(0.0, CesiumMath.EPSILON5);
expect(position.z).toEqualEpsilon(0.0, CesiumMath.EPSILON5);
});
});
});
it('clamps to the globe', function() {
if (!scene.clampToHeightSupported) {
return;
}
var cartesians = [
Cartesian3.fromRadians(0.0, 0.0, 100000.0),
Cartesian3.fromRadians(0.0001, 0.0001, 100000.0),
Cartesian3.fromRadians(0.0002, 0.0002, 100000.0)
];
var clonedCartesians = [
Cartesian3.fromRadians(0.0, 0.0, 100000.0),
Cartesian3.fromRadians(0.0001, 0.0001, 100000.0),
Cartesian3.fromRadians(0.0002, 0.0002, 100000.0)
];
return createGlobe().then(function() {
return clampToHeightMostDetailed(cartesians).then(function(updatedCartesians) {
expect(updatedCartesians).toBe(cartesians);
expect(updatedCartesians.length).toBe(3);
var previousCartesian;
for (var i = 0; i < 3; ++i) {
expect(updatedCartesians[i]).not.toEqual(clonedCartesians[i]);
expect(updatedCartesians[i]).not.toEqual(previousCartesian);
previousCartesian = updatedCartesians[i];
}
});
});
});
it('does not clamp to offscreen globe tiles', function() {
if (!scene.clampToHeightSupported) {
return;
}
var cartesians = [Cartesian3.fromRadians(0.0, 0.0, 100000.0)];
scene.camera.setView({ destination : offscreenRectangle });
return createGlobe().then(function() {
return clampToHeightMostDetailed(cartesians).then(function(updatedCartesians) {
expect(updatedCartesians[0]).toBeUndefined();
});
});
});
it('clamps to multiple primitives', function() {
if (!scene.clampToHeightSupported) {
return;
}
createRectangle(0.0, smallRectangle);
createRectangle(0.0, offscreenRectangle);
var cartesians = [
Cartographic.toCartesian(Rectangle.center(smallRectangle)),
Cartographic.toCartesian(Rectangle.center(offscreenRectangle)),
Cartesian3.fromRadians(-2.0, -2.0)
];
scene.camera.setView({ destination : offscreenRectangle });
return clampToHeightMostDetailed(cartesians).then(function(updatedCartesians) {
expect(updatedCartesians[0]).toBeDefined();
expect(updatedCartesians[1]).toBeDefined();
expect(updatedCartesians[2]).toBeUndefined(); // No primitive occupies this space
});
});
it('clamps to primitive', function() {
if (!scene.clampToHeightSupported) {
return;
}
createSmallRectangle(0.0);
var cartesians = [
Cartesian3.fromRadians(0.0, 0.0, 100000.0),
Cartesian3.fromRadians(-0.000001, -0.000001, 100000.0),
Cartesian3.fromRadians(0.0000005, 0.0000005, 100000.0)
];
var expectedCartesians = [
Cartesian3.fromRadians(0.0, 0.0, 0.0),
Cartesian3.fromRadians(-0.000001, -0.000001, 0.0),
Cartesian3.fromRadians(0.0000005, 0.0000005, 0.0)
];
scene.camera.setView({ destination : offscreenRectangle });
return clampToHeightMostDetailed(cartesians).then(function(updatedCartesians) {
var previousCartesian;
for (var i = 0; i < 3; ++i) {
expect(updatedCartesians[i]).toEqualEpsilon(expectedCartesians[i], CesiumMath.EPSILON5);
expect(updatedCartesians[i]).not.toEqual(previousCartesian);
previousCartesian = updatedCartesians[i];
}
});
});
it('clamps to top primitive', function() {
if (!scene.clampToHeightSupported) {
return;
}
createSmallRectangle(0.0);
createSmallRectangle(1.0);
var cartesians = [Cartesian3.fromRadians(0.0, 0.0)];
scene.camera.setView({ destination : offscreenRectangle });
return clampToHeightMostDetailed(cartesians).then(function(updatedCartesians) {
var expectedCartesian = Cartesian3.fromRadians(0.0, 0.0, 1.0);
expect(updatedCartesians[0]).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON5);
});
});
it('excludes objects', function() {
if (!scene.clampToHeightSupported) {
return;
}
var rectangle1 = createRectangle(0.0, smallRectangle);
createRectangle(0.0, offscreenRectangle);
var rectangle3 = createRectangle(1.0, offscreenRectangle);
var cartesians = [
Cartographic.toCartesian(Rectangle.center(smallRectangle)),
Cartographic.toCartesian(Rectangle.center(offscreenRectangle)),
Cartesian3.fromRadians(-2.0, -2.0)
];
scene.camera.setView({ destination : offscreenRectangle });
return clampToHeightMostDetailed(cartesians, [rectangle1, rectangle3]).then(function(updatedCartesians) {
var expectedCartesian = Cartographic.toCartesian(Rectangle.center(offscreenRectangle));
expect(updatedCartesians[0]).toBeUndefined(); // This rectangle was excluded
expect(updatedCartesians[1]).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON2);
expect(updatedCartesians[2]).toBeUndefined(); // No primitive occupies this space
});
});
it('excludes primitive that doesn\'t write depth', function() {
if (!scene.clampToHeightSupported) {
return;
}
var rectangle = createSmallRectangle(0.0);
var height = 100.0;
var cartesian = Cartesian3.fromRadians(0.0, 0.0, height);
var cartesians1 = [Cartesian3.clone(cartesian)];
var cartesians2 = [Cartesian3.clone(cartesian)];
var cartesians3 = [Cartesian3.clone(cartesian)];
var collection = scene.primitives.add(new PointPrimitiveCollection());
var point = collection.add({
position : cartesian
});
scene.camera.setView({ destination : offscreenRectangle });
return clampToHeightMostDetailed(cartesians1).then(function(updatedCartesians) {
expect(updatedCartesians[0]).toEqualEpsilon(cartesian, CesiumMath.EPSILON3);
}).then(function() {
point.disableDepthTestDistance = Number.POSITIVE_INFINITY;
return clampToHeightMostDetailed(cartesians2).then(function(updatedCartesians) {
expect(updatedCartesians[0]).toEqualEpsilon(cartesian, CesiumMath.EPSILON3);
});
}).then(function() {
rectangle.show = false;
return clampToHeightMostDetailed(cartesians3).then(function(updatedCartesians) {
expect(updatedCartesians[0]).toBeUndefined();
});
});
});
it('handles empty array', function() {
if (!scene.clampToHeightSupported) {
return;
}
var cartesians = [];
return sampleHeightMostDetailed(cartesians).then(function(updatedCartesians) {
expect(updatedCartesians.length).toBe(0);
});
});
it('throws if cartesians is undefined', function() {
if (!scene.clampToHeightSupported) {
return;
}
expect(function() {
scene.clampToHeightMostDetailed(undefined);
}).toThrowDeveloperError();
});
it('throws if scene camera is in 2D', function() {
if (!scene.clampToHeightSupported) {
return;
}
scene.morphTo2D(0.0);
var cartesians = [Cartesian3.fromRadians(0.0, 0.0)];
expect(function() {
scene.clampToHeightMostDetailed(cartesians);
}).toThrowDeveloperError();
});
it('throws if scene camera is in CV', function() {
if (!scene.clampToHeightSupported) {
return;
}
scene.morphToColumbusView(0.0);
var cartesians = [Cartesian3.fromRadians(0.0, 0.0)];
expect(function() {
scene.clampToHeightMostDetailed(cartesians);
}).toThrowDeveloperError();
});
it('throws if clampToHeight is not supported', function() {
if (!scene.clampToHeightSupported) {
return;
}
// Disable extension
var depthTexture = scene.context._depthTexture;
scene.context._depthTexture = false;
var cartesians = [Cartesian3.fromRadians(0.0, 0.0)];
expect(function() {
scene.clampToHeightMostDetailed(cartesians);
}).toThrowDeveloperError();
// Re-enable extension
scene.context._depthTexture = depthTexture;
});
});
it('calls multiple picking functions within the same frame', function() {
if (!scene.clampToHeightSupported || !scene.pickPositionSupported) {
return;
}
createSmallRectangle(0.0);
var offscreenRectanglePrimitive = createRectangle(0.0, offscreenRectangle);
offscreenRectanglePrimitive.appearance.material.uniforms.color = new Color(1.0, 0.0, 0.0, 1.0);
scene.camera.setView({ destination : offscreenRectangle });
// Call render. Lays down depth for the pickPosition call
scene.renderForSpecs();
var cartographic = Cartographic.fromRadians(0.0, 0.0, 100000.0);
var cartesian = Cartographic.toCartesian(cartographic);
var cartesians = [Cartesian3.clone(cartesian)];
var cartographics = [cartographic];
// Call clampToHeight
expect(scene).toClampToHeightAndCall(function(cartesian) {
var expectedCartesian = Cartesian3.fromRadians(0.0, 0.0);
expect(cartesian).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON5);
}, cartesian);
// Call pickPosition
expect(scene).toPickPositionAndCall(function(cartesian) {
var expectedCartesian = Cartographic.toCartesian(Rectangle.center(offscreenRectangle));
expect(cartesian).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON5);
});
// Call clampToHeight again
expect(scene).toClampToHeightAndCall(function(cartesian) {
var expectedCartesian = Cartesian3.fromRadians(0.0, 0.0);
expect(cartesian).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON5);
}, cartesian);
// Call pick
expect(scene).toPickPrimitive(offscreenRectanglePrimitive);
// Call clampToHeight again
expect(scene).toClampToHeightAndCall(function(cartesian) {
var expectedCartesian = Cartesian3.fromRadians(0.0, 0.0);
expect(cartesian).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON5);
}, cartesian);
// Call pickPosition on translucent primitive and returns undefined
offscreenRectanglePrimitive.appearance.material.uniforms.color = new Color(1.0, 0.0, 0.0, 0.5);
scene.renderForSpecs();
expect(scene).toPickPositionAndCall(function(cartesian) {
expect(cartesian).toBeUndefined();
});
// Call clampToHeight again
expect(scene).toClampToHeightAndCall(function(cartesian) {
var expectedCartesian = Cartesian3.fromRadians(0.0, 0.0);
expect(cartesian).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON5);
}, cartesian);
// Call pickPosition on translucent primitive with pickTranslucentDepth
scene.pickTranslucentDepth = true;
scene.renderForSpecs();
expect(scene).toPickPositionAndCall(function(cartesian) {
var expectedCartesian = Cartographic.toCartesian(Rectangle.center(offscreenRectangle));
expect(cartesian).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON5);
});
// Mix async and sync requests
var results = [];
var completed = 0;
scene.clampToHeightMostDetailed(cartesians).then(function(updatedCartesians) {
results.push(updatedCartesians);
completed++;
});
scene.sampleHeightMostDetailed(cartographics).then(function(updatedCartographics) {
results.push(updatedCartographics);
completed++;
});
// Call clampToHeight again
expect(scene).toClampToHeightAndCall(function(cartesian) {
var expectedCartesian = Cartesian3.fromRadians(0.0, 0.0);
expect(cartesian).toEqualEpsilon(expectedCartesian, CesiumMath.EPSILON5);
}, cartesian);
return pollToPromise(function() {
// Scene requires manual updates in the tests to move along the promise
scene.render();
return completed === 2;
}).then(function() {
expect(results[0][0]).toBeDefined();
expect(results[1][0].height).toBeDefined();
});
});
}, 'WebGL');