cesium/packages/engine/Specs/DataSources/ModelVisualizerSpec.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

843 lines
28 KiB
JavaScript
Raw Permalink Normal View History

import {
BoundingSphere,
Cartesian2,
Cartesian3,
Color,
defined,
DistanceDisplayCondition,
HeightReference,
JulianDate,
Math as CesiumMath,
Matrix4,
Quaternion,
Resource,
Transforms,
BoundingSphereState,
2023-12-15 02:40:26 +08:00
Cesium3DTileset,
ConstantPositionProperty,
ConstantProperty,
EntityCollection,
ModelGraphics,
ModelVisualizer,
NodeTransformationProperty,
ClippingPlane,
ClippingPlaneCollection,
CustomShader,
Globe,
2022-08-05 22:24:29 +08:00
Cartographic,
2022-11-02 03:39:57 +08:00
} from "../../index.js";
import createScene from "../../../../Specs/createScene.js";
import pollToPromise from "../../../../Specs/pollToPromise.js";
2020-04-17 08:31:36 +08:00
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;
2022-07-13 03:18:56 +08:00
let entityCollection;
let visualizer;
beforeAll(function () {
scene = createScene();
2022-07-13 03:18:56 +08:00
});
2022-07-13 03:18:56 +08:00
beforeEach(function () {
scene.globe = new Globe();
2022-07-13 03:18:56 +08:00
entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
});
afterEach(function () {
visualizer = visualizer && visualizer.destroy();
entityCollection.removeAll();
2023-12-15 02:40:26 +08:00
scene.primitives.removeAll();
});
afterAll(function () {
2015-02-07 00:30:34 +08:00
scene.destroyForSpecs();
});
it("constructor throws if no scene is passed", function () {
2022-07-13 03:18:56 +08:00
expect(function () {
return new ModelVisualizer(undefined, entityCollection);
}).toThrowDeveloperError();
});
it("constructor throws if no entityCollection is passed", function () {
expect(function () {
2022-07-13 03:18:56 +08:00
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 () {
2014-04-29 22:43:17 +08:00
expect(visualizer.isDestroyed()).toEqual(false);
visualizer.destroy();
expect(visualizer.isDestroyed()).toEqual(true);
visualizer = undefined;
});
2014-07-31 22:10:45 +08:00
it("removes the listener from the entity collection when destroyed", function () {
expect(entityCollection.collectionChanged.numberOfListeners).toEqual(1);
visualizer.destroy();
2014-07-31 22:10:45 +08:00
expect(entityCollection.collectionChanged.numberOfListeners).toEqual(0);
visualizer = undefined;
2014-07-31 22:10:45 +08:00
});
it("object with no model does not create one", function () {
2014-07-08 21:57:19 +08:00
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 () {
2014-07-08 21:57:19 +08:00
const testObject = entityCollection.getOrCreateEntity("test");
2014-07-03 03:34:44 +08:00
const model = (testObject.model = new ModelGraphics());
2015-03-06 22:05:12 +08:00
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();
2020-04-17 08:31:36 +08:00
2014-07-03 03:34:44 +08:00
const model = new ModelGraphics();
model.show = new ConstantProperty(true);
model.scale = new ConstantProperty(2);
model.minimumPixelSize = new ConstantProperty(24.0);
2022-07-13 03:18:56 +08:00
model.uri = new ConstantProperty(boxArticulationsUrl);
model.distanceDisplayCondition = new ConstantProperty(
new DistanceDisplayCondition(10.0, 100.0),
);
2020-04-17 08:31:36 +08:00
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 = {
2022-07-13 03:18:56 +08:00
Root: new NodeTransformationProperty({
translation: new ConstantProperty(translation),
rotation: new ConstantProperty(rotation),
scale: new ConstantProperty(scale),
2015-06-19 11:44:46 +08:00
}),
2020-04-17 08:31:36 +08:00
};
2015-06-19 11:44:46 +08:00
model.nodeTransformations = nodeTransforms;
2020-04-17 08:31:36 +08:00
const clippingPlanes = new ClippingPlaneCollection({
planes: [new ClippingPlane(Cartesian3.UNIT_X, 0.0)],
});
2015-06-19 11:44:46 +08:00
model.clippingPlanes = new ConstantProperty(clippingPlanes);
2020-04-17 08:31:36 +08:00
const customShader = new CustomShader();
model.customShader = new ConstantProperty(customShader);
2015-06-19 11:44:46 +08:00
model.imageBasedLightingFactor = new ConstantProperty(
new Cartesian2(0.5, 0.5),
2020-04-17 08:31:36 +08:00
);
model.lightColor = new ConstantProperty(new Color(1.0, 1.0, 0.0, 1.0));
2020-04-17 08:31:36 +08:00
const testObject = entityCollection.getOrCreateEntity("test");
testObject.position = new ConstantPositionProperty(
Cartesian3.fromDegrees(1, 2, 3),
2020-04-17 08:31:36 +08:00
);
testObject.model = model;
2020-04-17 08:31:36 +08:00
visualizer.update(time);
2020-04-17 08:31:36 +08:00
let primitive;
await pollToPromise(function () {
primitive = scene.primitives.get(0);
return defined(primitive);
});
2020-04-17 08:31:36 +08:00
visualizer.update(time);
expect(primitive.show).toEqual(true);
expect(primitive.scale).toEqual(2);
expect(primitive.minimumPixelSize).toEqual(24.0);
2014-09-20 04:30:41 +08:00
expect(primitive.modelMatrix).toEqual(
Transforms.eastNorthUpToFixedFrame(
Cartesian3.fromDegrees(1, 2, 3),
scene.globe.ellipsoid,
2020-04-17 08:31:36 +08:00
),
);
expect(primitive.distanceDisplayCondition).toEqual(
new DistanceDisplayCondition(10.0, 100.0),
2020-04-17 08:31:36 +08:00
);
expect(primitive.clippingPlanes._planes.length).toEqual(
2017-12-01 06:07:36 +08:00
clippingPlanes._planes.length,
);
2020-04-17 08:31:36 +08:00
expect(
2017-12-01 06:07:36 +08:00
Cartesian3.equals(
primitive.clippingPlanes._planes[0].normal,
clippingPlanes._planes[0].normal,
2020-04-17 08:31:36 +08:00
),
).toBe(true);
2017-12-01 06:07:36 +08:00
expect(primitive.clippingPlanes._planes[0].distance).toEqual(
2018-10-10 04:30:57 +08:00
clippingPlanes._planes[0].distance,
);
expect(primitive.customShader).toEqual(customShader);
expect(primitive.imageBasedLighting.imageBasedLightingFactor).toEqual(
2018-10-10 04:30:57 +08:00
new Cartesian2(0.5, 0.5),
2020-04-17 08:31:36 +08:00
);
2023-03-18 02:20:46 +08:00
expect(primitive.lightColor).toEqual(new Cartesian3(1.0, 1.0, 0.0));
2020-04-17 08:31:36 +08:00
expect(primitive.environmentMapManager.enabled).toBeTrue();
expect(primitive.environmentMapManager.maximumPositionEpsilon).toEqual(
Number.POSITIVE_INFINITY,
);
2024-12-05 17:15:53 +08:00
2014-07-25 23:42:45 +08:00
// wait till the model is loaded before we can check node transformations
await pollToPromise(function () {
2014-07-25 23:42:45 +08:00
scene.render();
return primitive.ready;
});
visualizer.update(time);
const node = primitive.getNode("Root");
expect(node).toBeDefined();
2022-07-13 03:18:56 +08:00
const transformationMatrix =
Matrix4.fromTranslationQuaternionRotationScale(
translation,
rotation,
scale,
);
2022-07-13 03:18:56 +08:00
Matrix4.multiplyTransformation(
node.originalMatrix,
transformationMatrix,
transformationMatrix,
);
expect(node.matrix).toEqual(transformationMatrix);
});
it("can apply model articulations", async function () {
const time = JulianDate.now();
2020-04-17 08:31:36 +08:00
const model = new ModelGraphics();
model.uri = new ConstantProperty(boxArticulationsUrl);
2020-04-17 08:31:36 +08:00
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;
2020-04-17 08:31:36 +08:00
const testObject = entityCollection.getOrCreateEntity("test");
testObject.position = new ConstantPositionProperty(
Cartesian3.fromDegrees(1, 2, 3),
);
testObject.model = model;
2020-04-17 08:31:36 +08:00
2018-01-17 04:15:07 +08:00
visualizer.update(time);
2020-04-17 08:31:36 +08:00
let primitive;
await pollToPromise(function () {
primitive = scene.primitives.get(0);
return defined(primitive);
});
2020-04-17 08:31:36 +08:00
// wait till the model is loaded before we can check articulations
await pollToPromise(function () {
2018-01-17 04:15:07 +08:00
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 () {
2018-01-17 04:15:07 +08:00
const time = JulianDate.now();
const model = new ModelGraphics();
model.show = new ConstantProperty(true);
model.uri = new ConstantProperty(
new Resource({
2022-07-13 03:18:56 +08:00
url: boxArticulationsUrl,
2020-04-17 08:31:36 +08:00
}),
2018-01-17 04:15:07 +08:00
);
const testObject = entityCollection.getOrCreateEntity("test");
testObject.position = new ConstantPositionProperty(
Cartesian3.fromDegrees(1, 2, 3),
2020-04-17 08:31:36 +08:00
);
testObject.model = model;
2018-01-17 04:15:07 +08:00
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();
2015-03-06 22:05:12 +08:00
model.uri = new ConstantProperty(boxUrl);
2020-04-17 08:31:36 +08:00
const time = JulianDate.now();
2014-07-08 21:57:19 +08:00
const testObject = entityCollection.getOrCreateEntity("test");
testObject.position = new ConstantProperty(
new Cartesian3(5678, 1234, 1101112),
);
2015-03-06 22:05:12 +08:00
testObject.model = model;
visualizer.update(time);
2020-04-17 08:31:36 +08:00
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),
);
2015-03-06 22:05:12 +08:00
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();
2018-03-21 10:51:09 +08:00
const testObject = entityCollection.getOrCreateEntity("test");
const model = new ModelGraphics();
testObject.model = model;
2020-04-17 08:31:36 +08:00
2018-03-21 10:51:09 +08:00
testObject.position = new ConstantProperty(
new Cartesian3(5678, 1234, 1101112),
2020-04-17 08:31:36 +08:00
);
2015-03-06 22:05:12 +08:00
model.uri = new ConstantProperty(boxUrl);
visualizer.update(time);
2020-04-17 08:31:36 +08:00
let primitive;
await pollToPromise(function () {
primitive = scene.primitives.get(0);
return defined(primitive);
});
const result = new BoundingSphere();
let state = visualizer.getBoundingSphere(testObject, result);
2018-03-21 10:51:09 +08:00
expect(state).toBe(BoundingSphereState.PENDING);
2020-04-17 08:31:36 +08:00
await pollToPromise(function () {
2018-03-21 10:51:09 +08:00
scene.render();
2023-03-18 02:20:46 +08:00
visualizer.update(time);
2018-03-21 10:51:09 +08:00
state = visualizer.getBoundingSphere(testObject, result);
return state !== BoundingSphereState.PENDING;
2020-04-17 08:31:36 +08:00
});
expect(state).toBe(BoundingSphereState.DONE);
const expected = BoundingSphere.clone(
primitive.boundingSphere,
new BoundingSphere(),
);
expect(result).toEqual(expected);
});
2023-12-15 02:40:26 +08:00
it("computes bounding sphere with height reference clamp to terrain", async function () {
2022-08-09 00:22:31 +08:00
// Setup a position for the model.
const position = Cartesian3.fromDegrees(149.515332, -34.984799);
2023-12-15 02:40:26 +08:00
const tileset = new Cesium3DTileset({
enableCollision: true,
});
2023-12-15 02:40:26 +08:00
scene.primitives.add(tileset);
2022-08-09 00:22:31 +08:00
// Initialize the Entity and the ModelGraphics.
2022-08-05 03:09:40 +08:00
const time = JulianDate.now();
const testObject = entityCollection.getOrCreateEntity("test");
const model = new ModelGraphics({
2023-12-15 02:40:26 +08:00
heightReference: HeightReference.CLAMP_TO_TERRAIN,
2022-08-05 03:09:40 +08:00
});
testObject.model = model;
2022-08-05 22:24:29 +08:00
testObject.position = new ConstantProperty(position);
2022-08-05 03:09:40 +08:00
model.uri = new ConstantProperty(boxUrl);
2022-08-09 00:22:31 +08:00
2022-08-05 03:09:40 +08:00
visualizer.update(time);
2022-08-09 00:22:31 +08:00
// Request the bounding sphere once.
2022-08-05 03:09:40 +08:00
const result = new BoundingSphere();
let state = visualizer.getBoundingSphere(testObject, result);
expect(state).toBe(BoundingSphereState.PENDING);
2022-08-04 01:51:16 +08:00
2023-12-15 02:40:26 +08:00
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();
2023-03-18 02:20:46 +08:00
2023-12-15 02:40:26 +08:00
const expectedCenter = Cartographic.fromCartesian(position);
expectedCenter.height = 10.0;
expect(result.center).toEqualEpsilon(
Cartographic.toCartesian(expectedCenter),
CesiumMath.EPSILON8,
2023-03-18 02:20:46 +08:00
);
2023-12-15 02:40:26 +08:00
});
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,
2023-03-18 02:20:46 +08:00
);
const tileset = new Cesium3DTileset({
enableCollision: true,
});
2023-12-15 02:40:26 +08:00
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);
2023-03-18 02:20:46 +08:00
// Repeatedly request the bounding sphere until it's ready.
await pollToPromise(function () {
2023-12-15 02:40:26 +08:00
scene.renderForSpecs();
2023-03-18 02:20:46 +08:00
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();
2023-12-15 02:40:26 +08:00
const expectedCenter = Cartographic.fromCartesian(position);
expectedCenter.height = heightOffset + 10.0;
expect(result.center).toEqualEpsilon(
Cartographic.toCartesian(expectedCenter),
CesiumMath.EPSILON8,
);
2022-08-05 22:24:29 +08:00
});
2023-12-15 02:40:26 +08:00
it("computes bounding sphere with height reference clamp to 3D Tiles", async function () {
// Setup a position for the model.
2023-12-15 02:40:26 +08:00
const position = Cartesian3.fromDegrees(149.515332, -34.984799);
const tileset = new Cesium3DTileset({
enableCollision: true,
});
2023-12-15 02:40:26 +08:00
scene.primitives.add(tileset);
// Initialize the Entity and the ModelGraphics.
const time = JulianDate.now();
const testObject = entityCollection.getOrCreateEntity("test");
const model = new ModelGraphics({
2023-12-15 02:40:26 +08:00
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);
2023-12-15 02:40:26 +08:00
spyOn(scene.globe, "getHeight").and.returnValue(20.0);
spyOn(tileset, "getHeight").and.returnValue(10.0);
// Repeatedly request the bounding sphere until it's ready.
2023-12-15 02:40:26 +08:00
await pollToPromise(function () {
scene.renderForSpecs();
2023-03-18 02:20:46 +08:00
visualizer.update(time);
state = visualizer.getBoundingSphere(testObject, result);
return state !== BoundingSphereState.PENDING;
});
2023-12-15 02:40:26 +08:00
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,
);
});
2023-12-15 02:40:26 +08:00
it("computes bounding sphere with height reference relative to 3D Tiles", async function () {
2022-08-09 00:22:31 +08:00
// Setup a position for the model.
const heightOffset = 1000.0;
const position = Cartesian3.fromDegrees(
149.515332,
-34.984799,
2022-08-09 00:22:31 +08:00
heightOffset,
);
const tileset = new Cesium3DTileset({
enableCollision: true,
});
2023-12-15 02:40:26 +08:00
scene.primitives.add(tileset);
2022-08-05 22:24:29 +08:00
2022-08-09 00:22:31 +08:00
// Initialize the Entity and the ModelGraphics.
2022-08-05 22:24:29 +08:00
const time = JulianDate.now();
const testObject = entityCollection.getOrCreateEntity("test");
const model = new ModelGraphics({
2023-12-15 02:40:26 +08:00
heightReference: HeightReference.RELATIVE_TO_3D_TILE,
});
2022-08-05 22:24:29 +08:00
testObject.model = model;
testObject.position = new ConstantProperty(position);
model.uri = new ConstantProperty(boxUrl);
2022-08-09 00:22:31 +08:00
2022-08-05 22:24:29 +08:00
visualizer.update(time);
2022-08-09 00:22:31 +08:00
// Request the bounding sphere once.
2022-08-05 22:24:29 +08:00
const result = new BoundingSphere();
let state = visualizer.getBoundingSphere(testObject, result);
expect(state).toBe(BoundingSphereState.PENDING);
2023-12-15 02:40:26 +08:00
spyOn(scene.globe, "getHeight").and.returnValue(20.0);
spyOn(tileset, "getHeight").and.returnValue(10.0);
2023-03-18 02:20:46 +08:00
2023-12-15 02:40:26 +08:00
// 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,
2023-03-18 02:20:46 +08:00
);
2023-12-15 02:40:26 +08:00
});
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,
});
2023-12-15 02:40:26 +08:00
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);
2023-03-18 02:20:46 +08:00
// Repeatedly request the bounding sphere until it's ready.
await pollToPromise(function () {
2023-12-15 02:40:26 +08:00
scene.renderForSpecs();
2023-03-18 02:20:46 +08:00
visualizer.update(time);
state = visualizer.getBoundingSphere(testObject, result);
return state !== BoundingSphereState.PENDING;
});
2023-12-15 02:40:26 +08:00
2023-03-18 02:20:46 +08:00
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();
2023-12-15 02:40:26 +08:00
const expectedCenter = Cartographic.fromCartesian(position);
expectedCenter.height = 20.0;
expect(result.center).toEqualEpsilon(
Cartographic.toCartesian(expectedCenter),
CesiumMath.EPSILON8,
);
});
2023-12-15 02:40:26 +08:00
it("computes bounding sphere with height reference relative to ground", async function () {
// Setup a position for the model.
2023-12-15 02:40:26 +08:00
const heightOffset = 1000.0;
const position = Cartesian3.fromDegrees(
149.515332,
-34.984799,
heightOffset,
);
const tileset = new Cesium3DTileset({
enableCollision: true,
});
2023-12-15 02:40:26 +08:00
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);
2023-12-15 02:40:26 +08:00
spyOn(scene.globe, "getHeight").and.returnValue(10.0);
spyOn(tileset, "getHeight").and.returnValue(20.0);
// Repeatedly request the bounding sphere until it's ready.
2023-12-15 02:40:26 +08:00
await pollToPromise(function () {
scene.renderForSpecs();
2023-03-18 02:20:46 +08:00
visualizer.update(time);
state = visualizer.getBoundingSphere(testObject, result);
return state !== BoundingSphereState.PENDING;
});
2023-12-15 02:40:26 +08:00
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");
2018-03-21 10:51:09 +08:00
visualizer.update(JulianDate.now());
const result = new BoundingSphere();
const state = visualizer.getBoundingSphere(testObject, result);
2018-03-21 22:38:18 +08:00
expect(state).toBe(BoundingSphereState.FAILED);
2018-03-21 10:51:09 +08:00
});
2023-03-18 02:20:46 +08:00
it("fails bounding sphere when model fails to load", async function () {
const time = JulianDate.now();
const testObject = entityCollection.getOrCreateEntity("test");
2018-03-21 10:51:09 +08:00
const model = new ModelGraphics();
testObject.model = model;
2020-04-17 08:31:36 +08:00
2018-03-21 10:51:09 +08:00
testObject.position = new ConstantProperty(
new Cartesian3(5678, 1234, 1101112),
2020-04-17 08:31:36 +08:00
);
2018-03-21 22:38:18 +08:00
model.uri = new ConstantProperty("/path/to/incorrect/file");
visualizer.update(time);
2020-04-17 08:31:36 +08:00
2018-03-21 10:51:09 +08:00
const result = new BoundingSphere();
let state = visualizer.getBoundingSphere(testObject, result);
2023-03-18 02:20:46 +08:00
await pollToPromise(function () {
2018-03-21 10:51:09 +08:00
scene.render();
2023-03-18 02:20:46 +08:00
visualizer.update(time);
2018-03-21 10:51:09 +08:00
state = visualizer.getBoundingSphere(testObject, result);
return state !== BoundingSphereState.PENDING;
});
2023-03-18 02:20:46 +08:00
expect(state).toBe(BoundingSphereState.FAILED);
2018-03-21 10:51:09 +08:00
});
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",
);