import {
|
combine,
|
GltfLoader,
|
PickingPipelineStage,
|
ShaderBuilder,
|
Resource,
|
ResourceCache,
|
defined,
|
} from "../../../Source/Cesium.js";
|
import createScene from "../../createScene.js";
|
import ShaderBuilderTester from "../../ShaderBuilderTester.js";
|
import waitForLoaderProcess from "../../waitForLoaderProcess.js";
|
|
describe("Scene/ModelExperimental/PickingPipelineStage", function () {
|
var boxVertexColors =
|
"./Data/Models/GltfLoader/BoxVertexColors/glTF/BoxVertexColors.gltf";
|
var boxInstanced =
|
"./Data/Models/GltfLoader/BoxInstanced/glTF/box-instanced.gltf";
|
var microcosm = "./Data/Models/GltfLoader/Microcosm/glTF/microcosm.gltf";
|
|
var scene;
|
var gltfLoaders = [];
|
|
beforeAll(function () {
|
scene = createScene();
|
});
|
|
afterAll(function () {
|
scene.destroyForSpecs();
|
});
|
|
afterEach(function () {
|
var gltfLoadersLength = gltfLoaders.length;
|
for (var i = 0; i < gltfLoadersLength; ++i) {
|
var gltfLoader = gltfLoaders[i];
|
if (!gltfLoader.isDestroyed()) {
|
gltfLoader.destroy();
|
}
|
}
|
gltfLoaders.length = 0;
|
ResourceCache.clearForSpecs();
|
});
|
|
function getOptions(gltfPath, options) {
|
var resource = new Resource({
|
url: gltfPath,
|
});
|
|
return combine(options, {
|
gltfResource: resource,
|
incrementallyLoadTexture: false,
|
});
|
}
|
|
function loadGltf(gltfPath, options) {
|
var gltfLoader = new GltfLoader(getOptions(gltfPath, options));
|
gltfLoaders.push(gltfLoader);
|
gltfLoader.load();
|
|
return waitForLoaderProcess(gltfLoader, scene);
|
}
|
|
function expectUniformMap(uniformMap, expected) {
|
for (var key in expected) {
|
if (expected.hasOwnProperty(key)) {
|
var expectedValue = expected[key];
|
var uniformFunction = uniformMap[key];
|
expect(uniformFunction).toBeDefined();
|
expect(uniformFunction()).toEqual(expectedValue);
|
}
|
}
|
}
|
|
function verifyPickObject(pickObject, renderResources, instanceId) {
|
var model = renderResources.model;
|
var content = model.content;
|
|
expect(pickObject).toBeDefined();
|
if (defined(content)) {
|
// 3D Tiles case
|
expect(pickObject.primitive).toEqual(content.tileset);
|
expect(pickObject.content).toEqual(content);
|
} else {
|
// ModelExperimental case
|
expect(pickObject.primitive).toEqual(model);
|
}
|
|
if (defined(instanceId)) {
|
expect(pickObject.instanceId).toEqual(instanceId);
|
}
|
|
var detailPickObject = pickObject.detail;
|
expect(detailPickObject).toBeDefined();
|
expect(detailPickObject.model).toEqual(model);
|
expect(detailPickObject.node).toEqual(renderResources.runtimeNode);
|
expect(detailPickObject.primitive).toEqual(
|
renderResources.runtimePrimitive
|
);
|
}
|
|
it("sets the picking variables in render resources for 3D Tiles", function () {
|
var renderResources = {
|
attributeIndex: 1,
|
pickId: undefined,
|
shaderBuilder: new ShaderBuilder(),
|
model: {
|
_resources: [],
|
// Setting the content property here makes PickingPipelineStage handle this
|
// as part of a tileset.
|
content: {
|
tileset: {},
|
},
|
},
|
runtimePrimitive: {},
|
runtimeNode: {
|
node: {},
|
},
|
uniformMap: {},
|
};
|
|
return loadGltf(boxVertexColors).then(function (gltfLoader) {
|
var components = gltfLoader.components;
|
var primitive = components.nodes[0].primitives[0];
|
|
var frameState = scene.frameState;
|
var context = frameState.context;
|
// Reset pick objects.
|
context._pickObjects = [];
|
|
PickingPipelineStage.process(renderResources, primitive, frameState);
|
|
var shaderBuilder = renderResources.shaderBuilder;
|
ShaderBuilderTester.expectHasFragmentUniforms(shaderBuilder, [
|
"uniform vec4 czm_pickColor;",
|
]);
|
|
var pickObject =
|
context._pickObjects[Object.keys(context._pickObjects)[0]];
|
verifyPickObject(pickObject, renderResources);
|
|
var uniformMap = renderResources.uniformMap;
|
expect(uniformMap.czm_pickColor).toBeDefined();
|
expect(uniformMap.czm_pickColor()).toBeDefined();
|
|
expect(renderResources.model._resources.length).toEqual(1);
|
|
expect(renderResources.pickId).toEqual("czm_pickColor");
|
});
|
});
|
|
it("sets the picking variables in render resources for models", function () {
|
var renderResources = {
|
attributeIndex: 1,
|
pickId: undefined,
|
shaderBuilder: new ShaderBuilder(),
|
model: {
|
_resources: [],
|
},
|
runtimePrimitive: {
|
primitive: {},
|
},
|
runtimeNode: {
|
node: {},
|
},
|
uniformMap: {},
|
};
|
|
return loadGltf(boxVertexColors).then(function (gltfLoader) {
|
var components = gltfLoader.components;
|
var primitive = components.nodes[0].primitives[0];
|
|
var frameState = scene.frameState;
|
var context = frameState.context;
|
// Reset pick objects.
|
context._pickObjects = [];
|
|
PickingPipelineStage.process(renderResources, primitive, frameState);
|
|
var shaderBuilder = renderResources.shaderBuilder;
|
ShaderBuilderTester.expectHasFragmentUniforms(shaderBuilder, [
|
"uniform vec4 czm_pickColor;",
|
]);
|
|
var pickObject =
|
context._pickObjects[Object.keys(context._pickObjects)[0]];
|
verifyPickObject(pickObject, renderResources);
|
|
var uniformMap = renderResources.uniformMap;
|
expect(uniformMap.czm_pickColor).toBeDefined();
|
expect(uniformMap.czm_pickColor()).toBeDefined();
|
|
expect(renderResources.model._resources.length).toEqual(1);
|
|
expect(renderResources.pickId).toEqual("czm_pickColor");
|
});
|
});
|
|
it("sets the picking variables in render resources with instancing", function () {
|
var renderResources = {
|
attributeIndex: 1,
|
instanceCount: 4,
|
pickId: undefined,
|
shaderBuilder: new ShaderBuilder(),
|
model: {
|
_resources: [],
|
},
|
runtimePrimitive: {
|
primitive: {},
|
},
|
runtimeNode: {
|
node: {
|
instances: {
|
featureIdAttributes: [{}, {}],
|
},
|
},
|
},
|
attributes: [],
|
};
|
|
return loadGltf(boxInstanced).then(function (gltfLoader) {
|
var components = gltfLoader.components;
|
var primitive = components.nodes[0].primitives[0];
|
renderResources.runtimeNode.node = components.nodes[0];
|
|
var frameState = scene.frameState;
|
var context = frameState.context;
|
// Reset pick objects.
|
context._pickObjects = [];
|
|
PickingPipelineStage.process(renderResources, primitive, frameState);
|
|
var shaderBuilder = renderResources.shaderBuilder;
|
ShaderBuilderTester.expectHasAttributes(shaderBuilder, undefined, [
|
"attribute vec4 a_pickColor;",
|
]);
|
ShaderBuilderTester.expectHasVaryings(shaderBuilder, [
|
"varying vec4 v_pickColor;",
|
]);
|
|
var i = 0;
|
for (var key in context._pickObjects) {
|
if (context._pickObjects.hasOwnProperty(key)) {
|
var pickObject = context._pickObjects[key];
|
verifyPickObject(pickObject, renderResources, i++);
|
}
|
}
|
|
var pickIdAttribute = renderResources.attributes[0];
|
expect(pickIdAttribute).toBeDefined();
|
expect(pickIdAttribute.index).toEqual(1);
|
// Each time an attribute is added, the attribute index should be incremented.
|
expect(renderResources.attributeIndex).toEqual(2);
|
expect(pickIdAttribute.vertexBuffer).toBeDefined();
|
expect(pickIdAttribute.vertexBuffer._sizeInBytes).toEqual(
|
renderResources.instanceCount * 4
|
);
|
expect(pickIdAttribute.instanceDivisor).toEqual(1);
|
|
expect(renderResources.model._resources.length).toEqual(5);
|
|
expect(renderResources.pickId).toEqual("v_pickColor");
|
});
|
});
|
|
it("sets the picking variables in render resources with feature ID textures", function () {
|
var mockModelFeatureTable = {
|
batchTexture: {
|
pickTexture: "mockPickTexture",
|
},
|
};
|
|
var renderResources = {
|
attributeIndex: 1,
|
hasFeatureIds: true,
|
pickId: undefined,
|
shaderBuilder: new ShaderBuilder(),
|
uniformMap: {},
|
model: {
|
featureIdTextureIndex: 0,
|
_resources: [],
|
featureTables: [mockModelFeatureTable],
|
},
|
runtimeNode: {
|
node: {},
|
},
|
};
|
|
return loadGltf(microcosm).then(function (gltfLoader) {
|
var components = gltfLoader.components;
|
var primitive = components.nodes[0].primitives[0];
|
|
var frameState = scene.frameState;
|
var context = frameState.context;
|
// Reset pick objects.
|
context._pickObjects = [];
|
|
PickingPipelineStage.process(renderResources, primitive, frameState);
|
|
var expectedUniforms = {
|
model_pickTexture: mockModelFeatureTable.batchTexture.pickTexture,
|
};
|
expectUniformMap(renderResources.uniformMap, expectedUniforms);
|
|
var shaderBuilder = renderResources.shaderBuilder;
|
ShaderBuilderTester.expectHasFragmentUniforms(shaderBuilder, [
|
"uniform sampler2D model_pickTexture;",
|
]);
|
|
expect(renderResources.pickId).toEqual(
|
"((feature.id < int(model_featuresLength)) ? texture2D(model_pickTexture, feature.st) : vec4(0.0))"
|
);
|
});
|
});
|
});
|