15832144755
2022-01-06 7b4c8991dca9cf2a809a95e239d144697d3afb56
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
import Check from "../Core/Check.js";
import clone from "../Core/clone.js";
import defaultValue from "../Core/defaultValue.js";
import defined from "../Core/defined.js";
import PropertyTable from "./PropertyTable.js";
import PropertyTexture from "./PropertyTexture.js";
import FeatureMetadata from "./FeatureMetadata.js";
import MetadataTable from "./MetadataTable.js";
 
/**
 * Parse the <code>EXT_mesh_features</code> glTF extension to create a
 * feature 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 {FeatureMetadata} A feature 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 parseFeatureMetadata(options) {
  options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  var extension = options.extension;
 
  // The calling code is responsible for loading the schema.
  // This keeps metadata parsing synchronous.
  var schema = options.schema;
 
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.object("options.extension", extension);
  Check.typeOf.object("options.schema", schema);
  //>>includeEnd('debug');
 
  var i;
  var propertyTables = [];
  if (defined(extension.propertyTables)) {
    for (i = 0; i < extension.propertyTables.length; i++) {
      var propertyTable = extension.propertyTables[i];
      var classDefinition = schema.classes[propertyTable.class];
      var metadataTable = new MetadataTable({
        count: propertyTable.count,
        properties: propertyTable.properties,
        class: classDefinition,
        bufferViews: options.bufferViews,
      });
      propertyTables.push(
        new PropertyTable({
          id: i,
          name: propertyTable.name,
          count: propertyTable.count,
          metadataTable: metadataTable,
          extras: propertyTable.extras,
          extensions: propertyTable.extensions,
        })
      );
    }
  }
 
  var propertyTextures = [];
  if (defined(extension.propertyTextures)) {
    for (i = 0; i < extension.propertyTextures.length; i++) {
      var propertyTexture = extension.propertyTextures[i];
      propertyTextures.push(
        new PropertyTexture({
          id: i,
          name: propertyTexture.name,
          featureTexture: reformatPropertyTexture(propertyTexture),
          class: schema.classes[propertyTexture.class],
          textures: options.textures,
        })
      );
    }
  }
 
  return new FeatureMetadata({
    schema: schema,
    propertyTables: propertyTables,
    propertyTextures: propertyTextures,
    statistics: extension.statistics,
    extras: extension.extras,
    extensions: extension.extensions,
  });
}
 
/**
 * The legacy EXT_feature_metadata schema was a bit broad in what it could do.
 * The properties in a feature texture could potentially belong to different
 * textures. For full backwards compatibility, here we transcode <i>backwards</i>
 * from EXT_mesh_features to EXT_feature_metadata.
 *
 * @param {Object} propertyTexture The property texture JSON from EXT_mesh_features
 * @return {Object} The corresponding feature texture JSON for the legacy EXT_feature_metadata
 * @private
 */
function reformatPropertyTexture(propertyTexture) {
  // in EXT_mesh_features propertyTexture is a valid glTF textureInfo
  // since it has an index and a texCoord.
  var textureInfo = clone(propertyTexture);
 
  var featureTexture = clone(propertyTexture);
  featureTexture.properties = {};
 
  var originalProperties = propertyTexture.properties;
  for (var propertyId in originalProperties) {
    if (originalProperties.hasOwnProperty(propertyId)) {
      var channels = originalProperties[propertyId];
      featureTexture.properties[propertyId] = {
        texture: textureInfo,
        channels: reformatChannels(channels),
      };
    }
  }
 
  return featureTexture;
}
 
/**
 * Reformat from an array of channel indices like <code>[0, 1]</code> to a
 * string of channels as would be used in GLSL swizzling (e.g. "rg")
 *
 * @param {Number[]} channels the channel indices
 * @return {String} The channels as a string of "r", "g", "b" or "a" characters.
 * @private
 */
function reformatChannels(channels) {
  return channels
    .map(function (channelIndex) {
      return "rgba".charAt(channelIndex);
    })
    .join("");
}