You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

440 lines
15 KiB
JavaScript

import { BoundingSphere } from "../../Source/Cesium.js";
import { Cartesian2 } from "../../Source/Cesium.js";
import { Cartesian3 } from "../../Source/Cesium.js";
import { Color } from "../../Source/Cesium.js";
import { defined } from "../../Source/Cesium.js";
import { DistanceDisplayCondition } from "../../Source/Cesium.js";
import { JulianDate } from "../../Source/Cesium.js";
import { Math as CesiumMath } from "../../Source/Cesium.js";
import { Matrix4 } from "../../Source/Cesium.js";
import { Quaternion } from "../../Source/Cesium.js";
import { Resource } from "../../Source/Cesium.js";
import { Transforms } from "../../Source/Cesium.js";
import { BoundingSphereState } from "../../Source/Cesium.js";
import { ConstantPositionProperty } from "../../Source/Cesium.js";
import { ConstantProperty } from "../../Source/Cesium.js";
import { EntityCollection } from "../../Source/Cesium.js";
import { ModelGraphics } from "../../Source/Cesium.js";
import { ModelVisualizer } from "../../Source/Cesium.js";
import { NodeTransformationProperty } from "../../Source/Cesium.js";
import { ClippingPlane } from "../../Source/Cesium.js";
import { ClippingPlaneCollection } from "../../Source/Cesium.js";
import { Globe } from "../../Source/Cesium.js";
import createScene from "../createScene.js";
import pollToPromise from "../pollToPromise.js";
describe(
"DataSources/ModelVisualizer",
function () {
var boxUrl = "./Data/Models/Box/CesiumBoxTest.gltf";
var boxArticulationsUrl =
"./Data/Models/Box-Articulations/Box-Articulations.gltf";
var scene;
var visualizer;
beforeAll(function () {
scene = createScene();
scene.globe = new Globe();
});
afterAll(function () {
scene.destroyForSpecs();
});
afterEach(function () {
if (defined(visualizer)) {
visualizer = visualizer.destroy();
}
});
it("constructor throws if no scene is passed.", function () {
expect(function () {
return new ModelVisualizer();
}).toThrowDeveloperError();
});
it("update throws if no time specified.", function () {
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
expect(function () {
visualizer.update();
}).toThrowDeveloperError();
});
it("isDestroy returns false until destroyed.", function () {
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
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 () {
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
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 () {
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
var 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 () {
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
var testObject = entityCollection.getOrCreateEntity("test");
var model = (testObject.model = new ModelGraphics());
model.uri = new ConstantProperty(boxUrl);
visualizer.update(JulianDate.now());
expect(scene.primitives.length).toEqual(0);
});
it("A ModelGraphics causes a primitive to be created and updated.", function () {
var time = JulianDate.now();
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
var model = new ModelGraphics();
model.show = new ConstantProperty(true);
model.scale = new ConstantProperty(2);
model.minimumPixelSize = new ConstantProperty(24.0);
model.uri = new ConstantProperty(boxUrl);
model.distanceDisplayCondition = new ConstantProperty(
new DistanceDisplayCondition(10.0, 100.0)
);
var translation = new Cartesian3(1.0, 2.0, 3.0);
var rotation = new Quaternion(0.0, 0.707, 0.0, 0.707);
var scale = new Cartesian3(2.0, 2.0, 2.0);
var nodeTransforms = {
Mesh: new NodeTransformationProperty({
translation: new ConstantProperty(translation),
rotation: new ConstantProperty(rotation),
scale: new ConstantProperty(scale),
}),
};
model.nodeTransformations = nodeTransforms;
var clippingPlanes = new ClippingPlaneCollection({
planes: [new ClippingPlane(Cartesian3.UNIT_X, 0.0)],
});
model.clippingPlanes = new ConstantProperty(clippingPlanes);
model.imageBasedLightingFactor = new ConstantProperty(
new Cartesian2(0.5, 0.5)
);
model.lightColor = new ConstantProperty(new Color(1.0, 1.0, 0.0, 1.0));
var testObject = entityCollection.getOrCreateEntity("test");
testObject.position = new ConstantPositionProperty(
Cartesian3.fromDegrees(1, 2, 3)
);
testObject.model = model;
visualizer.update(time);
expect(scene.primitives.length).toEqual(1);
var primitive = scene.primitives.get(0);
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.imageBasedLightingFactor).toEqual(
new Cartesian2(0.5, 0.5)
);
expect(primitive.lightColor).toEqual(new Color(1.0, 1.0, 0.0, 1.0));
// wait till the model is loaded before we can check node transformations
return pollToPromise(function () {
scene.render();
return primitive.ready;
}).then(function () {
visualizer.update(time);
var node = primitive.getNode("Mesh");
expect(node).toBeDefined();
var transformationMatrix = Matrix4.fromTranslationQuaternionRotationScale(
translation,
rotation,
scale
);
expect(node.matrix).toEqual(transformationMatrix);
});
});
it("can apply model articulations", function () {
var time = JulianDate.now();
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
var model = new ModelGraphics();
model.uri = new ConstantProperty(boxArticulationsUrl);
var 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;
var testObject = entityCollection.getOrCreateEntity("test");
testObject.position = new ConstantPositionProperty(
Cartesian3.fromDegrees(1, 2, 3)
);
testObject.model = model;
visualizer.update(time);
expect(scene.primitives.length).toEqual(1);
var primitive = scene.primitives.get(0);
// wait till the model is loaded before we can check articulations
return pollToPromise(function () {
scene.render();
return primitive.ready;
}).then(function () {
visualizer.update(time);
var node = primitive.getNode("Root");
expect(node.useMatrix).toBe(true);
var 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("A ModelGraphics with a Resource causes a primitive to be created.", function () {
var time = JulianDate.now();
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
var model = new ModelGraphics();
model.show = new ConstantProperty(true);
model.uri = new ConstantProperty(
new Resource({
url: boxUrl,
})
);
var testObject = entityCollection.getOrCreateEntity("test");
testObject.position = new ConstantPositionProperty(
Cartesian3.fromDegrees(1, 2, 3)
);
testObject.model = model;
visualizer.update(time);
expect(scene.primitives.length).toEqual(1);
var primitive = scene.primitives.get(0);
// wait till the model is loaded before we can check node transformations
return pollToPromise(function () {
scene.render();
return primitive.ready;
}).then(function () {
visualizer.update(time);
var node = primitive.getNode("Mesh");
expect(node).toBeDefined();
});
});
it("removing removes primitives.", function () {
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
var model = new ModelGraphics();
model.uri = new ConstantProperty(boxUrl);
var time = JulianDate.now();
var testObject = entityCollection.getOrCreateEntity("test");
testObject.position = new ConstantProperty(
new Cartesian3(5678, 1234, 1101112)
);
testObject.model = model;
visualizer.update(time);
expect(scene.primitives.length).toEqual(1);
visualizer.update(time);
entityCollection.removeAll();
visualizer.update(time);
expect(scene.primitives.length).toEqual(0);
});
it("Visualizer sets id property.", function () {
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
var time = JulianDate.now();
var testObject = entityCollection.getOrCreateEntity("test");
var model = new ModelGraphics();
testObject.model = model;
testObject.position = new ConstantProperty(
new Cartesian3(5678, 1234, 1101112)
);
model.uri = new ConstantProperty(boxUrl);
visualizer.update(time);
var modelPrimitive = scene.primitives.get(0);
expect(modelPrimitive.id).toEqual(testObject);
});
it("Computes bounding sphere.", function () {
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
var time = JulianDate.now();
var testObject = entityCollection.getOrCreateEntity("test");
var model = new ModelGraphics();
testObject.model = model;
testObject.position = new ConstantProperty(
new Cartesian3(5678, 1234, 1101112)
);
model.uri = new ConstantProperty(boxUrl);
visualizer.update(time);
var modelPrimitive = scene.primitives.get(0);
var result = new BoundingSphere();
var state = visualizer.getBoundingSphere(testObject, result);
expect(state).toBe(BoundingSphereState.PENDING);
return pollToPromise(function () {
scene.render();
state = visualizer.getBoundingSphere(testObject, result);
return state !== BoundingSphereState.PENDING;
}).then(function () {
expect(state).toBe(BoundingSphereState.DONE);
var expected = BoundingSphere.transform(
modelPrimitive.boundingSphere,
modelPrimitive.modelMatrix,
new BoundingSphere()
);
expect(result).toEqual(expected);
});
});
it("Fails bounding sphere for entity without billboard.", function () {
var entityCollection = new EntityCollection();
var testObject = entityCollection.getOrCreateEntity("test");
visualizer = new ModelVisualizer(scene, entityCollection);
visualizer.update(JulianDate.now());
var result = new BoundingSphere();
var state = visualizer.getBoundingSphere(testObject, result);
expect(state).toBe(BoundingSphereState.FAILED);
});
it("Fails bounding sphere when model fails to load.", function () {
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
var time = JulianDate.now();
var testObject = entityCollection.getOrCreateEntity("test");
var 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);
var result = new BoundingSphere();
var state = visualizer.getBoundingSphere(testObject, result);
expect(state).toBe(BoundingSphereState.PENDING);
return pollToPromise(function () {
scene.render();
state = visualizer.getBoundingSphere(testObject, result);
return state !== BoundingSphereState.PENDING;
}).then(function () {
expect(state).toBe(BoundingSphereState.FAILED);
});
});
it("Compute bounding sphere throws without entity.", function () {
var entityCollection = new EntityCollection();
visualizer = new ModelVisualizer(scene, entityCollection);
var result = new BoundingSphere();
expect(function () {
visualizer.getBoundingSphere(undefined, result);
}).toThrowDeveloperError();
});
it("Compute bounding sphere throws without result.", function () {
var entityCollection = new EntityCollection();
var testObject = entityCollection.getOrCreateEntity("test");
visualizer = new ModelVisualizer(scene, entityCollection);
expect(function () {
visualizer.getBoundingSphere(testObject, undefined);
}).toThrowDeveloperError();
});
},
"WebGL"
);