import { Cartesian4 } from "../../Source/Cesium.js"; import { ComponentDatatype } from "../../Source/Cesium.js"; import { Math as CesiumMath } from "../../Source/Cesium.js"; import { PixelDatatype } from "../../Source/Cesium.js"; import { Texture } from "../../Source/Cesium.js"; import { BatchTable } from "../../Source/Cesium.js"; import createScene from "../createScene.js"; describe( "Scene/BatchTable", function () { var unsignedByteAttributes = [ { functionName: "batchTable_getShow", componentDatatype: ComponentDatatype.UNSIGNED_BYTE, componentsPerAttribute: 1, }, { functionName: "batchTable_getPickColor", componentDatatype: ComponentDatatype.UNSIGNED_BYTE, componentsPerAttribute: 4, normalize: true, }, ]; var floatAttributes = [ { functionName: "batchTable_getShow", componentDatatype: ComponentDatatype.UNSIGNED_BYTE, componentsPerAttribute: 1, }, { functionName: "batchTable_getCenter", componentDatatype: ComponentDatatype.FLOAT, componentsPerAttribute: 4, }, ]; var batchTable; var scene; var context; beforeAll(function () { scene = createScene(); context = scene.context; }); afterAll(function () { scene.destroyForSpecs(); }); afterEach(function () { batchTable = batchTable && !batchTable.isDestroyed() && batchTable.destroy(); }); it("constructor", function () { batchTable = new BatchTable(context, unsignedByteAttributes, 2); expect(batchTable.attributes).toBe(unsignedByteAttributes); expect(batchTable.numberOfInstances).toEqual(2); }); it("constructior throws without context", function () { expect(function () { batchTable = new BatchTable(undefined, unsignedByteAttributes, 5); }).toThrowDeveloperError(); }); it("constructior throws without attributes", function () { expect(function () { batchTable = new BatchTable(context, undefined, 5); }).toThrowDeveloperError(); }); it("constructor throws without number of instances", function () { expect(function () { batchTable = new BatchTable(context, unsignedByteAttributes, undefined); }).toThrowDeveloperError(); }); it("sets and gets entries in the table", function () { batchTable = new BatchTable(context, unsignedByteAttributes, 5); var i; var color = new Cartesian4(0, 1, 2, 3); for (i = 0; i < batchTable.numberOfInstances; ++i) { batchTable.setBatchedAttribute(i, 0, 1); batchTable.setBatchedAttribute(i, 1, color); } for (i = 0; i < batchTable.numberOfInstances; ++i) { expect(batchTable.getBatchedAttribute(3, 0)).toEqual(1); expect(batchTable.getBatchedAttribute(3, 1)).toEqual(color); } color = new Cartesian4(4, 5, 6, 7); batchTable.setBatchedAttribute(3, 0, 0); batchTable.setBatchedAttribute(3, 1, color); expect(batchTable.getBatchedAttribute(3, 0)).toEqual(0); expect(batchTable.getBatchedAttribute(3, 1)).toEqual(color); }); it("sets and gets entries in the table with float attributes", function () { var context = { floatingPointTexture: true, }; batchTable = new BatchTable(context, floatAttributes, 5); var i; var color = new Cartesian4(0, 1, 2, 3); for (i = 0; i < batchTable.numberOfInstances; ++i) { batchTable.setBatchedAttribute(i, 0, 1); batchTable.setBatchedAttribute(i, 1, color); } for (i = 0; i < batchTable.numberOfInstances; ++i) { expect(batchTable.getBatchedAttribute(3, 0)).toEqual(1); expect(batchTable.getBatchedAttribute(3, 1)).toEqual(color); } color = new Cartesian4(4, 5, 6, 7); batchTable.setBatchedAttribute(3, 0, 0); batchTable.setBatchedAttribute(3, 1, color); expect(batchTable.getBatchedAttribute(3, 0)).toEqual(0); expect(batchTable.getBatchedAttribute(3, 1)).toEqual(color); }); it("sets and gets entries in the table with float attributes and forced packing", function () { var context = { floatingPointTexture: false, }; batchTable = new BatchTable(context, floatAttributes, 5); var i; var color = new Cartesian4( 1.23456e12, -2.34567e30, 3.45678e-6, -4.56789e-10 ); for (i = 0; i < batchTable.numberOfInstances; ++i) { batchTable.setBatchedAttribute(i, 0, 1); batchTable.setBatchedAttribute(i, 1, color); } var value; for (i = 0; i < batchTable.numberOfInstances; ++i) { value = batchTable.getBatchedAttribute(3, 0); expect(value).toEqual(1); value = batchTable.getBatchedAttribute(3, 1); expect(value).toEqualEpsilon(color, CesiumMath.EPSILON6); } color = new Cartesian4( 0, Number.MAX_VALUE, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY ); batchTable.setBatchedAttribute(3, 0, 0); batchTable.setBatchedAttribute(3, 1, color); value = batchTable.getBatchedAttribute(3, 0); expect(value).toEqual(0); value = batchTable.getBatchedAttribute(3, 1); expect(value.x).toEqual(0.0); expect(value.y).toEqual(Number.POSITIVE_INFINITY); expect(value.z).toEqual(Number.POSITIVE_INFINITY); expect(value.w).toEqual(Number.NEGATIVE_INFINITY); }); it("gets with result parameter", function () { batchTable = new BatchTable(context, unsignedByteAttributes, 5); var color = new Cartesian4(0, 1, 2, 3); batchTable.setBatchedAttribute(0, 1, color); var result = new Cartesian4(); var returndValue = batchTable.getBatchedAttribute(0, 1, result); expect(returndValue).toBe(result); expect(result).toEqual(color); }); it("get entry throws when instance index is out of range", function () { batchTable = new BatchTable(context, unsignedByteAttributes, 5); expect(function () { batchTable.getBatchedAttribute(-1, 0); }).toThrowDeveloperError(); expect(function () { batchTable.getBatchedAttribute(100, 0); }).toThrowDeveloperError(); }); it("get entry throws when attribute index is out of range", function () { batchTable = new BatchTable(context, unsignedByteAttributes, 5); expect(function () { batchTable.getBatchedAttribute(0, -1); }).toThrowDeveloperError(); expect(function () { batchTable.getBatchedAttribute(0, 100); }).toThrowDeveloperError(); }); it("set entry throws when instance index is out of range", function () { batchTable = new BatchTable(context, unsignedByteAttributes, 5); expect(function () { batchTable.setBatchedAttribute(-1, 0, 0); }).toThrowDeveloperError(); expect(function () { batchTable.setBatchedAttribute(100, 0, 1); }).toThrowDeveloperError(); }); it("set entry throws when attribute index is out of range", function () { batchTable = new BatchTable(context, unsignedByteAttributes, 5); expect(function () { batchTable.setBatchedAttribute(0, -1, 1); }).toThrowDeveloperError(); expect(function () { batchTable.setBatchedAttribute(0, 100, 1); }).toThrowDeveloperError(); }); it("set entry throws when value is undefined", function () { batchTable = new BatchTable(context, unsignedByteAttributes, 5); expect(function () { batchTable.setBatchedAttribute(0, 0, undefined); }).toThrowDeveloperError(); }); it("creates a uniform callback with unsigned byte texture", function () { batchTable = new BatchTable(context, unsignedByteAttributes, 5); batchTable.update(scene.frameState); var uniforms = batchTable.getUniformMapCallback()({}); expect(uniforms.batchTexture).toBeDefined(); expect(uniforms.batchTexture()).toBeInstanceOf(Texture); expect(uniforms.batchTexture().pixelDatatype).toEqual( PixelDatatype.UNSIGNED_BYTE ); expect(uniforms.batchTextureDimensions).toBeDefined(); expect(uniforms.batchTextureDimensions().x).toBeGreaterThan(0); expect(uniforms.batchTextureDimensions().y).toBeGreaterThan(0); expect(uniforms.batchTextureStep).toBeDefined(); expect(uniforms.batchTextureStep().x).toBeGreaterThan(0); expect(uniforms.batchTextureStep().y).toBeGreaterThan(0); expect(uniforms.batchTextureStep().z).toBeGreaterThan(0); expect(uniforms.batchTextureStep().w).toBeGreaterThan(0); }); it("creates a uniform callback with float texture", function () { if (!context.floatingPointTexture) { return; } batchTable = new BatchTable(context, floatAttributes, 5); batchTable.update(scene.frameState); var uniforms = batchTable.getUniformMapCallback()({}); expect(uniforms.batchTexture).toBeDefined(); expect(uniforms.batchTexture()).toBeInstanceOf(Texture); expect(uniforms.batchTexture().pixelDatatype).toEqual( PixelDatatype.FLOAT ); expect(uniforms.batchTextureDimensions).toBeDefined(); expect(uniforms.batchTextureDimensions().x).toBeGreaterThan(0); expect(uniforms.batchTextureDimensions().y).toBeGreaterThan(0); expect(uniforms.batchTextureStep).toBeDefined(); expect(uniforms.batchTextureStep().x).toBeGreaterThan(0); expect(uniforms.batchTextureStep().y).toBeGreaterThan(0); expect(uniforms.batchTextureStep().z).toBeGreaterThan(0); expect(uniforms.batchTextureStep().w).toBeGreaterThan(0); if (scene.context.floatingPointTexture) { expect(uniforms.batchTexture().pixelDatatype).toEqual( PixelDatatype.FLOAT ); } else { expect(uniforms.batchTexture().pixelDatatype).toEqual( PixelDatatype.UNSIGNED_BYTE ); } }); it("create shader functions", function () { batchTable = new BatchTable(context, unsignedByteAttributes, 5); var shader = "void main() { gl_Position = vec4(0.0); }"; var modifiedShader = batchTable.getVertexShaderCallback()(shader); expect( modifiedShader.indexOf(batchTable.attributes[0].functionName) ).not.toEqual(-1); expect( modifiedShader.indexOf(batchTable.attributes[1].functionName) ).not.toEqual(-1); }); it("isDestroyed", function () { batchTable = new BatchTable(context, unsignedByteAttributes, 5); expect(batchTable.isDestroyed()).toEqual(false); batchTable.destroy(); expect(batchTable.isDestroyed()).toEqual(true); }); }, "WebGL" );