All files / engine/Source/Scene parseFeatureMetadataLegacy.js

100% Statements 36/36
75% Branches 6/8
100% Functions 3/3
100% Lines 35/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140                                              12x 12x       12x     12x 11x       10x   10x       5x 5x 8x 8x 8x   8x             8x                       10x 10x       2x 2x 3x 3x 3x                     10x                     3x         3x 3x 4x 4x 4x                     4x               3x       4x 4x 4x 6x   4x        
import Check from "../Core/Check.js";
import combine from "../Core/combine.js";
import Frozen from "../Core/Frozen.js";
import defined from "../Core/defined.js";
import PropertyTable from "./PropertyTable.js";
import PropertyTexture from "./PropertyTexture.js";
import StructuralMetadata from "./StructuralMetadata.js";
import MetadataTable from "./MetadataTable.js";
 
/**
 * Parse the <code>EXT_feature_metadata</code> glTF extension to create a
 * structural metadata object.
 *
 * @param {object} options Object with the following properties:
 * @param {object} options.extension The extension JSON object.
 * @param {MetadataSchema} options.schema The parsed schema.
 * @param {Object<string, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects.
 * @param {Object<string, Texture>} [options.textures] An object mapping texture IDs to {@link Texture} objects.
 * @return {StructuralMetadata} A 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.
 */
function parseFeatureMetadataLegacy(options) {
  options = options ?? Frozen.EMPTY_OBJECT;
  const extension = options.extension;
 
  // The calling code is responsible for loading the schema.
  // This keeps metadata parsing synchronous.
  const schema = options.schema;
 
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.object("options.extension", extension);
  Check.typeOf.object("options.schema", schema);
  //>>includeEnd('debug');
 
  let i;
  const propertyTables = [];
  let sortedIds;
  if (defined(extension.featureTables)) {
    // Store textures in an array sorted by the dictionary keys. This
    // allows compatibility with the newer EXT_structural_metadata extension
    // which is array-based.
    sortedIds = Object.keys(extension.featureTables).sort();
    for (i = 0; i < sortedIds.length; i++) {
      const featureTableId = sortedIds[i];
      const featureTable = extension.featureTables[featureTableId];
      const classDefinition = schema.classes[featureTable.class];
 
      const metadataTable = new MetadataTable({
        count: featureTable.count,
        properties: featureTable.properties,
        class: classDefinition,
        bufferViews: options.bufferViews,
      });
 
      propertyTables.push(
        new PropertyTable({
          id: featureTableId,
          count: featureTable.count,
          metadataTable: metadataTable,
          extras: featureTable.extras,
          extensions: featureTable.extensions,
        }),
      );
    }
  }
 
  const propertyTextures = [];
  if (defined(extension.featureTextures)) {
    // Store textures in an array sorted by the dictionary keys. This
    // allows compatibility with the newer EXT_structural_metadata extension
    // which is array-based.
    sortedIds = Object.keys(extension.featureTextures).sort();
    for (i = 0; i < sortedIds.length; i++) {
      const featureTextureId = sortedIds[i];
      const featureTexture = extension.featureTextures[featureTextureId];
      propertyTextures.push(
        new PropertyTexture({
          id: featureTextureId,
          propertyTexture: transcodeToPropertyTexture(featureTexture),
          class: schema.classes[featureTexture.class],
          textures: options.textures,
        }),
      );
    }
  }
 
  return new StructuralMetadata({
    schema: schema,
    propertyTables: propertyTables,
    propertyTextures: propertyTextures,
    statistics: extension.statistics,
    extras: extension.extras,
    extensions: extension.extensions,
  });
}
 
function transcodeToPropertyTexture(featureTexture) {
  const propertyTexture = {
    class: featureTexture.class,
    properties: {},
  };
 
  const properties = featureTexture.properties;
  for (const propertyId in properties) {
    Eif (properties.hasOwnProperty(propertyId)) {
      const oldProperty = properties[propertyId];
      const property = {
        // EXT_structural_metadata uses numeric channel indices instead of
        // a string of channel letters like "rgba".
        channels: reformatChannels(oldProperty.channels),
        extras: oldProperty.extras,
        extensions: oldProperty.extensions,
      };
 
      // EXT_feature_metadata puts the textureInfo in property.texture.
      // EXT_structural_metadata flattens this structure; essentially a
      // textureInfo + channels
      propertyTexture.properties[propertyId] = combine(
        oldProperty.texture,
        property,
        true,
      );
    }
  }
 
  return propertyTexture;
}
 
function reformatChannels(channelsString) {
  const length = channelsString.length;
  const result = new Array(length);
  for (let i = 0; i < length; i++) {
    result[i] = "rgba".indexOf(channelsString[i]);
  }
  return result;
}
 
export default parseFeatureMetadataLegacy;