@loaders.gl/tile-converter 4.0.0-alpha.18 → 4.0.0-alpha.20
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/bin/converter.js +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/converter-cli.js +10 -2
- package/dist/converter.min.js +172 -103
- package/dist/deps-installer/deps-installer.d.ts +3 -2
- package/dist/deps-installer/deps-installer.d.ts.map +1 -1
- package/dist/deps-installer/deps-installer.js +36 -10
- package/dist/dist.min.js +226 -151
- package/dist/es5/constants.js +5 -1
- package/dist/es5/constants.js.map +1 -1
- package/dist/es5/converter-cli.js +7 -2
- package/dist/es5/converter-cli.js.map +1 -1
- package/dist/es5/deps-installer/deps-installer.js +112 -38
- package/dist/es5/deps-installer/deps-installer.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js +21 -8
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js +7 -6
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-converter.js +78 -67
- package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js +38 -9
- package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -1
- package/dist/es5/i3s-converter/i3s-converter.js +86 -99
- package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/es5/i3s-converter/types.js +11 -11
- package/dist/es5/i3s-converter/types.js.map +1 -1
- package/dist/es5/i3s-server/controllers/slpk-controller.js +1 -1
- package/dist/es5/i3s-server/controllers/slpk-controller.js.map +1 -1
- package/dist/es5/index.js +3 -3
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/pgm-loader.js +1 -1
- package/dist/es5/slpk-extractor/helpers/{file-handle-provider.js → file-handle-file.js} +9 -9
- package/dist/es5/slpk-extractor/helpers/file-handle-file.js.map +1 -0
- package/dist/es5/slpk-extractor/slpk-extractor.js +5 -5
- package/dist/es5/slpk-extractor/slpk-extractor.js.map +1 -1
- package/dist/esm/constants.js +2 -0
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/converter-cli.js +7 -2
- package/dist/esm/converter-cli.js.map +1 -1
- package/dist/esm/deps-installer/deps-installer.js +37 -11
- package/dist/esm/deps-installer/deps-installer.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js +18 -6
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js +7 -6
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-converter.js +37 -25
- package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js +28 -9
- package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -1
- package/dist/esm/i3s-converter/i3s-converter.js +49 -36
- package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/esm/i3s-converter/types.js +9 -9
- package/dist/esm/i3s-converter/types.js.map +1 -1
- package/dist/esm/i3s-server/bin/i3s-server.min.js +71 -71
- package/dist/esm/i3s-server/controllers/slpk-controller.js +2 -2
- package/dist/esm/i3s-server/controllers/slpk-controller.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/pgm-loader.js +1 -1
- package/dist/esm/slpk-extractor/helpers/{file-handle-provider.js → file-handle-file.js} +3 -3
- package/dist/esm/slpk-extractor/helpers/file-handle-file.js.map +1 -0
- package/dist/esm/slpk-extractor/slpk-extractor.js +3 -3
- package/dist/esm/slpk-extractor/slpk-extractor.js.map +1 -1
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +11 -1
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/batch-ids-extensions.js +33 -13
- package/dist/i3s-converter/helpers/geometry-attributes.js +7 -6
- package/dist/i3s-converter/helpers/geometry-converter.d.ts +7 -6
- package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.js +59 -47
- package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts +2 -2
- package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/preprocess-3d-tiles.js +39 -14
- package/dist/i3s-converter/i3s-converter.d.ts +2 -1
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.js +49 -31
- package/dist/i3s-converter/types.d.ts +4 -2
- package/dist/i3s-converter/types.d.ts.map +1 -1
- package/dist/i3s-converter/types.js +11 -11
- package/dist/i3s-server/controllers/slpk-controller.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/slpk-extractor/helpers/{file-handle-provider.d.ts → file-handle-file.d.ts} +5 -5
- package/dist/slpk-extractor/helpers/file-handle-file.d.ts.map +1 -0
- package/dist/slpk-extractor/helpers/{file-handle-provider.js → file-handle-file.js} +5 -5
- package/dist/slpk-extractor/slpk-extractor.js +5 -5
- package/dist/slpk-extractor.min.js +32 -32
- package/package.json +15 -14
- package/src/constants.ts +3 -0
- package/src/converter-cli.ts +9 -2
- package/src/deps-installer/deps-installer.ts +55 -10
- package/src/i3s-converter/helpers/batch-ids-extensions.ts +39 -12
- package/src/i3s-converter/helpers/geometry-attributes.ts +15 -8
- package/src/i3s-converter/helpers/geometry-converter.ts +84 -48
- package/src/i3s-converter/helpers/preprocess-3d-tiles.ts +48 -18
- package/src/i3s-converter/i3s-converter.ts +65 -39
- package/src/i3s-converter/types.ts +4 -2
- package/src/i3s-server/controllers/slpk-controller.ts +2 -2
- package/src/index.ts +1 -1
- package/src/slpk-extractor/helpers/{file-handle-provider.ts → file-handle-file.ts} +5 -5
- package/src/slpk-extractor/slpk-extractor.ts +3 -3
- package/dist/es5/slpk-extractor/helpers/file-handle-provider.js.map +0 -1
- package/dist/esm/slpk-extractor/helpers/file-handle-provider.js.map +0 -1
- package/dist/slpk-extractor/helpers/file-handle-provider.d.ts.map +0 -1
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
import {NumberArray, TypedArray} from '@loaders.gl/loader-utils';
|
|
36
36
|
import {Geoid} from '@math.gl/geoid';
|
|
37
37
|
import {prepareDataForAttributesConversion} from './gltf-attributes';
|
|
38
|
-
import {handleBatchIdsExtensions} from './batch-ids-extensions';
|
|
38
|
+
import {getTextureByMetadataClass, handleBatchIdsExtensions} from './batch-ids-extensions';
|
|
39
39
|
import {checkPropertiesLength, flattenPropertyTableByFeatureIds} from './feature-attributes';
|
|
40
40
|
import {GL} from '@loaders.gl/math';
|
|
41
41
|
|
|
@@ -47,6 +47,7 @@ import {GL} from '@loaders.gl/math';
|
|
|
47
47
|
import type {GLTFAttributesData, TextureImageProperties, TypedArrayConstructor} from '../types';
|
|
48
48
|
import {generateSyntheticIndices} from '../../lib/utils/geometry-utils';
|
|
49
49
|
import {BoundingSphere, OrientedBoundingBox} from '@math.gl/culling';
|
|
50
|
+
import {EXT_FEATURE_METADATA, EXT_MESH_FEATURES} from '../../constants';
|
|
50
51
|
|
|
51
52
|
// Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.7/pbrMetallicRoughness.cmn.md
|
|
52
53
|
const DEFAULT_ROUGHNESS_FACTOR = 1;
|
|
@@ -67,9 +68,6 @@ const OBJECT_ID_TYPE = 'Oid32';
|
|
|
67
68
|
*/
|
|
68
69
|
const BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES = ['CUSTOM_ATTRIBUTE_2', '_BATCHID', 'BATCHID'];
|
|
69
70
|
|
|
70
|
-
const EXT_FEATURE_METADATA = 'EXT_feature_metadata';
|
|
71
|
-
const EXT_MESH_FEATURES = 'EXT_mesh_features';
|
|
72
|
-
|
|
73
71
|
let scratchVector = new Vector3();
|
|
74
72
|
|
|
75
73
|
/**
|
|
@@ -87,7 +85,8 @@ let scratchVector = new Vector3();
|
|
|
87
85
|
* @param generateBoundingVolumes - is converter should create accurate bounding voulmes from geometry attributes
|
|
88
86
|
* @param shouldMergeMaterials - Try to merge similar materials to be able to merge meshes into one node
|
|
89
87
|
* @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
|
|
90
|
-
* @param
|
|
88
|
+
* @param libraries - dynamicaly loaded 3rd-party libraries
|
|
89
|
+
* @param metadataClass `- user selected feature metadata class name`
|
|
91
90
|
* @returns Array of node resources to create one or more i3s nodes
|
|
92
91
|
*/
|
|
93
92
|
export default async function convertB3dmToI3sGeometry(
|
|
@@ -102,7 +101,8 @@ export default async function convertB3dmToI3sGeometry(
|
|
|
102
101
|
generateBoundingVolumes: boolean,
|
|
103
102
|
shouldMergeMaterials: boolean,
|
|
104
103
|
geoidHeightModel: Geoid,
|
|
105
|
-
|
|
104
|
+
libraries: Record<string, string>,
|
|
105
|
+
metadataClass?: string
|
|
106
106
|
): Promise<I3SConvertedResources[] | null> {
|
|
107
107
|
const useCartesianPositions = generateBoundingVolumes;
|
|
108
108
|
const materialAndTextureList: I3SMaterialWithTexture[] = await convertMaterials(
|
|
@@ -115,10 +115,12 @@ export default async function convertB3dmToI3sGeometry(
|
|
|
115
115
|
tileTransform,
|
|
116
116
|
tileBoundingVolume
|
|
117
117
|
);
|
|
118
|
+
const featureTexture = getTextureByMetadataClass(tileContent, metadataClass);
|
|
118
119
|
const convertedAttributesMap: Map<string, ConvertedAttributes> = await convertAttributes(
|
|
119
120
|
dataForAttributesConversion,
|
|
120
121
|
materialAndTextureList,
|
|
121
|
-
useCartesianPositions
|
|
122
|
+
useCartesianPositions,
|
|
123
|
+
featureTexture
|
|
122
124
|
);
|
|
123
125
|
/** Usage of worker here brings more overhead than advantage */
|
|
124
126
|
// const convertedAttributesMap: Map<string, ConvertedAttributes> =
|
|
@@ -156,7 +158,7 @@ export default async function convertB3dmToI3sGeometry(
|
|
|
156
158
|
propertyTable,
|
|
157
159
|
attributeStorageInfo,
|
|
158
160
|
draco,
|
|
159
|
-
|
|
161
|
+
libraries
|
|
160
162
|
})
|
|
161
163
|
);
|
|
162
164
|
}
|
|
@@ -208,7 +210,7 @@ function _generateBoundingVolumesFromGeometry(
|
|
|
208
210
|
* @param params.propertyTable - batch table (corresponding to feature attributes data)
|
|
209
211
|
* @param params.attributeStorageInfo - attributes metadata from 3DSceneLayer json
|
|
210
212
|
* @param params.draco - is converter should create draco compressed geometry
|
|
211
|
-
* @param
|
|
213
|
+
* @param libraries - dynamicaly loaded 3rd-party libraries
|
|
212
214
|
* @returns Array of I3S node resources
|
|
213
215
|
*/
|
|
214
216
|
async function _makeNodeResources({
|
|
@@ -221,7 +223,7 @@ async function _makeNodeResources({
|
|
|
221
223
|
propertyTable,
|
|
222
224
|
attributeStorageInfo,
|
|
223
225
|
draco,
|
|
224
|
-
|
|
226
|
+
libraries
|
|
225
227
|
}: {
|
|
226
228
|
convertedAttributes: ConvertedAttributes;
|
|
227
229
|
material: I3SMaterialDefinition;
|
|
@@ -232,7 +234,7 @@ async function _makeNodeResources({
|
|
|
232
234
|
propertyTable: FeatureTableJson | null;
|
|
233
235
|
attributeStorageInfo?: AttributeStorageInfo[];
|
|
234
236
|
draco: boolean;
|
|
235
|
-
|
|
237
|
+
libraries: Record<string, string>;
|
|
236
238
|
}): Promise<I3SConvertedResources> {
|
|
237
239
|
const boundingVolumes = convertedAttributes.boundingVolumes;
|
|
238
240
|
const vertexCount = convertedAttributes.positions.length / VALUES_PER_VERTEX;
|
|
@@ -277,7 +279,7 @@ async function _makeNodeResources({
|
|
|
277
279
|
featureIds,
|
|
278
280
|
faceRange
|
|
279
281
|
},
|
|
280
|
-
|
|
282
|
+
libraries
|
|
281
283
|
)
|
|
282
284
|
: null;
|
|
283
285
|
|
|
@@ -312,12 +314,14 @@ async function _makeNodeResources({
|
|
|
312
314
|
* @param materialAndTextureList - array of data about materials and textures of the content
|
|
313
315
|
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
314
316
|
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
317
|
+
* @param featureTexture - feature texture key
|
|
315
318
|
* @returns map of converted geometry attributes
|
|
316
319
|
*/
|
|
317
320
|
export async function convertAttributes(
|
|
318
321
|
attributesData: GLTFAttributesData,
|
|
319
322
|
materialAndTextureList: I3SMaterialWithTexture[],
|
|
320
|
-
useCartesianPositions: boolean
|
|
323
|
+
useCartesianPositions: boolean,
|
|
324
|
+
featureTexture: string | null
|
|
321
325
|
): Promise<Map<string, ConvertedAttributes>> {
|
|
322
326
|
const {nodes, images, cartographicOrigin, cartesianModelMatrix} = attributesData;
|
|
323
327
|
const attributesMap = new Map<string, ConvertedAttributes>();
|
|
@@ -345,7 +349,9 @@ export async function convertAttributes(
|
|
|
345
349
|
cartographicOrigin,
|
|
346
350
|
cartesianModelMatrix,
|
|
347
351
|
attributesMap,
|
|
348
|
-
useCartesianPositions
|
|
352
|
+
useCartesianPositions,
|
|
353
|
+
undefined,
|
|
354
|
+
featureTexture
|
|
349
355
|
);
|
|
350
356
|
|
|
351
357
|
for (const attrKey of attributesMap.keys()) {
|
|
@@ -379,6 +385,7 @@ export async function convertAttributes(
|
|
|
379
385
|
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
380
386
|
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
381
387
|
* @param matrix - transformation matrix - cumulative transformation matrix formed from all parent node matrices
|
|
388
|
+
* @param featureTexture - feature texture key
|
|
382
389
|
* @returns {void}
|
|
383
390
|
*/
|
|
384
391
|
function convertNodes(
|
|
@@ -388,7 +395,8 @@ function convertNodes(
|
|
|
388
395
|
cartesianModelMatrix: Matrix4,
|
|
389
396
|
attributesMap: Map<string, ConvertedAttributes>,
|
|
390
397
|
useCartesianPositions: boolean,
|
|
391
|
-
matrix: Matrix4 = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
|
|
398
|
+
matrix: Matrix4 = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
|
|
399
|
+
featureTexture: string | null
|
|
392
400
|
) {
|
|
393
401
|
if (nodes) {
|
|
394
402
|
for (const node of nodes) {
|
|
@@ -399,7 +407,8 @@ function convertNodes(
|
|
|
399
407
|
cartesianModelMatrix,
|
|
400
408
|
attributesMap,
|
|
401
409
|
useCartesianPositions,
|
|
402
|
-
matrix
|
|
410
|
+
matrix,
|
|
411
|
+
featureTexture
|
|
403
412
|
);
|
|
404
413
|
}
|
|
405
414
|
}
|
|
@@ -441,11 +450,12 @@ function getCompositeTransformationMatrix(node: GLTFNodePostprocessed, matrix: M
|
|
|
441
450
|
* @param images - gltf images array
|
|
442
451
|
* @param cartographicOrigin - cartographic origin of bounding volume
|
|
443
452
|
* @param cartesianModelMatrix - cartesian model matrix to convert coordinates to cartographic
|
|
444
|
-
* @param
|
|
453
|
+
* @param attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
|
|
445
454
|
* attributes
|
|
446
455
|
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
447
456
|
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
448
|
-
* @param
|
|
457
|
+
* @param matrix - transformation matrix - cumulative transformation matrix formed from all parent node matrices
|
|
458
|
+
* @param featureTexture - feature texture key
|
|
449
459
|
*/
|
|
450
460
|
function convertNode(
|
|
451
461
|
node: GLTFNodePostprocessed,
|
|
@@ -454,7 +464,8 @@ function convertNode(
|
|
|
454
464
|
cartesianModelMatrix: Matrix4,
|
|
455
465
|
attributesMap: Map<string, ConvertedAttributes>,
|
|
456
466
|
useCartesianPositions,
|
|
457
|
-
matrix = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
|
|
467
|
+
matrix = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
|
|
468
|
+
featureTexture: string | null
|
|
458
469
|
) {
|
|
459
470
|
const transformationMatrix = getCompositeTransformationMatrix(node, matrix);
|
|
460
471
|
|
|
@@ -468,7 +479,8 @@ function convertNode(
|
|
|
468
479
|
cartesianModelMatrix,
|
|
469
480
|
attributesMap,
|
|
470
481
|
useCartesianPositions,
|
|
471
|
-
transformationMatrix
|
|
482
|
+
transformationMatrix,
|
|
483
|
+
featureTexture
|
|
472
484
|
);
|
|
473
485
|
}
|
|
474
486
|
|
|
@@ -479,7 +491,8 @@ function convertNode(
|
|
|
479
491
|
cartesianModelMatrix,
|
|
480
492
|
attributesMap,
|
|
481
493
|
useCartesianPositions,
|
|
482
|
-
transformationMatrix
|
|
494
|
+
transformationMatrix,
|
|
495
|
+
featureTexture
|
|
483
496
|
);
|
|
484
497
|
}
|
|
485
498
|
|
|
@@ -491,12 +504,12 @@ function convertNode(
|
|
|
491
504
|
* @param cartesianModelMatrix - cartesian model matrix to convert coordinates to cartographic
|
|
492
505
|
* @param attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
|
|
493
506
|
* attributes
|
|
494
|
-
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
507
|
+
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
495
508
|
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
496
509
|
* @param attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
|
|
497
510
|
* attributes
|
|
498
|
-
|
|
499
|
-
* @param
|
|
511
|
+
* @param matrix - transformation matrix - cumulative transformation matrix formed from all parent node matrices
|
|
512
|
+
* @param featureTexture - feature texture key
|
|
500
513
|
*/
|
|
501
514
|
function convertMesh(
|
|
502
515
|
mesh: GLTFMeshPostprocessed,
|
|
@@ -505,7 +518,8 @@ function convertMesh(
|
|
|
505
518
|
cartesianModelMatrix: Matrix4,
|
|
506
519
|
attributesMap: Map<string, ConvertedAttributes>,
|
|
507
520
|
useCartesianPositions = false,
|
|
508
|
-
matrix = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
|
|
521
|
+
matrix = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
|
|
522
|
+
featureTexture: string | null
|
|
509
523
|
) {
|
|
510
524
|
for (const primitive of mesh.primitives) {
|
|
511
525
|
let outputAttributes: ConvertedAttributes | null | undefined = null;
|
|
@@ -576,7 +590,7 @@ function convertMesh(
|
|
|
576
590
|
|
|
577
591
|
outputAttributes.featureIndicesGroups = outputAttributes.featureIndicesGroups || [];
|
|
578
592
|
outputAttributes.featureIndicesGroups.push(
|
|
579
|
-
flattenBatchIds(getBatchIds(attributes, primitive, images), indices)
|
|
593
|
+
flattenBatchIds(getBatchIds(attributes, primitive, images, featureTexture), indices)
|
|
580
594
|
);
|
|
581
595
|
}
|
|
582
596
|
}
|
|
@@ -803,15 +817,23 @@ function flattenBatchIds(batchedIds: NumberArray, indices: TypedArray): number[]
|
|
|
803
817
|
* @param attributes - gltf accessors
|
|
804
818
|
* @param primitive - gltf primitive data
|
|
805
819
|
* @param images - gltf texture images
|
|
820
|
+
* @param featureTexture - feature texture key
|
|
821
|
+
* @return batch IDs
|
|
806
822
|
*/
|
|
807
823
|
function getBatchIds(
|
|
808
824
|
attributes: {
|
|
809
825
|
[key: string]: GLTFAccessorPostprocessed;
|
|
810
826
|
},
|
|
811
827
|
primitive: GLTFMeshPrimitivePostprocessed,
|
|
812
|
-
images: (TextureImageProperties | null)[]
|
|
828
|
+
images: (TextureImageProperties | null)[],
|
|
829
|
+
featureTexture: string | null
|
|
813
830
|
): NumberArray {
|
|
814
|
-
const batchIds: NumberArray = handleBatchIdsExtensions(
|
|
831
|
+
const batchIds: NumberArray = handleBatchIdsExtensions(
|
|
832
|
+
attributes,
|
|
833
|
+
primitive,
|
|
834
|
+
images,
|
|
835
|
+
featureTexture
|
|
836
|
+
);
|
|
815
837
|
|
|
816
838
|
if (batchIds.length) {
|
|
817
839
|
return batchIds;
|
|
@@ -1451,17 +1473,17 @@ function generateBigUint64Array(featureIds: any[]): BigUint64Array {
|
|
|
1451
1473
|
|
|
1452
1474
|
/**
|
|
1453
1475
|
* Generates draco compressed geometry
|
|
1454
|
-
* @param
|
|
1455
|
-
* @param
|
|
1456
|
-
* @param
|
|
1457
|
-
* @param
|
|
1458
|
-
* @returns
|
|
1476
|
+
* @param vertexCount
|
|
1477
|
+
* @param convertedAttributes - get rid of this argument here
|
|
1478
|
+
* @param attributes - geometry attributes to compress
|
|
1479
|
+
* @param libraries - dynamicaly loaded 3rd-party libraries
|
|
1480
|
+
* @returns - Compressed geometry.
|
|
1459
1481
|
*/
|
|
1460
1482
|
async function generateCompressedGeometry(
|
|
1461
1483
|
vertexCount: number,
|
|
1462
1484
|
convertedAttributes: Record<string, any>,
|
|
1463
1485
|
attributes: Record<string, any>,
|
|
1464
|
-
|
|
1486
|
+
libraries: Record<string, string>
|
|
1465
1487
|
): Promise<ArrayBuffer> {
|
|
1466
1488
|
const {positions, normals, texCoords, colors, uvRegions, featureIds, faceRange} = attributes;
|
|
1467
1489
|
const indices = new Uint32Array(vertexCount);
|
|
@@ -1510,12 +1532,17 @@ async function generateCompressedGeometry(
|
|
|
1510
1532
|
|
|
1511
1533
|
return encode({attributes: compressedAttributes, indices}, DracoWriterWorker, {
|
|
1512
1534
|
...DracoWriterWorker.options,
|
|
1513
|
-
source: dracoWorkerSoure,
|
|
1514
1535
|
reuseWorkers: true,
|
|
1515
1536
|
_nodeWorkers: true,
|
|
1537
|
+
modules: libraries,
|
|
1538
|
+
useLocalLibraries: true,
|
|
1516
1539
|
draco: {
|
|
1517
1540
|
method: 'MESH_SEQUENTIAL_ENCODING',
|
|
1518
1541
|
attributesMetadata
|
|
1542
|
+
},
|
|
1543
|
+
['draco-writer']: {
|
|
1544
|
+
// We need to load local fs workers because nodejs can't load workers from the Internet
|
|
1545
|
+
workerUrl: './modules/draco/dist/draco-writer-worker-node.js'
|
|
1519
1546
|
}
|
|
1520
1547
|
});
|
|
1521
1548
|
}
|
|
@@ -1550,9 +1577,13 @@ function generateFeatureIndexAttribute(
|
|
|
1550
1577
|
* Find property table in tile
|
|
1551
1578
|
* For example it can be batchTable for b3dm files or property table in gLTF extension.
|
|
1552
1579
|
* @param tileContent - 3DTiles tile content
|
|
1580
|
+
* @param metadataClass - - user selected feature metadata class name
|
|
1553
1581
|
* @return batch table from b3dm / feature properties from EXT_FEATURE_METADATA
|
|
1554
1582
|
*/
|
|
1555
|
-
export function getPropertyTable(
|
|
1583
|
+
export function getPropertyTable(
|
|
1584
|
+
tileContent: Tiles3DTileContent | null,
|
|
1585
|
+
metadataClass?: string
|
|
1586
|
+
): FeatureTableJson | null {
|
|
1556
1587
|
if (!tileContent) {
|
|
1557
1588
|
return null;
|
|
1558
1589
|
}
|
|
@@ -1571,7 +1602,10 @@ export function getPropertyTable(tileContent: Tiles3DTileContent | null): Featur
|
|
|
1571
1602
|
return null;
|
|
1572
1603
|
}
|
|
1573
1604
|
case EXT_FEATURE_METADATA: {
|
|
1574
|
-
return getPropertyTableFromExtFeatureMetadata(
|
|
1605
|
+
return getPropertyTableFromExtFeatureMetadata(
|
|
1606
|
+
extension as GLTF_EXT_feature_metadata_GLTF,
|
|
1607
|
+
metadataClass
|
|
1608
|
+
);
|
|
1575
1609
|
}
|
|
1576
1610
|
default:
|
|
1577
1611
|
return null;
|
|
@@ -1614,10 +1648,11 @@ function getPropertyTableExtension(tileContent: Tiles3DTileContent): {
|
|
|
1614
1648
|
|
|
1615
1649
|
/**
|
|
1616
1650
|
* Handle EXT_feature_metadata to get property table
|
|
1617
|
-
* @param extension
|
|
1651
|
+
* @param extension - global level of EXT_FEATURE_METADATA extension
|
|
1618
1652
|
*/
|
|
1619
1653
|
function getPropertyTableFromExtFeatureMetadata(
|
|
1620
|
-
extension: GLTF_EXT_feature_metadata_GLTF
|
|
1654
|
+
extension: GLTF_EXT_feature_metadata_GLTF,
|
|
1655
|
+
metadataClass?: string
|
|
1621
1656
|
): FeatureTableJson | null {
|
|
1622
1657
|
if (extension?.featureTables) {
|
|
1623
1658
|
/**
|
|
@@ -1641,15 +1676,16 @@ function getPropertyTableFromExtFeatureMetadata(
|
|
|
1641
1676
|
}
|
|
1642
1677
|
|
|
1643
1678
|
if (extension?.featureTextures) {
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1679
|
+
let featureTexture: string | undefined;
|
|
1680
|
+
for (const textureKey in extension.featureTextures) {
|
|
1681
|
+
const texture = extension.featureTextures[textureKey];
|
|
1682
|
+
if (texture.class === metadataClass) {
|
|
1683
|
+
featureTexture = textureKey;
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
if (typeof featureTexture === 'string') {
|
|
1688
|
+
const featureTable = extension?.featureTextures[featureTexture];
|
|
1653
1689
|
const propertyTable = {};
|
|
1654
1690
|
|
|
1655
1691
|
for (const propertyName in featureTable.properties) {
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import {Tiles3DTileContent} from '@loaders.gl/3d-tiles';
|
|
2
|
-
import {
|
|
3
|
-
import {GLTF, GLTFLoader} from '@loaders.gl/gltf';
|
|
2
|
+
import {GLTFPrimitiveModeString, PreprocessData} from '../types';
|
|
3
|
+
import {GLTF, GLTFLoader, GLTF_EXT_feature_metadata_GLTF} from '@loaders.gl/gltf';
|
|
4
4
|
import {parse} from '@loaders.gl/core';
|
|
5
|
+
import {EXT_FEATURE_METADATA} from '../../constants';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* glTF primitive modes
|
|
8
9
|
* @see https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_mode
|
|
9
10
|
*/
|
|
10
11
|
export const GLTF_PRIMITIVE_MODES = [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
GLTFPrimitiveModeString.POINTS, // 0
|
|
13
|
+
GLTFPrimitiveModeString.LINES, // 1
|
|
14
|
+
GLTFPrimitiveModeString.LINE_LOOP, // 2
|
|
15
|
+
GLTFPrimitiveModeString.LINE_STRIP, // 3
|
|
16
|
+
GLTFPrimitiveModeString.TRIANGLES, // 4
|
|
17
|
+
GLTFPrimitiveModeString.TRIANGLE_STRIP, // 5
|
|
18
|
+
GLTFPrimitiveModeString.TRIANGLE_FAN // 6
|
|
18
19
|
];
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -26,11 +27,12 @@ export const GLTF_PRIMITIVE_MODES = [
|
|
|
26
27
|
export const analyzeTileContent = async (
|
|
27
28
|
tileContent: Tiles3DTileContent | null
|
|
28
29
|
): Promise<PreprocessData> => {
|
|
29
|
-
const
|
|
30
|
-
meshTopologyTypes: new Set()
|
|
30
|
+
const defaultResult = {
|
|
31
|
+
meshTopologyTypes: new Set<GLTFPrimitiveModeString>(),
|
|
32
|
+
metadataClasses: new Set<string>()
|
|
31
33
|
};
|
|
32
34
|
if (!tileContent?.gltfArrayBuffer) {
|
|
33
|
-
return
|
|
35
|
+
return defaultResult;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
const gltfData = await parse(tileContent.gltfArrayBuffer, GLTFLoader, {
|
|
@@ -39,11 +41,14 @@ export const analyzeTileContent = async (
|
|
|
39
41
|
const gltf = gltfData.json;
|
|
40
42
|
|
|
41
43
|
if (!gltf) {
|
|
42
|
-
return
|
|
44
|
+
return defaultResult;
|
|
43
45
|
}
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
return
|
|
46
|
+
const meshTopologyTypes = getMeshTypesFromGltf(gltf);
|
|
47
|
+
const metadataClasses = getMetadataClassesFromGltf(gltf);
|
|
48
|
+
return {
|
|
49
|
+
meshTopologyTypes,
|
|
50
|
+
metadataClasses
|
|
51
|
+
};
|
|
47
52
|
};
|
|
48
53
|
|
|
49
54
|
/**
|
|
@@ -51,8 +56,8 @@ export const analyzeTileContent = async (
|
|
|
51
56
|
* @param gltfJson - JSON part of GLB content
|
|
52
57
|
* @returns array of mesh types found
|
|
53
58
|
*/
|
|
54
|
-
const getMeshTypesFromGltf = (gltfJson: GLTF): Set<
|
|
55
|
-
const result: Set<
|
|
59
|
+
const getMeshTypesFromGltf = (gltfJson: GLTF): Set<GLTFPrimitiveModeString> => {
|
|
60
|
+
const result: Set<GLTFPrimitiveModeString> = new Set();
|
|
56
61
|
for (const mesh of gltfJson.meshes || []) {
|
|
57
62
|
for (const primitive of mesh.primitives) {
|
|
58
63
|
let {mode} = primitive;
|
|
@@ -65,6 +70,26 @@ const getMeshTypesFromGltf = (gltfJson: GLTF): Set<GltfPrimitiveModeString> => {
|
|
|
65
70
|
return result;
|
|
66
71
|
};
|
|
67
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Get feature metadata classes from glTF
|
|
75
|
+
* @param gltfJson - JSON part of GLB content
|
|
76
|
+
* @returns array of classes
|
|
77
|
+
*/
|
|
78
|
+
const getMetadataClassesFromGltf = (gltfJson: GLTF): Set<string> => {
|
|
79
|
+
const result: Set<string> = new Set();
|
|
80
|
+
|
|
81
|
+
const classes = (gltfJson.extensions?.[EXT_FEATURE_METADATA] as GLTF_EXT_feature_metadata_GLTF)
|
|
82
|
+
?.schema?.classes;
|
|
83
|
+
|
|
84
|
+
if (classes) {
|
|
85
|
+
for (const classKey of Object.keys(classes)) {
|
|
86
|
+
result.add(classKey);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return result;
|
|
91
|
+
};
|
|
92
|
+
|
|
68
93
|
/**
|
|
69
94
|
* Merge object2 into object1
|
|
70
95
|
* @param object1
|
|
@@ -76,4 +101,9 @@ export const mergePreprocessData = (object1: PreprocessData, object2: Preprocess
|
|
|
76
101
|
for (const type of object2.meshTopologyTypes) {
|
|
77
102
|
object1.meshTopologyTypes.add(type);
|
|
78
103
|
}
|
|
104
|
+
|
|
105
|
+
// Merge feature metadata classes
|
|
106
|
+
for (const metadataClass of object2.metadataClasses) {
|
|
107
|
+
object1.metadataClasses.add(metadataClass);
|
|
108
|
+
}
|
|
79
109
|
};
|