@loaders.gl/tile-converter 3.2.6 → 3.3.0-alpha.2
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 +1123 -624
- 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 +146 -0
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/feature-attributes.js +60 -0
- package/dist/es5/i3s-converter/helpers/feature-attributes.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js +39 -7
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-converter.js +177 -59
- 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 +50 -51
- 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 +128 -0
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/feature-attributes.js +34 -0
- package/dist/esm/i3s-converter/helpers/feature-attributes.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js +23 -7
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-converter.js +145 -38
- 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 +21 -27
- 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 +138 -0
- package/dist/i3s-converter/helpers/feature-attributes.d.ts +24 -0
- package/dist/i3s-converter/helpers/feature-attributes.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/feature-attributes.js +55 -0
- package/dist/i3s-converter/helpers/geometry-attributes.js +26 -7
- package/dist/i3s-converter/helpers/geometry-converter.d.ts +9 -2
- package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.js +140 -44
- 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 +7 -14
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.js +44 -35
- package/dist/lib/utils/write-queue.d.ts.map +1 -1
- package/dist/lib/utils/write-queue.js +3 -4
- package/package.json +15 -15
- package/src/converter-cli.ts +33 -7
- package/src/i3s-converter/helpers/batch-ids-extensions.ts +199 -0
- package/src/i3s-converter/helpers/feature-attributes.ts +65 -0
- package/src/i3s-converter/helpers/geometry-attributes.ts +30 -7
- package/src/i3s-converter/helpers/geometry-converter.ts +187 -48
- package/src/i3s-converter/helpers/gltf-attributes.ts +15 -0
- package/src/i3s-converter/i3s-converter.ts +38 -41
- package/src/lib/utils/write-queue.ts +7 -5
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
/**
|
|
4
|
+
* Getting batchIds from 3DTilesNext extensions.
|
|
5
|
+
* @param attributes
|
|
6
|
+
* @param primitive
|
|
7
|
+
* @param textures
|
|
8
|
+
*/
|
|
9
|
+
export declare function handleBatchIdsExtensions(attributes: {
|
|
10
|
+
[key: string]: GLTFAccessorPostprocessed;
|
|
11
|
+
}, primitive: MeshPrimitive, images: Image[]): number[];
|
|
12
|
+
//# sourceMappingURL=batch-ids-extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-ids-extensions.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/batch-ids-extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,uCAAuC,CAAC;AACrF,OAAO,KAAK,EAAC,KAAK,EAAE,aAAa,EAAC,MAAM,sDAAsD,CAAC;AAS/F;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE;IACV,CAAC,GAAG,EAAE,MAAM,GAAG,yBAAyB,CAAC;CAC1C,EACD,SAAS,EAAE,aAAa,EACxB,MAAM,EAAE,KAAK,EAAE,GACd,MAAM,EAAE,CAwBV"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleBatchIdsExtensions = void 0;
|
|
4
|
+
const EXT_MESH_FEATURES = 'EXT_mesh_features';
|
|
5
|
+
const EXT_FEATURE_METADATA = 'EXT_feature_metadata';
|
|
6
|
+
/**
|
|
7
|
+
* Getting batchIds from 3DTilesNext extensions.
|
|
8
|
+
* @param attributes
|
|
9
|
+
* @param primitive
|
|
10
|
+
* @param textures
|
|
11
|
+
*/
|
|
12
|
+
function handleBatchIdsExtensions(attributes, primitive, images) {
|
|
13
|
+
const extensions = primitive?.extensions;
|
|
14
|
+
if (!extensions) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
for (const [extensionName, extensionData] of Object.entries(extensions || {})) {
|
|
18
|
+
switch (extensionName) {
|
|
19
|
+
case EXT_FEATURE_METADATA:
|
|
20
|
+
return handleExtFeatureMetadataExtension(attributes, extensionData, images);
|
|
21
|
+
case EXT_MESH_FEATURES:
|
|
22
|
+
console.warn('EXT_mesh_features extension is not supported yet');
|
|
23
|
+
return [];
|
|
24
|
+
default:
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
exports.handleBatchIdsExtensions = handleBatchIdsExtensions;
|
|
31
|
+
/**
|
|
32
|
+
* Get batchIds from EXT_feature_metadata extension.
|
|
33
|
+
* Docs - https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata
|
|
34
|
+
* @param attributes
|
|
35
|
+
* @param extFeatureMetadata
|
|
36
|
+
* @param textures
|
|
37
|
+
*/
|
|
38
|
+
function handleExtFeatureMetadataExtension(attributes, extFeatureMetadata, images) {
|
|
39
|
+
// Take only first extension object to get batchIds attribute name.
|
|
40
|
+
const featureIdAttribute = extFeatureMetadata?.featureIdAttributes?.[0];
|
|
41
|
+
if (featureIdAttribute?.featureIds?.attribute) {
|
|
42
|
+
const batchIdsAttribute = attributes[featureIdAttribute.featureIds.attribute];
|
|
43
|
+
return batchIdsAttribute.value;
|
|
44
|
+
}
|
|
45
|
+
if (featureIdAttribute?.featureIds?.hasOwnProperty('constant') &&
|
|
46
|
+
featureIdAttribute?.featureIds?.hasOwnProperty('divisor')) {
|
|
47
|
+
const featuresCount = attributes?.POSITIONS?.value.length / 3 || 0;
|
|
48
|
+
return generateImplicitFeatureIds(featuresCount, featureIdAttribute.featureIds.constant, featureIdAttribute.featureIds.divisor);
|
|
49
|
+
}
|
|
50
|
+
// Take only first extension object to get batchIds attribute name.
|
|
51
|
+
const featureIdTexture = extFeatureMetadata?.featureIdTextures && extFeatureMetadata?.featureIdTextures[0];
|
|
52
|
+
if (featureIdTexture) {
|
|
53
|
+
const textureAttributeIndex = featureIdTexture?.featureIds?.texture?.texCoord || 0;
|
|
54
|
+
const textCoordAttribute = `TEXCOORD_${textureAttributeIndex}`;
|
|
55
|
+
const textureCoordinates = attributes[textCoordAttribute].value;
|
|
56
|
+
return generateBatchIdsFromTexture(featureIdTexture, textureCoordinates, images);
|
|
57
|
+
}
|
|
58
|
+
// Take only first extension texture to get batchIds from the root EXT_feature_metadata object.
|
|
59
|
+
const featureTexture = extFeatureMetadata?.featureTextures && extFeatureMetadata?.featureTextures[0];
|
|
60
|
+
/**
|
|
61
|
+
* TODO need to get batchIds from root extension
|
|
62
|
+
*/
|
|
63
|
+
if (featureTexture) {
|
|
64
|
+
console.warn("EXT_feature_metadata doesn't yet support featureTextures in primitive");
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Generates implicit feature ids
|
|
71
|
+
* Spec - https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata#implicit-feature-ids
|
|
72
|
+
* @param featuresCount
|
|
73
|
+
* @param constant
|
|
74
|
+
* @param devisor
|
|
75
|
+
*/
|
|
76
|
+
function generateImplicitFeatureIds(featuresCount, constant = 0, divisor = 0) {
|
|
77
|
+
let featureIds = [];
|
|
78
|
+
if (divisor > 0) {
|
|
79
|
+
let currentValue = constant;
|
|
80
|
+
let devisorCounter = divisor;
|
|
81
|
+
for (let index = 0; index < featuresCount; index++) {
|
|
82
|
+
featureIds.push(currentValue);
|
|
83
|
+
devisorCounter -= 1;
|
|
84
|
+
if (devisorCounter === 0) {
|
|
85
|
+
currentValue++;
|
|
86
|
+
devisorCounter = divisor;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
featureIds = Array(featuresCount).fill(constant, 0, featuresCount);
|
|
92
|
+
}
|
|
93
|
+
return featureIds;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get batchIds from texture.
|
|
97
|
+
* @param primitive
|
|
98
|
+
* @param featureIdTextures
|
|
99
|
+
*/
|
|
100
|
+
function generateBatchIdsFromTexture(featureIdTexture, textureCoordinates, images) {
|
|
101
|
+
const CHANNELS_MAP = {
|
|
102
|
+
r: 0,
|
|
103
|
+
g: 1,
|
|
104
|
+
b: 2,
|
|
105
|
+
a: 3
|
|
106
|
+
};
|
|
107
|
+
const textureIndex = featureIdTexture?.featureIds?.texture?.index;
|
|
108
|
+
const featureChannel = featureIdTexture?.featureIds?.channels;
|
|
109
|
+
if (!featureChannel || textureIndex === undefined) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
const image = images[textureIndex];
|
|
113
|
+
const batchIds = [];
|
|
114
|
+
const channels = CHANNELS_MAP[featureChannel];
|
|
115
|
+
if (!image.compressed) {
|
|
116
|
+
for (let index = 0; index < textureCoordinates.length; index += 2) {
|
|
117
|
+
const u = textureCoordinates[index];
|
|
118
|
+
const v = textureCoordinates[index + 1];
|
|
119
|
+
const tx = Math.min((emod(u) * image.width) | 0, image.width - 1);
|
|
120
|
+
const ty = Math.min((emod(v) * image.height) | 0, image.height - 1);
|
|
121
|
+
const offset = (ty * image.width + tx) * image.components + channels;
|
|
122
|
+
const batchId = new Uint8Array(image.data)[offset];
|
|
123
|
+
batchIds.push(batchId);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
console.warn(`Can't get batch Ids from ${image.mimeType} compressed texture`);
|
|
128
|
+
}
|
|
129
|
+
return batchIds;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Handle UVs if they are out of range [0,1].
|
|
133
|
+
* @param n
|
|
134
|
+
* @param m
|
|
135
|
+
*/
|
|
136
|
+
function emod(n) {
|
|
137
|
+
return ((n % 1) + 1) % 1;
|
|
138
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { FeatureTableJson } from '@loaders.gl/3d-tiles';
|
|
2
|
+
/**
|
|
3
|
+
* Takes attributes from property table based on featureIds.
|
|
4
|
+
* If there is no property value for particular featureId (index) the property will be null.
|
|
5
|
+
* Example:
|
|
6
|
+
* Initial data:
|
|
7
|
+
* OBJECTID: [0, 1, 5]
|
|
8
|
+
* component: ['Windows', 'Frames', 'Wall', 'Roof', 'Skylight']
|
|
9
|
+
* Result:
|
|
10
|
+
* OBJECTID: [0, 1, 5]
|
|
11
|
+
* component: ['Windows', 'Frames', 'null']
|
|
12
|
+
* @param featureIds
|
|
13
|
+
* @param propertyTable
|
|
14
|
+
*/
|
|
15
|
+
export declare function flattenPropertyTableByFeatureIds(featureIds: number[], propertyTable: FeatureTableJson): FeatureTableJson;
|
|
16
|
+
/**
|
|
17
|
+
* Check that all attributes in propertyTable have the same length as FeatureIds.
|
|
18
|
+
* If there are differencies between lengths we should flatten property table based on exiesting featureIds.
|
|
19
|
+
* @param featureIds
|
|
20
|
+
* @param propertyTable
|
|
21
|
+
* @returns
|
|
22
|
+
*/
|
|
23
|
+
export declare function checkPropertiesLength(featureIds: number[], propertyTable: FeatureTableJson): boolean;
|
|
24
|
+
//# sourceMappingURL=feature-attributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-attributes.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/feature-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAE3D;;;;;;;;;;;;GAYG;AACH,wBAAgB,gCAAgC,CAC9C,UAAU,EAAE,MAAM,EAAE,EACpB,aAAa,EAAE,gBAAgB,GAC9B,gBAAgB,CAQlB;AAkBD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAAE,EACpB,aAAa,EAAE,gBAAgB,GAC9B,OAAO,CAUT"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkPropertiesLength = exports.flattenPropertyTableByFeatureIds = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Takes attributes from property table based on featureIds.
|
|
6
|
+
* If there is no property value for particular featureId (index) the property will be null.
|
|
7
|
+
* Example:
|
|
8
|
+
* Initial data:
|
|
9
|
+
* OBJECTID: [0, 1, 5]
|
|
10
|
+
* component: ['Windows', 'Frames', 'Wall', 'Roof', 'Skylight']
|
|
11
|
+
* Result:
|
|
12
|
+
* OBJECTID: [0, 1, 5]
|
|
13
|
+
* component: ['Windows', 'Frames', 'null']
|
|
14
|
+
* @param featureIds
|
|
15
|
+
* @param propertyTable
|
|
16
|
+
*/
|
|
17
|
+
function flattenPropertyTableByFeatureIds(featureIds, propertyTable) {
|
|
18
|
+
const resultPropertyTable = {};
|
|
19
|
+
for (const propertyName in propertyTable) {
|
|
20
|
+
const properties = propertyTable[propertyName];
|
|
21
|
+
resultPropertyTable[propertyName] = getPropertiesByFeatureIds(properties, featureIds);
|
|
22
|
+
}
|
|
23
|
+
return resultPropertyTable;
|
|
24
|
+
}
|
|
25
|
+
exports.flattenPropertyTableByFeatureIds = flattenPropertyTableByFeatureIds;
|
|
26
|
+
/**
|
|
27
|
+
* Getting properties by featureId index
|
|
28
|
+
* @param properties
|
|
29
|
+
* @param featureIds
|
|
30
|
+
*/
|
|
31
|
+
function getPropertiesByFeatureIds(properties, featureIds) {
|
|
32
|
+
const resultProperties = [];
|
|
33
|
+
for (const featureId of featureIds) {
|
|
34
|
+
const property = properties[featureId] || null;
|
|
35
|
+
resultProperties.push(property);
|
|
36
|
+
}
|
|
37
|
+
return resultProperties;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check that all attributes in propertyTable have the same length as FeatureIds.
|
|
41
|
+
* If there are differencies between lengths we should flatten property table based on exiesting featureIds.
|
|
42
|
+
* @param featureIds
|
|
43
|
+
* @param propertyTable
|
|
44
|
+
* @returns
|
|
45
|
+
*/
|
|
46
|
+
function checkPropertiesLength(featureIds, propertyTable) {
|
|
47
|
+
let needFlatten = false;
|
|
48
|
+
for (const attribute of Object.values(propertyTable)) {
|
|
49
|
+
if (featureIds.length !== attribute.length) {
|
|
50
|
+
needFlatten = true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return needFlatten;
|
|
54
|
+
}
|
|
55
|
+
exports.checkPropertiesLength = checkPropertiesLength;
|
|
@@ -38,30 +38,49 @@ exports.generateAttributes = generateAttributes;
|
|
|
38
38
|
function calculateFaceRangesAndFeaturesCount(featureIndices) {
|
|
39
39
|
let rangeIndex = 1;
|
|
40
40
|
let featureIndex = 1;
|
|
41
|
-
let currentFeatureId = featureIndices
|
|
41
|
+
let currentFeatureId = getFrequentValue(featureIndices.slice(0, VALUES_PER_VERTEX));
|
|
42
42
|
const faceRangeList = [];
|
|
43
43
|
const featureIds = [];
|
|
44
44
|
const uniqueFeatureIds = [currentFeatureId];
|
|
45
45
|
faceRangeList[0] = 0;
|
|
46
46
|
featureIds[0] = currentFeatureId;
|
|
47
|
-
for (let index =
|
|
48
|
-
|
|
47
|
+
for (let index = VALUES_PER_VERTEX; index < featureIndices.length; index += VALUES_PER_VERTEX) {
|
|
48
|
+
const newFeatureId = getFrequentValue(featureIndices.slice(index, index + VALUES_PER_VERTEX));
|
|
49
|
+
if (currentFeatureId !== newFeatureId) {
|
|
49
50
|
faceRangeList[rangeIndex] = index / VALUES_PER_VERTEX - 1;
|
|
50
51
|
faceRangeList[rangeIndex + 1] = index / VALUES_PER_VERTEX;
|
|
51
|
-
featureIds[featureIndex] =
|
|
52
|
-
if (!uniqueFeatureIds.includes(
|
|
53
|
-
uniqueFeatureIds.push(
|
|
52
|
+
featureIds[featureIndex] = newFeatureId;
|
|
53
|
+
if (!uniqueFeatureIds.includes(newFeatureId)) {
|
|
54
|
+
uniqueFeatureIds.push(newFeatureId);
|
|
54
55
|
}
|
|
55
56
|
rangeIndex += 2;
|
|
56
57
|
featureIndex += 1;
|
|
57
58
|
}
|
|
58
|
-
currentFeatureId =
|
|
59
|
+
currentFeatureId = newFeatureId;
|
|
59
60
|
}
|
|
60
61
|
faceRangeList[rangeIndex] = featureIndices.length / VALUES_PER_VERTEX - 1;
|
|
61
62
|
const faceRange = new Uint32Array(faceRangeList);
|
|
62
63
|
const featureCount = uniqueFeatureIds.length;
|
|
63
64
|
return { faceRange, featureCount, featureIds };
|
|
64
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Find most frequent value to avoid situation where one vertex can be part of multiple features (objects).
|
|
68
|
+
* @param values
|
|
69
|
+
*/
|
|
70
|
+
function getFrequentValue(values) {
|
|
71
|
+
const map = {};
|
|
72
|
+
let mostFrequentValue = values[0];
|
|
73
|
+
let maxCount = 1;
|
|
74
|
+
for (const value of values) {
|
|
75
|
+
// Save item and it's frequency count to the map.
|
|
76
|
+
map[value] = (map[value] || 0) + 1;
|
|
77
|
+
// Find max count of frequency.
|
|
78
|
+
maxCount = maxCount > map[value] ? maxCount : map[value];
|
|
79
|
+
// Find the most frequent value.
|
|
80
|
+
mostFrequentValue = maxCount > map[value] ? mostFrequentValue : value;
|
|
81
|
+
}
|
|
82
|
+
return mostFrequentValue;
|
|
83
|
+
}
|
|
65
84
|
/**
|
|
66
85
|
* Generate list of attribute object grouped by feature ids.
|
|
67
86
|
* @param attributes
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { B3DMContent, FeatureTableJson } from '@loaders.gl/3d-tiles';
|
|
2
|
+
import { Tile3D } from '@loaders.gl/tiles';
|
|
1
3
|
import { ConvertedAttributes, I3SConvertedResources } from '../types';
|
|
2
|
-
import { B3DMContent } from '@loaders.gl/3d-tiles';
|
|
3
4
|
import { AttributeStorageInfo } from '@loaders.gl/i3s';
|
|
4
5
|
import { Geoid } from '@math.gl/geoid';
|
|
5
6
|
import { B3DMAttributesData } from '../../i3s-attributes-worker';
|
|
@@ -15,7 +16,7 @@ import { B3DMAttributesData } from '../../i3s-attributes-worker';
|
|
|
15
16
|
* @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
|
|
16
17
|
* @returns Array of node resources to create one or more i3s nodes
|
|
17
18
|
*/
|
|
18
|
-
export default function convertB3dmToI3sGeometry(tileContent: B3DMContent, nodeId: number, featuresHashArray: string[], attributeStorageInfo: AttributeStorageInfo[] | undefined, draco: boolean, generateBoundingVolumes: boolean, geoidHeightModel: Geoid, workerSource: {
|
|
19
|
+
export default function convertB3dmToI3sGeometry(tileContent: B3DMContent, nodeId: number, propertyTable: FeatureTableJson | null, featuresHashArray: string[], attributeStorageInfo: AttributeStorageInfo[] | undefined, draco: boolean, generateBoundingVolumes: boolean, geoidHeightModel: Geoid, workerSource: {
|
|
19
20
|
[key: string]: string;
|
|
20
21
|
}): Promise<I3SConvertedResources[] | null>;
|
|
21
22
|
/**
|
|
@@ -26,4 +27,10 @@ export default function convertB3dmToI3sGeometry(tileContent: B3DMContent, nodeI
|
|
|
26
27
|
* @returns map of converted geometry attributes
|
|
27
28
|
*/
|
|
28
29
|
export declare function convertAttributes(attributesData: B3DMAttributesData, useCartesianPositions: boolean): Promise<Map<string, ConvertedAttributes>>;
|
|
30
|
+
/**
|
|
31
|
+
* Find property table in tile
|
|
32
|
+
* For example it can be batchTable for b3dm files or property table in gLTF extension.
|
|
33
|
+
* @param sourceTile
|
|
34
|
+
*/
|
|
35
|
+
export declare function getPropertyTable(sourceTile: Tile3D): FeatureTableJson | null;
|
|
29
36
|
//# sourceMappingURL=geometry-converter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry-converter.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-converter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"geometry-converter.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-converter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,WAAW,EAAE,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAQxE,OAAO,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAKzC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EAGtB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,oBAAoB,EAIrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAC,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAMrC,OAAO,EAAC,kBAAkB,EAAqC,MAAM,6BAA6B,CAAC;AA6BnG;;;;;;;;;;;GAWG;AACH,wBAA8B,wBAAwB,CACpD,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,gBAAgB,GAAG,IAAI,EACtC,iBAAiB,EAAE,MAAM,EAAE,EAC3B,oBAAoB,EAAE,oBAAoB,EAAE,GAAG,SAAS,EACxD,KAAK,EAAE,OAAO,EACd,uBAAuB,EAAE,OAAO,EAChC,gBAAgB,EAAE,KAAK,EACvB,YAAY,EAAE;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAC,2CAqEtC;AAuID;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,cAAc,EAAE,kBAAkB,EAClC,qBAAqB,EAAE,OAAO,GAC7B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CA0C3C;AAu7BD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAoB5E"}
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.convertAttributes = void 0;
|
|
6
|
+
exports.getPropertyTable = exports.convertAttributes = void 0;
|
|
7
7
|
const core_1 = require("@math.gl/core");
|
|
8
8
|
const geospatial_1 = require("@math.gl/geospatial");
|
|
9
9
|
const draco_1 = require("@loaders.gl/draco");
|
|
@@ -13,6 +13,8 @@ const md5_1 = __importDefault(require("md5"));
|
|
|
13
13
|
const geometry_attributes_1 = require("./geometry-attributes");
|
|
14
14
|
const coordinate_converter_1 = require("./coordinate-converter");
|
|
15
15
|
const gltf_attributes_1 = require("./gltf-attributes");
|
|
16
|
+
const batch_ids_extensions_1 = require("./batch-ids-extensions");
|
|
17
|
+
const feature_attributes_1 = require("./feature-attributes");
|
|
16
18
|
// Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.7/pbrMetallicRoughness.cmn.md
|
|
17
19
|
const DEFAULT_ROUGHNESS_FACTOR = 1;
|
|
18
20
|
const DEFAULT_METALLIC_FACTOR = 1;
|
|
@@ -29,6 +31,8 @@ const OBJECT_ID_TYPE = 'Oid32';
|
|
|
29
31
|
* BATCHID - Legacy attribute name which includes batch info.
|
|
30
32
|
*/
|
|
31
33
|
const BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES = ['CUSTOM_ATTRIBUTE_2', '_BATCHID', 'BATCHID'];
|
|
34
|
+
const EXT_FEATURE_METADATA = 'EXT_feature_metadata';
|
|
35
|
+
const EXT_MESH_FEATURES = 'EXT_mesh_features';
|
|
32
36
|
let scratchVector = new core_1.Vector3();
|
|
33
37
|
/**
|
|
34
38
|
* Convert binary data from b3dm file to i3s resources
|
|
@@ -42,7 +46,7 @@ let scratchVector = new core_1.Vector3();
|
|
|
42
46
|
* @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
|
|
43
47
|
* @returns Array of node resources to create one or more i3s nodes
|
|
44
48
|
*/
|
|
45
|
-
async function convertB3dmToI3sGeometry(tileContent, nodeId, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, geoidHeightModel, workerSource) {
|
|
49
|
+
async function convertB3dmToI3sGeometry(tileContent, nodeId, propertyTable, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, geoidHeightModel, workerSource) {
|
|
46
50
|
const useCartesianPositions = generateBoundingVolumes;
|
|
47
51
|
const materialAndTextureList = convertMaterials(tileContent.gltf?.materials);
|
|
48
52
|
const dataForAttributesConversion = (0, gltf_attributes_1.prepareDataForAttributesConversion)(tileContent);
|
|
@@ -86,6 +90,7 @@ async function convertB3dmToI3sGeometry(tileContent, nodeId, featuresHashArray,
|
|
|
86
90
|
tileContent,
|
|
87
91
|
nodeId: nodesCounter,
|
|
88
92
|
featuresHashArray,
|
|
93
|
+
propertyTable,
|
|
89
94
|
attributeStorageInfo,
|
|
90
95
|
draco,
|
|
91
96
|
workerSource
|
|
@@ -131,7 +136,7 @@ function _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeigh
|
|
|
131
136
|
* @param params.draco - is converter should create draco compressed geometry
|
|
132
137
|
* @returns Array of I3S node resources
|
|
133
138
|
*/
|
|
134
|
-
async function _makeNodeResources({ convertedAttributes, material, texture, tileContent, nodeId, featuresHashArray, attributeStorageInfo, draco, workerSource }) {
|
|
139
|
+
async function _makeNodeResources({ convertedAttributes, material, texture, tileContent, nodeId, featuresHashArray, propertyTable, attributeStorageInfo, draco, workerSource }) {
|
|
135
140
|
const boundingVolumes = convertedAttributes.boundingVolumes;
|
|
136
141
|
const vertexCount = convertedAttributes.positions.length / VALUES_PER_VERTEX;
|
|
137
142
|
const { faceRange, featureIds, positions, normals, colors, texCoords, featureCount } = (0, geometry_attributes_1.generateAttributes)(convertedAttributes);
|
|
@@ -152,7 +157,10 @@ async function _makeNodeResources({ convertedAttributes, material, texture, tile
|
|
|
152
157
|
faceRange
|
|
153
158
|
}, workerSource.draco)
|
|
154
159
|
: null;
|
|
155
|
-
|
|
160
|
+
let attributes = [];
|
|
161
|
+
if (attributeStorageInfo && propertyTable) {
|
|
162
|
+
attributes = convertPropertyTableToAttributeBuffers(featureIds, propertyTable, attributeStorageInfo);
|
|
163
|
+
}
|
|
156
164
|
return {
|
|
157
165
|
geometry: fileBuffer,
|
|
158
166
|
compressedGeometry,
|
|
@@ -258,8 +266,9 @@ function getCompositeTransformationMatrix(node, matrix) {
|
|
|
258
266
|
function convertNode(node, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions, matrix = new core_1.Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])) {
|
|
259
267
|
const transformationMatrix = getCompositeTransformationMatrix(node, matrix);
|
|
260
268
|
const mesh = node.mesh;
|
|
269
|
+
const images = node.images;
|
|
261
270
|
if (mesh) {
|
|
262
|
-
convertMesh(mesh, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions, transformationMatrix);
|
|
271
|
+
convertMesh(mesh, images, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions, transformationMatrix);
|
|
263
272
|
}
|
|
264
273
|
convertNodes(node.children || [], cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions, transformationMatrix);
|
|
265
274
|
}
|
|
@@ -274,7 +283,7 @@ function convertNode(node, cartographicOrigin, cartesianModelMatrix, attributesM
|
|
|
274
283
|
|
|
275
284
|
* @param {Matrix4} matrix - transformation matrix - cumulative transformation matrix formed from all parent node matrices
|
|
276
285
|
*/
|
|
277
|
-
function convertMesh(mesh, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions = false, matrix = new core_1.Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])) {
|
|
286
|
+
function convertMesh(mesh, images, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions = false, matrix = new core_1.Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])) {
|
|
278
287
|
for (const primitive of mesh.primitives) {
|
|
279
288
|
let outputAttributes = null;
|
|
280
289
|
if (primitive.material) {
|
|
@@ -309,7 +318,7 @@ function convertMesh(mesh, cartographicOrigin, cartesianModelMatrix, attributesM
|
|
|
309
318
|
outputAttributes.texCoords = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.texCoords, flattenTexCoords(attributes.TEXCOORD_0 && attributes.TEXCOORD_0.value, primitive.indices?.value));
|
|
310
319
|
outputAttributes.colors = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.colors, flattenColors(attributes.COLOR_0, primitive.indices?.value));
|
|
311
320
|
outputAttributes.featureIndicesGroups = outputAttributes.featureIndicesGroups || [];
|
|
312
|
-
outputAttributes.featureIndicesGroups.push(flattenBatchIds(
|
|
321
|
+
outputAttributes.featureIndicesGroups.push(flattenBatchIds(getBatchIds(attributes, primitive, images), primitive.indices?.value));
|
|
313
322
|
}
|
|
314
323
|
}
|
|
315
324
|
/**
|
|
@@ -446,21 +455,24 @@ function flattenBatchIds(batchedIds, indices) {
|
|
|
446
455
|
return newBatchIds;
|
|
447
456
|
}
|
|
448
457
|
/**
|
|
449
|
-
*
|
|
450
|
-
* @param attributes
|
|
451
|
-
* @
|
|
458
|
+
* Get batchIds for featureIds creation
|
|
459
|
+
* @param attributes
|
|
460
|
+
* @param primitive
|
|
461
|
+
* @param textures
|
|
452
462
|
*/
|
|
453
|
-
function
|
|
454
|
-
|
|
463
|
+
function getBatchIds(attributes, primitive, images) {
|
|
464
|
+
const batchIds = (0, batch_ids_extensions_1.handleBatchIdsExtensions)(attributes, primitive, images);
|
|
465
|
+
if (batchIds.length) {
|
|
466
|
+
return batchIds;
|
|
467
|
+
}
|
|
455
468
|
for (let index = 0; index < BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES.length; index++) {
|
|
456
469
|
const possibleBatchIdAttributeName = BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES[index];
|
|
457
470
|
if (attributes[possibleBatchIdAttributeName] &&
|
|
458
471
|
attributes[possibleBatchIdAttributeName].value) {
|
|
459
|
-
|
|
460
|
-
break;
|
|
472
|
+
return attributes[possibleBatchIdAttributeName].value;
|
|
461
473
|
}
|
|
462
474
|
}
|
|
463
|
-
return
|
|
475
|
+
return [];
|
|
464
476
|
}
|
|
465
477
|
/**
|
|
466
478
|
* Convert GLTF material to I3S material definitions and textures
|
|
@@ -738,43 +750,53 @@ function replaceIndicesByUnique(indicesArray, featureMap) {
|
|
|
738
750
|
}
|
|
739
751
|
}
|
|
740
752
|
/**
|
|
741
|
-
* Convert
|
|
742
|
-
* @param {Object}
|
|
753
|
+
* Convert property table data to attribute buffers.
|
|
754
|
+
* @param {Object} propertyTable - table with metadata for particular feature.
|
|
743
755
|
* @param {Array} featureIds
|
|
744
756
|
* @param {Array} attributeStorageInfo
|
|
745
757
|
* @returns {Array} - Array of file buffers.
|
|
746
758
|
*/
|
|
747
|
-
function
|
|
759
|
+
function convertPropertyTableToAttributeBuffers(featureIds, propertyTable, attributeStorageInfo) {
|
|
748
760
|
const attributeBuffers = [];
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
case DOUBLE_TYPE:
|
|
763
|
-
attributeBuffer = generateDoubleAttributeBuffer(batchTableWithFeatureIds[key]);
|
|
764
|
-
break;
|
|
765
|
-
case STRING_TYPE:
|
|
766
|
-
attributeBuffer = generateStringAttributeBuffer(batchTableWithFeatureIds[key]);
|
|
767
|
-
break;
|
|
768
|
-
default:
|
|
769
|
-
attributeBuffer = generateStringAttributeBuffer(batchTableWithFeatureIds[key]);
|
|
770
|
-
}
|
|
771
|
-
if (attributeBuffer) {
|
|
772
|
-
attributeBuffers.push(attributeBuffer);
|
|
773
|
-
}
|
|
774
|
-
}
|
|
761
|
+
const needFlattenPropertyTable = (0, feature_attributes_1.checkPropertiesLength)(featureIds, propertyTable);
|
|
762
|
+
const properties = needFlattenPropertyTable
|
|
763
|
+
? (0, feature_attributes_1.flattenPropertyTableByFeatureIds)(featureIds, propertyTable)
|
|
764
|
+
: propertyTable;
|
|
765
|
+
const propertyTableWithObjectIds = {
|
|
766
|
+
OBJECTID: featureIds,
|
|
767
|
+
...properties
|
|
768
|
+
};
|
|
769
|
+
for (const propertyName in propertyTableWithObjectIds) {
|
|
770
|
+
const type = getAttributeType(propertyName, attributeStorageInfo);
|
|
771
|
+
const value = propertyTableWithObjectIds[propertyName];
|
|
772
|
+
const attributeBuffer = generateAttributeBuffer(type, value);
|
|
773
|
+
attributeBuffers.push(attributeBuffer);
|
|
775
774
|
}
|
|
776
775
|
return attributeBuffers;
|
|
777
776
|
}
|
|
777
|
+
/**
|
|
778
|
+
* Generates attribute buffer based on attribute type
|
|
779
|
+
* @param type
|
|
780
|
+
* @param value
|
|
781
|
+
*/
|
|
782
|
+
function generateAttributeBuffer(type, value) {
|
|
783
|
+
let attributeBuffer;
|
|
784
|
+
switch (type) {
|
|
785
|
+
case OBJECT_ID_TYPE:
|
|
786
|
+
case SHORT_INT_TYPE:
|
|
787
|
+
attributeBuffer = generateShortIntegerAttributeBuffer(value);
|
|
788
|
+
break;
|
|
789
|
+
case DOUBLE_TYPE:
|
|
790
|
+
attributeBuffer = generateDoubleAttributeBuffer(value);
|
|
791
|
+
break;
|
|
792
|
+
case STRING_TYPE:
|
|
793
|
+
attributeBuffer = generateStringAttributeBuffer(value);
|
|
794
|
+
break;
|
|
795
|
+
default:
|
|
796
|
+
attributeBuffer = generateStringAttributeBuffer(value);
|
|
797
|
+
}
|
|
798
|
+
return attributeBuffer;
|
|
799
|
+
}
|
|
778
800
|
/**
|
|
779
801
|
* Return attribute type.
|
|
780
802
|
* @param {String} key
|
|
@@ -899,3 +921,77 @@ function generateFeatureIndexAttribute(featureIndex, faceRange) {
|
|
|
899
921
|
}
|
|
900
922
|
return orderedFeatureIndices;
|
|
901
923
|
}
|
|
924
|
+
/**
|
|
925
|
+
* Find property table in tile
|
|
926
|
+
* For example it can be batchTable for b3dm files or property table in gLTF extension.
|
|
927
|
+
* @param sourceTile
|
|
928
|
+
*/
|
|
929
|
+
function getPropertyTable(sourceTile) {
|
|
930
|
+
const batchTableJson = sourceTile?.content?.batchTableJson;
|
|
931
|
+
if (batchTableJson) {
|
|
932
|
+
return batchTableJson;
|
|
933
|
+
}
|
|
934
|
+
const { extensionName, extension } = getPropertyTableExtension(sourceTile);
|
|
935
|
+
switch (extensionName) {
|
|
936
|
+
case EXT_MESH_FEATURES: {
|
|
937
|
+
console.warn('The I3S converter does not yet support the EXT_mesh_features extension');
|
|
938
|
+
return null;
|
|
939
|
+
}
|
|
940
|
+
case EXT_FEATURE_METADATA: {
|
|
941
|
+
return getPropertyTableFromExtFeatureMetadata(extension);
|
|
942
|
+
}
|
|
943
|
+
default:
|
|
944
|
+
return null;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
exports.getPropertyTable = getPropertyTable;
|
|
948
|
+
/**
|
|
949
|
+
* Check extensions which can be with property table inside.
|
|
950
|
+
* @param sourceTile
|
|
951
|
+
*/
|
|
952
|
+
function getPropertyTableExtension(sourceTile) {
|
|
953
|
+
const extensionsWithPropertyTables = [EXT_FEATURE_METADATA, EXT_MESH_FEATURES];
|
|
954
|
+
const extensionsUsed = sourceTile?.content?.gltf?.extensionsUsed;
|
|
955
|
+
if (!extensionsUsed) {
|
|
956
|
+
return { extensionName: null, extension: null };
|
|
957
|
+
}
|
|
958
|
+
let extensionName = '';
|
|
959
|
+
for (const extensionItem of sourceTile?.content?.gltf?.extensionsUsed) {
|
|
960
|
+
if (extensionsWithPropertyTables.includes(extensionItem)) {
|
|
961
|
+
extensionName = extensionItem;
|
|
962
|
+
break;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
const extension = sourceTile?.content?.gltf?.extensions?.[extensionName];
|
|
966
|
+
return { extensionName, extension };
|
|
967
|
+
}
|
|
968
|
+
/**
|
|
969
|
+
* Handle EXT_feature_metadata to get property table
|
|
970
|
+
* @param extension
|
|
971
|
+
* TODO add EXT_feature_metadata feature textures support.
|
|
972
|
+
*/
|
|
973
|
+
function getPropertyTableFromExtFeatureMetadata(extension) {
|
|
974
|
+
if (extension?.featureTextures) {
|
|
975
|
+
console.warn('The I3S converter does not yet support the EXT_feature_metadata feature textures');
|
|
976
|
+
return null;
|
|
977
|
+
}
|
|
978
|
+
if (extension?.featureTables) {
|
|
979
|
+
/**
|
|
980
|
+
* Take only first feature table to generate attributes storage info object.
|
|
981
|
+
* TODO: Think about getting data from all feature tables?
|
|
982
|
+
* It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
|
|
983
|
+
* In I3S we should decide which featureIds attribute will be passed to geometry data.
|
|
984
|
+
*/
|
|
985
|
+
const firstFeatureTableName = Object.keys(extension.featureTables)?.[0];
|
|
986
|
+
if (firstFeatureTableName) {
|
|
987
|
+
const featureTable = extension?.featureTables[firstFeatureTableName];
|
|
988
|
+
const propertyTable = {};
|
|
989
|
+
for (const propertyName in featureTable.properties) {
|
|
990
|
+
propertyTable[propertyName] = featureTable.properties[propertyName].data;
|
|
991
|
+
}
|
|
992
|
+
return propertyTable;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
console.warn("The I3S converter couldn't handle EXT_feature_metadata extension");
|
|
996
|
+
return null;
|
|
997
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gltf-attributes.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/gltf-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,6BAA6B,CAAC;AAsBpE;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,WAAW,EAAE,WAAW,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"gltf-attributes.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/gltf-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,6BAA6B,CAAC;AAsBpE;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,WAAW,EAAE,WAAW,GAAG,kBAAkB,CAqD/F"}
|
|
@@ -25,12 +25,25 @@ function prepareDataForAttributesConversion(tileContent) {
|
|
|
25
25
|
tileContent.gltf?.scenes?.[0]?.nodes ||
|
|
26
26
|
tileContent.gltf?.nodes ||
|
|
27
27
|
[];
|
|
28
|
+
const images = tileContent.gltf?.images?.map((imageObject) => {
|
|
29
|
+
// Need data only for uncompressed images because we can't get batchIds from compressed textures.
|
|
30
|
+
const data = imageObject?.image?.compressed ? null : imageObject?.image?.data.subarray();
|
|
31
|
+
return {
|
|
32
|
+
data,
|
|
33
|
+
compressed: Boolean(imageObject?.image?.compressed),
|
|
34
|
+
height: imageObject.image.height,
|
|
35
|
+
width: imageObject.image.width,
|
|
36
|
+
components: imageObject.image.components,
|
|
37
|
+
mimeType: imageObject.mimeType
|
|
38
|
+
};
|
|
39
|
+
}) || [];
|
|
28
40
|
const prepearedNodes = nodes.map((node) => {
|
|
29
41
|
if (!node.mesh) {
|
|
30
42
|
return node;
|
|
31
43
|
}
|
|
32
44
|
return {
|
|
33
45
|
...node,
|
|
46
|
+
images,
|
|
34
47
|
mesh: {
|
|
35
48
|
...node.mesh,
|
|
36
49
|
primitives: node.mesh?.primitives.map((primitive) => ({
|