import {
|
Cartesian3,
|
combine,
|
GltfLoader,
|
InstancingPipelineStage,
|
Resource,
|
ResourceCache,
|
ShaderBuilder,
|
Math as CesiumMath,
|
} from "../../../Source/Cesium.js";
|
import createScene from "../../createScene.js";
|
import waitForLoaderProcess from "../../waitForLoaderProcess.js";
|
|
describe("Scene/ModelExperimental/InstancingPipelineStage", function () {
|
var boxInstanced =
|
"./Data/Models/GltfLoader/BoxInstanced/glTF/box-instanced.gltf";
|
var boxInstancedTranslation =
|
"./Data/Models/GltfLoader/BoxInstancedTranslation/glTF/box-instanced-translation.gltf";
|
var boxInstancedTranslationMinMax =
|
"./Data/Models/GltfLoader/BoxInstancedTranslationWithMinMax/glTF/box-instanced-translation-min-max.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);
|
}
|
|
it("correctly computes instancing TRANSLATION min and max from typed arrays", function () {
|
var renderResources = {
|
attributeIndex: 1,
|
attributes: [],
|
instancingTranslationMax: undefined,
|
instancingTranslationMin: undefined,
|
shaderBuilder: new ShaderBuilder(),
|
model: {
|
_resources: [],
|
},
|
};
|
|
return loadGltf(boxInstanced).then(function (gltfLoader) {
|
var components = gltfLoader.components;
|
var node = components.nodes[0];
|
|
scene.renderForSpecs();
|
InstancingPipelineStage.process(renderResources, node, scene.frameState);
|
|
expect(renderResources.instancingTranslationMax).toEqual(
|
new Cartesian3(2, 2, 0)
|
);
|
expect(renderResources.instancingTranslationMin).toEqual(
|
new Cartesian3(-2, -2, 0)
|
);
|
expect(renderResources.attributes.length).toBe(4);
|
});
|
});
|
|
it("sets instancing TRANSLATION min and max from attributes", function () {
|
var renderResources = {
|
attributeIndex: 1,
|
attributes: [],
|
instancingTranslationMax: undefined,
|
instancingTranslationMin: undefined,
|
shaderBuilder: new ShaderBuilder(),
|
model: {
|
_resources: [],
|
},
|
};
|
|
return loadGltf(boxInstancedTranslationMinMax).then(function (gltfLoader) {
|
var components = gltfLoader.components;
|
var node = components.nodes[0];
|
|
InstancingPipelineStage.process(renderResources, node);
|
|
expect(renderResources.instancingTranslationMax).toEqual(
|
new Cartesian3(2, 2, 0)
|
);
|
expect(renderResources.instancingTranslationMin).toEqual(
|
new Cartesian3(-2, -2, 0)
|
);
|
expect(renderResources.attributes.length).toBe(1);
|
});
|
});
|
|
it("creates instancing matrices vertex attributes when ROTATION is present", function () {
|
var renderResources = {
|
attributeIndex: 1,
|
attributes: [],
|
instancingTranslationMax: undefined,
|
instancingTranslationMin: undefined,
|
shaderBuilder: new ShaderBuilder(),
|
model: {
|
_resources: [],
|
},
|
};
|
|
return loadGltf(boxInstanced).then(function (gltfLoader) {
|
var components = gltfLoader.components;
|
var node = components.nodes[0];
|
|
scene.renderForSpecs();
|
InstancingPipelineStage.process(renderResources, node, scene.frameState);
|
|
expect(renderResources.instancingTranslationMax).toEqual(
|
new Cartesian3(2, 2, 0)
|
);
|
expect(renderResources.instancingTranslationMin).toEqual(
|
new Cartesian3(-2, -2, 0)
|
);
|
expect(renderResources.attributes.length).toBe(4);
|
|
var attributeLines = renderResources.shaderBuilder._attributeLines;
|
var vertexDefineLines =
|
renderResources.shaderBuilder._vertexShaderParts.defineLines;
|
var fragmentDefineLines =
|
renderResources.shaderBuilder._fragmentShaderParts.defineLines;
|
|
expect(vertexDefineLines[0]).toEqual("HAS_INSTANCING");
|
expect(vertexDefineLines[0]).toEqual("HAS_INSTANCING");
|
expect(vertexDefineLines[1]).toEqual("HAS_INSTANCE_MATRICES");
|
expect(fragmentDefineLines[1]).toEqual("HAS_INSTANCE_MATRICES");
|
expect(attributeLines[0]).toEqual(
|
"attribute vec4 a_instancingTransformRow0;"
|
);
|
expect(attributeLines[1]).toEqual(
|
"attribute vec4 a_instancingTransformRow1;"
|
);
|
expect(attributeLines[2]).toEqual(
|
"attribute vec4 a_instancingTransformRow2;"
|
);
|
});
|
});
|
|
it("creates instance matrices vertex attributes when TRANSLATION min and max are not present", function () {
|
var renderResources = {
|
attributeIndex: 1,
|
attributes: [],
|
instancingTranslationMax: undefined,
|
instancingTranslationMin: undefined,
|
shaderBuilder: new ShaderBuilder(),
|
model: {
|
_resources: [],
|
},
|
};
|
|
return loadGltf(boxInstancedTranslation).then(function (gltfLoader) {
|
var components = gltfLoader.components;
|
var node = components.nodes[0];
|
|
scene.renderForSpecs();
|
InstancingPipelineStage.process(renderResources, node, scene.frameState);
|
|
expect(renderResources.instancingTranslationMax).toEqual(
|
new Cartesian3(2, 2, 0)
|
);
|
expect(renderResources.instancingTranslationMin).toEqual(
|
new Cartesian3(-2, -2, 0)
|
);
|
expect(renderResources.attributes.length).toBe(3);
|
|
var attributeLines = renderResources.shaderBuilder._attributeLines;
|
var vertexDefineLines =
|
renderResources.shaderBuilder._vertexShaderParts.defineLines;
|
var fragmentDefineLines =
|
renderResources.shaderBuilder._fragmentShaderParts.defineLines;
|
|
expect(vertexDefineLines[0]).toEqual("HAS_INSTANCING");
|
expect(vertexDefineLines[0]).toEqual("HAS_INSTANCING");
|
expect(vertexDefineLines[1]).toEqual("HAS_INSTANCE_MATRICES");
|
expect(fragmentDefineLines[1]).toEqual("HAS_INSTANCE_MATRICES");
|
|
expect(attributeLines[0]).toEqual(
|
"attribute vec4 a_instancingTransformRow0;"
|
);
|
expect(attributeLines[1]).toEqual(
|
"attribute vec4 a_instancingTransformRow1;"
|
);
|
expect(attributeLines[2]).toEqual(
|
"attribute vec4 a_instancingTransformRow2;"
|
);
|
|
expect(renderResources.model._resources.length).toEqual(1);
|
});
|
});
|
|
it("correctly creates transform matrices", function () {
|
var renderResources = {
|
attributeIndex: 1,
|
attributes: [],
|
instancingTranslationMax: undefined,
|
instancingTranslationMin: undefined,
|
shaderBuilder: new ShaderBuilder(),
|
model: {
|
_resources: [],
|
},
|
};
|
|
return loadGltf(boxInstanced).then(function (gltfLoader) {
|
var components = gltfLoader.components;
|
var node = components.nodes[0];
|
|
var expectedTransformsTypedArray = new Float32Array([
|
0.5999999642372131,
|
0,
|
0,
|
-2,
|
0,
|
0.4949747323989868,
|
-0.7071067094802856,
|
2,
|
0,
|
0.49497467279434204,
|
0.7071067690849304,
|
0,
|
0.7071068286895752,
|
4.174155421310388e-8,
|
0.3535534143447876,
|
-2,
|
0.5,
|
0.7071068286895752,
|
-0.2500000298023224,
|
-2,
|
-0.5000000596046448,
|
0.7071068286895752,
|
0.25,
|
0,
|
0.375,
|
-0.10000001639127731,
|
0.3535534143447876,
|
2,
|
0.6401650905609131,
|
0.029289301484823227,
|
-0.2500000298023224,
|
-2,
|
0.10983504354953766,
|
0.1707106977701187,
|
0.25,
|
0,
|
0.4898979365825653,
|
-0.3674234449863434,
|
0.44999992847442627,
|
2,
|
0.5277916193008423,
|
0.028420301154255867,
|
-0.6749999523162842,
|
2,
|
0.3484765887260437,
|
0.4734894633293152,
|
0.3897113800048828,
|
0,
|
]);
|
var transformsTypedArray = InstancingPipelineStage._getInstanceTransformsTypedArray(
|
node.instances,
|
node.instances.attributes[0].count,
|
renderResources
|
);
|
|
expect(transformsTypedArray.length).toEqual(
|
expectedTransformsTypedArray.length
|
);
|
for (var i = 0; i < expectedTransformsTypedArray.length; i++) {
|
expect(transformsTypedArray[i]).toEqualEpsilon(
|
expectedTransformsTypedArray[i],
|
CesiumMath.EPSILON10
|
);
|
}
|
});
|
});
|
|
it("creates TRANSLATION vertex attributes", function () {
|
var renderResources = {
|
attributeIndex: 1,
|
attributes: [],
|
instancingTranslationMax: undefined,
|
instancingTranslationMin: undefined,
|
shaderBuilder: new ShaderBuilder(),
|
model: {
|
_resources: [],
|
},
|
};
|
|
return loadGltf(boxInstancedTranslationMinMax).then(function (gltfLoader) {
|
var components = gltfLoader.components;
|
var node = components.nodes[0];
|
|
scene.renderForSpecs();
|
InstancingPipelineStage.process(renderResources, node, scene.frameState);
|
|
expect(renderResources.instancingTranslationMax).toEqual(
|
new Cartesian3(2, 2, 0)
|
);
|
expect(renderResources.instancingTranslationMin).toEqual(
|
new Cartesian3(-2, -2, 0)
|
);
|
expect(renderResources.attributes.length).toBe(1);
|
|
var attributeLines = renderResources.shaderBuilder._attributeLines;
|
var vertexDefineLines =
|
renderResources.shaderBuilder._vertexShaderParts.defineLines;
|
var fragmentDefineLines =
|
renderResources.shaderBuilder._fragmentShaderParts.defineLines;
|
|
expect(vertexDefineLines[0]).toEqual("HAS_INSTANCING");
|
expect(vertexDefineLines[0]).toEqual("HAS_INSTANCING");
|
expect(vertexDefineLines[1]).toEqual("HAS_INSTANCE_TRANSLATION");
|
expect(fragmentDefineLines[1]).toEqual("HAS_INSTANCE_TRANSLATION");
|
|
expect(attributeLines[0]).toEqual(
|
"attribute vec3 a_instanceTranslation;"
|
);
|
});
|
});
|
});
|