@loaders.gl/tile-converter 3.2.3 → 3.3.0-alpha.1
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.
- package/dist/3d-tiles-attributes-worker.js +3 -3
- package/dist/3d-tiles-attributes-worker.js.map +1 -1
- package/dist/converter-cli.js +30 -7
- package/dist/converter.min.js +1 -1
- package/dist/dist.min.js +820 -517
- package/dist/es5/3d-tiles-attributes-worker.js +1 -1
- package/dist/es5/3d-tiles-attributes-worker.js.map +1 -1
- package/dist/es5/converter-cli.js +42 -12
- package/dist/es5/converter-cli.js.map +1 -1
- package/dist/es5/i3s-attributes-worker.js +1 -1
- package/dist/es5/i3s-attributes-worker.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js +135 -0
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/geometry-converter.js +16 -10
- package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/gltf-attributes.js +15 -1
- package/dist/es5/i3s-converter/helpers/gltf-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/i3s-converter.js +19 -15
- package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/es5/lib/utils/write-queue.js +3 -5
- package/dist/es5/lib/utils/write-queue.js.map +1 -1
- package/dist/es5/pgm-loader.js +1 -1
- package/dist/es5/pgm-loader.js.map +1 -1
- package/dist/esm/3d-tiles-attributes-worker.js +1 -1
- package/dist/esm/3d-tiles-attributes-worker.js.map +1 -1
- package/dist/esm/converter-cli.js +37 -7
- package/dist/esm/converter-cli.js.map +1 -1
- package/dist/esm/i3s-attributes-worker.js +1 -1
- package/dist/esm/i3s-attributes-worker.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js +117 -0
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/geometry-converter.js +13 -8
- package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/gltf-attributes.js +15 -1
- package/dist/esm/i3s-converter/helpers/gltf-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/i3s-converter.js +5 -1
- package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/esm/lib/utils/write-queue.js +3 -5
- package/dist/esm/lib/utils/write-queue.js.map +1 -1
- package/dist/esm/pgm-loader.js +1 -1
- package/dist/esm/pgm-loader.js.map +1 -1
- package/dist/i3s-attributes-worker.js +3 -3
- package/dist/i3s-attributes-worker.js.map +3 -3
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +12 -0
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/batch-ids-extensions.js +127 -0
- package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.js +16 -11
- package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/gltf-attributes.js +13 -0
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.js +4 -1
- package/dist/i3s-converter/types.d.ts +48 -0
- package/dist/i3s-converter/types.d.ts.map +1 -1
- package/dist/lib/utils/write-queue.d.ts.map +1 -1
- package/dist/lib/utils/write-queue.js +3 -4
- package/package.json +16 -16
- package/src/converter-cli.ts +33 -7
- package/src/i3s-converter/helpers/batch-ids-extensions.ts +182 -0
- package/src/i3s-converter/helpers/geometry-converter.ts +26 -11
- package/src/i3s-converter/helpers/gltf-attributes.ts +15 -0
- package/src/i3s-converter/i3s-converter.ts +13 -6
- package/src/i3s-converter/types.ts +51 -0
- package/src/lib/utils/write-queue.ts +7 -5
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type {GLTFAccessorPostprocessed} from 'modules/gltf/src/lib/types/gltf-types';
|
|
2
|
+
import type {Image, MeshPrimitive} from 'modules/gltf/src/lib/types/gltf-postprocessed-schema';
|
|
3
|
+
import type {ExtFeatureMetadata, ExtFeatureMetadataAttribute} from '../types';
|
|
4
|
+
|
|
5
|
+
const EXT_MESH_FEATURES = 'EXT_mesh_features';
|
|
6
|
+
const EXT_FEATURE_METADATA = 'EXT_feature_metadata';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Getting batchIds from 3DTilesNext extensions.
|
|
10
|
+
* @param attributes
|
|
11
|
+
* @param primitive
|
|
12
|
+
* @param textures
|
|
13
|
+
*/
|
|
14
|
+
export function handleBatchIdsExtensions(
|
|
15
|
+
attributes: {
|
|
16
|
+
[key: string]: GLTFAccessorPostprocessed;
|
|
17
|
+
},
|
|
18
|
+
primitive: MeshPrimitive,
|
|
19
|
+
images: Image[]
|
|
20
|
+
): number[] {
|
|
21
|
+
const extensions = primitive?.extensions;
|
|
22
|
+
|
|
23
|
+
if (!extensions) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
for (const [extensionName, extensionData] of Object.entries(extensions || {})) {
|
|
28
|
+
switch (extensionName) {
|
|
29
|
+
case EXT_FEATURE_METADATA:
|
|
30
|
+
return handleExtFeatureMetadataExtension(
|
|
31
|
+
attributes,
|
|
32
|
+
extensionData as ExtFeatureMetadata,
|
|
33
|
+
images
|
|
34
|
+
);
|
|
35
|
+
case EXT_MESH_FEATURES:
|
|
36
|
+
console.warn('EXT_mesh_features extension is not supported yet');
|
|
37
|
+
return [];
|
|
38
|
+
default:
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get batchIds from EXT_feature_metadata extension.
|
|
48
|
+
* Docs - https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata
|
|
49
|
+
* @param attributes
|
|
50
|
+
* @param extFeatureMetadata
|
|
51
|
+
* @param textures
|
|
52
|
+
*/
|
|
53
|
+
function handleExtFeatureMetadataExtension(
|
|
54
|
+
attributes: {
|
|
55
|
+
[key: string]: GLTFAccessorPostprocessed;
|
|
56
|
+
},
|
|
57
|
+
extFeatureMetadata: ExtFeatureMetadata,
|
|
58
|
+
images: Image[]
|
|
59
|
+
): number[] {
|
|
60
|
+
// Take only first extension object to get batchIds attribute name.
|
|
61
|
+
const featureIdAttribute = extFeatureMetadata?.featureIdAttributes?.[0];
|
|
62
|
+
|
|
63
|
+
if (featureIdAttribute?.featureIds?.attribute) {
|
|
64
|
+
const batchIdsAttribute = attributes[featureIdAttribute.featureIds.attribute];
|
|
65
|
+
return batchIdsAttribute.value;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (
|
|
69
|
+
featureIdAttribute?.featureIds?.hasOwnProperty('constant') &&
|
|
70
|
+
featureIdAttribute?.featureIds?.hasOwnProperty('divisor')
|
|
71
|
+
) {
|
|
72
|
+
const featuresCount = attributes?.POSITIONS?.value.length / 3 || 0;
|
|
73
|
+
return generateImplicitFeatureIds(
|
|
74
|
+
featuresCount,
|
|
75
|
+
featureIdAttribute.featureIds.constant,
|
|
76
|
+
featureIdAttribute.featureIds.divisor
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Take only first extension object to get batchIds attribute name.
|
|
81
|
+
const featureIdTexture =
|
|
82
|
+
extFeatureMetadata?.featureIdTextures && extFeatureMetadata?.featureIdTextures[0];
|
|
83
|
+
|
|
84
|
+
if (featureIdTexture) {
|
|
85
|
+
const textureCoordinates = attributes.TEXCOORD_0.value;
|
|
86
|
+
return generateBatchIdsFromTexture(featureIdTexture, textureCoordinates, images);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Generates implicit feature ids
|
|
94
|
+
* Spec - https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata#implicit-feature-ids
|
|
95
|
+
* @param featuresCount
|
|
96
|
+
* @param constant
|
|
97
|
+
* @param devisor
|
|
98
|
+
*/
|
|
99
|
+
function generateImplicitFeatureIds(
|
|
100
|
+
featuresCount: number,
|
|
101
|
+
constant: number = 0,
|
|
102
|
+
divisor: number = 0
|
|
103
|
+
): number[] {
|
|
104
|
+
let featureIds: number[] = [];
|
|
105
|
+
|
|
106
|
+
if (divisor > 0) {
|
|
107
|
+
let currentValue = constant;
|
|
108
|
+
let devisorCounter = divisor;
|
|
109
|
+
|
|
110
|
+
for (let index = 0; index < featuresCount; index++) {
|
|
111
|
+
featureIds.push(currentValue);
|
|
112
|
+
|
|
113
|
+
devisorCounter -= 1;
|
|
114
|
+
|
|
115
|
+
if (devisorCounter === 0) {
|
|
116
|
+
currentValue++;
|
|
117
|
+
devisorCounter = divisor;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
featureIds = Array<number>(featuresCount).fill(constant, 0, featuresCount);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return featureIds;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get batchIds from texture.
|
|
129
|
+
* @param primitive
|
|
130
|
+
* @param featureIdTextures
|
|
131
|
+
*/
|
|
132
|
+
function generateBatchIdsFromTexture(
|
|
133
|
+
featureIdTexture: ExtFeatureMetadataAttribute,
|
|
134
|
+
textureCoordinates: Float32Array,
|
|
135
|
+
images: Image[]
|
|
136
|
+
) {
|
|
137
|
+
const CHANNELS_MAP = {
|
|
138
|
+
r: 0,
|
|
139
|
+
g: 1,
|
|
140
|
+
b: 2,
|
|
141
|
+
a: 3
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const textureIndex = featureIdTexture?.featureIds?.texture?.index;
|
|
145
|
+
const featureChannel = featureIdTexture?.featureIds?.channels;
|
|
146
|
+
|
|
147
|
+
if (!featureChannel || textureIndex === undefined) {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const image = images[textureIndex];
|
|
152
|
+
const batchIds: number[] = [];
|
|
153
|
+
const channels = CHANNELS_MAP[featureChannel];
|
|
154
|
+
|
|
155
|
+
if (!image.compressed) {
|
|
156
|
+
for (let index = 0; index < textureCoordinates.length; index += 2) {
|
|
157
|
+
const u = textureCoordinates[index];
|
|
158
|
+
const v = textureCoordinates[index + 1];
|
|
159
|
+
|
|
160
|
+
const tx = Math.min((emod(u) * image.width) | 0, image.width - 1);
|
|
161
|
+
const ty = Math.min((emod(v) * image.height) | 0, image.height - 1);
|
|
162
|
+
|
|
163
|
+
const offset = (ty * image.width + tx) * image.components + channels;
|
|
164
|
+
const batchId = new Uint8Array(image.data)[offset];
|
|
165
|
+
|
|
166
|
+
batchIds.push(batchId);
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
console.warn(`Can't get batch Ids from ${image.mimeType} compressed texture`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return batchIds;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Handle UVs if they are out of range [0,1].
|
|
177
|
+
* @param n
|
|
178
|
+
* @param m
|
|
179
|
+
*/
|
|
180
|
+
function emod(n: number): number {
|
|
181
|
+
return ((n % 1) + 1) % 1;
|
|
182
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type {Image, MeshPrimitive} from 'modules/gltf/src/lib/types/gltf-postprocessed-schema';
|
|
2
|
+
|
|
1
3
|
import {Vector3, Matrix4, Vector4} from '@math.gl/core';
|
|
2
4
|
import {Ellipsoid} from '@math.gl/geospatial';
|
|
3
5
|
|
|
@@ -30,6 +32,7 @@ import {
|
|
|
30
32
|
} from 'modules/gltf/src/lib/types/gltf-types';
|
|
31
33
|
import {B3DMAttributesData /*transformI3SAttributesOnWorker */} from '../../i3s-attributes-worker';
|
|
32
34
|
import {prepareDataForAttributesConversion} from './gltf-attributes';
|
|
35
|
+
import {handleBatchIdsExtensions} from './batch-ids-extensions';
|
|
33
36
|
|
|
34
37
|
// Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.7/pbrMetallicRoughness.cmn.md
|
|
35
38
|
const DEFAULT_ROUGHNESS_FACTOR = 1;
|
|
@@ -407,9 +410,12 @@ function convertNode(
|
|
|
407
410
|
const transformationMatrix = getCompositeTransformationMatrix(node, matrix);
|
|
408
411
|
|
|
409
412
|
const mesh = node.mesh;
|
|
413
|
+
const images = node.images;
|
|
414
|
+
|
|
410
415
|
if (mesh) {
|
|
411
416
|
convertMesh(
|
|
412
417
|
mesh,
|
|
418
|
+
images,
|
|
413
419
|
cartographicOrigin,
|
|
414
420
|
cartesianModelMatrix,
|
|
415
421
|
attributesMap,
|
|
@@ -441,6 +447,7 @@ function convertNode(
|
|
|
441
447
|
*/
|
|
442
448
|
function convertMesh(
|
|
443
449
|
mesh: GLTFMeshPostprocessed,
|
|
450
|
+
images: Image[],
|
|
444
451
|
cartographicOrigin: Vector3,
|
|
445
452
|
cartesianModelMatrix: Matrix4,
|
|
446
453
|
attributesMap: Map<string, ConvertedAttributes>,
|
|
@@ -498,7 +505,7 @@ function convertMesh(
|
|
|
498
505
|
|
|
499
506
|
outputAttributes.featureIndicesGroups = outputAttributes.featureIndicesGroups || [];
|
|
500
507
|
outputAttributes.featureIndicesGroups.push(
|
|
501
|
-
flattenBatchIds(
|
|
508
|
+
flattenBatchIds(getBatchIds(attributes, primitive, images), primitive.indices?.value)
|
|
502
509
|
);
|
|
503
510
|
}
|
|
504
511
|
}
|
|
@@ -665,14 +672,23 @@ function flattenBatchIds(batchedIds: number[], indices: Uint8Array): number[] {
|
|
|
665
672
|
}
|
|
666
673
|
|
|
667
674
|
/**
|
|
668
|
-
*
|
|
669
|
-
* @param attributes
|
|
670
|
-
* @
|
|
675
|
+
* Get batchIds for featureIds creation
|
|
676
|
+
* @param attributes
|
|
677
|
+
* @param primitive
|
|
678
|
+
* @param textures
|
|
671
679
|
*/
|
|
672
|
-
function
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
680
|
+
function getBatchIds(
|
|
681
|
+
attributes: {
|
|
682
|
+
[key: string]: GLTFAccessorPostprocessed;
|
|
683
|
+
},
|
|
684
|
+
primitive: MeshPrimitive,
|
|
685
|
+
images: Image[]
|
|
686
|
+
): number[] {
|
|
687
|
+
const batchIds: number[] = handleBatchIdsExtensions(attributes, primitive, images);
|
|
688
|
+
|
|
689
|
+
if (batchIds.length) {
|
|
690
|
+
return batchIds;
|
|
691
|
+
}
|
|
676
692
|
|
|
677
693
|
for (let index = 0; index < BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES.length; index++) {
|
|
678
694
|
const possibleBatchIdAttributeName = BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES[index];
|
|
@@ -680,12 +696,11 @@ function getBatchIdsByAttributeName(attributes: {
|
|
|
680
696
|
attributes[possibleBatchIdAttributeName] &&
|
|
681
697
|
attributes[possibleBatchIdAttributeName].value
|
|
682
698
|
) {
|
|
683
|
-
|
|
684
|
-
break;
|
|
699
|
+
return attributes[possibleBatchIdAttributeName].value;
|
|
685
700
|
}
|
|
686
701
|
}
|
|
687
702
|
|
|
688
|
-
return
|
|
703
|
+
return [];
|
|
689
704
|
}
|
|
690
705
|
|
|
691
706
|
/**
|
|
@@ -35,6 +35,20 @@ export function prepareDataForAttributesConversion(tileContent: B3DMContent): B3
|
|
|
35
35
|
tileContent.gltf?.nodes ||
|
|
36
36
|
[];
|
|
37
37
|
|
|
38
|
+
const images =
|
|
39
|
+
tileContent.gltf?.images?.map((imageObject) => {
|
|
40
|
+
// Need data only for uncompressed images because we can't get batchIds from compressed textures.
|
|
41
|
+
const data = imageObject?.image?.compressed ? null : imageObject?.image?.data.subarray();
|
|
42
|
+
return {
|
|
43
|
+
data,
|
|
44
|
+
compressed: Boolean(imageObject?.image?.compressed),
|
|
45
|
+
height: imageObject.image.height,
|
|
46
|
+
width: imageObject.image.width,
|
|
47
|
+
components: imageObject.image.components,
|
|
48
|
+
mimeType: imageObject.mimeType
|
|
49
|
+
};
|
|
50
|
+
}) || [];
|
|
51
|
+
|
|
38
52
|
const prepearedNodes = nodes.map((node) => {
|
|
39
53
|
if (!node.mesh) {
|
|
40
54
|
return node;
|
|
@@ -42,6 +56,7 @@ export function prepareDataForAttributesConversion(tileContent: B3DMContent): B3
|
|
|
42
56
|
|
|
43
57
|
return {
|
|
44
58
|
...node,
|
|
59
|
+
images,
|
|
45
60
|
mesh: {
|
|
46
61
|
...node.mesh,
|
|
47
62
|
primitives: node.mesh?.primitives.map((primitive) => ({
|
|
@@ -938,12 +938,19 @@ export default class I3SConverter {
|
|
|
938
938
|
|
|
939
939
|
if (this.generateTextures) {
|
|
940
940
|
formats.push({name: '1', format: 'ktx2'});
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
941
|
+
// For Node.js texture.image.data is type of Buffer
|
|
942
|
+
const copyArrayBuffer = texture.image.data.subarray();
|
|
943
|
+
const arrayToEncode = new Uint8Array(copyArrayBuffer);
|
|
944
|
+
const ktx2TextureData = encode(
|
|
945
|
+
{...texture.image, data: arrayToEncode},
|
|
946
|
+
KTX2BasisWriterWorker,
|
|
947
|
+
{
|
|
948
|
+
...KTX2BasisWriterWorker.options,
|
|
949
|
+
source: this.workerSource.ktx2,
|
|
950
|
+
reuseWorkers: true,
|
|
951
|
+
_nodeWorkers: true
|
|
952
|
+
}
|
|
953
|
+
);
|
|
947
954
|
|
|
948
955
|
await this.writeTextureFile(ktx2TextureData, '1', 'ktx2', childPath, slpkChildPath);
|
|
949
956
|
}
|
|
@@ -122,3 +122,54 @@ export type I3SMaterialWithTexture = {
|
|
|
122
122
|
/** Texture content (image) */
|
|
123
123
|
texture?: ImageDataType;
|
|
124
124
|
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* 3DTilesNext EXT_feature_metadata extension
|
|
128
|
+
* Spec - https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata
|
|
129
|
+
*/
|
|
130
|
+
export type ExtFeatureMetadata = {
|
|
131
|
+
/** Feature ids definition in attributes */
|
|
132
|
+
featureIdAttributes?: ExtFeatureMetadataAttribute[];
|
|
133
|
+
/** Feature ids definition in textures */
|
|
134
|
+
featureIdTextures?: ExtFeatureMetadataAttribute[];
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Attribute which described featureIds definition.
|
|
139
|
+
*/
|
|
140
|
+
export type ExtFeatureMetadataAttribute = {
|
|
141
|
+
/** Name of feature table */
|
|
142
|
+
featureTable: string;
|
|
143
|
+
/** Described how feature ids are defined */
|
|
144
|
+
featureIds: ExtFeatureMetadataFeatureIds;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Defining featureIds by attributes or implicitly.
|
|
149
|
+
*/
|
|
150
|
+
type ExtFeatureMetadataFeatureIds = {
|
|
151
|
+
/** Name of attribute where featureIds are defined */
|
|
152
|
+
attribute?: string;
|
|
153
|
+
/** Sets a constant feature ID for each vertex. The default is 0. */
|
|
154
|
+
constant?: number;
|
|
155
|
+
/** Sets the rate at which feature IDs increment.
|
|
156
|
+
* If divisor is zero then constant is used.
|
|
157
|
+
* If divisor is greater than zero the feature ID increments once per divisor sets of vertices, starting at constant.
|
|
158
|
+
* The default is 0
|
|
159
|
+
*/
|
|
160
|
+
divisor?: number;
|
|
161
|
+
/** gLTF textureInfo object - https://github.com/CesiumGS/glTF/blob/3d-tiles-next/specification/2.0/schema/textureInfo.schema.json */
|
|
162
|
+
texture?: ExtFeatureMetadataTexture;
|
|
163
|
+
/** Must be a single channel ("r", "g", "b", or "a") */
|
|
164
|
+
channels?: 'r' | 'g' | 'b' | 'a';
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Reference to a texture.
|
|
169
|
+
*/
|
|
170
|
+
type ExtFeatureMetadataTexture = {
|
|
171
|
+
/** The set index of texture's TEXCOORD attribute used for texture coordinate mapping.*/
|
|
172
|
+
texCoord: number;
|
|
173
|
+
/** The index of the texture. */
|
|
174
|
+
index: number;
|
|
175
|
+
};
|
|
@@ -57,19 +57,21 @@ export default class WriteQueue<T extends WriteQueueItem> extends Queue<T> {
|
|
|
57
57
|
archiveKeys.push(archiveKey);
|
|
58
58
|
promises.push(writePromise);
|
|
59
59
|
}
|
|
60
|
-
const writeResults = await Promise.
|
|
60
|
+
const writeResults = await Promise.allSettled(promises);
|
|
61
61
|
this.updateFileMap(archiveKeys, writeResults);
|
|
62
62
|
}
|
|
63
63
|
this.writePromise = null;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
private updateFileMap(
|
|
66
|
+
private updateFileMap(
|
|
67
|
+
archiveKeys: (string | undefined)[],
|
|
68
|
+
writeResults: PromiseSettledResult<string>[]
|
|
69
|
+
) {
|
|
67
70
|
for (let i = 0; i < archiveKeys.length; i++) {
|
|
68
71
|
const archiveKey = archiveKeys[i];
|
|
69
|
-
if (
|
|
70
|
-
|
|
72
|
+
if (archiveKey && 'value' in writeResults[i]) {
|
|
73
|
+
this.fileMap[archiveKey] = (writeResults[i] as PromiseFulfilledResult<string>).value;
|
|
71
74
|
}
|
|
72
|
-
this.fileMap[archiveKey] = writeResults[i];
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
77
|
}
|