@loaders.gl/tile-converter 3.3.0-alpha.8 → 3.3.0
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 +2 -2
- package/dist/3d-tiles-attributes-worker.js.map +3 -3
- package/dist/converter-cli.js +14 -2
- package/dist/converter.min.js +22 -22
- package/dist/deps-installer/deps-installer.d.ts.map +1 -1
- package/dist/deps-installer/deps-installer.js +8 -0
- package/dist/dist.min.js +1165 -846
- 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 +14 -2
- package/dist/es5/converter-cli.js.map +1 -1
- package/dist/es5/deps-installer/deps-installer.js +13 -2
- package/dist/es5/deps-installer/deps-installer.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.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js +16 -7
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-converter.js +363 -113
- package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/gltf-attributes.js +6 -11
- package/dist/es5/i3s-converter/helpers/gltf-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/node-index-document.js +517 -0
- package/dist/es5/i3s-converter/helpers/node-index-document.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/node-pages.js +455 -173
- package/dist/es5/i3s-converter/helpers/node-pages.js.map +1 -1
- package/dist/es5/i3s-converter/i3s-converter.js +549 -618
- package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/es5/i3s-converter/json-templates/geometry-definitions.js +107 -0
- package/dist/es5/i3s-converter/json-templates/geometry-definitions.js.map +1 -0
- package/dist/es5/i3s-converter/json-templates/layers.js +2 -93
- package/dist/es5/i3s-converter/json-templates/layers.js.map +1 -1
- package/dist/es5/i3s-converter/json-templates/shared-resources.js +3 -3
- package/dist/es5/i3s-converter/json-templates/shared-resources.js.map +1 -1
- package/dist/es5/i3s-converter/types.js.map +1 -1
- package/dist/es5/lib/utils/file-utils.js +93 -9
- package/dist/es5/lib/utils/file-utils.js.map +1 -1
- package/dist/es5/lib/utils/write-queue.js +38 -25
- 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/es5/workers/i3s-attributes-worker.js +1 -1
- package/dist/es5/workers/i3s-attributes-worker.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 +14 -2
- package/dist/esm/converter-cli.js.map +1 -1
- package/dist/esm/deps-installer/deps-installer.js +9 -1
- package/dist/esm/deps-installer/deps-installer.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.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js +16 -7
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-converter.js +150 -40
- package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/gltf-attributes.js +6 -9
- package/dist/esm/i3s-converter/helpers/gltf-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/node-index-document.js +202 -0
- package/dist/esm/i3s-converter/helpers/node-index-document.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/node-pages.js +162 -76
- package/dist/esm/i3s-converter/helpers/node-pages.js.map +1 -1
- package/dist/esm/i3s-converter/i3s-converter.js +115 -220
- package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/esm/i3s-converter/json-templates/geometry-definitions.js +89 -0
- package/dist/esm/i3s-converter/json-templates/geometry-definitions.js.map +1 -0
- package/dist/esm/i3s-converter/json-templates/layers.js +2 -85
- package/dist/esm/i3s-converter/json-templates/layers.js.map +1 -1
- package/dist/esm/i3s-converter/json-templates/shared-resources.js +3 -3
- package/dist/esm/i3s-converter/json-templates/shared-resources.js.map +1 -1
- package/dist/esm/i3s-converter/types.js.map +1 -1
- package/dist/esm/lib/utils/file-utils.js +44 -3
- package/dist/esm/lib/utils/file-utils.js.map +1 -1
- package/dist/esm/lib/utils/write-queue.js +19 -10
- 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/esm/workers/i3s-attributes-worker.js +1 -1
- package/dist/esm/workers/i3s-attributes-worker.js.map +1 -1
- package/dist/i3s-attributes-worker.js +2 -2
- package/dist/i3s-attributes-worker.js.map +2 -2
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +3 -3
- package/dist/i3s-converter/helpers/batch-ids-extensions.js +3 -3
- package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-attributes.js +16 -10
- package/dist/i3s-converter/helpers/geometry-converter.d.ts +8 -4
- package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.js +200 -44
- package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/gltf-attributes.js +2 -3
- package/dist/i3s-converter/helpers/node-index-document.d.ts +95 -0
- package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/node-index-document.js +250 -0
- package/dist/i3s-converter/helpers/node-pages.d.ts +78 -43
- package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/node-pages.js +195 -94
- package/dist/i3s-converter/i3s-converter.d.ts +33 -58
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.js +122 -233
- package/dist/i3s-converter/json-templates/geometry-definitions.d.ts +7 -0
- package/dist/i3s-converter/json-templates/geometry-definitions.d.ts.map +1 -0
- package/dist/i3s-converter/json-templates/geometry-definitions.js +87 -0
- package/dist/i3s-converter/json-templates/layers.d.ts +1 -30
- package/dist/i3s-converter/json-templates/layers.d.ts.map +1 -1
- package/dist/i3s-converter/json-templates/layers.js +2 -86
- package/dist/i3s-converter/json-templates/shared-resources.js +3 -3
- package/dist/i3s-converter/types.d.ts +28 -2
- package/dist/i3s-converter/types.d.ts.map +1 -1
- package/dist/lib/utils/file-utils.d.ts +17 -1
- package/dist/lib/utils/file-utils.d.ts.map +1 -1
- package/dist/lib/utils/file-utils.js +64 -7
- package/dist/lib/utils/write-queue.d.ts +18 -2
- package/dist/lib/utils/write-queue.d.ts.map +1 -1
- package/dist/lib/utils/write-queue.js +18 -12
- package/dist/workers/i3s-attributes-worker.js +1 -1
- package/package.json +25 -20
- package/src/converter-cli.ts +22 -2
- package/src/deps-installer/deps-installer.ts +9 -0
- package/src/i3s-converter/helpers/batch-ids-extensions.ts +3 -3
- package/src/i3s-converter/helpers/geometry-attributes.ts +16 -11
- package/src/i3s-converter/helpers/geometry-converter.ts +217 -48
- package/src/i3s-converter/helpers/gltf-attributes.ts +2 -3
- package/src/i3s-converter/helpers/node-index-document.ts +315 -0
- package/src/i3s-converter/helpers/node-pages.ts +215 -110
- package/src/i3s-converter/i3s-converter.ts +170 -312
- package/src/i3s-converter/json-templates/geometry-definitions.ts +83 -0
- package/src/i3s-converter/json-templates/layers.ts +2 -91
- package/src/i3s-converter/json-templates/shared-resources.ts +3 -3
- package/src/i3s-converter/types.ts +29 -2
- package/src/lib/utils/file-utils.ts +62 -7
- package/src/lib/utils/write-queue.ts +36 -15
- package/src/workers/i3s-attributes-worker.ts +2 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { GLTFAccessorPostprocessed, GLTFImagePostprocessed, GLTFMeshPrimitivePostprocessed } from '@loaders.gl/gltf';
|
|
2
2
|
/**
|
|
3
3
|
* Getting batchIds from 3DTilesNext extensions.
|
|
4
|
-
* @param attributes
|
|
5
|
-
* @param primitive
|
|
6
|
-
* @param
|
|
4
|
+
* @param attributes - gltf accessors
|
|
5
|
+
* @param primitive - gltf primitive data
|
|
6
|
+
* @param images - gltf texture images
|
|
7
7
|
*/
|
|
8
8
|
export declare function handleBatchIdsExtensions(attributes: {
|
|
9
9
|
[key: string]: GLTFAccessorPostprocessed;
|
|
@@ -5,9 +5,9 @@ const EXT_MESH_FEATURES = 'EXT_mesh_features';
|
|
|
5
5
|
const EXT_FEATURE_METADATA = 'EXT_feature_metadata';
|
|
6
6
|
/**
|
|
7
7
|
* Getting batchIds from 3DTilesNext extensions.
|
|
8
|
-
* @param attributes
|
|
9
|
-
* @param primitive
|
|
10
|
-
* @param
|
|
8
|
+
* @param attributes - gltf accessors
|
|
9
|
+
* @param primitive - gltf primitive data
|
|
10
|
+
* @param images - gltf texture images
|
|
11
11
|
*/
|
|
12
12
|
function handleBatchIdsExtensions(attributes, primitive, images) {
|
|
13
13
|
const extensions = primitive?.extensions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry-attributes.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAE,mBAAmB,EAA+B,MAAM,UAAU,CAAC;AAMpG;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,mBAAmB,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"geometry-attributes.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAE,mBAAmB,EAA+B,MAAM,UAAU,CAAC;AAMpG;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,mBAAmB,GAAG,kBAAkB,CAyBtF"}
|
|
@@ -10,7 +10,7 @@ const POSITIONS_AND_NORMALS_PER_TRIANGLE = 9;
|
|
|
10
10
|
* @returns attirbutes with featureCount, featureIds and changed faceRange.
|
|
11
11
|
*/
|
|
12
12
|
function generateAttributes(attributes) {
|
|
13
|
-
const { positions, normals, texCoords, colors, featureIndices } = attributes;
|
|
13
|
+
const { positions, normals, texCoords, colors, uvRegions, featureIndices } = attributes;
|
|
14
14
|
const triangleCount = positions.length / POSITIONS_AND_NORMALS_PER_TRIANGLE;
|
|
15
15
|
if (!featureIndices.length) {
|
|
16
16
|
return {
|
|
@@ -20,7 +20,8 @@ function generateAttributes(attributes) {
|
|
|
20
20
|
positions,
|
|
21
21
|
normals,
|
|
22
22
|
texCoords,
|
|
23
|
-
colors
|
|
23
|
+
colors,
|
|
24
|
+
uvRegions
|
|
24
25
|
};
|
|
25
26
|
}
|
|
26
27
|
const data = calculateFaceRangesAndFeaturesCount(featureIndices);
|
|
@@ -87,32 +88,34 @@ function getFrequentValue(values) {
|
|
|
87
88
|
* @returns sorted list of attribute objects.
|
|
88
89
|
*/
|
|
89
90
|
function makeAttributeObjects(attributes) {
|
|
90
|
-
const { featureIds, positions, normals, colors, texCoords, faceRange = new Uint32Array(0) } = attributes;
|
|
91
|
+
const { featureIds, positions, normals, colors, uvRegions, texCoords, faceRange = new Uint32Array(0) } = attributes;
|
|
91
92
|
const groupedData = [];
|
|
92
93
|
let positionsList = new Float32Array(positions);
|
|
93
94
|
let normalsList = new Float32Array(normals);
|
|
94
95
|
let colorsList = new Uint8Array(colors);
|
|
95
96
|
let texCoordsList = new Float32Array(texCoords);
|
|
96
|
-
let
|
|
97
|
+
let uvRegionsList = new Uint16Array(uvRegions);
|
|
97
98
|
for (let index = 0; index < featureIds.length; index++) {
|
|
98
|
-
const startIndex = faceRange[index
|
|
99
|
-
const endIndex = faceRange[index
|
|
99
|
+
const startIndex = faceRange[index * 2];
|
|
100
|
+
const endIndex = faceRange[index * 2 + 1];
|
|
100
101
|
const positionsCount = getSliceAttributeCount('positions', startIndex, endIndex);
|
|
101
102
|
const normalsCount = getSliceAttributeCount('normals', startIndex, endIndex);
|
|
102
103
|
const colorsCount = getSliceAttributeCount('colors', startIndex, endIndex);
|
|
104
|
+
const uvRegionsCount = getSliceAttributeCount('uvRegions', startIndex, endIndex);
|
|
103
105
|
const texCoordsCount = getSliceAttributeCount('texCoords', startIndex, endIndex);
|
|
104
106
|
groupedData.push({
|
|
105
107
|
featureId: featureIds[index],
|
|
106
108
|
positions: positionsList.slice(0, positionsCount),
|
|
107
109
|
normals: normalsList.slice(0, normalsCount),
|
|
108
110
|
colors: colorsList.slice(0, colorsCount),
|
|
111
|
+
uvRegions: uvRegionsList.slice(0, uvRegionsCount),
|
|
109
112
|
texCoords: texCoordsList.slice(0, texCoordsCount)
|
|
110
113
|
});
|
|
111
114
|
positionsList = positionsList.slice(positionsCount);
|
|
112
115
|
normalsList = normalsList.slice(normalsCount);
|
|
113
116
|
colorsList = colorsList.slice(colorsCount);
|
|
117
|
+
uvRegionsList = uvRegionsList.slice(uvRegionsCount);
|
|
114
118
|
texCoordsList = texCoordsList.slice(texCoordsCount);
|
|
115
|
-
faceRangeIndex += 1;
|
|
116
119
|
}
|
|
117
120
|
return groupedData.sort((first, second) => first.featureId - second.featureId);
|
|
118
121
|
}
|
|
@@ -124,7 +127,7 @@ function makeAttributeObjects(attributes) {
|
|
|
124
127
|
* @returns sliced count
|
|
125
128
|
*/
|
|
126
129
|
function getSliceAttributeCount(attributeName, startIndex, endIndex) {
|
|
127
|
-
const
|
|
130
|
+
const itemsPerVertex4 = 4;
|
|
128
131
|
const texCoordsPerVertex = 2;
|
|
129
132
|
const trianglesCount = endIndex - startIndex + 1;
|
|
130
133
|
const vertexCount = trianglesCount * 3;
|
|
@@ -133,7 +136,8 @@ function getSliceAttributeCount(attributeName, startIndex, endIndex) {
|
|
|
133
136
|
case 'normals':
|
|
134
137
|
return trianglesCount * POSITIONS_AND_NORMALS_PER_TRIANGLE;
|
|
135
138
|
case 'colors':
|
|
136
|
-
|
|
139
|
+
case 'uvRegions':
|
|
140
|
+
return vertexCount * itemsPerVertex4;
|
|
137
141
|
case 'texCoords':
|
|
138
142
|
return vertexCount * texCoordsPerVertex;
|
|
139
143
|
default:
|
|
@@ -173,6 +177,7 @@ function groupAttributesAndRangesByFeatureId(unifiedObjects, featureCount) {
|
|
|
173
177
|
let positions = new Float32Array(firstAttributeObject.positions);
|
|
174
178
|
let normals = new Float32Array(firstAttributeObject.normals);
|
|
175
179
|
let colors = new Uint8Array(firstAttributeObject.colors);
|
|
180
|
+
let uvRegions = new Uint16Array(firstAttributeObject.uvRegions);
|
|
176
181
|
let texCoords = new Float32Array(firstAttributeObject.texCoords);
|
|
177
182
|
const range = [0];
|
|
178
183
|
let objIndex = 0;
|
|
@@ -183,6 +188,7 @@ function groupAttributesAndRangesByFeatureId(unifiedObjects, featureCount) {
|
|
|
183
188
|
positions = (0, loader_utils_1.concatenateTypedArrays)(positions, currentAttributesObject.positions);
|
|
184
189
|
normals = (0, loader_utils_1.concatenateTypedArrays)(normals, currentAttributesObject.normals);
|
|
185
190
|
colors = (0, loader_utils_1.concatenateTypedArrays)(colors, currentAttributesObject.colors);
|
|
191
|
+
uvRegions = (0, loader_utils_1.concatenateTypedArrays)(uvRegions, currentAttributesObject.uvRegions);
|
|
186
192
|
texCoords = (0, loader_utils_1.concatenateTypedArrays)(texCoords, currentAttributesObject.texCoords);
|
|
187
193
|
const groupedObject = unifiedObjects[objIndex];
|
|
188
194
|
range.push(groupedObject.positions.length / POSITIONS_AND_NORMALS_PER_TRIANGLE - 1 + sum);
|
|
@@ -192,5 +198,5 @@ function groupAttributesAndRangesByFeatureId(unifiedObjects, featureCount) {
|
|
|
192
198
|
}
|
|
193
199
|
range.push(positions.length / POSITIONS_AND_NORMALS_PER_TRIANGLE - 1);
|
|
194
200
|
const faceRange = new Uint32Array(range);
|
|
195
|
-
return { faceRange, featureIds, positions, normals, colors, texCoords, featureCount };
|
|
201
|
+
return { faceRange, featureIds, positions, normals, colors, uvRegions, texCoords, featureCount };
|
|
196
202
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { B3DMContent, FeatureTableJson } from '@loaders.gl/3d-tiles';
|
|
2
|
-
import { ConvertedAttributes, I3SConvertedResources } from '../types';
|
|
2
|
+
import { ConvertedAttributes, I3SConvertedResources, I3SMaterialWithTexture } from '../types';
|
|
3
3
|
import { AttributeStorageInfo } from '@loaders.gl/i3s';
|
|
4
4
|
import { Geoid } from '@math.gl/geoid';
|
|
5
5
|
/** Usage of worker here brings more overhead than advantage */
|
|
@@ -9,24 +9,28 @@ import { B3DMAttributesData } from '../../i3s-attributes-worker';
|
|
|
9
9
|
*
|
|
10
10
|
* @param tileContent - 3d tile content
|
|
11
11
|
* @param addNodeToNodePage - function to add new node to node pages
|
|
12
|
+
* @param propertyTable - batch table (corresponding to feature attributes data)
|
|
12
13
|
* @param featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
|
|
13
14
|
* @param attributeStorageInfo - attributes metadata from 3DSceneLayer json
|
|
14
15
|
* @param draco - is converter should create draco compressed geometry
|
|
15
16
|
* @param generateBoundingVolumes - is converter should create accurate bounding voulmes from geometry attributes
|
|
17
|
+
* @param shouldMergeMaterials - Try to merge similar materials to be able to merge meshes into one node
|
|
16
18
|
* @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
|
|
19
|
+
* @param workerSource - source code of used workers
|
|
17
20
|
* @returns Array of node resources to create one or more i3s nodes
|
|
18
21
|
*/
|
|
19
|
-
export default function convertB3dmToI3sGeometry(tileContent: B3DMContent, addNodeToNodePage: () => number
|
|
22
|
+
export default function convertB3dmToI3sGeometry(tileContent: B3DMContent, addNodeToNodePage: () => Promise<number>, propertyTable: FeatureTableJson | null, featuresHashArray: string[], attributeStorageInfo: AttributeStorageInfo[] | undefined, draco: boolean, generateBoundingVolumes: boolean, shouldMergeMaterials: boolean, geoidHeightModel: Geoid, workerSource: {
|
|
20
23
|
[key: string]: string;
|
|
21
24
|
}): Promise<I3SConvertedResources[] | null>;
|
|
22
25
|
/**
|
|
23
26
|
* Convert attributes from the gltf nodes tree to i3s plain geometry
|
|
24
|
-
* @param
|
|
27
|
+
* @param attributesData - geometry attributes from gltf
|
|
28
|
+
* @param materialAndTextureList - array of data about materials and textures of the content
|
|
25
29
|
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
26
30
|
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
27
31
|
* @returns map of converted geometry attributes
|
|
28
32
|
*/
|
|
29
|
-
export declare function convertAttributes(attributesData: B3DMAttributesData, useCartesianPositions: boolean): Promise<Map<string, ConvertedAttributes>>;
|
|
33
|
+
export declare function convertAttributes(attributesData: B3DMAttributesData, materialAndTextureList: I3SMaterialWithTexture[], useCartesianPositions: boolean): Promise<Map<string, ConvertedAttributes>>;
|
|
30
34
|
/**
|
|
31
35
|
* Find property table in tile
|
|
32
36
|
* For example it can be batchTable for b3dm files or property table in gLTF extension.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry-converter.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-converter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAE,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"geometry-converter.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-converter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAE,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAsBxE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EAGvB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,oBAAoB,EAIrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAC,KAAK,EAAC,MAAM,gBAAgB,CAAC;AACrC,+DAA+D;AAC/D,OAAO,EAAC,kBAAkB,EAAsC,MAAM,6BAA6B,CAAC;AA6BpG;;;;;;;;;;;;;;GAcG;AACH,wBAA8B,wBAAwB,CACpD,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EACxC,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,oBAAoB,EAAE,OAAO,EAC7B,gBAAgB,EAAE,KAAK,EACvB,YAAY,EAAE;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAC,GACpC,OAAO,CAAC,qBAAqB,EAAE,GAAG,IAAI,CAAC,CA0DzC;AA6ID;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,cAAc,EAAE,kBAAkB,EAClC,sBAAsB,EAAE,sBAAsB,EAAE,EAChD,qBAAqB,EAAE,OAAO,GAC7B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAgD3C;AA8lCD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,GAAG,gBAAgB,GAAG,IAAI,CAoBlF"}
|
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
@@ -10,6 +33,7 @@ const draco_1 = require("@loaders.gl/draco");
|
|
|
10
33
|
const core_2 = require("@loaders.gl/core");
|
|
11
34
|
const loader_utils_1 = require("@loaders.gl/loader-utils");
|
|
12
35
|
const md5_1 = __importDefault(require("md5"));
|
|
36
|
+
const uuid_1 = require("uuid");
|
|
13
37
|
const geometry_attributes_1 = require("./geometry-attributes");
|
|
14
38
|
const coordinate_converter_1 = require("./coordinate-converter");
|
|
15
39
|
const gltf_attributes_1 = require("./gltf-attributes");
|
|
@@ -39,18 +63,21 @@ let scratchVector = new core_1.Vector3();
|
|
|
39
63
|
*
|
|
40
64
|
* @param tileContent - 3d tile content
|
|
41
65
|
* @param addNodeToNodePage - function to add new node to node pages
|
|
66
|
+
* @param propertyTable - batch table (corresponding to feature attributes data)
|
|
42
67
|
* @param featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
|
|
43
68
|
* @param attributeStorageInfo - attributes metadata from 3DSceneLayer json
|
|
44
69
|
* @param draco - is converter should create draco compressed geometry
|
|
45
70
|
* @param generateBoundingVolumes - is converter should create accurate bounding voulmes from geometry attributes
|
|
71
|
+
* @param shouldMergeMaterials - Try to merge similar materials to be able to merge meshes into one node
|
|
46
72
|
* @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
|
|
73
|
+
* @param workerSource - source code of used workers
|
|
47
74
|
* @returns Array of node resources to create one or more i3s nodes
|
|
48
75
|
*/
|
|
49
|
-
async function convertB3dmToI3sGeometry(tileContent, addNodeToNodePage, propertyTable, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, geoidHeightModel, workerSource) {
|
|
76
|
+
async function convertB3dmToI3sGeometry(tileContent, addNodeToNodePage, propertyTable, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, shouldMergeMaterials, geoidHeightModel, workerSource) {
|
|
50
77
|
const useCartesianPositions = generateBoundingVolumes;
|
|
51
|
-
const materialAndTextureList = convertMaterials(tileContent.gltf?.materials);
|
|
78
|
+
const materialAndTextureList = await convertMaterials(tileContent.gltf?.materials, shouldMergeMaterials);
|
|
52
79
|
const dataForAttributesConversion = (0, gltf_attributes_1.prepareDataForAttributesConversion)(tileContent);
|
|
53
|
-
const convertedAttributesMap = await convertAttributes(dataForAttributesConversion, useCartesianPositions);
|
|
80
|
+
const convertedAttributesMap = await convertAttributes(dataForAttributesConversion, materialAndTextureList, useCartesianPositions);
|
|
54
81
|
/** Usage of worker here brings more overhead than advantage */
|
|
55
82
|
// const convertedAttributesMap: Map<string, ConvertedAttributes> =
|
|
56
83
|
// await transformI3SAttributesOnWorker(dataForAttributesConversion, {
|
|
@@ -62,27 +89,18 @@ async function convertB3dmToI3sGeometry(tileContent, addNodeToNodePage, property
|
|
|
62
89
|
if (generateBoundingVolumes) {
|
|
63
90
|
_generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeightModel);
|
|
64
91
|
}
|
|
65
|
-
if (convertedAttributesMap.has('default')) {
|
|
66
|
-
materialAndTextureList.push({
|
|
67
|
-
material: getDefaultMaterial()
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
92
|
const result = [];
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
for (let i = 0; i < materials.length; i++) {
|
|
76
|
-
const sourceMaterial = materials[i];
|
|
77
|
-
if (!convertedAttributesMap.has(sourceMaterial.id)) {
|
|
93
|
+
for (const materialAndTexture of materialAndTextureList) {
|
|
94
|
+
const originarMaterialId = materialAndTexture.mergedMaterials[0].originalMaterialId;
|
|
95
|
+
if (!convertedAttributesMap.has(originarMaterialId)) {
|
|
78
96
|
continue; // eslint-disable-line no-continue
|
|
79
97
|
}
|
|
80
|
-
const convertedAttributes = convertedAttributesMap.get(
|
|
98
|
+
const convertedAttributes = convertedAttributesMap.get(originarMaterialId);
|
|
81
99
|
if (!convertedAttributes) {
|
|
82
100
|
continue;
|
|
83
101
|
}
|
|
84
|
-
const { material, texture } =
|
|
85
|
-
const nodeId = addNodeToNodePage();
|
|
102
|
+
const { material, texture } = materialAndTexture;
|
|
103
|
+
const nodeId = await addNodeToNodePage();
|
|
86
104
|
result.push(await _makeNodeResources({
|
|
87
105
|
convertedAttributes,
|
|
88
106
|
material,
|
|
@@ -131,27 +149,30 @@ function _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeigh
|
|
|
131
149
|
* @param params.tileContent - B3DM decoded content
|
|
132
150
|
* @param params.nodeId - new node ID
|
|
133
151
|
* @param params.featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
|
|
134
|
-
* @param params.
|
|
152
|
+
* @param params.propertyTable - batch table (corresponding to feature attributes data)
|
|
153
|
+
* @param params.attributeStorageInfo - attributes metadata from 3DSceneLayer json
|
|
135
154
|
* @param params.draco - is converter should create draco compressed geometry
|
|
155
|
+
* @param params.workerSource - source code of used workers
|
|
136
156
|
* @returns Array of I3S node resources
|
|
137
157
|
*/
|
|
138
158
|
async function _makeNodeResources({ convertedAttributes, material, texture, tileContent, nodeId, featuresHashArray, propertyTable, attributeStorageInfo, draco, workerSource }) {
|
|
139
159
|
const boundingVolumes = convertedAttributes.boundingVolumes;
|
|
140
160
|
const vertexCount = convertedAttributes.positions.length / VALUES_PER_VERTEX;
|
|
141
|
-
const { faceRange, featureIds, positions, normals, colors, texCoords, featureCount } = (0, geometry_attributes_1.generateAttributes)(convertedAttributes);
|
|
161
|
+
const { faceRange, featureIds, positions, normals, colors, uvRegions, texCoords, featureCount } = (0, geometry_attributes_1.generateAttributes)(convertedAttributes);
|
|
142
162
|
if (tileContent.batchTableJson) {
|
|
143
163
|
makeFeatureIdsUnique(featureIds, convertedAttributes.featureIndices, featuresHashArray, tileContent.batchTableJson);
|
|
144
164
|
}
|
|
145
165
|
const header = new Uint32Array(2);
|
|
146
166
|
const typedFeatureIds = generateBigUint64Array(featureIds);
|
|
147
167
|
header.set([vertexCount, featureCount], 0);
|
|
148
|
-
const fileBuffer = new Uint8Array((0, loader_utils_1.concatenateArrayBuffers)(header.buffer, positions.buffer, normals.buffer, texture ? texCoords.buffer : new ArrayBuffer(0), colors.buffer, typedFeatureIds.buffer, faceRange.buffer));
|
|
168
|
+
const fileBuffer = new Uint8Array((0, loader_utils_1.concatenateArrayBuffers)(header.buffer, positions.buffer, normals.buffer, texture ? texCoords.buffer : new ArrayBuffer(0), colors.buffer, uvRegions, typedFeatureIds.buffer, faceRange.buffer));
|
|
149
169
|
const compressedGeometry = draco
|
|
150
170
|
? generateCompressedGeometry(vertexCount, convertedAttributes, {
|
|
151
171
|
positions,
|
|
152
172
|
normals,
|
|
153
173
|
texCoords: texture ? texCoords : new Float32Array(0),
|
|
154
174
|
colors,
|
|
175
|
+
uvRegions,
|
|
155
176
|
featureIds,
|
|
156
177
|
faceRange
|
|
157
178
|
}, workerSource.draco)
|
|
@@ -165,6 +186,7 @@ async function _makeNodeResources({ convertedAttributes, material, texture, tile
|
|
|
165
186
|
geometry: fileBuffer,
|
|
166
187
|
compressedGeometry,
|
|
167
188
|
texture,
|
|
189
|
+
hasUvRegions: Boolean(uvRegions.length),
|
|
168
190
|
sharedResources: getSharedResources(tileContent.gltf?.materials || [], nodeId),
|
|
169
191
|
meshMaterial: material,
|
|
170
192
|
vertexCount,
|
|
@@ -175,24 +197,30 @@ async function _makeNodeResources({ convertedAttributes, material, texture, tile
|
|
|
175
197
|
}
|
|
176
198
|
/**
|
|
177
199
|
* Convert attributes from the gltf nodes tree to i3s plain geometry
|
|
178
|
-
* @param
|
|
200
|
+
* @param attributesData - geometry attributes from gltf
|
|
201
|
+
* @param materialAndTextureList - array of data about materials and textures of the content
|
|
179
202
|
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
180
203
|
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
181
204
|
* @returns map of converted geometry attributes
|
|
182
205
|
*/
|
|
183
|
-
async function convertAttributes(attributesData, useCartesianPositions) {
|
|
184
|
-
const {
|
|
206
|
+
async function convertAttributes(attributesData, materialAndTextureList, useCartesianPositions) {
|
|
207
|
+
const { nodes, images, cartographicOrigin, cartesianModelMatrix } = attributesData;
|
|
185
208
|
const attributesMap = new Map();
|
|
186
|
-
for (const
|
|
187
|
-
|
|
209
|
+
for (const materialAndTexture of materialAndTextureList) {
|
|
210
|
+
const attributes = {
|
|
188
211
|
positions: new Float32Array(0),
|
|
189
212
|
normals: new Float32Array(0),
|
|
190
213
|
texCoords: new Float32Array(0),
|
|
191
214
|
colors: new Uint8Array(0),
|
|
215
|
+
uvRegions: new Uint16Array(0),
|
|
192
216
|
featureIndicesGroups: [],
|
|
193
217
|
featureIndices: [],
|
|
194
|
-
boundingVolumes: null
|
|
195
|
-
|
|
218
|
+
boundingVolumes: null,
|
|
219
|
+
mergedMaterials: materialAndTexture.mergedMaterials
|
|
220
|
+
};
|
|
221
|
+
for (const mergedMaterial of materialAndTexture.mergedMaterials) {
|
|
222
|
+
attributesMap.set(mergedMaterial.originalMaterialId, attributes);
|
|
223
|
+
}
|
|
196
224
|
}
|
|
197
225
|
convertNodes(nodes, images, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions);
|
|
198
226
|
for (const attrKey of attributesMap.keys()) {
|
|
@@ -217,7 +245,8 @@ exports.convertAttributes = convertAttributes;
|
|
|
217
245
|
* The goal is applying tranformation matrix for all children. Functions "convertNodes" and "convertNode" work together recursively.
|
|
218
246
|
* @param nodes - gltf nodes array
|
|
219
247
|
* @param images - gltf images array
|
|
220
|
-
* @param
|
|
248
|
+
* @param cartographicOrigin - cartographic origin of bounding volume
|
|
249
|
+
* @param cartesianModelMatrix - cartesian model matrix to convert coordinates to cartographic
|
|
221
250
|
* @param attributesMap - for recursive concatenation of attributes
|
|
222
251
|
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
223
252
|
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
@@ -258,7 +287,8 @@ function getCompositeTransformationMatrix(node, matrix) {
|
|
|
258
287
|
* Convert all primitives of node and all children nodes
|
|
259
288
|
* @param node - gltf node
|
|
260
289
|
* @param images - gltf images array
|
|
261
|
-
* @param
|
|
290
|
+
* @param cartographicOrigin - cartographic origin of bounding volume
|
|
291
|
+
* @param cartesianModelMatrix - cartesian model matrix to convert coordinates to cartographic
|
|
262
292
|
* @param {Map} attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
|
|
263
293
|
* attributes
|
|
264
294
|
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
@@ -274,9 +304,13 @@ function convertNode(node, images, cartographicOrigin, cartesianModelMatrix, att
|
|
|
274
304
|
convertNodes(node.children || [], images, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions, transformationMatrix);
|
|
275
305
|
}
|
|
276
306
|
/**
|
|
277
|
-
* Convert all primitives of
|
|
278
|
-
* @param mesh - gltf
|
|
279
|
-
* @param
|
|
307
|
+
* Convert all primitives of the mesh
|
|
308
|
+
* @param mesh - gltf mesh data
|
|
309
|
+
* @param images - gltf images array
|
|
310
|
+
* @param cartographicOrigin - cartographic origin of bounding volume
|
|
311
|
+
* @param cartesianModelMatrix - cartesian model matrix to convert coordinates to cartographic
|
|
312
|
+
* @param attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
|
|
313
|
+
* attributes
|
|
280
314
|
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
281
315
|
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
282
316
|
* @param attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
|
|
@@ -287,8 +321,10 @@ function convertNode(node, images, cartographicOrigin, cartesianModelMatrix, att
|
|
|
287
321
|
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])) {
|
|
288
322
|
for (const primitive of mesh.primitives) {
|
|
289
323
|
let outputAttributes = null;
|
|
324
|
+
let materialUvRegion;
|
|
290
325
|
if (primitive.material) {
|
|
291
|
-
outputAttributes = attributesMap.get(primitive.material.
|
|
326
|
+
outputAttributes = attributesMap.get(primitive.material.uniqueId);
|
|
327
|
+
materialUvRegion = outputAttributes?.mergedMaterials.find(({ originalMaterialId }) => originalMaterialId === primitive.material?.uniqueId)?.uvRegion;
|
|
292
328
|
}
|
|
293
329
|
else if (attributesMap.has('default')) {
|
|
294
330
|
outputAttributes = attributesMap.get('default');
|
|
@@ -318,6 +354,9 @@ function convertMesh(mesh, images, cartographicOrigin, cartesianModelMatrix, att
|
|
|
318
354
|
}));
|
|
319
355
|
outputAttributes.texCoords = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.texCoords, flattenTexCoords(attributes.TEXCOORD_0 && attributes.TEXCOORD_0.value, primitive.indices?.value));
|
|
320
356
|
outputAttributes.colors = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.colors, flattenColors(attributes.COLOR_0, primitive.indices?.value));
|
|
357
|
+
if (materialUvRegion) {
|
|
358
|
+
outputAttributes.uvRegions = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.uvRegions, createUvRegion(materialUvRegion, primitive.indices?.value));
|
|
359
|
+
}
|
|
321
360
|
outputAttributes.featureIndicesGroups = outputAttributes.featureIndicesGroups || [];
|
|
322
361
|
outputAttributes.featureIndicesGroups.push(flattenBatchIds(getBatchIds(attributes, primitive, images), primitive.indices?.value));
|
|
323
362
|
}
|
|
@@ -438,6 +477,19 @@ function flattenColors(colorsAttribute, indices) {
|
|
|
438
477
|
}
|
|
439
478
|
return newColors;
|
|
440
479
|
}
|
|
480
|
+
/**
|
|
481
|
+
* Create per-vertex uv-region array
|
|
482
|
+
* @param materialUvRegion - uv-region fragment for a single vertex
|
|
483
|
+
* @param indices - geometry indices data
|
|
484
|
+
* @returns - uv-region array
|
|
485
|
+
*/
|
|
486
|
+
function createUvRegion(materialUvRegion, indices) {
|
|
487
|
+
const result = new Uint16Array(indices.length * 4);
|
|
488
|
+
for (let i = 0; i < result.length; i += 4) {
|
|
489
|
+
result.set(materialUvRegion, i);
|
|
490
|
+
}
|
|
491
|
+
return result;
|
|
492
|
+
}
|
|
441
493
|
/**
|
|
442
494
|
* Flatten batchedIds list based on indices to right ordered array, compatible with i3s
|
|
443
495
|
* @param batchedIds - gltf primitive
|
|
@@ -457,9 +509,9 @@ function flattenBatchIds(batchedIds, indices) {
|
|
|
457
509
|
}
|
|
458
510
|
/**
|
|
459
511
|
* Get batchIds for featureIds creation
|
|
460
|
-
* @param attributes
|
|
461
|
-
* @param primitive
|
|
462
|
-
* @param
|
|
512
|
+
* @param attributes - gltf accessors
|
|
513
|
+
* @param primitive - gltf primitive data
|
|
514
|
+
* @param images - gltf texture images
|
|
463
515
|
*/
|
|
464
516
|
function getBatchIds(attributes, primitive, images) {
|
|
465
517
|
const batchIds = (0, batch_ids_extensions_1.handleBatchIdsExtensions)(attributes, primitive, images);
|
|
@@ -478,15 +530,107 @@ function getBatchIds(attributes, primitive, images) {
|
|
|
478
530
|
/**
|
|
479
531
|
* Convert GLTF material to I3S material definitions and textures
|
|
480
532
|
* @param sourceMaterials Source GLTF materials
|
|
533
|
+
* @param shouldMergeMaterials - if true - the converter will try to merge similar materials
|
|
534
|
+
* to be able to merge primitives having those materials
|
|
481
535
|
* @returns Array of Couples I3SMaterialDefinition + texture content
|
|
482
536
|
*/
|
|
483
|
-
function convertMaterials(sourceMaterials = []) {
|
|
484
|
-
|
|
537
|
+
async function convertMaterials(sourceMaterials = [], shouldMergeMaterials) {
|
|
538
|
+
let materials = [];
|
|
485
539
|
for (const sourceMaterial of sourceMaterials) {
|
|
486
|
-
|
|
540
|
+
materials.push(convertMaterial(sourceMaterial));
|
|
541
|
+
}
|
|
542
|
+
if (shouldMergeMaterials) {
|
|
543
|
+
materials = await mergeAllMaterials(materials);
|
|
544
|
+
}
|
|
545
|
+
return materials;
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Merge materials when possible
|
|
549
|
+
* @param materials materials array
|
|
550
|
+
* @returns merged materials array
|
|
551
|
+
*/
|
|
552
|
+
async function mergeAllMaterials(materials) {
|
|
553
|
+
const result = [];
|
|
554
|
+
while (materials.length > 0) {
|
|
555
|
+
let newMaterial = materials.splice(0, 1)[0];
|
|
556
|
+
const mergedIndices = [];
|
|
557
|
+
for (let i = 0; i < materials.length; i++) {
|
|
558
|
+
const material = materials[i];
|
|
559
|
+
if ((newMaterial.texture && material.texture) ||
|
|
560
|
+
(!newMaterial.texture && !material.texture)) {
|
|
561
|
+
newMaterial = await mergeMaterials(newMaterial, material);
|
|
562
|
+
mergedIndices.push(i);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
if (newMaterial.texture && mergedIndices.length) {
|
|
566
|
+
const newWidth = newMaterial.mergedMaterials?.reduce((accum, { textureSize }) => accum + (textureSize?.width || 0), 0);
|
|
567
|
+
const newHeight = newMaterial.mergedMaterials?.reduce((accum, { textureSize }) => Math.max(accum, textureSize?.height || 0), 0);
|
|
568
|
+
let currentX = -1;
|
|
569
|
+
for (const aTextureMetadata of newMaterial.mergedMaterials) {
|
|
570
|
+
if (aTextureMetadata.textureSize) {
|
|
571
|
+
const newX = currentX +
|
|
572
|
+
1 +
|
|
573
|
+
(aTextureMetadata.textureSize.width / newWidth) *
|
|
574
|
+
2 ** (Uint16Array.BYTES_PER_ELEMENT * 8) -
|
|
575
|
+
1;
|
|
576
|
+
aTextureMetadata.uvRegion = new Uint16Array([
|
|
577
|
+
currentX + 1,
|
|
578
|
+
0,
|
|
579
|
+
newX,
|
|
580
|
+
(aTextureMetadata.textureSize.height / newHeight) *
|
|
581
|
+
2 ** (Uint16Array.BYTES_PER_ELEMENT * 8) -
|
|
582
|
+
1
|
|
583
|
+
]);
|
|
584
|
+
currentX = newX;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
newMaterial.texture.image.width = newWidth;
|
|
588
|
+
newMaterial.texture.image.height = newHeight;
|
|
589
|
+
}
|
|
590
|
+
for (const index of mergedIndices.reverse()) {
|
|
591
|
+
materials.splice(index, 1);
|
|
592
|
+
}
|
|
593
|
+
result.push(newMaterial);
|
|
594
|
+
}
|
|
595
|
+
if (!result.length) {
|
|
596
|
+
result.push({
|
|
597
|
+
material: getDefaultMaterial(),
|
|
598
|
+
mergedMaterials: [{ originalMaterialId: 'default' }]
|
|
599
|
+
});
|
|
487
600
|
}
|
|
488
601
|
return result;
|
|
489
602
|
}
|
|
603
|
+
/**
|
|
604
|
+
* Merge 2 materials including texture
|
|
605
|
+
* @param material1
|
|
606
|
+
* @param material2
|
|
607
|
+
* @returns
|
|
608
|
+
*/
|
|
609
|
+
async function mergeMaterials(material1, material2) {
|
|
610
|
+
if (material1.texture?.bufferView &&
|
|
611
|
+
material2.texture?.bufferView &&
|
|
612
|
+
material1.mergedMaterials &&
|
|
613
|
+
material2.mergedMaterials) {
|
|
614
|
+
const buffer1 = Buffer.from(material1.texture.bufferView.data);
|
|
615
|
+
const buffer2 = Buffer.from(material2.texture.bufferView.data);
|
|
616
|
+
try {
|
|
617
|
+
// @ts-ignore
|
|
618
|
+
const { joinImages } = await Promise.resolve().then(() => __importStar(require('join-images')));
|
|
619
|
+
const sharpData = await joinImages([buffer1, buffer2], { direction: 'horizontal' });
|
|
620
|
+
material1.texture.bufferView.data = await sharpData
|
|
621
|
+
.toFormat(material1.texture.mimeType === 'image/png' ? 'png' : 'jpeg')
|
|
622
|
+
.toBuffer();
|
|
623
|
+
}
|
|
624
|
+
catch (error) {
|
|
625
|
+
console.log('Join images into a texture atlas has failed. Consider usage `--split-nodes` option. (See documentation https://loaders.gl/modules/tile-converter/docs/cli-reference/tile-converter)');
|
|
626
|
+
throw error;
|
|
627
|
+
}
|
|
628
|
+
// @ts-ignore
|
|
629
|
+
material1.material.pbrMetallicRoughness.baseColorTexture.textureSetDefinitionId = 1;
|
|
630
|
+
}
|
|
631
|
+
material1.mergedMaterials = material1.mergedMaterials.concat(material2.mergedMaterials);
|
|
632
|
+
return material1;
|
|
633
|
+
}
|
|
490
634
|
/**
|
|
491
635
|
* Convert texture and material from gltf 2.0 material object
|
|
492
636
|
* @param sourceMaterial - material object
|
|
@@ -518,6 +662,9 @@ function convertMaterial(sourceMaterial) {
|
|
|
518
662
|
textureSetDefinitionId: 0
|
|
519
663
|
};
|
|
520
664
|
}
|
|
665
|
+
const uniqueId = (0, uuid_1.v4)();
|
|
666
|
+
sourceMaterial.uniqueId = uniqueId;
|
|
667
|
+
let mergedMaterials = [{ originalMaterialId: uniqueId }];
|
|
521
668
|
if (!texture) {
|
|
522
669
|
// Should use default baseColorFactor if it is not present in source material
|
|
523
670
|
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#reference-pbrmetallicroughness
|
|
@@ -525,7 +672,10 @@ function convertMaterial(sourceMaterial) {
|
|
|
525
672
|
material.pbrMetallicRoughness.baseColorFactor =
|
|
526
673
|
(baseColorFactor && baseColorFactor.map((c) => Math.round(c * 255))) || undefined;
|
|
527
674
|
}
|
|
528
|
-
|
|
675
|
+
else {
|
|
676
|
+
mergedMaterials[0].textureSize = { width: texture.image.width, height: texture.image.height };
|
|
677
|
+
}
|
|
678
|
+
return { material, texture, mergedMaterials };
|
|
529
679
|
}
|
|
530
680
|
/**
|
|
531
681
|
* Converts from `alphaMode` material property from GLTF to I3S format
|
|
@@ -663,7 +813,7 @@ function extractSharedResourcesTextureInfo(texture, nodeId) {
|
|
|
663
813
|
};
|
|
664
814
|
}
|
|
665
815
|
/**
|
|
666
|
-
* Formula for
|
|
816
|
+
* Formula for calculating imageId:
|
|
667
817
|
* https://github.com/Esri/i3s-spec/blob/0a6366a9249b831db8436c322f8d27521e86cf07/format/Indexed%203d%20Scene%20Layer%20Format%20Specification.md#generating-image-ids
|
|
668
818
|
* @param texture - texture image info
|
|
669
819
|
* @param nodeId - I3S node ID
|
|
@@ -754,8 +904,8 @@ function replaceIndicesByUnique(indicesArray, featureMap) {
|
|
|
754
904
|
}
|
|
755
905
|
/**
|
|
756
906
|
* Convert property table data to attribute buffers.
|
|
757
|
-
* @param {Object} propertyTable - table with metadata for particular feature.
|
|
758
907
|
* @param {Array} featureIds
|
|
908
|
+
* @param {Object} propertyTable - table with metadata for particular feature.
|
|
759
909
|
* @param {Array} attributeStorageInfo
|
|
760
910
|
* @returns {Array} - Array of file buffers.
|
|
761
911
|
*/
|
|
@@ -873,7 +1023,7 @@ function generateBigUint64Array(featureIds) {
|
|
|
873
1023
|
* @returns {Promise<object>} - COmpressed geometry.
|
|
874
1024
|
*/
|
|
875
1025
|
async function generateCompressedGeometry(vertexCount, convertedAttributes, attributes, dracoWorkerSoure) {
|
|
876
|
-
const { positions, normals, texCoords, colors, featureIds, faceRange } = attributes;
|
|
1026
|
+
const { positions, normals, texCoords, colors, uvRegions, featureIds, faceRange } = attributes;
|
|
877
1027
|
const indices = new Uint32Array(vertexCount);
|
|
878
1028
|
for (let index = 0; index < indices.length; index++) {
|
|
879
1029
|
indices.set([index], index);
|
|
@@ -895,6 +1045,12 @@ async function generateCompressedGeometry(vertexCount, convertedAttributes, attr
|
|
|
895
1045
|
'i3s-feature-ids': new Int32Array(featureIds)
|
|
896
1046
|
}
|
|
897
1047
|
};
|
|
1048
|
+
if (uvRegions.length) {
|
|
1049
|
+
compressedAttributes['uv-region'] = uvRegions;
|
|
1050
|
+
attributesMetadata['uv-region'] = {
|
|
1051
|
+
'i3s-attribute-type': 'uv-region'
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
898
1054
|
return (0, core_2.encode)({ attributes: compressedAttributes, indices }, draco_1.DracoWriterWorker, {
|
|
899
1055
|
...draco_1.DracoWriterWorker.options,
|
|
900
1056
|
source: dracoWorkerSoure,
|
|
@@ -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,CAyC/F"}
|
|
@@ -20,7 +20,6 @@ function getB3DMAttributesWithoutBufferView(attributes) {
|
|
|
20
20
|
* @returns
|
|
21
21
|
*/
|
|
22
22
|
function prepareDataForAttributesConversion(tileContent) {
|
|
23
|
-
const gltfMaterials = tileContent.gltf?.materials?.map((material) => ({ id: material.id }));
|
|
24
23
|
let nodes = tileContent.gltf?.scene?.nodes ||
|
|
25
24
|
tileContent.gltf?.scenes?.[0]?.nodes ||
|
|
26
25
|
tileContent.gltf?.nodes ||
|
|
@@ -51,7 +50,6 @@ function prepareDataForAttributesConversion(tileContent) {
|
|
|
51
50
|
const cartographicOrigin = tileContent.cartographicOrigin;
|
|
52
51
|
const cartesianModelMatrix = tileContent.cartesianModelMatrix;
|
|
53
52
|
return {
|
|
54
|
-
gltfMaterials,
|
|
55
53
|
nodes,
|
|
56
54
|
images,
|
|
57
55
|
cartographicOrigin,
|
|
@@ -76,7 +74,8 @@ function prepareNodes(nodes) {
|
|
|
76
74
|
indices: { value: primitive?.indices?.value },
|
|
77
75
|
attributes: getB3DMAttributesWithoutBufferView(primitive.attributes),
|
|
78
76
|
material: {
|
|
79
|
-
id: primitive?.material?.id
|
|
77
|
+
id: primitive?.material?.id,
|
|
78
|
+
uniqueId: primitive?.material?.uniqueId
|
|
80
79
|
}
|
|
81
80
|
}))
|
|
82
81
|
}
|