@loaders.gl/draco 4.2.0-alpha.4 → 4.2.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/dist.dev.js +268 -79
  2. package/dist/dist.min.js +11 -0
  3. package/dist/draco-loader.d.ts +2 -2
  4. package/dist/draco-loader.d.ts.map +1 -1
  5. package/dist/draco-loader.js +23 -17
  6. package/dist/draco-worker-node.js +186 -127
  7. package/dist/draco-worker-node.js.map +3 -3
  8. package/dist/draco-worker.js +5 -3
  9. package/dist/draco-worker.js.map +2 -2
  10. package/dist/draco-writer-worker-node.js +188 -127
  11. package/dist/draco-writer-worker-node.js.map +3 -3
  12. package/dist/draco-writer-worker.js +5 -3
  13. package/dist/draco-writer-worker.js.map +2 -2
  14. package/dist/draco-writer.d.ts +2 -2
  15. package/dist/draco-writer.d.ts.map +1 -1
  16. package/dist/draco-writer.js +30 -23
  17. package/dist/draco3d/draco3d-types.js +48 -41
  18. package/dist/index.cjs +34 -71
  19. package/dist/index.cjs.map +7 -0
  20. package/dist/index.d.ts +6 -6
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +27 -21
  23. package/dist/lib/draco-builder.d.ts +2 -2
  24. package/dist/lib/draco-builder.d.ts.map +1 -1
  25. package/dist/lib/draco-builder.js +314 -243
  26. package/dist/lib/draco-module-loader.js +78 -62
  27. package/dist/lib/draco-parser.d.ts +2 -2
  28. package/dist/lib/draco-parser.d.ts.map +1 -1
  29. package/dist/lib/draco-parser.js +437 -323
  30. package/dist/lib/draco-types.js +1 -1
  31. package/dist/lib/utils/get-draco-schema.d.ts +1 -1
  32. package/dist/lib/utils/get-draco-schema.d.ts.map +1 -1
  33. package/dist/lib/utils/get-draco-schema.js +29 -32
  34. package/dist/lib/utils/version.js +4 -2
  35. package/dist/workers/draco-worker-node.js +1 -1
  36. package/dist/workers/draco-worker.js +0 -1
  37. package/dist/workers/draco-writer-worker-node.js +20 -25
  38. package/dist/workers/draco-writer-worker.js +19 -25
  39. package/package.json +10 -10
  40. package/dist/draco-loader.js.map +0 -1
  41. package/dist/draco-writer.js.map +0 -1
  42. package/dist/draco3d/draco3d-types.js.map +0 -1
  43. package/dist/index.js.map +0 -1
  44. package/dist/lib/draco-builder.js.map +0 -1
  45. package/dist/lib/draco-module-loader.js.map +0 -1
  46. package/dist/lib/draco-parser.js.map +0 -1
  47. package/dist/lib/draco-types.js.map +0 -1
  48. package/dist/lib/utils/get-draco-schema.js.map +0 -1
  49. package/dist/lib/utils/version.js.map +0 -1
  50. package/dist/libs/libs/draco_decoder.wasm +0 -0
  51. package/dist/libs/libs/draco_encoder.js +0 -52
  52. package/dist/libs/libs/draco_wasm_wrapper.js +0 -117
  53. package/dist/workers/draco-worker-node.js.map +0 -1
  54. package/dist/workers/draco-worker.js.map +0 -1
  55. package/dist/workers/draco-writer-worker-node.js.map +0 -1
  56. package/dist/workers/draco-writer-worker.js.map +0 -1
@@ -1,269 +1,340 @@
1
+ // Native Draco attribute names to GLTF attribute names.
1
2
  const GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP = {
2
- POSITION: 'POSITION',
3
- NORMAL: 'NORMAL',
4
- COLOR_0: 'COLOR',
5
- TEXCOORD_0: 'TEX_COORD'
3
+ POSITION: 'POSITION',
4
+ NORMAL: 'NORMAL',
5
+ COLOR_0: 'COLOR',
6
+ TEXCOORD_0: 'TEX_COORD'
6
7
  };
7
- const noop = () => {};
8
+ const noop = () => { };
8
9
  export default class DracoBuilder {
9
- constructor(draco) {
10
- this.draco = void 0;
11
- this.dracoEncoder = void 0;
12
- this.dracoMeshBuilder = void 0;
13
- this.dracoMetadataBuilder = void 0;
14
- this.log = void 0;
15
- this.draco = draco;
16
- this.dracoEncoder = new this.draco.Encoder();
17
- this.dracoMeshBuilder = new this.draco.MeshBuilder();
18
- this.dracoMetadataBuilder = new this.draco.MetadataBuilder();
19
- }
20
- destroy() {
21
- this.destroyEncodedObject(this.dracoMeshBuilder);
22
- this.destroyEncodedObject(this.dracoEncoder);
23
- this.destroyEncodedObject(this.dracoMetadataBuilder);
24
- this.dracoMeshBuilder = null;
25
- this.dracoEncoder = null;
26
- this.draco = null;
27
- }
28
- destroyEncodedObject(object) {
29
- if (object) {
30
- this.draco.destroy(object);
10
+ draco;
11
+ dracoEncoder;
12
+ dracoMeshBuilder;
13
+ dracoMetadataBuilder;
14
+ log;
15
+ // draco - the draco decoder, either import `draco3d` or load dynamically
16
+ constructor(draco) {
17
+ this.draco = draco;
18
+ this.dracoEncoder = new this.draco.Encoder();
19
+ this.dracoMeshBuilder = new this.draco.MeshBuilder();
20
+ this.dracoMetadataBuilder = new this.draco.MetadataBuilder();
31
21
  }
32
- }
33
- encodeSync(mesh) {
34
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
35
- this.log = noop;
36
- this._setOptions(options);
37
- return options.pointcloud ? this._encodePointCloud(mesh, options) : this._encodeMesh(mesh, options);
38
- }
39
- _getAttributesFromMesh(mesh) {
40
- const attributes = {
41
- ...mesh,
42
- ...mesh.attributes
43
- };
44
- if (mesh.indices) {
45
- attributes.indices = mesh.indices;
22
+ destroy() {
23
+ this.destroyEncodedObject(this.dracoMeshBuilder);
24
+ this.destroyEncodedObject(this.dracoEncoder);
25
+ this.destroyEncodedObject(this.dracoMetadataBuilder);
26
+ // @ts-ignore
27
+ this.dracoMeshBuilder = null;
28
+ // @ts-ignore
29
+ this.dracoEncoder = null;
30
+ // @ts-ignore
31
+ this.draco = null;
46
32
  }
47
- return attributes;
48
- }
49
- _encodePointCloud(pointcloud, options) {
50
- const dracoPointCloud = new this.draco.PointCloud();
51
- if (options.metadata) {
52
- this._addGeometryMetadata(dracoPointCloud, options.metadata);
53
- }
54
- const attributes = this._getAttributesFromMesh(pointcloud);
55
- this._createDracoPointCloud(dracoPointCloud, attributes, options);
56
- const dracoData = new this.draco.DracoInt8Array();
57
- try {
58
- const encodedLen = this.dracoEncoder.EncodePointCloudToDracoBuffer(dracoPointCloud, false, dracoData);
59
- if (!(encodedLen > 0)) {
60
- throw new Error('Draco encoding failed.');
61
- }
62
- this.log(`DRACO encoded ${dracoPointCloud.num_points()} points
63
- with ${dracoPointCloud.num_attributes()} attributes into ${encodedLen} bytes`);
64
- return dracoInt8ArrayToArrayBuffer(dracoData);
65
- } finally {
66
- this.destroyEncodedObject(dracoData);
67
- this.destroyEncodedObject(dracoPointCloud);
33
+ // TBD - when does this need to be called?
34
+ destroyEncodedObject(object) {
35
+ if (object) {
36
+ this.draco.destroy(object);
37
+ }
68
38
  }
69
- }
70
- _encodeMesh(mesh, options) {
71
- const dracoMesh = new this.draco.Mesh();
72
- if (options.metadata) {
73
- this._addGeometryMetadata(dracoMesh, options.metadata);
39
+ /**
40
+ * Encode mesh or point cloud
41
+ * @param mesh =({})
42
+ * @param options
43
+ */
44
+ encodeSync(mesh, options = {}) {
45
+ this.log = noop; // TODO
46
+ this._setOptions(options);
47
+ return options.pointcloud
48
+ ? this._encodePointCloud(mesh, options)
49
+ : this._encodeMesh(mesh, options);
74
50
  }
75
- const attributes = this._getAttributesFromMesh(mesh);
76
- this._createDracoMesh(dracoMesh, attributes, options);
77
- const dracoData = new this.draco.DracoInt8Array();
78
- try {
79
- const encodedLen = this.dracoEncoder.EncodeMeshToDracoBuffer(dracoMesh, dracoData);
80
- if (encodedLen <= 0) {
81
- throw new Error('Draco encoding failed.');
82
- }
83
- this.log(`DRACO encoded ${dracoMesh.num_points()} points
84
- with ${dracoMesh.num_attributes()} attributes into ${encodedLen} bytes`);
85
- return dracoInt8ArrayToArrayBuffer(dracoData);
86
- } finally {
87
- this.destroyEncodedObject(dracoData);
88
- this.destroyEncodedObject(dracoMesh);
51
+ // PRIVATE
52
+ _getAttributesFromMesh(mesh) {
53
+ // TODO - Change the encodePointCloud interface instead?
54
+ const attributes = { ...mesh, ...mesh.attributes };
55
+ // Fold indices into the attributes
56
+ if (mesh.indices) {
57
+ attributes.indices = mesh.indices;
58
+ }
59
+ return attributes;
89
60
  }
90
- }
91
- _setOptions(options) {
92
- if ('speed' in options) {
93
- this.dracoEncoder.SetSpeedOptions(...options.speed);
61
+ _encodePointCloud(pointcloud, options) {
62
+ const dracoPointCloud = new this.draco.PointCloud();
63
+ if (options.metadata) {
64
+ this._addGeometryMetadata(dracoPointCloud, options.metadata);
65
+ }
66
+ const attributes = this._getAttributesFromMesh(pointcloud);
67
+ // Build a `DracoPointCloud` from the input data
68
+ this._createDracoPointCloud(dracoPointCloud, attributes, options);
69
+ const dracoData = new this.draco.DracoInt8Array();
70
+ try {
71
+ const encodedLen = this.dracoEncoder.EncodePointCloudToDracoBuffer(dracoPointCloud, false, dracoData);
72
+ if (!(encodedLen > 0)) {
73
+ throw new Error('Draco encoding failed.');
74
+ }
75
+ this.log(`DRACO encoded ${dracoPointCloud.num_points()} points
76
+ with ${dracoPointCloud.num_attributes()} attributes into ${encodedLen} bytes`);
77
+ return dracoInt8ArrayToArrayBuffer(dracoData);
78
+ }
79
+ finally {
80
+ this.destroyEncodedObject(dracoData);
81
+ this.destroyEncodedObject(dracoPointCloud);
82
+ }
94
83
  }
95
- if ('method' in options) {
96
- const dracoMethod = this.draco[options.method || 'MESH_SEQUENTIAL_ENCODING'];
97
- this.dracoEncoder.SetEncodingMethod(dracoMethod);
84
+ _encodeMesh(mesh, options) {
85
+ const dracoMesh = new this.draco.Mesh();
86
+ if (options.metadata) {
87
+ this._addGeometryMetadata(dracoMesh, options.metadata);
88
+ }
89
+ const attributes = this._getAttributesFromMesh(mesh);
90
+ // Build a `DracoMesh` from the input data
91
+ this._createDracoMesh(dracoMesh, attributes, options);
92
+ const dracoData = new this.draco.DracoInt8Array();
93
+ try {
94
+ const encodedLen = this.dracoEncoder.EncodeMeshToDracoBuffer(dracoMesh, dracoData);
95
+ if (encodedLen <= 0) {
96
+ throw new Error('Draco encoding failed.');
97
+ }
98
+ this.log(`DRACO encoded ${dracoMesh.num_points()} points
99
+ with ${dracoMesh.num_attributes()} attributes into ${encodedLen} bytes`);
100
+ return dracoInt8ArrayToArrayBuffer(dracoData);
101
+ }
102
+ finally {
103
+ this.destroyEncodedObject(dracoData);
104
+ this.destroyEncodedObject(dracoMesh);
105
+ }
98
106
  }
99
- if ('quantization' in options) {
100
- for (const attribute in options.quantization) {
101
- const bits = options.quantization[attribute];
102
- const dracoPosition = this.draco[attribute];
103
- this.dracoEncoder.SetAttributeQuantization(dracoPosition, bits);
104
- }
107
+ /**
108
+ * Set encoding options.
109
+ * @param {{speed?: any; method?: any; quantization?: any;}} options
110
+ */
111
+ _setOptions(options) {
112
+ if ('speed' in options) {
113
+ // @ts-ignore
114
+ this.dracoEncoder.SetSpeedOptions(...options.speed);
115
+ }
116
+ if ('method' in options) {
117
+ const dracoMethod = this.draco[options.method || 'MESH_SEQUENTIAL_ENCODING'];
118
+ // assert(dracoMethod)
119
+ this.dracoEncoder.SetEncodingMethod(dracoMethod);
120
+ }
121
+ if ('quantization' in options) {
122
+ for (const attribute in options.quantization) {
123
+ const bits = options.quantization[attribute];
124
+ const dracoPosition = this.draco[attribute];
125
+ this.dracoEncoder.SetAttributeQuantization(dracoPosition, bits);
126
+ }
127
+ }
105
128
  }
106
- }
107
- _createDracoMesh(dracoMesh, attributes, options) {
108
- const optionalMetadata = options.attributesMetadata || {};
109
- try {
110
- const positions = this._getPositionAttribute(attributes);
111
- if (!positions) {
112
- throw new Error('positions');
113
- }
114
- const vertexCount = positions.length / 3;
115
- for (let attributeName in attributes) {
116
- const attribute = attributes[attributeName];
117
- attributeName = GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP[attributeName] || attributeName;
118
- const uniqueId = this._addAttributeToMesh(dracoMesh, attributeName, attribute, vertexCount);
119
- if (uniqueId !== -1) {
120
- this._addAttributeMetadata(dracoMesh, uniqueId, {
121
- name: attributeName,
122
- ...(optionalMetadata[attributeName] || {})
123
- });
129
+ /**
130
+ * @param {Mesh} dracoMesh
131
+ * @param {object} attributes
132
+ * @returns {Mesh}
133
+ */
134
+ _createDracoMesh(dracoMesh, attributes, options) {
135
+ const optionalMetadata = options.attributesMetadata || {};
136
+ try {
137
+ const positions = this._getPositionAttribute(attributes);
138
+ if (!positions) {
139
+ throw new Error('positions');
140
+ }
141
+ const vertexCount = positions.length / 3;
142
+ for (let attributeName in attributes) {
143
+ const attribute = attributes[attributeName];
144
+ attributeName = GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP[attributeName] || attributeName;
145
+ const uniqueId = this._addAttributeToMesh(dracoMesh, attributeName, attribute, vertexCount);
146
+ if (uniqueId !== -1) {
147
+ this._addAttributeMetadata(dracoMesh, uniqueId, {
148
+ name: attributeName,
149
+ ...(optionalMetadata[attributeName] || {})
150
+ });
151
+ }
152
+ }
124
153
  }
125
- }
126
- } catch (error) {
127
- this.destroyEncodedObject(dracoMesh);
128
- throw error;
154
+ catch (error) {
155
+ this.destroyEncodedObject(dracoMesh);
156
+ throw error;
157
+ }
158
+ return dracoMesh;
129
159
  }
130
- return dracoMesh;
131
- }
132
- _createDracoPointCloud(dracoPointCloud, attributes, options) {
133
- const optionalMetadata = options.attributesMetadata || {};
134
- try {
135
- const positions = this._getPositionAttribute(attributes);
136
- if (!positions) {
137
- throw new Error('positions');
138
- }
139
- const vertexCount = positions.length / 3;
140
- for (let attributeName in attributes) {
141
- const attribute = attributes[attributeName];
142
- attributeName = GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP[attributeName] || attributeName;
143
- const uniqueId = this._addAttributeToMesh(dracoPointCloud, attributeName, attribute, vertexCount);
144
- if (uniqueId !== -1) {
145
- this._addAttributeMetadata(dracoPointCloud, uniqueId, {
146
- name: attributeName,
147
- ...(optionalMetadata[attributeName] || {})
148
- });
160
+ /**
161
+ * @param {} dracoPointCloud
162
+ * @param {object} attributes
163
+ */
164
+ _createDracoPointCloud(dracoPointCloud, attributes, options) {
165
+ const optionalMetadata = options.attributesMetadata || {};
166
+ try {
167
+ const positions = this._getPositionAttribute(attributes);
168
+ if (!positions) {
169
+ throw new Error('positions');
170
+ }
171
+ const vertexCount = positions.length / 3;
172
+ for (let attributeName in attributes) {
173
+ const attribute = attributes[attributeName];
174
+ attributeName = GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP[attributeName] || attributeName;
175
+ const uniqueId = this._addAttributeToMesh(dracoPointCloud, attributeName, attribute, vertexCount);
176
+ if (uniqueId !== -1) {
177
+ this._addAttributeMetadata(dracoPointCloud, uniqueId, {
178
+ name: attributeName,
179
+ ...(optionalMetadata[attributeName] || {})
180
+ });
181
+ }
182
+ }
183
+ }
184
+ catch (error) {
185
+ this.destroyEncodedObject(dracoPointCloud);
186
+ throw error;
149
187
  }
150
- }
151
- } catch (error) {
152
- this.destroyEncodedObject(dracoPointCloud);
153
- throw error;
188
+ return dracoPointCloud;
154
189
  }
155
- return dracoPointCloud;
156
- }
157
- _addAttributeToMesh(mesh, attributeName, attribute, vertexCount) {
158
- if (!ArrayBuffer.isView(attribute)) {
159
- return -1;
190
+ /**
191
+ * @param mesh
192
+ * @param attributeName
193
+ * @param attribute
194
+ * @param vertexCount
195
+ */
196
+ _addAttributeToMesh(mesh, attributeName, attribute, vertexCount) {
197
+ if (!ArrayBuffer.isView(attribute)) {
198
+ return -1;
199
+ }
200
+ const type = this._getDracoAttributeType(attributeName);
201
+ // @ts-ignore TODO/fix types
202
+ const size = attribute.length / vertexCount;
203
+ if (type === 'indices') {
204
+ // @ts-ignore TODO/fix types
205
+ const numFaces = attribute.length / 3;
206
+ this.log(`Adding attribute ${attributeName}, size ${numFaces}`);
207
+ // @ts-ignore assumes mesh is a Mesh, not a point cloud
208
+ this.dracoMeshBuilder.AddFacesToMesh(mesh, numFaces, attribute);
209
+ return -1;
210
+ }
211
+ this.log(`Adding attribute ${attributeName}, size ${size}`);
212
+ const builder = this.dracoMeshBuilder;
213
+ const { buffer } = attribute;
214
+ switch (attribute.constructor) {
215
+ case Int8Array:
216
+ return builder.AddInt8Attribute(mesh, type, vertexCount, size, new Int8Array(buffer));
217
+ case Int16Array:
218
+ return builder.AddInt16Attribute(mesh, type, vertexCount, size, new Int16Array(buffer));
219
+ case Int32Array:
220
+ return builder.AddInt32Attribute(mesh, type, vertexCount, size, new Int32Array(buffer));
221
+ case Uint8Array:
222
+ case Uint8ClampedArray:
223
+ return builder.AddUInt8Attribute(mesh, type, vertexCount, size, new Uint8Array(buffer));
224
+ case Uint16Array:
225
+ return builder.AddUInt16Attribute(mesh, type, vertexCount, size, new Uint16Array(buffer));
226
+ case Uint32Array:
227
+ return builder.AddUInt32Attribute(mesh, type, vertexCount, size, new Uint32Array(buffer));
228
+ case Float32Array:
229
+ default:
230
+ return builder.AddFloatAttribute(mesh, type, vertexCount, size, new Float32Array(buffer));
231
+ }
160
232
  }
161
- const type = this._getDracoAttributeType(attributeName);
162
- const size = attribute.length / vertexCount;
163
- if (type === 'indices') {
164
- const numFaces = attribute.length / 3;
165
- this.log(`Adding attribute ${attributeName}, size ${numFaces}`);
166
- this.dracoMeshBuilder.AddFacesToMesh(mesh, numFaces, attribute);
167
- return -1;
233
+ /**
234
+ * DRACO can compress attributes of know type better
235
+ * TODO - expose an attribute type map?
236
+ * @param attributeName
237
+ */
238
+ _getDracoAttributeType(attributeName) {
239
+ switch (attributeName.toLowerCase()) {
240
+ case 'indices':
241
+ return 'indices';
242
+ case 'position':
243
+ case 'positions':
244
+ case 'vertices':
245
+ return this.draco.POSITION;
246
+ case 'normal':
247
+ case 'normals':
248
+ return this.draco.NORMAL;
249
+ case 'color':
250
+ case 'colors':
251
+ return this.draco.COLOR;
252
+ case 'texcoord':
253
+ case 'texcoords':
254
+ return this.draco.TEX_COORD;
255
+ default:
256
+ return this.draco.GENERIC;
257
+ }
168
258
  }
169
- this.log(`Adding attribute ${attributeName}, size ${size}`);
170
- const builder = this.dracoMeshBuilder;
171
- const {
172
- buffer
173
- } = attribute;
174
- switch (attribute.constructor) {
175
- case Int8Array:
176
- return builder.AddInt8Attribute(mesh, type, vertexCount, size, new Int8Array(buffer));
177
- case Int16Array:
178
- return builder.AddInt16Attribute(mesh, type, vertexCount, size, new Int16Array(buffer));
179
- case Int32Array:
180
- return builder.AddInt32Attribute(mesh, type, vertexCount, size, new Int32Array(buffer));
181
- case Uint8Array:
182
- case Uint8ClampedArray:
183
- return builder.AddUInt8Attribute(mesh, type, vertexCount, size, new Uint8Array(buffer));
184
- case Uint16Array:
185
- return builder.AddUInt16Attribute(mesh, type, vertexCount, size, new Uint16Array(buffer));
186
- case Uint32Array:
187
- return builder.AddUInt32Attribute(mesh, type, vertexCount, size, new Uint32Array(buffer));
188
- case Float32Array:
189
- default:
190
- return builder.AddFloatAttribute(mesh, type, vertexCount, size, new Float32Array(buffer));
259
+ _getPositionAttribute(attributes) {
260
+ for (const attributeName in attributes) {
261
+ const attribute = attributes[attributeName];
262
+ const dracoType = this._getDracoAttributeType(attributeName);
263
+ if (dracoType === this.draco.POSITION) {
264
+ return attribute;
265
+ }
266
+ }
267
+ return null;
191
268
  }
192
- }
193
- _getDracoAttributeType(attributeName) {
194
- switch (attributeName.toLowerCase()) {
195
- case 'indices':
196
- return 'indices';
197
- case 'position':
198
- case 'positions':
199
- case 'vertices':
200
- return this.draco.POSITION;
201
- case 'normal':
202
- case 'normals':
203
- return this.draco.NORMAL;
204
- case 'color':
205
- case 'colors':
206
- return this.draco.COLOR;
207
- case 'texcoord':
208
- case 'texcoords':
209
- return this.draco.TEX_COORD;
210
- default:
211
- return this.draco.GENERIC;
269
+ /**
270
+ * Add metadata for the geometry.
271
+ * @param dracoGeometry - WASM Draco Object
272
+ * @param metadata
273
+ */
274
+ _addGeometryMetadata(dracoGeometry, metadata) {
275
+ const dracoMetadata = new this.draco.Metadata();
276
+ this._populateDracoMetadata(dracoMetadata, metadata);
277
+ this.dracoMeshBuilder.AddMetadata(dracoGeometry, dracoMetadata);
212
278
  }
213
- }
214
- _getPositionAttribute(attributes) {
215
- for (const attributeName in attributes) {
216
- const attribute = attributes[attributeName];
217
- const dracoType = this._getDracoAttributeType(attributeName);
218
- if (dracoType === this.draco.POSITION) {
219
- return attribute;
220
- }
279
+ /**
280
+ * Add metadata for an attribute to geometry.
281
+ * @param dracoGeometry - WASM Draco Object
282
+ * @param uniqueAttributeId
283
+ * @param metadata
284
+ */
285
+ _addAttributeMetadata(dracoGeometry, uniqueAttributeId, metadata) {
286
+ // Note: Draco JS IDL doesn't seem to expose draco.AttributeMetadata, however it seems to
287
+ // create such objects automatically from draco.Metadata object.
288
+ const dracoAttributeMetadata = new this.draco.Metadata();
289
+ this._populateDracoMetadata(dracoAttributeMetadata, metadata);
290
+ // Draco3d doc note: Directly add attribute metadata to geometry.
291
+ // You can do this without explicitly adding |GeometryMetadata| to mesh.
292
+ this.dracoMeshBuilder.SetMetadataForAttribute(dracoGeometry, uniqueAttributeId, dracoAttributeMetadata);
221
293
  }
222
- return null;
223
- }
224
- _addGeometryMetadata(dracoGeometry, metadata) {
225
- const dracoMetadata = new this.draco.Metadata();
226
- this._populateDracoMetadata(dracoMetadata, metadata);
227
- this.dracoMeshBuilder.AddMetadata(dracoGeometry, dracoMetadata);
228
- }
229
- _addAttributeMetadata(dracoGeometry, uniqueAttributeId, metadata) {
230
- const dracoAttributeMetadata = new this.draco.Metadata();
231
- this._populateDracoMetadata(dracoAttributeMetadata, metadata);
232
- this.dracoMeshBuilder.SetMetadataForAttribute(dracoGeometry, uniqueAttributeId, dracoAttributeMetadata);
233
- }
234
- _populateDracoMetadata(dracoMetadata, metadata) {
235
- for (const [key, value] of getEntries(metadata)) {
236
- switch (typeof value) {
237
- case 'number':
238
- if (Math.trunc(value) === value) {
239
- this.dracoMetadataBuilder.AddIntEntry(dracoMetadata, key, value);
240
- } else {
241
- this.dracoMetadataBuilder.AddDoubleEntry(dracoMetadata, key, value);
242
- }
243
- break;
244
- case 'object':
245
- if (value instanceof Int32Array) {
246
- this.dracoMetadataBuilder.AddIntEntryArray(dracoMetadata, key, value, value.length);
247
- }
248
- break;
249
- case 'string':
250
- default:
251
- this.dracoMetadataBuilder.AddStringEntry(dracoMetadata, key, value);
252
- }
294
+ /**
295
+ * Add contents of object or map to a WASM Draco Metadata Object
296
+ * @param dracoMetadata - WASM Draco Object
297
+ * @param metadata
298
+ */
299
+ _populateDracoMetadata(dracoMetadata, metadata) {
300
+ for (const [key, value] of getEntries(metadata)) {
301
+ switch (typeof value) {
302
+ case 'number':
303
+ if (Math.trunc(value) === value) {
304
+ this.dracoMetadataBuilder.AddIntEntry(dracoMetadata, key, value);
305
+ }
306
+ else {
307
+ this.dracoMetadataBuilder.AddDoubleEntry(dracoMetadata, key, value);
308
+ }
309
+ break;
310
+ case 'object':
311
+ if (value instanceof Int32Array) {
312
+ this.dracoMetadataBuilder.AddIntEntryArray(dracoMetadata, key, value, value.length);
313
+ }
314
+ break;
315
+ case 'string':
316
+ default:
317
+ this.dracoMetadataBuilder.AddStringEntry(dracoMetadata, key, value);
318
+ }
319
+ }
253
320
  }
254
- }
255
321
  }
322
+ // HELPER FUNCTIONS
323
+ /**
324
+ * Copy encoded data to buffer
325
+ * @param dracoData
326
+ */
256
327
  function dracoInt8ArrayToArrayBuffer(dracoData) {
257
- const byteLength = dracoData.size();
258
- const outputBuffer = new ArrayBuffer(byteLength);
259
- const outputData = new Int8Array(outputBuffer);
260
- for (let i = 0; i < byteLength; ++i) {
261
- outputData[i] = dracoData.GetValue(i);
262
- }
263
- return outputBuffer;
328
+ const byteLength = dracoData.size();
329
+ const outputBuffer = new ArrayBuffer(byteLength);
330
+ const outputData = new Int8Array(outputBuffer);
331
+ for (let i = 0; i < byteLength; ++i) {
332
+ outputData[i] = dracoData.GetValue(i);
333
+ }
334
+ return outputBuffer;
264
335
  }
336
+ /** Enable iteration over either an object or a map */
265
337
  function getEntries(container) {
266
- const hasEntriesFunc = container.entries && !container.hasOwnProperty('entries');
267
- return hasEntriesFunc ? container.entries() : Object.entries(container);
338
+ const hasEntriesFunc = container.entries && !container.hasOwnProperty('entries');
339
+ return hasEntriesFunc ? container.entries() : Object.entries(container);
268
340
  }
269
- //# sourceMappingURL=draco-builder.js.map