mirror of https://github.com/CesiumGS/cesium.git
843 lines
28 KiB
JavaScript
843 lines
28 KiB
JavaScript
import {
|
|
BoundingSphere,
|
|
Cartesian2,
|
|
Cartesian3,
|
|
Color,
|
|
defined,
|
|
DistanceDisplayCondition,
|
|
HeightReference,
|
|
JulianDate,
|
|
Math as CesiumMath,
|
|
Matrix4,
|
|
Quaternion,
|
|
Resource,
|
|
Transforms,
|
|
BoundingSphereState,
|
|
Cesium3DTileset,
|
|
ConstantPositionProperty,
|
|
ConstantProperty,
|
|
EntityCollection,
|
|
ModelGraphics,
|
|
ModelVisualizer,
|
|
NodeTransformationProperty,
|
|
ClippingPlane,
|
|
ClippingPlaneCollection,
|
|
CustomShader,
|
|
Globe,
|
|
Cartographic,
|
|
} from "../../index.js";
|
|
import createScene from "../../../../Specs/createScene.js";
|
|
import pollToPromise from "../../../../Specs/pollToPromise.js";
|
|
|
|
describe(
|
|
"DataSources/ModelVisualizer",
|
|
function () {
|
|
const boxUrl = "./Data/Models/glTF-2.0/BoxTextured/glTF/BoxTextured.gltf";
|
|
const boxArticulationsUrl =
|
|
"./Data/Models/glTF-2.0/BoxArticulations/glTF/BoxArticulations.gltf";
|
|
|
|
let scene;
|
|
let entityCollection;
|
|
let visualizer;
|
|
|
|
beforeAll(function () {
|
|
scene = createScene();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
scene.globe = new Globe();
|
|
entityCollection = new EntityCollection();
|
|
visualizer = new ModelVisualizer(scene, entityCollection);
|
|
});
|
|
|
|
afterEach(function () {
|
|
visualizer = visualizer && visualizer.destroy();
|
|
entityCollection.removeAll();
|
|
scene.primitives.removeAll();
|
|
});
|
|
|
|
afterAll(function () {
|
|
scene.destroyForSpecs();
|
|
});
|
|
|
|
it("constructor throws if no scene is passed", function () {
|
|
expect(function () {
|
|
return new ModelVisualizer(undefined, entityCollection);
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("constructor throws if no entityCollection is passed", function () {
|
|
expect(function () {
|
|
return new ModelVisualizer(scene, undefined);
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("update throws if no time specified", function () {
|
|
expect(function () {
|
|
visualizer.update();
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("isDestroy returns false until destroyed", function () {
|
|
expect(visualizer.isDestroyed()).toEqual(false);
|
|
visualizer.destroy();
|
|
expect(visualizer.isDestroyed()).toEqual(true);
|
|
visualizer = undefined;
|
|
});
|
|
|
|
it("removes the listener from the entity collection when destroyed", function () {
|
|
expect(entityCollection.collectionChanged.numberOfListeners).toEqual(1);
|
|
visualizer.destroy();
|
|
expect(entityCollection.collectionChanged.numberOfListeners).toEqual(0);
|
|
visualizer = undefined;
|
|
});
|
|
|
|
it("object with no model does not create one", function () {
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
testObject.position = new ConstantProperty(
|
|
new Cartesian3(1234, 5678, 9101112),
|
|
);
|
|
visualizer.update(JulianDate.now());
|
|
expect(scene.primitives.length).toEqual(0);
|
|
});
|
|
|
|
it("object with no position does not create a model", function () {
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
const model = (testObject.model = new ModelGraphics());
|
|
model.uri = new ConstantProperty(boxUrl);
|
|
|
|
visualizer.update(JulianDate.now());
|
|
expect(scene.primitives.length).toEqual(0);
|
|
});
|
|
|
|
it("creates and updates a primitive from ModelGraphics", async function () {
|
|
const time = JulianDate.now();
|
|
|
|
const model = new ModelGraphics();
|
|
model.show = new ConstantProperty(true);
|
|
model.scale = new ConstantProperty(2);
|
|
model.minimumPixelSize = new ConstantProperty(24.0);
|
|
model.uri = new ConstantProperty(boxArticulationsUrl);
|
|
model.distanceDisplayCondition = new ConstantProperty(
|
|
new DistanceDisplayCondition(10.0, 100.0),
|
|
);
|
|
|
|
const translation = new Cartesian3(1.0, 2.0, 3.0);
|
|
const rotation = new Quaternion(0.0, 0.707, 0.0, 0.707);
|
|
const scale = new Cartesian3(2.0, 2.0, 2.0);
|
|
const nodeTransforms = {
|
|
Root: new NodeTransformationProperty({
|
|
translation: new ConstantProperty(translation),
|
|
rotation: new ConstantProperty(rotation),
|
|
scale: new ConstantProperty(scale),
|
|
}),
|
|
};
|
|
model.nodeTransformations = nodeTransforms;
|
|
|
|
const clippingPlanes = new ClippingPlaneCollection({
|
|
planes: [new ClippingPlane(Cartesian3.UNIT_X, 0.0)],
|
|
});
|
|
model.clippingPlanes = new ConstantProperty(clippingPlanes);
|
|
|
|
const customShader = new CustomShader();
|
|
model.customShader = new ConstantProperty(customShader);
|
|
|
|
model.imageBasedLightingFactor = new ConstantProperty(
|
|
new Cartesian2(0.5, 0.5),
|
|
);
|
|
model.lightColor = new ConstantProperty(new Color(1.0, 1.0, 0.0, 1.0));
|
|
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
testObject.position = new ConstantPositionProperty(
|
|
Cartesian3.fromDegrees(1, 2, 3),
|
|
);
|
|
testObject.model = model;
|
|
|
|
visualizer.update(time);
|
|
|
|
let primitive;
|
|
await pollToPromise(function () {
|
|
primitive = scene.primitives.get(0);
|
|
return defined(primitive);
|
|
});
|
|
|
|
visualizer.update(time);
|
|
|
|
expect(primitive.show).toEqual(true);
|
|
expect(primitive.scale).toEqual(2);
|
|
expect(primitive.minimumPixelSize).toEqual(24.0);
|
|
expect(primitive.modelMatrix).toEqual(
|
|
Transforms.eastNorthUpToFixedFrame(
|
|
Cartesian3.fromDegrees(1, 2, 3),
|
|
scene.globe.ellipsoid,
|
|
),
|
|
);
|
|
expect(primitive.distanceDisplayCondition).toEqual(
|
|
new DistanceDisplayCondition(10.0, 100.0),
|
|
);
|
|
expect(primitive.clippingPlanes._planes.length).toEqual(
|
|
clippingPlanes._planes.length,
|
|
);
|
|
expect(
|
|
Cartesian3.equals(
|
|
primitive.clippingPlanes._planes[0].normal,
|
|
clippingPlanes._planes[0].normal,
|
|
),
|
|
).toBe(true);
|
|
expect(primitive.clippingPlanes._planes[0].distance).toEqual(
|
|
clippingPlanes._planes[0].distance,
|
|
);
|
|
|
|
expect(primitive.customShader).toEqual(customShader);
|
|
|
|
expect(primitive.imageBasedLighting.imageBasedLightingFactor).toEqual(
|
|
new Cartesian2(0.5, 0.5),
|
|
);
|
|
|
|
expect(primitive.lightColor).toEqual(new Cartesian3(1.0, 1.0, 0.0));
|
|
|
|
expect(primitive.environmentMapManager.enabled).toBeTrue();
|
|
expect(primitive.environmentMapManager.maximumPositionEpsilon).toEqual(
|
|
Number.POSITIVE_INFINITY,
|
|
);
|
|
|
|
// wait till the model is loaded before we can check node transformations
|
|
await pollToPromise(function () {
|
|
scene.render();
|
|
return primitive.ready;
|
|
});
|
|
|
|
visualizer.update(time);
|
|
|
|
const node = primitive.getNode("Root");
|
|
expect(node).toBeDefined();
|
|
|
|
const transformationMatrix =
|
|
Matrix4.fromTranslationQuaternionRotationScale(
|
|
translation,
|
|
rotation,
|
|
scale,
|
|
);
|
|
|
|
Matrix4.multiplyTransformation(
|
|
node.originalMatrix,
|
|
transformationMatrix,
|
|
transformationMatrix,
|
|
);
|
|
|
|
expect(node.matrix).toEqual(transformationMatrix);
|
|
});
|
|
|
|
it("can apply model articulations", async function () {
|
|
const time = JulianDate.now();
|
|
|
|
const model = new ModelGraphics();
|
|
model.uri = new ConstantProperty(boxArticulationsUrl);
|
|
|
|
const articulations = {
|
|
"SampleArticulation MoveX": 1.0,
|
|
"SampleArticulation MoveY": 2.0,
|
|
"SampleArticulation MoveZ": 3.0,
|
|
"SampleArticulation Yaw": 4.0,
|
|
"SampleArticulation Pitch": 5.0,
|
|
"SampleArticulation Roll": 6.0,
|
|
"SampleArticulation Size": 0.9,
|
|
"SampleArticulation SizeX": 0.8,
|
|
"SampleArticulation SizeY": 0.7,
|
|
"SampleArticulation SizeZ": 0.6,
|
|
};
|
|
model.articulations = articulations;
|
|
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
testObject.position = new ConstantPositionProperty(
|
|
Cartesian3.fromDegrees(1, 2, 3),
|
|
);
|
|
testObject.model = model;
|
|
|
|
visualizer.update(time);
|
|
|
|
let primitive;
|
|
await pollToPromise(function () {
|
|
primitive = scene.primitives.get(0);
|
|
return defined(primitive);
|
|
});
|
|
|
|
// wait till the model is loaded before we can check articulations
|
|
await pollToPromise(function () {
|
|
scene.render();
|
|
return primitive.ready;
|
|
});
|
|
visualizer.update(time);
|
|
|
|
const node = primitive.getNode("Root");
|
|
|
|
const expected = [
|
|
0.7147690483240505, -0.04340611926232735, -0.0749741046529782, 0,
|
|
-0.06188330295778636, 0.05906797312763484, -0.6241645867602773, 0,
|
|
0.03752515582279579, 0.5366347296529127, 0.04706410108373541, 0, 1, 3,
|
|
-2, 1,
|
|
];
|
|
|
|
expect(node.matrix).toEqualEpsilon(expected, CesiumMath.EPSILON14);
|
|
});
|
|
|
|
it("can apply model environmentMapOptions", async function () {
|
|
const time = JulianDate.now();
|
|
|
|
const model = new ModelGraphics();
|
|
model.uri = new ConstantProperty(boxArticulationsUrl);
|
|
|
|
model.environmentMapOptions = {
|
|
enabled: false,
|
|
};
|
|
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
testObject.position = new ConstantPositionProperty(
|
|
Cartesian3.fromDegrees(1, 2, 3),
|
|
);
|
|
testObject.model = model;
|
|
|
|
visualizer.update(time);
|
|
|
|
let primitive;
|
|
await pollToPromise(function () {
|
|
primitive = scene.primitives.get(0);
|
|
return defined(primitive);
|
|
});
|
|
|
|
// wait till the model is loaded before we can check articulations
|
|
await pollToPromise(function () {
|
|
scene.render();
|
|
return primitive.ready;
|
|
});
|
|
visualizer.update(time);
|
|
|
|
expect(primitive.environmentMapManager.enabled).toBeFalse();
|
|
expect(primitive.environmentMapManager.maximumPositionEpsilon).toEqual(
|
|
Number.POSITIVE_INFINITY,
|
|
);
|
|
});
|
|
|
|
it("creates a primitive from ModelGraphics with a Resource", async function () {
|
|
const time = JulianDate.now();
|
|
|
|
const model = new ModelGraphics();
|
|
model.show = new ConstantProperty(true);
|
|
model.uri = new ConstantProperty(
|
|
new Resource({
|
|
url: boxArticulationsUrl,
|
|
}),
|
|
);
|
|
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
testObject.position = new ConstantPositionProperty(
|
|
Cartesian3.fromDegrees(1, 2, 3),
|
|
);
|
|
testObject.model = model;
|
|
|
|
visualizer.update(time);
|
|
|
|
let primitive;
|
|
await pollToPromise(function () {
|
|
primitive = scene.primitives.get(0);
|
|
return defined(primitive);
|
|
});
|
|
|
|
// wait till the model is loaded before we can check node transformations
|
|
await pollToPromise(function () {
|
|
scene.render();
|
|
return primitive.ready;
|
|
});
|
|
|
|
visualizer.update(time);
|
|
|
|
const node = primitive.getNode("Root");
|
|
expect(node).toBeDefined();
|
|
});
|
|
|
|
it("removes primitives on Entity removal", async function () {
|
|
const model = new ModelGraphics();
|
|
model.uri = new ConstantProperty(boxUrl);
|
|
|
|
const time = JulianDate.now();
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
testObject.position = new ConstantProperty(
|
|
new Cartesian3(5678, 1234, 1101112),
|
|
);
|
|
testObject.model = model;
|
|
visualizer.update(time);
|
|
|
|
let primitive;
|
|
await pollToPromise(function () {
|
|
primitive = scene.primitives.get(0);
|
|
return defined(primitive);
|
|
});
|
|
|
|
visualizer.update(time);
|
|
entityCollection.removeAll();
|
|
visualizer.update(time);
|
|
expect(scene.primitives.length).toEqual(0);
|
|
});
|
|
|
|
it("sets id property", async function () {
|
|
const time = JulianDate.now();
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
const model = new ModelGraphics();
|
|
testObject.model = model;
|
|
|
|
testObject.position = new ConstantProperty(
|
|
new Cartesian3(5678, 1234, 1101112),
|
|
);
|
|
model.uri = new ConstantProperty(boxUrl);
|
|
visualizer.update(time);
|
|
|
|
let primitive;
|
|
await pollToPromise(function () {
|
|
primitive = scene.primitives.get(0);
|
|
return defined(primitive);
|
|
});
|
|
|
|
expect(primitive.id).toEqual(testObject);
|
|
});
|
|
|
|
it("computes bounding sphere", async function () {
|
|
const time = JulianDate.now();
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
const model = new ModelGraphics();
|
|
testObject.model = model;
|
|
|
|
testObject.position = new ConstantProperty(
|
|
new Cartesian3(5678, 1234, 1101112),
|
|
);
|
|
model.uri = new ConstantProperty(boxUrl);
|
|
visualizer.update(time);
|
|
|
|
let primitive;
|
|
await pollToPromise(function () {
|
|
primitive = scene.primitives.get(0);
|
|
return defined(primitive);
|
|
});
|
|
|
|
const result = new BoundingSphere();
|
|
let state = visualizer.getBoundingSphere(testObject, result);
|
|
expect(state).toBe(BoundingSphereState.PENDING);
|
|
|
|
await pollToPromise(function () {
|
|
scene.render();
|
|
visualizer.update(time);
|
|
state = visualizer.getBoundingSphere(testObject, result);
|
|
return state !== BoundingSphereState.PENDING;
|
|
});
|
|
expect(state).toBe(BoundingSphereState.DONE);
|
|
const expected = BoundingSphere.clone(
|
|
primitive.boundingSphere,
|
|
new BoundingSphere(),
|
|
);
|
|
expect(result).toEqual(expected);
|
|
});
|
|
|
|
it("computes bounding sphere with height reference clamp to terrain", async function () {
|
|
// Setup a position for the model.
|
|
const position = Cartesian3.fromDegrees(149.515332, -34.984799);
|
|
|
|
const tileset = new Cesium3DTileset({
|
|
enableCollision: true,
|
|
});
|
|
scene.primitives.add(tileset);
|
|
|
|
// Initialize the Entity and the ModelGraphics.
|
|
const time = JulianDate.now();
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
const model = new ModelGraphics({
|
|
heightReference: HeightReference.CLAMP_TO_TERRAIN,
|
|
});
|
|
testObject.model = model;
|
|
testObject.position = new ConstantProperty(position);
|
|
model.uri = new ConstantProperty(boxUrl);
|
|
|
|
visualizer.update(time);
|
|
|
|
// Request the bounding sphere once.
|
|
const result = new BoundingSphere();
|
|
let state = visualizer.getBoundingSphere(testObject, result);
|
|
expect(state).toBe(BoundingSphereState.PENDING);
|
|
|
|
spyOn(scene.globe, "getHeight").and.returnValue(10.0);
|
|
spyOn(tileset, "getHeight").and.returnValue(20.0);
|
|
|
|
// Repeatedly request the bounding sphere until it's ready.
|
|
await pollToPromise(function () {
|
|
scene.renderForSpecs();
|
|
visualizer.update(time);
|
|
state = visualizer.getBoundingSphere(testObject, result);
|
|
return state !== BoundingSphereState.PENDING;
|
|
});
|
|
|
|
expect(state).toBe(BoundingSphereState.DONE);
|
|
|
|
// Ensure that flags and results computed for this model are reset.
|
|
const modelData = visualizer._modelHash[testObject.id];
|
|
expect(modelData.clampedBoundingSphere).toBeUndefined();
|
|
|
|
const expectedCenter = Cartographic.fromCartesian(position);
|
|
expectedCenter.height = 10.0;
|
|
expect(result.center).toEqualEpsilon(
|
|
Cartographic.toCartesian(expectedCenter),
|
|
CesiumMath.EPSILON8,
|
|
);
|
|
});
|
|
|
|
it("computes bounding sphere with height reference relative to terrain", async function () {
|
|
// Setup a position for the model.
|
|
const heightOffset = 1000.0;
|
|
const position = Cartesian3.fromDegrees(
|
|
149.515332,
|
|
-34.984799,
|
|
heightOffset,
|
|
);
|
|
|
|
const tileset = new Cesium3DTileset({
|
|
enableCollision: true,
|
|
});
|
|
scene.primitives.add(tileset);
|
|
|
|
// Initialize the Entity and the ModelGraphics.
|
|
const time = JulianDate.now();
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
const model = new ModelGraphics({
|
|
heightReference: HeightReference.RELATIVE_TO_TERRAIN,
|
|
});
|
|
testObject.model = model;
|
|
testObject.position = new ConstantProperty(position);
|
|
model.uri = new ConstantProperty(boxUrl);
|
|
|
|
visualizer.update(time);
|
|
|
|
// Request the bounding sphere once.
|
|
const result = new BoundingSphere();
|
|
let state = visualizer.getBoundingSphere(testObject, result);
|
|
expect(state).toBe(BoundingSphereState.PENDING);
|
|
|
|
spyOn(scene.globe, "getHeight").and.returnValue(10.0);
|
|
spyOn(tileset, "getHeight").and.returnValue(20.0);
|
|
|
|
// Repeatedly request the bounding sphere until it's ready.
|
|
await pollToPromise(function () {
|
|
scene.renderForSpecs();
|
|
visualizer.update(time);
|
|
state = visualizer.getBoundingSphere(testObject, result);
|
|
return state !== BoundingSphereState.PENDING;
|
|
});
|
|
expect(state).toBe(BoundingSphereState.DONE);
|
|
|
|
// Ensure that flags and results computed for this model are reset.
|
|
const modelData = visualizer._modelHash[testObject.id];
|
|
expect(modelData.clampedBoundingSphere).toBeUndefined();
|
|
|
|
const expectedCenter = Cartographic.fromCartesian(position);
|
|
expectedCenter.height = heightOffset + 10.0;
|
|
expect(result.center).toEqualEpsilon(
|
|
Cartographic.toCartesian(expectedCenter),
|
|
CesiumMath.EPSILON8,
|
|
);
|
|
});
|
|
|
|
it("computes bounding sphere with height reference clamp to 3D Tiles", async function () {
|
|
// Setup a position for the model.
|
|
const position = Cartesian3.fromDegrees(149.515332, -34.984799);
|
|
|
|
const tileset = new Cesium3DTileset({
|
|
enableCollision: true,
|
|
});
|
|
scene.primitives.add(tileset);
|
|
|
|
// Initialize the Entity and the ModelGraphics.
|
|
const time = JulianDate.now();
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
const model = new ModelGraphics({
|
|
heightReference: HeightReference.CLAMP_TO_3D_TILE,
|
|
});
|
|
testObject.model = model;
|
|
testObject.position = new ConstantProperty(position);
|
|
model.uri = new ConstantProperty(boxUrl);
|
|
|
|
visualizer.update(time);
|
|
|
|
// Request the bounding sphere once.
|
|
const result = new BoundingSphere();
|
|
let state = visualizer.getBoundingSphere(testObject, result);
|
|
expect(state).toBe(BoundingSphereState.PENDING);
|
|
|
|
spyOn(scene.globe, "getHeight").and.returnValue(20.0);
|
|
spyOn(tileset, "getHeight").and.returnValue(10.0);
|
|
|
|
// Repeatedly request the bounding sphere until it's ready.
|
|
await pollToPromise(function () {
|
|
scene.renderForSpecs();
|
|
visualizer.update(time);
|
|
state = visualizer.getBoundingSphere(testObject, result);
|
|
return state !== BoundingSphereState.PENDING;
|
|
});
|
|
|
|
expect(state).toBe(BoundingSphereState.DONE);
|
|
|
|
// Ensure that flags and results computed for this model are reset.
|
|
const modelData = visualizer._modelHash[testObject.id];
|
|
expect(modelData.clampedBoundingSphere).toBeUndefined();
|
|
|
|
const expectedCenter = Cartographic.fromCartesian(position);
|
|
expectedCenter.height = 10.0;
|
|
expect(result.center).toEqualEpsilon(
|
|
Cartographic.toCartesian(expectedCenter),
|
|
CesiumMath.EPSILON8,
|
|
);
|
|
});
|
|
|
|
it("computes bounding sphere with height reference relative to 3D Tiles", async function () {
|
|
// Setup a position for the model.
|
|
const heightOffset = 1000.0;
|
|
const position = Cartesian3.fromDegrees(
|
|
149.515332,
|
|
-34.984799,
|
|
heightOffset,
|
|
);
|
|
|
|
const tileset = new Cesium3DTileset({
|
|
enableCollision: true,
|
|
});
|
|
scene.primitives.add(tileset);
|
|
|
|
// Initialize the Entity and the ModelGraphics.
|
|
const time = JulianDate.now();
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
const model = new ModelGraphics({
|
|
heightReference: HeightReference.RELATIVE_TO_3D_TILE,
|
|
});
|
|
testObject.model = model;
|
|
testObject.position = new ConstantProperty(position);
|
|
model.uri = new ConstantProperty(boxUrl);
|
|
|
|
visualizer.update(time);
|
|
|
|
// Request the bounding sphere once.
|
|
const result = new BoundingSphere();
|
|
let state = visualizer.getBoundingSphere(testObject, result);
|
|
expect(state).toBe(BoundingSphereState.PENDING);
|
|
|
|
spyOn(scene.globe, "getHeight").and.returnValue(20.0);
|
|
spyOn(tileset, "getHeight").and.returnValue(10.0);
|
|
|
|
// Repeatedly request the bounding sphere until it's ready.
|
|
await pollToPromise(function () {
|
|
scene.renderForSpecs();
|
|
visualizer.update(time);
|
|
state = visualizer.getBoundingSphere(testObject, result);
|
|
return state !== BoundingSphereState.PENDING;
|
|
});
|
|
expect(state).toBe(BoundingSphereState.DONE);
|
|
|
|
// Ensure that flags and results computed for this model are reset.
|
|
const modelData = visualizer._modelHash[testObject.id];
|
|
expect(modelData.clampedBoundingSphere).toBeUndefined();
|
|
|
|
const expectedCenter = Cartographic.fromCartesian(position);
|
|
expectedCenter.height = heightOffset + 10.0;
|
|
expect(result.center).toEqualEpsilon(
|
|
Cartographic.toCartesian(expectedCenter),
|
|
CesiumMath.EPSILON8,
|
|
);
|
|
});
|
|
|
|
it("computes bounding sphere with height reference clamp to ground", async function () {
|
|
// Setup a position for the model.
|
|
const position = Cartesian3.fromDegrees(149.515332, -34.984799);
|
|
|
|
const tileset = new Cesium3DTileset({
|
|
enableCollision: true,
|
|
});
|
|
scene.primitives.add(tileset);
|
|
|
|
// Initialize the Entity and the ModelGraphics.
|
|
const time = JulianDate.now();
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
const model = new ModelGraphics({
|
|
heightReference: HeightReference.CLAMP_TO_GROUND,
|
|
});
|
|
testObject.model = model;
|
|
testObject.position = new ConstantProperty(position);
|
|
model.uri = new ConstantProperty(boxUrl);
|
|
|
|
visualizer.update(time);
|
|
|
|
// Request the bounding sphere once.
|
|
const result = new BoundingSphere();
|
|
let state = visualizer.getBoundingSphere(testObject, result);
|
|
expect(state).toBe(BoundingSphereState.PENDING);
|
|
|
|
spyOn(scene.globe, "getHeight").and.returnValue(10.0);
|
|
spyOn(tileset, "getHeight").and.returnValue(20.0);
|
|
|
|
// Repeatedly request the bounding sphere until it's ready.
|
|
await pollToPromise(function () {
|
|
scene.renderForSpecs();
|
|
visualizer.update(time);
|
|
state = visualizer.getBoundingSphere(testObject, result);
|
|
return state !== BoundingSphereState.PENDING;
|
|
});
|
|
|
|
expect(state).toBe(BoundingSphereState.DONE);
|
|
|
|
// Ensure that flags and results computed for this model are reset.
|
|
const modelData = visualizer._modelHash[testObject.id];
|
|
expect(modelData.clampedBoundingSphere).toBeUndefined();
|
|
|
|
const expectedCenter = Cartographic.fromCartesian(position);
|
|
expectedCenter.height = 20.0;
|
|
expect(result.center).toEqualEpsilon(
|
|
Cartographic.toCartesian(expectedCenter),
|
|
CesiumMath.EPSILON8,
|
|
);
|
|
});
|
|
|
|
it("computes bounding sphere with height reference relative to ground", async function () {
|
|
// Setup a position for the model.
|
|
const heightOffset = 1000.0;
|
|
const position = Cartesian3.fromDegrees(
|
|
149.515332,
|
|
-34.984799,
|
|
heightOffset,
|
|
);
|
|
|
|
const tileset = new Cesium3DTileset({
|
|
enableCollision: true,
|
|
});
|
|
scene.primitives.add(tileset);
|
|
|
|
// Initialize the Entity and the ModelGraphics.
|
|
const time = JulianDate.now();
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
const model = new ModelGraphics({
|
|
heightReference: HeightReference.RELATIVE_TO_GROUND,
|
|
});
|
|
testObject.model = model;
|
|
testObject.position = new ConstantProperty(position);
|
|
model.uri = new ConstantProperty(boxUrl);
|
|
|
|
visualizer.update(time);
|
|
|
|
// Request the bounding sphere once.
|
|
const result = new BoundingSphere();
|
|
let state = visualizer.getBoundingSphere(testObject, result);
|
|
expect(state).toBe(BoundingSphereState.PENDING);
|
|
|
|
spyOn(scene.globe, "getHeight").and.returnValue(10.0);
|
|
spyOn(tileset, "getHeight").and.returnValue(20.0);
|
|
|
|
// Repeatedly request the bounding sphere until it's ready.
|
|
await pollToPromise(function () {
|
|
scene.renderForSpecs();
|
|
visualizer.update(time);
|
|
state = visualizer.getBoundingSphere(testObject, result);
|
|
return state !== BoundingSphereState.PENDING;
|
|
});
|
|
expect(state).toBe(BoundingSphereState.DONE);
|
|
|
|
// Ensure that flags and results computed for this model are reset.
|
|
const modelData = visualizer._modelHash[testObject.id];
|
|
expect(modelData.clampedBoundingSphere).toBeUndefined();
|
|
|
|
const expectedCenter = Cartographic.fromCartesian(position);
|
|
expectedCenter.height = heightOffset + 20.0;
|
|
expect(result.center).toEqualEpsilon(
|
|
Cartographic.toCartesian(expectedCenter),
|
|
CesiumMath.EPSILON8,
|
|
);
|
|
});
|
|
|
|
it("computes bounding sphere where globe is undefined", async function () {
|
|
scene.globe = undefined;
|
|
|
|
const time = JulianDate.now();
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
const model = new ModelGraphics();
|
|
testObject.model = model;
|
|
|
|
testObject.position = new ConstantProperty(
|
|
new Cartesian3(5678, 1234, 1101112),
|
|
);
|
|
model.uri = new ConstantProperty(boxUrl);
|
|
visualizer.update(time);
|
|
|
|
let primitive;
|
|
await pollToPromise(function () {
|
|
primitive = scene.primitives.get(0);
|
|
return defined(primitive);
|
|
});
|
|
|
|
const result = new BoundingSphere();
|
|
let state = visualizer.getBoundingSphere(testObject, result);
|
|
expect(state).toBe(BoundingSphereState.PENDING);
|
|
|
|
await pollToPromise(function () {
|
|
scene.render();
|
|
visualizer.update(time);
|
|
state = visualizer.getBoundingSphere(testObject, result);
|
|
return state !== BoundingSphereState.PENDING;
|
|
});
|
|
expect(state).toBe(BoundingSphereState.DONE);
|
|
const expected = BoundingSphere.clone(
|
|
primitive.boundingSphere,
|
|
new BoundingSphere(),
|
|
);
|
|
expect(result).toEqual(expected);
|
|
});
|
|
|
|
it("fails bounding sphere for entity without ModelGraphics", function () {
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
visualizer.update(JulianDate.now());
|
|
const result = new BoundingSphere();
|
|
const state = visualizer.getBoundingSphere(testObject, result);
|
|
expect(state).toBe(BoundingSphereState.FAILED);
|
|
});
|
|
|
|
it("fails bounding sphere when model fails to load", async function () {
|
|
const time = JulianDate.now();
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
const model = new ModelGraphics();
|
|
testObject.model = model;
|
|
|
|
testObject.position = new ConstantProperty(
|
|
new Cartesian3(5678, 1234, 1101112),
|
|
);
|
|
model.uri = new ConstantProperty("/path/to/incorrect/file");
|
|
visualizer.update(time);
|
|
|
|
const result = new BoundingSphere();
|
|
let state = visualizer.getBoundingSphere(testObject, result);
|
|
await pollToPromise(function () {
|
|
scene.render();
|
|
visualizer.update(time);
|
|
state = visualizer.getBoundingSphere(testObject, result);
|
|
return state !== BoundingSphereState.PENDING;
|
|
});
|
|
|
|
expect(state).toBe(BoundingSphereState.FAILED);
|
|
});
|
|
|
|
it("compute bounding sphere throws without entity", function () {
|
|
const result = new BoundingSphere();
|
|
expect(function () {
|
|
visualizer.getBoundingSphere(undefined, result);
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("compute bounding sphere throws without result", function () {
|
|
const testObject = entityCollection.getOrCreateEntity("test");
|
|
expect(function () {
|
|
visualizer.getBoundingSphere(testObject, undefined);
|
|
}).toThrowDeveloperError();
|
|
});
|
|
},
|
|
"WebGL",
|
|
);
|