| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 | 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 <code>EXT_structural_metadata</code> glTF extension * <p> * 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. * </p> * * @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 * <code>EXT_structural_metadata</code> * * @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.<String, Object>} binaryProperties A dictionary of property ID to property definition * @param {Uint8Array} [binaryBody] The binary body of the batch table * @return {Object} Transcoded data needed for constructing a {@link StructuralMetadata} object. * * @private */function transcodeBinaryProperties(  featureCount,  className,  binaryProperties,  binaryBody) {  const classProperties = {};  const featureTableProperties = {};  const bufferViewsU8 = {};  let bufferViewCount = 0;  for (const propertyId in binaryProperties) {    if (!binaryProperties.hasOwnProperty(propertyId)) {      continue;    }    if (!defined(binaryBody)) {      throw new RuntimeError(        `Property ${propertyId} requires a batch table binary.`      );    }    const property = binaryProperties[propertyId];    const binaryAccessor = getBinaryAccessor(property);    featureTableProperties[propertyId] = {      bufferView: bufferViewCount,    };    classProperties[propertyId] = transcodePropertyType(property);    bufferViewsU8[bufferViewCount] = binaryAccessor.createArrayBufferView(      binaryBody.buffer,      binaryBody.byteOffset + property.byteOffset,      featureCount    );    bufferViewCount++;  }  const schemaJson = {    classes: {},  };  schemaJson.classes[className] = {    properties: classProperties,  };  const transcodedSchema = new MetadataSchema(schemaJson);  const featureTableJson = {    class: className,    count: featureCount,    properties: featureTableProperties,  };  return {    featureTableJson: featureTableJson,    bufferViewsU8: bufferViewsU8,    transcodedSchema: transcodedSchema,    transcodedClass: transcodedSchema.classes[className],  };}/** * Given a property definition from the batch table, compute the equivalent * <code>EXT_structural_metadata</code> 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 <code>3DTILES_batch_table_hierarchy</code> extension is present * * @param {Object} [hierarchyExtension] The <code>3DTILES_batch_table_hierarchy</code> extension object. * @param {Uint8Array} binaryBody The binary body of the batch table * @return {BatchTableHierarchy} A batch table hierarchy, or <code>undefined</code> 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 testingparseBatchTable._deprecationWarning = deprecationWarning;
 |