@loaders.gl/tile-converter 4.0.0-alpha.23 → 4.0.0-alpha.25
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-converter/helpers/b3dm-converter.d.ts +4 -4
- package/dist/3d-tiles-converter/helpers/load-i3s.d.ts.map +1 -1
- package/dist/converter.min.js +105 -105
- package/dist/dist.min.js +725 -652
- package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js +18 -18
- package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
- package/dist/es5/3d-tiles-converter/helpers/load-i3s.js.map +1 -1
- package/dist/es5/deps-installer/deps-installer.js +1 -1
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js +16 -14
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/feature-attributes.js +6 -18
- package/dist/es5/i3s-converter/helpers/feature-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js +83 -44
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-converter.js +13 -83
- package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js +15 -8
- package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -1
- package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/es5/i3s-converter/types.js.map +1 -1
- package/dist/es5/pgm-loader.js +11 -3
- package/dist/es5/pgm-loader.js.map +1 -1
- package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js +8 -8
- package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
- package/dist/esm/3d-tiles-converter/helpers/load-i3s.js.map +1 -1
- package/dist/esm/deps-installer/deps-installer.js +1 -1
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js +5 -15
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/feature-attributes.js +5 -5
- package/dist/esm/i3s-converter/helpers/feature-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js +76 -34
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-converter.js +10 -80
- package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js +15 -9
- package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -1
- package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/esm/i3s-converter/types.js.map +1 -1
- package/dist/esm/i3s-server/bin/i3s-server.min.js +75 -75
- package/dist/esm/pgm-loader.js +7 -4
- package/dist/esm/pgm-loader.js.map +1 -1
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +4 -1
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/feature-attributes.d.ts +6 -6
- package/dist/i3s-converter/helpers/feature-attributes.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.d.ts +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/types.d.ts +13 -5
- package/dist/i3s-converter/types.d.ts.map +1 -1
- package/dist/pgm-loader.d.ts +9 -2
- package/dist/pgm-loader.d.ts.map +1 -1
- package/dist/slpk-extractor.min.js +42 -42
- package/package.json +14 -14
- package/src/3d-tiles-converter/helpers/b3dm-converter.ts +8 -8
- package/src/3d-tiles-converter/helpers/load-i3s.ts +1 -0
- package/src/i3s-converter/helpers/batch-ids-extensions.ts +14 -35
- package/src/i3s-converter/helpers/feature-attributes.ts +14 -11
- package/src/i3s-converter/helpers/geometry-attributes.ts +80 -50
- package/src/i3s-converter/helpers/geometry-converter.ts +41 -177
- package/src/i3s-converter/helpers/preprocess-3d-tiles.ts +30 -9
- package/src/i3s-converter/i3s-converter.ts +0 -2
- package/src/i3s-converter/types.ts +14 -5
- package/src/pgm-loader.ts +15 -7
- package/dist/3d-tiles-converter/3d-tiles-converter.js +0 -279
- package/dist/3d-tiles-converter/helpers/b3dm-converter.js +0 -271
- package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +0 -23
- package/dist/3d-tiles-converter/helpers/load-i3s.js +0 -42
- package/dist/3d-tiles-converter/helpers/texture-atlas.js +0 -54
- package/dist/3d-tiles-converter/json-templates/tileset.js +0 -43
- package/dist/bundle.js +0 -5
- package/dist/constants.js +0 -4
- package/dist/converter-cli.js +0 -222
- package/dist/deps-installer/deps-installer.js +0 -89
- package/dist/i3s-converter/helpers/batch-ids-extensions.js +0 -179
- package/dist/i3s-converter/helpers/coordinate-converter.js +0 -122
- package/dist/i3s-converter/helpers/create-scene-server-path.js +0 -28
- package/dist/i3s-converter/helpers/feature-attributes.js +0 -218
- package/dist/i3s-converter/helpers/geometry-attributes.js +0 -203
- package/dist/i3s-converter/helpers/geometry-converter.js +0 -1321
- package/dist/i3s-converter/helpers/gltf-attributes.js +0 -129
- package/dist/i3s-converter/helpers/load-3d-tiles.js +0 -99
- package/dist/i3s-converter/helpers/node-debug.js +0 -120
- package/dist/i3s-converter/helpers/node-index-document.js +0 -271
- package/dist/i3s-converter/helpers/node-pages.js +0 -316
- package/dist/i3s-converter/helpers/preprocess-3d-tiles.js +0 -100
- package/dist/i3s-converter/helpers/tileset-traversal.js +0 -29
- package/dist/i3s-converter/i3s-converter.js +0 -964
- package/dist/i3s-converter/json-templates/geometry-definitions.js +0 -87
- package/dist/i3s-converter/json-templates/layers.js +0 -139
- package/dist/i3s-converter/json-templates/metadata.js +0 -25
- package/dist/i3s-converter/json-templates/node.js +0 -89
- package/dist/i3s-converter/json-templates/scene-server.js +0 -31
- package/dist/i3s-converter/json-templates/shared-resources.js +0 -129
- package/dist/i3s-converter/json-templates/store.js +0 -103
- package/dist/i3s-converter/types.js +0 -17
- package/dist/i3s-server/app.js +0 -29
- package/dist/i3s-server/bin/www.js +0 -37
- package/dist/i3s-server/controllers/index-controller.js +0 -31
- package/dist/i3s-server/controllers/slpk-controller.js +0 -33
- package/dist/i3s-server/routes/index.js +0 -20
- package/dist/i3s-server/routes/slpk-router.js +0 -34
- package/dist/i3s-server/utils/create-scene-server.js +0 -22
- package/dist/i3s-server/utils/server-utils.js +0 -66
- package/dist/index.js +0 -10
- package/dist/lib/utils/cli-utils.js +0 -82
- package/dist/lib/utils/compress-util.js +0 -257
- package/dist/lib/utils/file-utils.js +0 -139
- package/dist/lib/utils/geometry-utils.js +0 -18
- package/dist/lib/utils/lod-conversion-utils.js +0 -76
- package/dist/lib/utils/queue.js +0 -18
- package/dist/lib/utils/statistic-utills.js +0 -64
- package/dist/lib/utils/write-queue.js +0 -80
- package/dist/pgm-loader.js +0 -24
- package/dist/slpk-extractor/slpk-extractor.js +0 -75
- package/dist/slpk-extractor-cli.js +0 -102
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import type {FeatureTableJson, Tiles3DTileContent} from '@loaders.gl/3d-tiles';
|
|
2
2
|
import type {
|
|
3
|
-
GLTF_EXT_mesh_features,
|
|
4
|
-
GLTF_EXT_structural_metadata,
|
|
5
3
|
GLTFAccessorPostprocessed,
|
|
6
4
|
GLTFMaterialPostprocessed,
|
|
7
5
|
GLTFNodePostprocessed,
|
|
8
6
|
GLTFMeshPrimitivePostprocessed,
|
|
9
7
|
GLTFMeshPostprocessed,
|
|
10
8
|
GLTFTexturePostprocessed,
|
|
11
|
-
GLTF_EXT_feature_metadata_GLTF
|
|
9
|
+
GLTF_EXT_feature_metadata_GLTF,
|
|
10
|
+
GLTF_EXT_structural_metadata_GLTF
|
|
12
11
|
} from '@loaders.gl/gltf';
|
|
13
12
|
|
|
14
13
|
import {Vector3, Matrix4, Vector4} from '@math.gl/core';
|
|
@@ -50,7 +49,12 @@ import type {GLTFAttributesData, TextureImageProperties, TypedArrayConstructor}
|
|
|
50
49
|
import {generateSyntheticIndices} from '../../lib/utils/geometry-utils';
|
|
51
50
|
import {BoundingSphere, OrientedBoundingBox} from '@math.gl/culling';
|
|
52
51
|
|
|
53
|
-
import {
|
|
52
|
+
import {
|
|
53
|
+
EXT_FEATURE_METADATA,
|
|
54
|
+
EXT_STRUCTURAL_METADATA,
|
|
55
|
+
getPropertyTableFromExtFeatureMetadata,
|
|
56
|
+
getPropertyTableFromExtStructuralMetadata
|
|
57
|
+
} from '@loaders.gl/gltf';
|
|
54
58
|
|
|
55
59
|
// Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.7/pbrMetallicRoughness.cmn.md
|
|
56
60
|
const DEFAULT_ROUGHNESS_FACTOR = 1;
|
|
@@ -244,12 +248,18 @@ async function _makeNodeResources({
|
|
|
244
248
|
const {faceRange, featureIds, positions, normals, colors, uvRegions, texCoords, featureCount} =
|
|
245
249
|
generateAttributes(convertedAttributes);
|
|
246
250
|
|
|
247
|
-
|
|
248
|
-
|
|
251
|
+
let featureIdsMap: Record<string, number> = {};
|
|
252
|
+
if (propertyTable) {
|
|
253
|
+
/**
|
|
254
|
+
* 3DTiles has featureIndices unique only for one tile.
|
|
255
|
+
* In I3S featureIds are unique layer-wide. We create featureIds from all feature properties.
|
|
256
|
+
* If 3DTiles features has equal set of properties they are considered as same feature in I3S.
|
|
257
|
+
*/
|
|
258
|
+
featureIdsMap = makeFeatureIdsUnique(
|
|
249
259
|
featureIds,
|
|
250
260
|
convertedAttributes.featureIndices,
|
|
251
261
|
featuresHashArray,
|
|
252
|
-
|
|
262
|
+
propertyTable
|
|
253
263
|
);
|
|
254
264
|
}
|
|
255
265
|
|
|
@@ -291,6 +301,7 @@ async function _makeNodeResources({
|
|
|
291
301
|
if (attributeStorageInfo && propertyTable) {
|
|
292
302
|
attributes = convertPropertyTableToAttributeBuffers(
|
|
293
303
|
featureIds,
|
|
304
|
+
featureIdsMap,
|
|
294
305
|
propertyTable,
|
|
295
306
|
attributeStorageInfo
|
|
296
307
|
);
|
|
@@ -378,7 +389,7 @@ export async function convertAttributes(
|
|
|
378
389
|
}
|
|
379
390
|
|
|
380
391
|
/**
|
|
381
|
-
*
|
|
392
|
+
* glTF has hierarchical structure of nodes. This function converts nodes starting from those which are in gltf scene object.
|
|
382
393
|
* The goal is applying tranformation matrix for all children. Functions "convertNodes" and "convertNode" work together recursively.
|
|
383
394
|
* @param nodes - gltf nodes array
|
|
384
395
|
* @param images - gltf images array
|
|
@@ -1046,7 +1057,7 @@ function convertMaterial(sourceMaterial: GLTFMaterialPostprocessed): I3SMaterial
|
|
|
1046
1057
|
|
|
1047
1058
|
/**
|
|
1048
1059
|
* Converts from `alphaMode` material property from GLTF to I3S format
|
|
1049
|
-
* @param gltfAlphaMode
|
|
1060
|
+
* @param gltfAlphaMode glTF material `alphaMode` property
|
|
1050
1061
|
* @returns I3SMaterialDefinition.alphaMode property
|
|
1051
1062
|
*/
|
|
1052
1063
|
function convertAlphaMode(
|
|
@@ -1252,17 +1263,18 @@ function generateImageId(texture: GLTFTexturePostprocessed, nodeId: number) {
|
|
|
1252
1263
|
* @param featureIndices
|
|
1253
1264
|
* @param featuresHashArray
|
|
1254
1265
|
* @param batchTable
|
|
1255
|
-
* @returns
|
|
1266
|
+
* @returns propertyTable indices to map featureIds
|
|
1256
1267
|
*/
|
|
1257
1268
|
function makeFeatureIdsUnique(
|
|
1258
1269
|
featureIds: number[],
|
|
1259
1270
|
featureIndices: number[],
|
|
1260
1271
|
featuresHashArray: string[],
|
|
1261
1272
|
batchTable: {[key: string]: any}
|
|
1262
|
-
) {
|
|
1273
|
+
): Record<string, number> {
|
|
1263
1274
|
const replaceMap = getFeaturesReplaceMap(featureIds, batchTable, featuresHashArray);
|
|
1264
1275
|
replaceIndicesByUnique(featureIndices, replaceMap);
|
|
1265
1276
|
replaceIndicesByUnique(featureIds, replaceMap);
|
|
1277
|
+
return replaceMap;
|
|
1266
1278
|
}
|
|
1267
1279
|
|
|
1268
1280
|
/**
|
|
@@ -1276,8 +1288,8 @@ function getFeaturesReplaceMap(
|
|
|
1276
1288
|
featureIds: any[],
|
|
1277
1289
|
batchTable: object,
|
|
1278
1290
|
featuresHashArray: any[]
|
|
1279
|
-
): Record<string,
|
|
1280
|
-
const featureMap: Record<string,
|
|
1291
|
+
): Record<string, number> {
|
|
1292
|
+
const featureMap: Record<string, number> = {};
|
|
1281
1293
|
|
|
1282
1294
|
for (let index = 0; index < featureIds.length; index++) {
|
|
1283
1295
|
const oldFeatureId = featureIds[index];
|
|
@@ -1329,7 +1341,7 @@ function getOrCreateUniqueFeatureId(
|
|
|
1329
1341
|
* @param featureMap
|
|
1330
1342
|
* @returns
|
|
1331
1343
|
*/
|
|
1332
|
-
function replaceIndicesByUnique(indicesArray:
|
|
1344
|
+
function replaceIndicesByUnique(indicesArray: number[], featureMap: Record<string, number>) {
|
|
1333
1345
|
for (let index = 0; index < indicesArray.length; index++) {
|
|
1334
1346
|
indicesArray[index] = featureMap[indicesArray[index]];
|
|
1335
1347
|
}
|
|
@@ -1344,6 +1356,7 @@ function replaceIndicesByUnique(indicesArray: any[], featureMap: Record<string,
|
|
|
1344
1356
|
*/
|
|
1345
1357
|
function convertPropertyTableToAttributeBuffers(
|
|
1346
1358
|
featureIds: number[],
|
|
1359
|
+
featureIdsMap: Record<string, number>,
|
|
1347
1360
|
propertyTable: FeatureTableJson,
|
|
1348
1361
|
attributeStorageInfo: AttributeStorageInfo[]
|
|
1349
1362
|
): any[] {
|
|
@@ -1351,7 +1364,7 @@ function convertPropertyTableToAttributeBuffers(
|
|
|
1351
1364
|
|
|
1352
1365
|
const needFlattenPropertyTable = checkPropertiesLength(featureIds, propertyTable);
|
|
1353
1366
|
const properties = needFlattenPropertyTable
|
|
1354
|
-
? flattenPropertyTableByFeatureIds(
|
|
1367
|
+
? flattenPropertyTableByFeatureIds(featureIdsMap, propertyTable)
|
|
1355
1368
|
: propertyTable;
|
|
1356
1369
|
|
|
1357
1370
|
const propertyTableWithObjectIds = {
|
|
@@ -1597,7 +1610,7 @@ function generateFeatureIndexAttribute(
|
|
|
1597
1610
|
* For example it can be batchTable for b3dm files or property table in gLTF extension.
|
|
1598
1611
|
* @param tileContent - 3DTiles tile content
|
|
1599
1612
|
* @param metadataClass - user selected feature metadata class name
|
|
1600
|
-
* @return batch table from b3dm / feature properties from EXT_FEATURE_METADATA
|
|
1613
|
+
* @return batch table from b3dm / feature properties from EXT_FEATURE_METADATA or EXT_STRUCTURAL_METADATA.
|
|
1601
1614
|
*/
|
|
1602
1615
|
export function getPropertyTable(
|
|
1603
1616
|
tileContent: Tiles3DTileContent | null,
|
|
@@ -1607,7 +1620,7 @@ export function getPropertyTable(
|
|
|
1607
1620
|
return null;
|
|
1608
1621
|
}
|
|
1609
1622
|
let propertyTable: FeatureTableJson | null;
|
|
1610
|
-
const batchTableJson = tileContent
|
|
1623
|
+
const batchTableJson = tileContent.batchTableJson;
|
|
1611
1624
|
|
|
1612
1625
|
if (batchTableJson) {
|
|
1613
1626
|
return batchTableJson;
|
|
@@ -1616,16 +1629,9 @@ export function getPropertyTable(
|
|
|
1616
1629
|
const {extensionName, extension} = getPropertyTableExtension(tileContent);
|
|
1617
1630
|
|
|
1618
1631
|
switch (extensionName) {
|
|
1619
|
-
case EXT_MESH_FEATURES: {
|
|
1620
|
-
propertyTable = getPropertyTableFromExtMeshFeatures(
|
|
1621
|
-
extension as GLTF_EXT_mesh_features,
|
|
1622
|
-
metadataClass
|
|
1623
|
-
);
|
|
1624
|
-
return propertyTable;
|
|
1625
|
-
}
|
|
1626
1632
|
case EXT_STRUCTURAL_METADATA: {
|
|
1627
1633
|
propertyTable = getPropertyTableFromExtStructuralMetadata(
|
|
1628
|
-
extension as
|
|
1634
|
+
extension as GLTF_EXT_structural_metadata_GLTF,
|
|
1629
1635
|
metadataClass
|
|
1630
1636
|
);
|
|
1631
1637
|
return propertyTable;
|
|
@@ -1648,18 +1654,9 @@ export function getPropertyTable(
|
|
|
1648
1654
|
*/
|
|
1649
1655
|
function getPropertyTableExtension(tileContent: Tiles3DTileContent): {
|
|
1650
1656
|
extensionName: null | string;
|
|
1651
|
-
extension:
|
|
1652
|
-
| string
|
|
1653
|
-
| GLTF_EXT_feature_metadata_GLTF
|
|
1654
|
-
| GLTF_EXT_structural_metadata
|
|
1655
|
-
| GLTF_EXT_mesh_features
|
|
1656
|
-
| null;
|
|
1657
|
+
extension: string | GLTF_EXT_feature_metadata_GLTF | GLTF_EXT_structural_metadata_GLTF | null;
|
|
1657
1658
|
} {
|
|
1658
|
-
const extensionsWithPropertyTables = [
|
|
1659
|
-
EXT_FEATURE_METADATA,
|
|
1660
|
-
EXT_STRUCTURAL_METADATA,
|
|
1661
|
-
EXT_MESH_FEATURES
|
|
1662
|
-
];
|
|
1659
|
+
const extensionsWithPropertyTables = [EXT_FEATURE_METADATA, EXT_STRUCTURAL_METADATA];
|
|
1663
1660
|
const extensionsUsed = tileContent?.gltf?.extensionsUsed;
|
|
1664
1661
|
|
|
1665
1662
|
if (!extensionsUsed) {
|
|
@@ -1670,6 +1667,12 @@ function getPropertyTableExtension(tileContent: Tiles3DTileContent): {
|
|
|
1670
1667
|
for (const extensionItem of tileContent?.gltf?.extensionsUsed || []) {
|
|
1671
1668
|
if (extensionsWithPropertyTables.includes(extensionItem)) {
|
|
1672
1669
|
extensionName = extensionItem;
|
|
1670
|
+
/*
|
|
1671
|
+
It returns the first extension containing the property table.
|
|
1672
|
+
We assume that there can be only one extension containing the property table:
|
|
1673
|
+
either EXT_FEATURE_METADATA, which is a depricated extension,
|
|
1674
|
+
or EXT_STRUCTURAL_METADATA.
|
|
1675
|
+
*/
|
|
1673
1676
|
break;
|
|
1674
1677
|
}
|
|
1675
1678
|
}
|
|
@@ -1680,147 +1683,8 @@ function getPropertyTableExtension(tileContent: Tiles3DTileContent): {
|
|
|
1680
1683
|
|
|
1681
1684
|
const extension = tileContent?.gltf?.extensions?.[extensionName] as
|
|
1682
1685
|
| string // EXT_mesh_features doesn't have global metadata
|
|
1683
|
-
| GLTF_EXT_feature_metadata_GLTF
|
|
1686
|
+
| GLTF_EXT_feature_metadata_GLTF
|
|
1687
|
+
| GLTF_EXT_structural_metadata_GLTF;
|
|
1684
1688
|
|
|
1685
1689
|
return {extensionName, extension};
|
|
1686
1690
|
}
|
|
1687
|
-
|
|
1688
|
-
/**
|
|
1689
|
-
* Handle EXT_feature_metadata to get property table
|
|
1690
|
-
* @param extension - global level of EXT_FEATURE_METADATA extension
|
|
1691
|
-
* @param metadataClass - user selected feature metadata class name
|
|
1692
|
-
* @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly.
|
|
1693
|
-
*/
|
|
1694
|
-
function getPropertyTableFromExtFeatureMetadata(
|
|
1695
|
-
extension: GLTF_EXT_feature_metadata_GLTF,
|
|
1696
|
-
metadataClass?: string
|
|
1697
|
-
): FeatureTableJson | null {
|
|
1698
|
-
if (extension?.featureTables) {
|
|
1699
|
-
/**
|
|
1700
|
-
* Take only first feature table to generate attributes storage info object.
|
|
1701
|
-
* TODO: Think about getting data from all feature tables?
|
|
1702
|
-
* It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
|
|
1703
|
-
* In I3S we should decide which featureIds attribute will be passed to geometry data.
|
|
1704
|
-
*/
|
|
1705
|
-
const firstFeatureTableName = Object.keys(extension.featureTables)?.[0];
|
|
1706
|
-
|
|
1707
|
-
if (firstFeatureTableName) {
|
|
1708
|
-
const featureTable = extension?.featureTables[firstFeatureTableName];
|
|
1709
|
-
const propertyTable = {};
|
|
1710
|
-
|
|
1711
|
-
for (const propertyName in featureTable.properties) {
|
|
1712
|
-
propertyTable[propertyName] = featureTable.properties[propertyName].data;
|
|
1713
|
-
}
|
|
1714
|
-
|
|
1715
|
-
return propertyTable;
|
|
1716
|
-
}
|
|
1717
|
-
}
|
|
1718
|
-
|
|
1719
|
-
if (extension?.featureTextures) {
|
|
1720
|
-
let featureTexture: string | undefined;
|
|
1721
|
-
for (const textureKey in extension.featureTextures) {
|
|
1722
|
-
const texture = extension.featureTextures[textureKey];
|
|
1723
|
-
if (texture.class === metadataClass) {
|
|
1724
|
-
featureTexture = textureKey;
|
|
1725
|
-
}
|
|
1726
|
-
}
|
|
1727
|
-
|
|
1728
|
-
if (typeof featureTexture === 'string') {
|
|
1729
|
-
const featureTable = extension?.featureTextures[featureTexture];
|
|
1730
|
-
const propertyTable = {};
|
|
1731
|
-
|
|
1732
|
-
for (const propertyName in featureTable.properties) {
|
|
1733
|
-
propertyTable[propertyName] = featureTable.properties[propertyName].data;
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
|
-
return propertyTable;
|
|
1737
|
-
}
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1740
|
-
console.warn(
|
|
1741
|
-
"The I3S converter couldn't handle EXT_feature_metadata extension: There is neither featureTables, no featureTextures in the extension."
|
|
1742
|
-
);
|
|
1743
|
-
return null;
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
|
-
/**
|
|
1747
|
-
* Handle EXT_structural_metadata to get property table
|
|
1748
|
-
* @param extension - global level of EXT_STRUCTURAL_METADATA extension
|
|
1749
|
-
* @param metadataClass - user selected feature metadata class name
|
|
1750
|
-
* @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly.
|
|
1751
|
-
*/
|
|
1752
|
-
function getPropertyTableFromExtStructuralMetadata(
|
|
1753
|
-
extension: GLTF_EXT_structural_metadata,
|
|
1754
|
-
metadataClass?: string
|
|
1755
|
-
): FeatureTableJson | null {
|
|
1756
|
-
if (extension?.propertyTables) {
|
|
1757
|
-
/**
|
|
1758
|
-
* Take only first feature table to generate attributes storage info object.
|
|
1759
|
-
* TODO: Think about getting data from all feature tables?
|
|
1760
|
-
* It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
|
|
1761
|
-
* In I3S we should decide which featureIds attribute will be passed to geometry data.
|
|
1762
|
-
*/
|
|
1763
|
-
const firstPropertyTable = extension?.propertyTables[0];
|
|
1764
|
-
const propertyTableWithData = {};
|
|
1765
|
-
|
|
1766
|
-
for (const propertyName in firstPropertyTable.properties) {
|
|
1767
|
-
propertyTableWithData[propertyName] = firstPropertyTable.properties[propertyName].data;
|
|
1768
|
-
}
|
|
1769
|
-
|
|
1770
|
-
return propertyTableWithData;
|
|
1771
|
-
}
|
|
1772
|
-
|
|
1773
|
-
if (extension?.propertyTextures) {
|
|
1774
|
-
/**
|
|
1775
|
-
* Take only first feature table to generate attributes storage info object.
|
|
1776
|
-
* TODO: Think about getting data from all feature tables?
|
|
1777
|
-
* It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
|
|
1778
|
-
* In I3S we should decide which featureIds attribute will be passed to geometry data.
|
|
1779
|
-
*/
|
|
1780
|
-
if (extension?.propertyTextures) {
|
|
1781
|
-
const firstPropertyTexture = extension?.propertyTextures[0];
|
|
1782
|
-
const propertyTableWithData = {};
|
|
1783
|
-
|
|
1784
|
-
for (const propertyName in firstPropertyTexture.properties) {
|
|
1785
|
-
propertyTableWithData[propertyName] = firstPropertyTexture.properties[propertyName].data;
|
|
1786
|
-
}
|
|
1787
|
-
|
|
1788
|
-
return propertyTableWithData;
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
|
|
1792
|
-
console.warn(
|
|
1793
|
-
"The I3S converter couldn't handle EXT_structural_metadata extension: There is neither propertyTables, no propertyTextures in the extension."
|
|
1794
|
-
);
|
|
1795
|
-
return null;
|
|
1796
|
-
}
|
|
1797
|
-
|
|
1798
|
-
/**
|
|
1799
|
-
* Handle EXT_mesh_features to get property table
|
|
1800
|
-
* @param extension - global level of EXT_MESH_FEATURES extension
|
|
1801
|
-
* @param metadataClass - user selected feature metadata class name
|
|
1802
|
-
* @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly.
|
|
1803
|
-
*/
|
|
1804
|
-
function getPropertyTableFromExtMeshFeatures(
|
|
1805
|
-
extension: GLTF_EXT_mesh_features,
|
|
1806
|
-
metadataClass?: string
|
|
1807
|
-
): FeatureTableJson | null {
|
|
1808
|
-
if (extension?.featureIds) {
|
|
1809
|
-
const firstFeatureId = extension?.featureIds[0];
|
|
1810
|
-
const propertyTableWithData = {};
|
|
1811
|
-
|
|
1812
|
-
// When firstFeatureId.propertyTable is defined, the property data will be taken from EXT_structural_metadata extension
|
|
1813
|
-
if (!firstFeatureId.propertyTable) {
|
|
1814
|
-
console.warn(
|
|
1815
|
-
'Should be implemented as we have the tileset with Ext_mesh_features not linked with EXT_structural_metadata extension'
|
|
1816
|
-
);
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
return propertyTableWithData;
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
console.warn(
|
|
1823
|
-
"The I3S converter couldn't handle EXT_mesh_features extension: There is no featureIds in the extension."
|
|
1824
|
-
);
|
|
1825
|
-
return null;
|
|
1826
|
-
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import {Tiles3DTileContent} from '@loaders.gl/3d-tiles';
|
|
2
2
|
import {GLTFPrimitiveModeString, PreprocessData} from '../types';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
EXT_STRUCTURAL_METADATA,
|
|
5
|
+
GLTF,
|
|
6
|
+
GLTFLoader,
|
|
7
|
+
GLTF_EXT_feature_metadata_GLTF,
|
|
8
|
+
GLTF_EXT_structural_metadata_GLTF
|
|
9
|
+
} from '@loaders.gl/gltf';
|
|
4
10
|
import {parse} from '@loaders.gl/core';
|
|
5
11
|
import {EXT_FEATURE_METADATA} from '@loaders.gl/gltf';
|
|
6
12
|
|
|
@@ -43,8 +49,8 @@ export const analyzeTileContent = async (
|
|
|
43
49
|
if (!gltf) {
|
|
44
50
|
return defaultResult;
|
|
45
51
|
}
|
|
46
|
-
const meshTopologyTypes =
|
|
47
|
-
const metadataClasses =
|
|
52
|
+
const meshTopologyTypes = getMeshTypesFromGLTF(gltf);
|
|
53
|
+
const metadataClasses = getMetadataClassesFromGLTF(gltf);
|
|
48
54
|
return {
|
|
49
55
|
meshTopologyTypes,
|
|
50
56
|
metadataClasses
|
|
@@ -56,7 +62,7 @@ export const analyzeTileContent = async (
|
|
|
56
62
|
* @param gltfJson - JSON part of GLB content
|
|
57
63
|
* @returns array of mesh types found
|
|
58
64
|
*/
|
|
59
|
-
const
|
|
65
|
+
const getMeshTypesFromGLTF = (gltfJson: GLTF): Set<GLTFPrimitiveModeString> => {
|
|
60
66
|
const result: Set<GLTFPrimitiveModeString> = new Set();
|
|
61
67
|
for (const mesh of gltfJson.meshes || []) {
|
|
62
68
|
for (const primitive of mesh.primitives) {
|
|
@@ -72,17 +78,32 @@ const getMeshTypesFromGltf = (gltfJson: GLTF): Set<GLTFPrimitiveModeString> => {
|
|
|
72
78
|
|
|
73
79
|
/**
|
|
74
80
|
* Get feature metadata classes from glTF
|
|
81
|
+
* The tileset might contain multiple metadata classes provided by EXT_feature_metadata and EXT_structural_metadata extensions.
|
|
82
|
+
* Every class is a set of properties. But I3S can consume only one set of properties.
|
|
83
|
+
* On the pre-process we collect all classes from the tileset in order to show the prompt to select one class for conversion to I3S.
|
|
75
84
|
* @param gltfJson - JSON part of GLB content
|
|
76
85
|
* @returns array of classes
|
|
77
86
|
*/
|
|
78
|
-
const
|
|
87
|
+
const getMetadataClassesFromGLTF = (gltfJson: GLTF): Set<string> => {
|
|
79
88
|
const result: Set<string> = new Set();
|
|
80
89
|
|
|
81
|
-
|
|
82
|
-
|
|
90
|
+
// Try to parse from EXT_feature_metadata
|
|
91
|
+
const extFeatureMetadataClasses = (
|
|
92
|
+
gltfJson.extensions?.[EXT_FEATURE_METADATA] as GLTF_EXT_feature_metadata_GLTF
|
|
93
|
+
)?.schema?.classes;
|
|
83
94
|
|
|
84
|
-
if (
|
|
85
|
-
for (const classKey of Object.keys(
|
|
95
|
+
if (extFeatureMetadataClasses) {
|
|
96
|
+
for (const classKey of Object.keys(extFeatureMetadataClasses)) {
|
|
97
|
+
result.add(classKey);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Try to parse from EXT_structural_metadata
|
|
102
|
+
const extStructuralMetadataClasses = (
|
|
103
|
+
gltfJson.extensions?.[EXT_STRUCTURAL_METADATA] as GLTF_EXT_structural_metadata_GLTF
|
|
104
|
+
)?.schema?.classes;
|
|
105
|
+
if (extStructuralMetadataClasses) {
|
|
106
|
+
for (const classKey of Object.keys(extStructuralMetadataClasses)) {
|
|
86
107
|
result.add(classKey);
|
|
87
108
|
}
|
|
88
109
|
}
|
|
@@ -656,7 +656,6 @@ export default class I3SConverter {
|
|
|
656
656
|
We will append new attributes only in case the property table is updated.
|
|
657
657
|
According to ver 1.9 (see https://github.com/Esri/i3s-spec/blob/master/docs/1.9/attributeStorageInfo.cmn.md):
|
|
658
658
|
"The attributeStorageInfo object describes the structure of the binary attribute data resource of a layer, which is the same for every node in the layer."
|
|
659
|
-
But the specification of ver 2.1 doesn't have such a requirement ("...the same for every node...")
|
|
660
659
|
*/
|
|
661
660
|
this._convertPropertyTableToNodeAttributes(propertyTable);
|
|
662
661
|
}
|
|
@@ -1167,7 +1166,6 @@ export default class I3SConverter {
|
|
|
1167
1166
|
We will append new attributes only in case the property table is updated.
|
|
1168
1167
|
According to ver 1.9 (see https://github.com/Esri/i3s-spec/blob/master/docs/1.9/attributeStorageInfo.cmn.md):
|
|
1169
1168
|
"The attributeStorageInfo object describes the structure of the binary attribute data resource of a layer, which is the same for every node in the layer."
|
|
1170
|
-
But the specification of ver 2.1 doesn't have such a requirement ("...the same for every node...")
|
|
1171
1169
|
*/
|
|
1172
1170
|
const found = this.layers0!.attributeStorageInfo!.find((element) => element.name === key);
|
|
1173
1171
|
if (!found) {
|
|
@@ -106,10 +106,8 @@ export type GeometryAttributes = {
|
|
|
106
106
|
featureCount: number;
|
|
107
107
|
};
|
|
108
108
|
|
|
109
|
-
/** Geometry attributes
|
|
110
|
-
export type
|
|
111
|
-
/** Feature Id */
|
|
112
|
-
featureId: number;
|
|
109
|
+
/** Geometry attributes applicable for reordering by featureId */
|
|
110
|
+
export type GroupedAttributes = {
|
|
113
111
|
/** POSITION attribute value */
|
|
114
112
|
positions: Float32Array;
|
|
115
113
|
/** NORMAL attribute value */
|
|
@@ -122,6 +120,12 @@ export type GroupedByFeatureIdAttributes = {
|
|
|
122
120
|
texCoords: Float32Array;
|
|
123
121
|
};
|
|
124
122
|
|
|
123
|
+
/** Geometry attributes specific for the particular feature */
|
|
124
|
+
export type GroupedByFeatureIdAttributes = GroupedAttributes & {
|
|
125
|
+
/** Feature Id */
|
|
126
|
+
featureId: number;
|
|
127
|
+
};
|
|
128
|
+
|
|
125
129
|
/** Shared resources made from GLTF material */
|
|
126
130
|
export type SharedResourcesArrays = {
|
|
127
131
|
/** material definitions list https://github.com/Esri/i3s-spec/blob/master/docs/1.8/materialDefinitionInfo.cmn.md */
|
|
@@ -183,7 +187,12 @@ export enum GLTFPrimitiveModeString {
|
|
|
183
187
|
export type PreprocessData = {
|
|
184
188
|
/** Mesh topology types used in gltf primitives of the tileset */
|
|
185
189
|
meshTopologyTypes: Set<GLTFPrimitiveModeString>;
|
|
186
|
-
/**
|
|
190
|
+
/**
|
|
191
|
+
* Featrue metadata classes found in glTF extensions
|
|
192
|
+
* The tileset might contain multiple metadata classes provided by EXT_feature_metadata and EXT_structural_metadata extensions.
|
|
193
|
+
* Every class is a set of properties. But I3S can consume only one set of properties.
|
|
194
|
+
* On the pre-process we collect all classes from the tileset in order to show the prompt to select one class for conversion to I3S.
|
|
195
|
+
*/
|
|
187
196
|
metadataClasses: Set<string>;
|
|
188
197
|
};
|
|
189
198
|
|
package/src/pgm-loader.ts
CHANGED
|
@@ -1,24 +1,32 @@
|
|
|
1
|
-
import type {LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
2
|
-
import {parsePGM} from '@math.gl/geoid';
|
|
1
|
+
import type {LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';
|
|
2
|
+
import {Geoid, parsePGM} from '@math.gl/geoid';
|
|
3
3
|
|
|
4
4
|
// __VERSION__ is injected by babel-plugin-version-inline
|
|
5
5
|
// @ts-ignore TS2304: Cannot find name '__VERSION__'.
|
|
6
6
|
const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
|
|
7
7
|
|
|
8
|
+
export {Geoid};
|
|
9
|
+
|
|
10
|
+
export type PGMLoaderOptions = LoaderOptions & {
|
|
11
|
+
pgm?: {
|
|
12
|
+
cubic?: boolean;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
8
16
|
/**
|
|
9
17
|
* Loader for PGM - Netpbm grayscale image format
|
|
10
18
|
*/
|
|
11
|
-
export const PGMLoader: LoaderWithParser = {
|
|
19
|
+
export const PGMLoader: LoaderWithParser<Geoid, never, PGMLoaderOptions> = {
|
|
12
20
|
name: 'PGM - Netpbm grayscale image format',
|
|
13
21
|
id: 'pgm',
|
|
14
22
|
module: 'tile-converter',
|
|
15
23
|
version: VERSION,
|
|
16
24
|
mimeTypes: ['image/x-portable-graymap'],
|
|
17
|
-
|
|
18
|
-
parse: async (arrayBuffer, options) => parsePGM(new Uint8Array(arrayBuffer), options),
|
|
25
|
+
parse: async (arrayBuffer, options) => parsePGM(new Uint8Array(arrayBuffer), options?.pgm || {}),
|
|
19
26
|
extensions: ['pgm'],
|
|
20
27
|
options: {
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
pgm: {
|
|
29
|
+
cubic: false
|
|
30
|
+
}
|
|
23
31
|
}
|
|
24
32
|
};
|