import Check from "../Core/Check.js";
import defined from "../Core/defined.js";
import deprecationWarning from "../Core/deprecationWarning.js";
import RuntimeError from "../Core/RuntimeError.js";
import BatchTableHierarchy from "./BatchTableHierarchy.js";
import StructuralMetadata from "./StructuralMetadata.js";
import PropertyTable from "./PropertyTable.js";
import getBinaryAccessor from "./getBinaryAccessor.js";
import JsonMetadataTable from "./JsonMetadataTable.js";
import MetadataClass from "./MetadataClass.js";
import MetadataSchema from "./MetadataSchema.js";
import MetadataTable from "./MetadataTable.js";
/**
* An object that parses the the 3D Tiles 1.0 batch table and transcodes it to
* be compatible with structural metadata from the EXT_structural_metadata
glTF extension
*
* See the {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata|EXT_structural_metadata Extension} for glTF. *
* * @param {Object} options Object with the following properties: * @param {Number} options.count The number of features in the batch table. * @param {Object} options.batchTable The batch table JSON * @param {Uint8Array} [options.binaryBody] The batch table binary body * @return {StructuralMetadata} A transcoded structural metadata object * * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ export default function parseBatchTable(options) { //>>includeStart('debug', pragmas.debug); Check.typeOf.number("options.count", options.count); Check.typeOf.object("options.batchTable", options.batchTable); //>>includeEnd('debug'); const featureCount = options.count; const batchTable = options.batchTable; const binaryBody = options.binaryBody; // divide properties into binary, json and hierarchy const partitionResults = partitionProperties(batchTable); const jsonMetadataTable = new JsonMetadataTable({ count: featureCount, properties: partitionResults.jsonProperties, }); const hierarchy = initializeHierarchy(partitionResults.hierarchy, binaryBody); const className = MetadataClass.BATCH_TABLE_CLASS_NAME; const binaryResults = transcodeBinaryProperties( featureCount, className, partitionResults.binaryProperties, binaryBody ); const featureTableJson = binaryResults.featureTableJson; const metadataTable = new MetadataTable({ count: featureTableJson.count, properties: featureTableJson.properties, class: binaryResults.transcodedClass, bufferViews: binaryResults.bufferViewsU8, }); const propertyTable = new PropertyTable({ id: 0, name: "Batch Table", count: featureTableJson.count, metadataTable: metadataTable, jsonMetadataTable: jsonMetadataTable, batchTableHierarchy: hierarchy, }); return new StructuralMetadata({ schema: binaryResults.transcodedSchema, propertyTables: [propertyTable], extensions: partitionResults.extensions, extras: partitionResults.extras, }); } /** * Divide the batch table's properties into binary, JSON and hierarchy * extension as each is handled separately * * @param {Object} batchTable The batch table JSON * @returns {Object} The batch table divided into binary, JSON and hierarchy portions. Extras and extensions are also divided out for ease of processing. * * @private */ function partitionProperties(batchTable) { const legacyHierarchy = batchTable.HIERARCHY; const extras = batchTable.extras; const extensions = batchTable.extensions; let hierarchyExtension; if (defined(legacyHierarchy)) { parseBatchTable._deprecationWarning( "batchTableHierarchyExtension", "The batch table HIERARCHY property has been moved to an extension. Use extensions.3DTILES_batch_table_hierarchy instead." ); hierarchyExtension = legacyHierarchy; } else if (defined(extensions)) { hierarchyExtension = extensions["3DTILES_batch_table_hierarchy"]; } const jsonProperties = {}; const binaryProperties = {}; for (const propertyId in batchTable) { if ( !batchTable.hasOwnProperty(propertyId) || // these cases were handled above; propertyId === "HIERARCHY" || propertyId === "extensions" || propertyId === "extras" ) { continue; } const property = batchTable[propertyId]; if (Array.isArray(property)) { jsonProperties[propertyId] = property; } else { binaryProperties[propertyId] = property; } } return { binaryProperties: binaryProperties, jsonProperties: jsonProperties, hierarchy: hierarchyExtension, extras: extras, extensions: extensions, }; } /** * Transcode the binary properties of the batch table to be compatible with *EXT_structural_metadata
*
* @param {Number} featureCount The number of features in the batch table
* @param {String} className The name of the metadata class to be created.
* @param {Object.EXT_structural_metadata
type definition
*
* @param {Object} property The batch table property definition
* @return {Object} The corresponding structural metadata property definition
* @private
*/
function transcodePropertyType(property) {
const componentType = transcodeComponentType(property.componentType);
return {
type: property.type,
componentType: componentType,
};
}
/**
* Convert the component type of a batch table property to the corresponding
* type used with structural metadata
*
* @property {String} componentType the batch table's component type
* @return {String} The corresponding structural metadata data type
*
* @private
*/
function transcodeComponentType(componentType) {
switch (componentType) {
case "BYTE":
return "INT8";
case "UNSIGNED_BYTE":
return "UINT8";
case "SHORT":
return "INT16";
case "UNSIGNED_SHORT":
return "UINT16";
case "INT":
return "INT32";
case "UNSIGNED_INT":
return "UINT32";
case "FLOAT":
return "FLOAT32";
case "DOUBLE":
return "FLOAT64";
}
}
/**
* Construct a batch table hierarchy object if the 3DTILES_batch_table_hierarchy
extension is present
*
* @param {Object} [hierarchyExtension] The 3DTILES_batch_table_hierarchy
extension object.
* @param {Uint8Array} binaryBody The binary body of the batch table
* @return {BatchTableHierarchy} A batch table hierarchy, or undefined
if the extension is not present.
*
* @private
*/
function initializeHierarchy(hierarchyExtension, binaryBody) {
if (defined(hierarchyExtension)) {
return new BatchTableHierarchy({
extension: hierarchyExtension,
binaryBody: binaryBody,
});
}
return undefined;
}
// exposed for testing
parseBatchTable._deprecationWarning = deprecationWarning;