import { ApproximateTerrainHeights } from "../../Source/Cesium.js";
|
import { Cartesian2 } from "../../Source/Cesium.js";
|
import { Cartesian3 } from "../../Source/Cesium.js";
|
import { Math as CesiumMath } from "../../Source/Cesium.js";
|
import { Color } from "../../Source/Cesium.js";
|
import { ColorGeometryInstanceAttribute } from "../../Source/Cesium.js";
|
import { destroyObject } from "../../Source/Cesium.js";
|
import { DistanceDisplayConditionGeometryInstanceAttribute } from "../../Source/Cesium.js";
|
import { Ellipsoid } from "../../Source/Cesium.js";
|
import { GeometryInstance } from "../../Source/Cesium.js";
|
import { GroundPolylineGeometry } from "../../Source/Cesium.js";
|
import { HeadingPitchRange } from "../../Source/Cesium.js";
|
import { Rectangle } from "../../Source/Cesium.js";
|
import { RectangleGeometry } from "../../Source/Cesium.js";
|
import { ShowGeometryInstanceAttribute } from "../../Source/Cesium.js";
|
import { Pass } from "../../Source/Cesium.js";
|
import { GroundPolylinePrimitive } from "../../Source/Cesium.js";
|
import { PerInstanceColorAppearance } from "../../Source/Cesium.js";
|
import { PolylineColorAppearance } from "../../Source/Cesium.js";
|
import { PolylineMaterialAppearance } from "../../Source/Cesium.js";
|
import { Primitive } from "../../Source/Cesium.js";
|
import createCanvas from "../createCanvas.js";
|
import createScene from "../createScene.js";
|
import pollToPromise from "../pollToPromise.js";
|
|
describe(
|
"Scene/GroundPolylinePrimitive",
|
function () {
|
var scene;
|
var context;
|
|
var ellipsoid;
|
|
var depthColor;
|
var polylineColor;
|
var polylineColorAttribute;
|
|
var groundPolylineInstance;
|
var groundPolylinePrimitive;
|
var depthRectanglePrimitive;
|
|
var positions = Cartesian3.fromDegreesArray([0.01, 0.0, 0.03, 0.0]);
|
|
var lookPosition = Cartesian3.fromDegrees(0.02, 0.0);
|
var lookPositionOffset = Cartesian3.fromDegrees(0.02, 0.0001);
|
|
var canvasWidth = 4;
|
var canvasHeight = 4;
|
|
beforeAll(function () {
|
var canvas = createCanvas(canvasWidth, canvasHeight);
|
scene = createScene({
|
canvas: canvas,
|
});
|
scene.postProcessStages.fxaa.enabled = false;
|
|
context = scene.context;
|
|
ellipsoid = Ellipsoid.WGS84;
|
return GroundPolylinePrimitive.initializeTerrainHeights();
|
});
|
|
afterAll(function () {
|
scene.destroyForSpecs();
|
|
// Leave ground primitive uninitialized
|
ApproximateTerrainHeights._initPromise = undefined;
|
ApproximateTerrainHeights._terrainHeights = undefined;
|
});
|
|
function MockGlobePrimitive(primitive) {
|
this._primitive = primitive;
|
this.pass = Pass.GLOBE;
|
}
|
|
MockGlobePrimitive.prototype.update = function (frameState) {
|
var commandList = frameState.commandList;
|
var startLength = commandList.length;
|
this._primitive.update(frameState);
|
|
for (var i = startLength; i < commandList.length; ++i) {
|
var command = commandList[i];
|
command.pass = this.pass;
|
}
|
};
|
|
MockGlobePrimitive.prototype.isDestroyed = function () {
|
return false;
|
};
|
|
MockGlobePrimitive.prototype.destroy = function () {
|
this._primitive.destroy();
|
return destroyObject(this);
|
};
|
|
beforeEach(function () {
|
scene.morphTo3D(0);
|
|
// Other specs can mess with camera near/far, which can interfere with the
|
// algorithm used to draw ground polylines.
|
scene.camera.frustum.near = 0.1;
|
scene.camera.frustum.far = 10000000000.0;
|
|
var depthpolylineColorAttribute = ColorGeometryInstanceAttribute.fromColor(
|
new Color(0.0, 0.0, 1.0, 1.0)
|
);
|
depthColor = depthpolylineColorAttribute.value;
|
var primitive = new Primitive({
|
geometryInstances: new GeometryInstance({
|
geometry: new RectangleGeometry({
|
ellipsoid: ellipsoid,
|
rectangle: Rectangle.fromDegrees(-1.0, -1.0, 1.0, 1.0),
|
}),
|
id: "depth rectangle",
|
attributes: {
|
color: depthpolylineColorAttribute,
|
},
|
}),
|
appearance: new PerInstanceColorAppearance({
|
translucent: false,
|
flat: true,
|
}),
|
asynchronous: false,
|
});
|
|
// wrap rectangle primitive so it gets executed during the globe pass to lay down depth
|
depthRectanglePrimitive = new MockGlobePrimitive(primitive);
|
|
polylineColorAttribute = ColorGeometryInstanceAttribute.fromColor(
|
new Color(0.0, 1.0, 1.0, 1.0)
|
);
|
polylineColor = polylineColorAttribute.value;
|
groundPolylineInstance = new GeometryInstance({
|
geometry: new GroundPolylineGeometry({
|
positions: positions,
|
granularity: 0.0,
|
width: 1.0,
|
loop: false,
|
ellipsoid: ellipsoid,
|
}),
|
id: "polyline on terrain",
|
attributes: {
|
color: polylineColorAttribute,
|
},
|
});
|
});
|
|
afterEach(function () {
|
scene.groundPrimitives.removeAll();
|
groundPolylinePrimitive =
|
groundPolylinePrimitive &&
|
!groundPolylinePrimitive.isDestroyed() &&
|
groundPolylinePrimitive.destroy();
|
depthRectanglePrimitive =
|
depthRectanglePrimitive &&
|
!depthRectanglePrimitive.isDestroyed() &&
|
depthRectanglePrimitive.destroy();
|
});
|
|
it("default constructs", function () {
|
groundPolylinePrimitive = new GroundPolylinePrimitive();
|
expect(groundPolylinePrimitive.geometryInstances).not.toBeDefined();
|
expect(groundPolylinePrimitive.appearance).toBeInstanceOf(
|
PolylineMaterialAppearance
|
);
|
expect(groundPolylinePrimitive.show).toEqual(true);
|
expect(groundPolylinePrimitive.interleave).toEqual(false);
|
expect(groundPolylinePrimitive.releaseGeometryInstances).toEqual(true);
|
expect(groundPolylinePrimitive.allowPicking).toEqual(true);
|
expect(groundPolylinePrimitive.asynchronous).toEqual(true);
|
expect(groundPolylinePrimitive.debugShowBoundingVolume).toEqual(false);
|
expect(groundPolylinePrimitive.debugShowShadowVolume).toEqual(false);
|
});
|
|
it("constructs with options", function () {
|
var geometryInstances = [];
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: geometryInstances,
|
show: false,
|
interleave: true,
|
releaseGeometryInstances: false,
|
allowPicking: false,
|
asynchronous: false,
|
debugShowBoundingVolume: true,
|
debugShowShadowVolume: true,
|
});
|
|
expect(groundPolylinePrimitive.geometryInstances).toEqual(
|
geometryInstances
|
);
|
expect(groundPolylinePrimitive.show).toEqual(false);
|
expect(groundPolylinePrimitive.interleave).toEqual(true);
|
expect(groundPolylinePrimitive.releaseGeometryInstances).toEqual(false);
|
expect(groundPolylinePrimitive.allowPicking).toEqual(false);
|
expect(groundPolylinePrimitive.asynchronous).toEqual(false);
|
expect(groundPolylinePrimitive.debugShowBoundingVolume).toEqual(true);
|
expect(groundPolylinePrimitive.debugShowShadowVolume).toEqual(true);
|
});
|
|
it("releases geometry instances when releaseGeometryInstances is true", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
releaseGeometryInstances: true,
|
asynchronous: false,
|
});
|
|
expect(groundPolylinePrimitive.geometryInstances).toBeDefined();
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
scene.renderForSpecs();
|
expect(groundPolylinePrimitive.geometryInstances).not.toBeDefined();
|
});
|
|
it("does not release geometry instances when releaseGeometryInstances is false", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
releaseGeometryInstances: false,
|
asynchronous: false,
|
});
|
|
expect(groundPolylinePrimitive.geometryInstances).toBeDefined();
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
scene.renderForSpecs();
|
expect(groundPolylinePrimitive.geometryInstances).toBeDefined();
|
});
|
|
it("adds afterRender promise to frame state", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
releaseGeometryInstances: false,
|
asynchronous: false,
|
});
|
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
scene.renderForSpecs();
|
|
return groundPolylinePrimitive.readyPromise.then(function (param) {
|
expect(param.ready).toBe(true);
|
});
|
});
|
|
it("does not render when geometryInstances is undefined", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: undefined,
|
asynchronous: false,
|
});
|
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
scene.renderForSpecs();
|
expect(scene.frameState.commandList.length).toEqual(0);
|
});
|
|
it("does not render when show is false", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
});
|
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
scene.renderForSpecs();
|
expect(scene.frameState.commandList.length).toBeGreaterThan(0);
|
|
groundPolylinePrimitive.show = false;
|
scene.renderForSpecs();
|
expect(scene.frameState.commandList.length).toEqual(0);
|
});
|
|
it("becomes ready when show is false", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = scene.groundPrimitives.add(
|
new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
})
|
);
|
groundPolylinePrimitive.show = false;
|
|
var ready = false;
|
groundPolylinePrimitive.readyPromise.then(function () {
|
ready = true;
|
});
|
|
return pollToPromise(function () {
|
scene.renderForSpecs();
|
return ready;
|
}).then(function () {
|
expect(ready).toEqual(true);
|
});
|
});
|
|
it("does not render other than for the color or pick pass", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
});
|
|
var frameState = scene.frameState;
|
frameState.passes.render = false;
|
frameState.passes.pick = false;
|
|
groundPolylinePrimitive.update(frameState);
|
expect(frameState.commandList.length).toEqual(0);
|
});
|
|
function coordinateOfPixelColor(rgba, color) {
|
for (var y = 0; y < canvasHeight; y++) {
|
for (var x = 0; x < canvasWidth; x++) {
|
var i = (y * canvasWidth + x) * 4;
|
if (
|
color[0] === rgba[i] &&
|
color[1] === rgba[i + 1] &&
|
color[2] === rgba[i + 2] &&
|
color[3] === rgba[i + 3]
|
) {
|
return new Cartesian2(x, canvasHeight - y);
|
}
|
}
|
}
|
}
|
|
function verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
primitive,
|
color
|
) {
|
scene.camera.lookAt(lookPosition, Cartesian3.UNIT_Z);
|
|
scene.groundPrimitives.add(depthRectanglePrimitive);
|
expect(scene).toRenderAndCall(function (rgba) {
|
expect(coordinateOfPixelColor(rgba, depthColor)).toBeDefined();
|
});
|
|
scene.groundPrimitives.add(primitive);
|
var coordinate;
|
expect(scene).toRenderAndCall(function (rgba) {
|
coordinate = coordinateOfPixelColor(rgba, color);
|
expect(coordinate).toBeDefined();
|
});
|
return coordinate;
|
}
|
|
it("renders in 3D", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
});
|
|
it("renders in Columbus view when scene3DOnly is false", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
scene.morphToColumbusView(0);
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
});
|
|
it("renders in 2D when scene3DOnly is false", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
scene.morphTo2D(0);
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
});
|
|
it("renders during morph when scene3DOnly is false", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: new GeometryInstance({
|
geometry: new GroundPolylineGeometry({
|
positions: Cartesian3.fromDegreesArray([-30, 0.0, 30, 0.0]),
|
granularity: 0.0,
|
width: 1000.0,
|
loop: false,
|
ellipsoid: ellipsoid,
|
}),
|
attributes: {
|
color: polylineColorAttribute,
|
},
|
}),
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
scene.groundPrimitives.add(depthRectanglePrimitive);
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
|
// Morph to 2D first
|
scene.morphTo2D(0);
|
scene.renderForSpecs();
|
|
scene.morphToColumbusView(1);
|
// Morph changes the view distance to be very far, so:
|
// * the mock globe may not be visible due to small canvas size
|
// * GroundPolylinePrimitive renders its volume instead of using the
|
// volume as a stencil for sampling the depth texture
|
// So just check that the ground polyline primitive rendered.
|
expect(scene).toRenderAndCall(function (rgba) {
|
expect(coordinateOfPixelColor(rgba, polylineColor)).toBeDefined();
|
});
|
|
scene.completeMorph();
|
});
|
|
it("renders batched instances", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
var instance1 = new GeometryInstance({
|
geometry: new GroundPolylineGeometry({
|
positions: positions,
|
granularity: 0.0,
|
width: 1.0,
|
loop: false,
|
ellipsoid: ellipsoid,
|
}),
|
id: "polyline on terrain",
|
attributes: {
|
color: ColorGeometryInstanceAttribute.fromColor(
|
new Color(1.0, 1.0, 1.0, 0.5)
|
),
|
},
|
});
|
|
var instance2 = new GeometryInstance({
|
geometry: new GroundPolylineGeometry({
|
positions: positions,
|
granularity: 0.0,
|
width: 1.0,
|
loop: false,
|
ellipsoid: ellipsoid,
|
}),
|
id: "polyline on terrain",
|
attributes: {
|
color: ColorGeometryInstanceAttribute.fromColor(
|
new Color(1.0, 1.0, 1.0, 0.5)
|
),
|
},
|
});
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: [instance1, instance2],
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
[192, 192, 255, 255]
|
);
|
});
|
|
it("renders bounding volume with debugShowBoundingVolume", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
debugShowBoundingVolume: true,
|
});
|
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
|
scene.camera.lookAt(lookPosition, Cartesian3.UNIT_Z);
|
expect(scene).toRenderAndCall(function (rgba) {
|
expect(rgba[1]).toBeGreaterThanOrEqualTo(0);
|
expect(rgba[1]).toBeGreaterThanOrEqualTo(0);
|
expect(rgba[2]).toBeGreaterThanOrEqualTo(0);
|
expect(rgba[3]).toEqual(255);
|
});
|
});
|
|
it("renders shadow volume with debugShowShadowVolume", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
debugShowShadowVolume: true,
|
});
|
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
|
scene.camera.lookAt(lookPosition, Cartesian3.UNIT_Z);
|
expect(scene).toRenderAndCall(function (rgba) {
|
expect(rgba[1]).toBeGreaterThanOrEqualTo(0);
|
expect(rgba[1]).toBeGreaterThanOrEqualTo(0);
|
expect(rgba[2]).toBeGreaterThanOrEqualTo(0);
|
expect(rgba[3]).toEqual(255);
|
});
|
});
|
|
it("get per instance attributes", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
|
var attributes = groundPolylinePrimitive.getGeometryInstanceAttributes(
|
"polyline on terrain"
|
);
|
expect(attributes.color).toBeDefined();
|
});
|
|
it("modify color instance attribute", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
|
// Remove so it can be re-added, but don't destroy.
|
scene.groundPrimitives.destroyPrimitives = false;
|
scene.groundPrimitives.removeAll();
|
scene.groundPrimitives.destroyPrimitives = true;
|
|
var newColor = [255, 255, 255, 255];
|
var attributes = groundPolylinePrimitive.getGeometryInstanceAttributes(
|
"polyline on terrain"
|
);
|
expect(attributes.color).toBeDefined();
|
attributes.color = newColor;
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
newColor
|
);
|
});
|
|
it("adds width instance attribute", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPositionOffset,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
|
scene.groundPrimitives.destroyPrimitives = false;
|
scene.groundPrimitives.removeAll();
|
scene.groundPrimitives.destroyPrimitives = true;
|
|
var attributes = groundPolylinePrimitive.getGeometryInstanceAttributes(
|
"polyline on terrain"
|
);
|
expect(attributes.width).toBeDefined();
|
attributes.width = [0];
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPositionOffset,
|
groundPolylinePrimitive,
|
depthColor
|
);
|
});
|
|
it("modify show instance attribute", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylineInstance.attributes.show = new ShowGeometryInstanceAttribute(
|
true
|
);
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
|
scene.groundPrimitives.destroyPrimitives = false;
|
scene.groundPrimitives.removeAll();
|
scene.groundPrimitives.destroyPrimitives = true;
|
|
var attributes = groundPolylinePrimitive.getGeometryInstanceAttributes(
|
"polyline on terrain"
|
);
|
expect(attributes.show).toBeDefined();
|
attributes.show = [0];
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
depthColor
|
);
|
});
|
|
it("renders with distance display condition per instance attribute", function () {
|
if (!context.floatingPointTexture) {
|
return;
|
}
|
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
var near = 10.0;
|
var far = 1000.0;
|
|
var geometryInstance = new GeometryInstance({
|
geometry: new GroundPolylineGeometry({
|
positions: positions,
|
granularity: 0.0,
|
width: 1000.0,
|
loop: false,
|
ellipsoid: ellipsoid,
|
}),
|
id: "polyline on terrain",
|
attributes: {
|
distanceDisplayCondition: new DistanceDisplayConditionGeometryInstanceAttribute(
|
near,
|
far
|
),
|
color: polylineColorAttribute,
|
},
|
});
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: geometryInstance,
|
asynchronous: false,
|
});
|
|
scene.groundPrimitives.add(depthRectanglePrimitive);
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
scene.camera.lookAt(lookPosition, Cartesian3.UNIT_Z);
|
scene.renderForSpecs();
|
|
var boundingSphere = groundPolylinePrimitive.getGeometryInstanceAttributes(
|
"polyline on terrain"
|
).boundingSphere;
|
var center = boundingSphere.center;
|
var radius = boundingSphere.radius;
|
|
scene.camera.lookAt(
|
center,
|
new HeadingPitchRange(0.0, -CesiumMath.PI_OVER_TWO, radius)
|
);
|
expect(scene).toRenderAndCall(function (rgba) {
|
expect(coordinateOfPixelColor(rgba, depthColor)).toBeDefined();
|
});
|
|
scene.camera.lookAt(
|
center,
|
new HeadingPitchRange(0.0, -CesiumMath.PI_OVER_TWO, radius + near + 1.0)
|
);
|
expect(scene).toRenderAndCall(function (rgba) {
|
expect(coordinateOfPixelColor(rgba, depthColor)).toBeUndefined();
|
});
|
|
scene.camera.lookAt(
|
center,
|
new HeadingPitchRange(0.0, -CesiumMath.PI_OVER_TWO, radius + far + 1.0)
|
);
|
expect(scene).toRenderAndCall(function (rgba) {
|
expect(coordinateOfPixelColor(rgba, depthColor)).toBeDefined();
|
});
|
});
|
|
it("getGeometryInstanceAttributes returns same object each time", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylineInstance.attributes.show = new ShowGeometryInstanceAttribute(
|
true
|
);
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
|
var attributes = groundPolylinePrimitive.getGeometryInstanceAttributes(
|
"polyline on terrain"
|
);
|
var attributes2 = groundPolylinePrimitive.getGeometryInstanceAttributes(
|
"polyline on terrain"
|
);
|
expect(attributes).toBe(attributes2);
|
});
|
|
it("picking in 3D", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
var polylineColorCoordinate = verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
|
expect(scene).toPickAndCall(function (result) {
|
expect(result.id).toEqual("polyline on terrain");
|
}, polylineColorCoordinate);
|
});
|
|
it("picking in 2D", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
scene.morphTo2D(0);
|
var polylineColorCoordinate = verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
|
expect(scene).toPickAndCall(function (result) {
|
expect(result.id).toEqual("polyline on terrain");
|
}, polylineColorCoordinate);
|
});
|
|
it("picking in Columbus View", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
scene.morphToColumbusView(0);
|
var polylineColorCoordinate = verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
|
scene.camera.lookAt(lookPosition, Cartesian3.UNIT_Z);
|
expect(scene).toPickAndCall(function (result) {
|
expect(result.id).toEqual("polyline on terrain");
|
}, polylineColorCoordinate);
|
});
|
|
it("picking in Morph", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: new GeometryInstance({
|
geometry: new GroundPolylineGeometry({
|
positions: Cartesian3.fromDegreesArray([-30, 0.0, 30, 0.0]),
|
granularity: 0.0,
|
width: 1000.0,
|
loop: false,
|
ellipsoid: ellipsoid,
|
}),
|
attributes: {
|
color: polylineColorAttribute,
|
},
|
id: "big polyline on terrain",
|
}),
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
// Morph to 2D first
|
scene.morphTo2D(0);
|
scene.renderForSpecs();
|
|
scene.morphToColumbusView(1);
|
// Morph changes the view distance to be very far, so:
|
// * the mock globe may not be visible due to small canvas size
|
// * GroundPolylinePrimitive renders its volume instead of using the
|
// volume as a stencil for sampling the depth texture
|
// So just check that the ground polyline primitive rendered.
|
scene.groundPrimitives.add(depthRectanglePrimitive);
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
|
var polylineColorCoordinate;
|
expect(scene).toRenderAndCall(function (rgba) {
|
polylineColorCoordinate = coordinateOfPixelColor(rgba, polylineColor);
|
});
|
|
scene.renderForSpecs();
|
expect(scene).toPickAndCall(function (result) {
|
expect(result.id).toEqual("big polyline on terrain");
|
}, polylineColorCoordinate);
|
|
scene.completeMorph();
|
});
|
|
it("does not pick when allowPicking is false", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
allowPicking: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
|
expect(scene).toPickAndCall(function (result) {
|
expect(result.id).toEqual("depth rectangle");
|
});
|
});
|
|
it("update throws when batched instance colors are missing", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: new GeometryInstance({
|
geometry: new GroundPolylineGeometry({
|
positions: positions,
|
}),
|
}),
|
appearance: new PolylineColorAppearance(),
|
asynchronous: false,
|
});
|
|
expect(function () {
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
}).toThrowDeveloperError();
|
});
|
|
it("setting per instance attribute throws when value is undefined", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
|
var attributes = groundPolylinePrimitive.getGeometryInstanceAttributes(
|
"polyline on terrain"
|
);
|
|
expect(function () {
|
attributes.color = undefined;
|
}).toThrowDeveloperError();
|
});
|
|
it("can disable picking when asynchronous", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: true,
|
allowPicking: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
|
return pollToPromise(function () {
|
scene.renderForSpecs();
|
return groundPolylinePrimitive.ready;
|
}).then(function () {
|
var attributes = groundPolylinePrimitive.getGeometryInstanceAttributes(
|
"polyline on terrain"
|
);
|
expect(function () {
|
attributes.color = undefined;
|
}).toThrowDeveloperError();
|
});
|
});
|
|
it("getGeometryInstanceAttributes throws without id", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
|
expect(function () {
|
groundPolylinePrimitive.getGeometryInstanceAttributes();
|
}).toThrowDeveloperError();
|
});
|
|
it("getGeometryInstanceAttributes returns undefined if id does not exist", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
expect(function () {
|
groundPolylinePrimitive.getGeometryInstanceAttributes("unknown");
|
}).toThrowDeveloperError();
|
});
|
|
it("isDestroyed", function () {
|
groundPolylinePrimitive = new GroundPolylinePrimitive();
|
expect(groundPolylinePrimitive.isDestroyed()).toEqual(false);
|
groundPolylinePrimitive.destroy();
|
expect(groundPolylinePrimitive.isDestroyed()).toEqual(true);
|
});
|
|
it("renders when using asynchronous pipeline", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: true,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
|
return pollToPromise(function () {
|
scene.renderForSpecs();
|
return groundPolylinePrimitive.ready;
|
}).then(function () {
|
// verifyGroundPolylinePrimitiveRender adds the primitive, so remove it to avoid being added twice.
|
scene.groundPrimitives.destroyPrimitives = false;
|
scene.groundPrimitives.removeAll();
|
scene.groundPrimitives.destroyPrimitives = true;
|
|
verifyGroundPolylinePrimitiveRender(
|
lookPosition,
|
groundPolylinePrimitive,
|
polylineColor
|
);
|
});
|
});
|
|
it("destroy before asynchronous pipeline is complete", function () {
|
if (!GroundPolylinePrimitive.isSupported(scene)) {
|
return;
|
}
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: true,
|
appearance: new PolylineColorAppearance(),
|
});
|
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
|
scene.renderForSpecs();
|
groundPolylinePrimitive.destroy();
|
expect(groundPolylinePrimitive.isDestroyed()).toEqual(true);
|
|
// The primitive has already been destroyed, so remove it from the scene so it doesn't get destroyed again.
|
scene.groundPrimitives.destroyPrimitives = false;
|
scene.groundPrimitives.removeAll();
|
scene.groundPrimitives.destroyPrimitives = true;
|
});
|
|
it("creating a synchronous primitive throws if initializeTerrainHeights wasn't called", function () {
|
// Make it seem like initializeTerrainHeights was never called
|
var initPromise = ApproximateTerrainHeights._initPromise;
|
var terrainHeights = ApproximateTerrainHeights._terrainHeights;
|
ApproximateTerrainHeights._initPromise = undefined;
|
ApproximateTerrainHeights._terrainHeights = undefined;
|
|
groundPolylinePrimitive = new GroundPolylinePrimitive({
|
geometryInstances: groundPolylineInstance,
|
asynchronous: false,
|
});
|
|
scene.groundPrimitives.add(groundPolylinePrimitive);
|
|
if (GroundPolylinePrimitive.isSupported(scene)) {
|
expect(function () {
|
scene.renderForSpecs();
|
}).toThrowDeveloperError();
|
}
|
|
// Set back to initialized state
|
ApproximateTerrainHeights._initPromise = initPromise;
|
ApproximateTerrainHeights._terrainHeights = terrainHeights;
|
});
|
},
|
"WebGL"
|
);
|