@loaders.gl/tile-converter 3.2.0-alpha.1 → 3.2.0-alpha.4
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.d.ts +28 -0
- package/dist/3d-tiles-attributes-worker.d.ts.map +1 -0
- package/dist/3d-tiles-attributes-worker.js +4 -0
- package/dist/3d-tiles-attributes-worker.js.map +7 -0
- package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +5 -1
- package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
- package/dist/3d-tiles-converter/3d-tiles-converter.js +34 -3
- package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts +5 -4
- package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -1
- package/dist/3d-tiles-converter/helpers/b3dm-converter.js +10 -10
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +4 -0
- package/dist/converter-cli.d.ts +2 -0
- package/dist/converter-cli.d.ts.map +1 -0
- package/dist/converter-cli.js +232 -0
- package/dist/converter.min.js +68 -68
- package/dist/deps-installer/deps-installer.d.ts +11 -1
- package/dist/deps-installer/deps-installer.d.ts.map +1 -1
- package/dist/deps-installer/deps-installer.js +10 -0
- package/dist/dist.min.js +910 -790
- package/dist/es5/3d-tiles-attributes-worker.js +29 -0
- package/dist/es5/3d-tiles-attributes-worker.js.map +1 -0
- package/dist/es5/3d-tiles-converter/3d-tiles-converter.js +116 -46
- package/dist/es5/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
- package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js +21 -23
- package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
- package/dist/es5/constants.js +9 -0
- package/dist/es5/constants.js.map +1 -0
- package/dist/es5/converter-cli.js +306 -0
- package/dist/es5/converter-cli.js.map +1 -0
- package/dist/es5/deps-installer/deps-installer.js.map +1 -1
- package/dist/es5/i3s-attributes-worker.js +29 -0
- package/dist/es5/i3s-attributes-worker.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/coordinate-converter.js +19 -11
- package/dist/es5/i3s-converter/helpers/coordinate-converter.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js +2 -2
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-converter.js +271 -182
- package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/gltf-attributes.js +71 -0
- package/dist/es5/i3s-converter/helpers/gltf-attributes.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/node-pages.js +47 -99
- package/dist/es5/i3s-converter/helpers/node-pages.js.map +1 -1
- package/dist/es5/i3s-converter/i3s-converter.js +293 -223
- package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/es5/i3s-converter/json-templates/layers.js +29 -0
- package/dist/es5/i3s-converter/json-templates/layers.js.map +1 -1
- package/dist/es5/index.js +0 -16
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/lib/utils/compress-util.js +14 -17
- package/dist/es5/lib/utils/compress-util.js.map +1 -1
- package/dist/es5/lib/utils/file-utils.js +39 -14
- package/dist/es5/lib/utils/file-utils.js.map +1 -1
- package/dist/es5/lib/utils/lod-conversion-utils.js.map +1 -1
- package/dist/es5/lib/utils/queue.js +61 -0
- package/dist/es5/lib/utils/queue.js.map +1 -0
- package/dist/es5/lib/utils/statistic-utills.js.map +1 -1
- package/dist/es5/lib/utils/write-queue.js +225 -0
- package/dist/es5/lib/utils/write-queue.js.map +1 -0
- package/dist/es5/pgm-loader.js +1 -1
- package/dist/es5/workers/3d-tiles-attributes-worker.js +37 -0
- package/dist/es5/workers/3d-tiles-attributes-worker.js.map +1 -0
- package/dist/es5/workers/i3s-attributes-worker.js +40 -0
- package/dist/es5/workers/i3s-attributes-worker.js.map +1 -0
- package/dist/esm/3d-tiles-attributes-worker.js +16 -0
- package/dist/esm/3d-tiles-attributes-worker.js.map +1 -0
- package/dist/esm/3d-tiles-converter/3d-tiles-converter.js +36 -4
- package/dist/esm/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
- package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js +16 -18
- package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
- package/dist/esm/constants.js +2 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/converter-cli.js +230 -0
- package/dist/esm/converter-cli.js.map +1 -0
- package/dist/esm/deps-installer/deps-installer.js.map +1 -1
- package/dist/esm/i3s-attributes-worker.js +16 -0
- package/dist/esm/i3s-attributes-worker.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/coordinate-converter.js +19 -11
- package/dist/esm/i3s-converter/helpers/coordinate-converter.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js +2 -2
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-converter.js +121 -62
- package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/gltf-attributes.js +54 -0
- package/dist/esm/i3s-converter/helpers/gltf-attributes.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/node-pages.js +12 -4
- package/dist/esm/i3s-converter/helpers/node-pages.js.map +1 -1
- package/dist/esm/i3s-converter/i3s-converter.js +157 -52
- package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/esm/i3s-converter/json-templates/layers.js +25 -0
- package/dist/esm/i3s-converter/json-templates/layers.js.map +1 -1
- package/dist/esm/index.js +0 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/utils/compress-util.js +6 -8
- package/dist/esm/lib/utils/compress-util.js.map +1 -1
- package/dist/esm/lib/utils/file-utils.js +11 -1
- package/dist/esm/lib/utils/file-utils.js.map +1 -1
- package/dist/esm/lib/utils/lod-conversion-utils.js.map +1 -1
- package/dist/esm/lib/utils/queue.js +19 -0
- package/dist/esm/lib/utils/queue.js.map +1 -0
- package/dist/esm/lib/utils/statistic-utills.js.map +1 -1
- package/dist/esm/lib/utils/write-queue.js +88 -0
- package/dist/esm/lib/utils/write-queue.js.map +1 -0
- package/dist/esm/pgm-loader.js +1 -1
- package/dist/esm/workers/3d-tiles-attributes-worker.js +5 -0
- package/dist/esm/workers/3d-tiles-attributes-worker.js.map +1 -0
- package/dist/esm/workers/i3s-attributes-worker.js +4 -0
- package/dist/esm/workers/i3s-attributes-worker.js.map +1 -0
- package/dist/i3s-attributes-worker.d.ts +33 -0
- package/dist/i3s-attributes-worker.d.ts.map +1 -0
- package/dist/i3s-attributes-worker.js +10 -0
- package/dist/i3s-attributes-worker.js.map +7 -0
- package/dist/i3s-converter/helpers/coordinate-converter.d.ts +7 -7
- package/dist/i3s-converter/helpers/coordinate-converter.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/coordinate-converter.js +25 -21
- package/dist/i3s-converter/helpers/geometry-attributes.d.ts +2 -2
- package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-attributes.js +2 -1
- package/dist/i3s-converter/helpers/geometry-converter.d.ts +28 -11
- package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.js +223 -113
- package/dist/i3s-converter/helpers/gltf-attributes.d.ts +9 -0
- package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/gltf-attributes.js +56 -0
- package/dist/i3s-converter/helpers/node-pages.d.ts +6 -5
- package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/node-pages.js +13 -8
- package/dist/i3s-converter/i3s-converter.d.ts +7 -5
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.js +126 -40
- package/dist/i3s-converter/json-templates/layers.d.ts +4 -0
- package/dist/i3s-converter/json-templates/layers.d.ts.map +1 -1
- package/dist/i3s-converter/json-templates/layers.js +24 -0
- package/dist/i3s-converter/types.d.ts +83 -8
- package/dist/i3s-converter/types.d.ts.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -5
- package/dist/lib/utils/compress-util.d.ts +44 -5
- package/dist/lib/utils/compress-util.d.ts.map +1 -1
- package/dist/lib/utils/compress-util.js +73 -6
- package/dist/lib/utils/file-utils.d.ts +34 -5
- package/dist/lib/utils/file-utils.d.ts.map +1 -1
- package/dist/lib/utils/file-utils.js +40 -1
- package/dist/lib/utils/lod-conversion-utils.d.ts +25 -4
- package/dist/lib/utils/lod-conversion-utils.d.ts.map +1 -1
- package/dist/lib/utils/lod-conversion-utils.js +21 -2
- package/dist/lib/utils/queue.d.ts +7 -0
- package/dist/lib/utils/queue.d.ts.map +1 -0
- package/dist/lib/utils/queue.js +18 -0
- package/dist/lib/utils/statistic-utills.d.ts +2 -2
- package/dist/lib/utils/statistic-utills.d.ts.map +1 -1
- package/dist/lib/utils/write-queue.d.ts +22 -0
- package/dist/lib/utils/write-queue.d.ts.map +1 -0
- package/dist/lib/utils/write-queue.js +62 -0
- package/dist/workers/3d-tiles-attributes-worker.d.ts +2 -0
- package/dist/workers/3d-tiles-attributes-worker.d.ts.map +1 -0
- package/dist/workers/3d-tiles-attributes-worker.js +9 -0
- package/dist/workers/i3s-attributes-worker.d.ts +2 -0
- package/dist/workers/i3s-attributes-worker.d.ts.map +1 -0
- package/dist/workers/i3s-attributes-worker.js +5 -0
- package/package.json +23 -18
- package/src/3d-tiles-attributes-worker.ts +43 -0
- package/src/3d-tiles-converter/3d-tiles-converter.ts +50 -5
- package/src/3d-tiles-converter/helpers/b3dm-converter.ts +15 -13
- package/src/constants.ts +2 -0
- package/src/converter-cli.ts +310 -0
- package/src/deps-installer/{deps-installer.js → deps-installer.ts} +11 -1
- package/src/i3s-attributes-worker.ts +46 -0
- package/src/i3s-converter/helpers/coordinate-converter.ts +29 -24
- package/src/i3s-converter/helpers/geometry-attributes.ts +4 -3
- package/src/i3s-converter/helpers/{geometry-converter.js → geometry-converter.ts} +425 -179
- package/src/i3s-converter/helpers/gltf-attributes.ts +68 -0
- package/src/i3s-converter/helpers/node-pages.ts +25 -17
- package/src/i3s-converter/i3s-converter.ts +150 -90
- package/src/i3s-converter/json-templates/layers.ts +25 -0
- package/src/i3s-converter/types.ts +90 -8
- package/src/index.ts +0 -4
- package/src/lib/utils/{compress-util.js → compress-util.ts} +105 -18
- package/src/lib/utils/file-utils.ts +84 -0
- package/src/lib/utils/{lod-conversion-utils.js → lod-conversion-utils.ts} +27 -5
- package/src/lib/utils/queue.ts +17 -0
- package/src/lib/utils/{statistic-utills.js → statistic-utills.ts} +0 -0
- package/src/lib/utils/write-queue.ts +75 -0
- package/src/workers/3d-tiles-attributes-worker.ts +6 -0
- package/src/workers/i3s-attributes-worker.ts +6 -0
- package/dist/es5/deps-installer/deps-installer.d.ts +0 -10
- package/dist/es5/i3s-converter/helpers/geometry-converter.d.ts +0 -44
- package/dist/es5/lib/utils/compress-util.d.ts +0 -53
- package/dist/es5/lib/utils/file-utils.d.ts +0 -43
- package/dist/es5/lib/utils/lod-conversion-utils.d.ts +0 -32
- package/dist/esm/deps-installer/deps-installer.d.ts +0 -10
- package/dist/esm/i3s-converter/helpers/geometry-converter.d.ts +0 -44
- package/dist/esm/lib/utils/compress-util.d.ts +0 -53
- package/dist/esm/lib/utils/file-utils.d.ts +0 -43
- package/dist/esm/lib/utils/lod-conversion-utils.d.ts +0 -32
- package/src/deps-installer/deps-installer.d.ts +0 -10
- package/src/i3s-converter/helpers/geometry-converter.d.ts +0 -44
- package/src/lib/utils/compress-util.d.ts +0 -53
- package/src/lib/utils/file-utils.d.ts +0 -43
- package/src/lib/utils/file-utils.js +0 -38
- package/src/lib/utils/lod-conversion-utils.d.ts +0 -32
|
@@ -1,12 +1,35 @@
|
|
|
1
1
|
import {Vector3, Matrix4, Vector4} from '@math.gl/core';
|
|
2
2
|
import {Ellipsoid} from '@math.gl/geospatial';
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import {DracoWriterWorker} from '@loaders.gl/draco';
|
|
5
|
+
import {assert, encode} from '@loaders.gl/core';
|
|
6
6
|
import {concatenateArrayBuffers, concatenateTypedArrays} from '@loaders.gl/loader-utils';
|
|
7
7
|
import md5 from 'md5';
|
|
8
8
|
import {generateAttributes} from './geometry-attributes';
|
|
9
9
|
import {createBoundingVolumesFromGeometry} from './coordinate-converter';
|
|
10
|
+
import {
|
|
11
|
+
ConvertedAttributes,
|
|
12
|
+
I3SConvertedResources,
|
|
13
|
+
I3SMaterialWithTexture,
|
|
14
|
+
SharedResourcesArrays
|
|
15
|
+
} from '../types';
|
|
16
|
+
import {B3DMContent} from '@loaders.gl/3d-tiles';
|
|
17
|
+
import {GLTFMaterialPostprocessed, GLTFNodePostprocessed} from '@loaders.gl/gltf';
|
|
18
|
+
import {
|
|
19
|
+
AttributeStorageInfo,
|
|
20
|
+
I3SMaterialDefinition,
|
|
21
|
+
MaterialDefinitionInfo,
|
|
22
|
+
TextureDefinitionInfo
|
|
23
|
+
} from '@loaders.gl/i3s';
|
|
24
|
+
import {TypedArray} from '@loaders.gl/schema';
|
|
25
|
+
import {Geoid} from '@math.gl/geoid';
|
|
26
|
+
import {
|
|
27
|
+
GLTFAccessorPostprocessed,
|
|
28
|
+
GLTFMeshPostprocessed,
|
|
29
|
+
GLTFTexturePostprocessed
|
|
30
|
+
} from 'modules/gltf/src/lib/types/gltf-types';
|
|
31
|
+
import {B3DMAttributesData /*transformI3SAttributesOnWorker */} from '../../i3s-attributes-worker';
|
|
32
|
+
import {prepareDataForAttributesConversion} from './gltf-attributes';
|
|
10
33
|
|
|
11
34
|
// Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.7/pbrMetallicRoughness.cmn.md
|
|
12
35
|
const DEFAULT_ROUGHNESS_FACTOR = 1;
|
|
@@ -29,18 +52,47 @@ const BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES = ['CUSTOM_ATTRIBUTE_2', '_BATCHID', '
|
|
|
29
52
|
|
|
30
53
|
let scratchVector = new Vector3();
|
|
31
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Convert binary data from b3dm file to i3s resources
|
|
57
|
+
*
|
|
58
|
+
* @param tileContent - 3d tile content
|
|
59
|
+
* @param nodeId - target nodeId. If a few nodes will be created - ids will be nodeId+n where n - index in the resulting array
|
|
60
|
+
* @param featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
|
|
61
|
+
* @param attributeStorageInfo - attributes metadata from 3DSceneLayer json
|
|
62
|
+
* @param draco - is converter should create draco compressed geometry
|
|
63
|
+
* @param generateBoundingVolumes - is converter should create accurate bounding voulmes from geometry attributes
|
|
64
|
+
* @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
|
|
65
|
+
* @returns Array of node resources to create one or more i3s nodes
|
|
66
|
+
*/
|
|
32
67
|
export default async function convertB3dmToI3sGeometry(
|
|
33
|
-
tileContent,
|
|
34
|
-
nodeId,
|
|
35
|
-
featuresHashArray,
|
|
36
|
-
attributeStorageInfo,
|
|
37
|
-
draco,
|
|
38
|
-
generateBoundingVolumes,
|
|
39
|
-
geoidHeightModel
|
|
68
|
+
tileContent: B3DMContent,
|
|
69
|
+
nodeId: number,
|
|
70
|
+
featuresHashArray: string[],
|
|
71
|
+
attributeStorageInfo: AttributeStorageInfo[] | undefined,
|
|
72
|
+
draco: boolean,
|
|
73
|
+
generateBoundingVolumes: boolean,
|
|
74
|
+
geoidHeightModel: Geoid,
|
|
75
|
+
workerSource: {[key: string]: string}
|
|
40
76
|
) {
|
|
41
77
|
const useCartesianPositions = generateBoundingVolumes;
|
|
42
|
-
const materialAndTextureList = convertMaterials(
|
|
43
|
-
|
|
78
|
+
const materialAndTextureList: I3SMaterialWithTexture[] = convertMaterials(
|
|
79
|
+
tileContent.gltf?.materials
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const dataForAttributesConversion = prepareDataForAttributesConversion(tileContent);
|
|
83
|
+
|
|
84
|
+
const convertedAttributesMap: Map<string, ConvertedAttributes> = await convertAttributes(
|
|
85
|
+
dataForAttributesConversion,
|
|
86
|
+
useCartesianPositions
|
|
87
|
+
);
|
|
88
|
+
// TODO uncomment it when worker will be published on CDN.
|
|
89
|
+
/*
|
|
90
|
+
const convertedAttributesMap: Map<string, ConvertedAttributes> =
|
|
91
|
+
await transformI3SAttributesOnWorker(dataForAttributesConversion, {
|
|
92
|
+
useCartesianPositions,
|
|
93
|
+
source: workerSource.I3SAttributes
|
|
94
|
+
});
|
|
95
|
+
*/
|
|
44
96
|
|
|
45
97
|
if (generateBoundingVolumes) {
|
|
46
98
|
_generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeightModel);
|
|
@@ -52,9 +104,9 @@ export default async function convertB3dmToI3sGeometry(
|
|
|
52
104
|
});
|
|
53
105
|
}
|
|
54
106
|
|
|
55
|
-
const result = [];
|
|
107
|
+
const result: I3SConvertedResources[] = [];
|
|
56
108
|
let nodesCounter = nodeId;
|
|
57
|
-
let {materials = []} = tileContent.gltf;
|
|
109
|
+
let {materials = []} = tileContent.gltf || {materials: []};
|
|
58
110
|
if (!materials?.length) {
|
|
59
111
|
materials.push({id: 'default'});
|
|
60
112
|
}
|
|
@@ -64,6 +116,9 @@ export default async function convertB3dmToI3sGeometry(
|
|
|
64
116
|
continue; // eslint-disable-line no-continue
|
|
65
117
|
}
|
|
66
118
|
const convertedAttributes = convertedAttributesMap.get(sourceMaterial.id);
|
|
119
|
+
if (!convertedAttributes) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
67
122
|
const {material, texture} = materialAndTextureList[i];
|
|
68
123
|
result.push(
|
|
69
124
|
await _makeNodeResources({
|
|
@@ -74,7 +129,8 @@ export default async function convertB3dmToI3sGeometry(
|
|
|
74
129
|
nodeId: nodesCounter,
|
|
75
130
|
featuresHashArray,
|
|
76
131
|
attributeStorageInfo,
|
|
77
|
-
draco
|
|
132
|
+
draco,
|
|
133
|
+
workerSource
|
|
78
134
|
})
|
|
79
135
|
);
|
|
80
136
|
nodesCounter++;
|
|
@@ -88,10 +144,13 @@ export default async function convertB3dmToI3sGeometry(
|
|
|
88
144
|
|
|
89
145
|
/**
|
|
90
146
|
* Create bounding volumes based on positions
|
|
91
|
-
* @param convertedAttributesMap
|
|
92
|
-
* @param geoidHeightModel
|
|
147
|
+
* @param convertedAttributesMap - geometry attributes map
|
|
148
|
+
* @param geoidHeightModel - geoid height model to convert elevation from elipsoidal to geoid
|
|
93
149
|
*/
|
|
94
|
-
function _generateBoundingVolumesFromGeometry(
|
|
150
|
+
function _generateBoundingVolumesFromGeometry(
|
|
151
|
+
convertedAttributesMap: Map<string, ConvertedAttributes>,
|
|
152
|
+
geoidHeightModel: Geoid
|
|
153
|
+
) {
|
|
95
154
|
for (const attributes of convertedAttributesMap.values()) {
|
|
96
155
|
const boundingVolumes = createBoundingVolumesFromGeometry(
|
|
97
156
|
attributes.positions,
|
|
@@ -112,6 +171,19 @@ function _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeigh
|
|
|
112
171
|
}
|
|
113
172
|
}
|
|
114
173
|
|
|
174
|
+
/**
|
|
175
|
+
*
|
|
176
|
+
* @param params
|
|
177
|
+
* @param params.convertedAttributes - Converted geometry attributes
|
|
178
|
+
* @param params.material - I3S PBR-like material definition
|
|
179
|
+
* @param params.texture - texture content
|
|
180
|
+
* @param params.tileContent - B3DM decoded content
|
|
181
|
+
* @param params.nodeId - new node ID
|
|
182
|
+
* @param params.featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
|
|
183
|
+
* @param params.attributesStorageInfo - attributes metadata from 3DSceneLayer json
|
|
184
|
+
* @param params.draco - is converter should create draco compressed geometry
|
|
185
|
+
* @returns Array of I3S node resources
|
|
186
|
+
*/
|
|
115
187
|
async function _makeNodeResources({
|
|
116
188
|
convertedAttributes,
|
|
117
189
|
material,
|
|
@@ -120,13 +192,23 @@ async function _makeNodeResources({
|
|
|
120
192
|
nodeId,
|
|
121
193
|
featuresHashArray,
|
|
122
194
|
attributeStorageInfo,
|
|
123
|
-
draco
|
|
124
|
-
|
|
195
|
+
draco,
|
|
196
|
+
workerSource
|
|
197
|
+
}: {
|
|
198
|
+
convertedAttributes: ConvertedAttributes;
|
|
199
|
+
material: I3SMaterialDefinition;
|
|
200
|
+
texture?: {};
|
|
201
|
+
tileContent: B3DMContent;
|
|
202
|
+
nodeId: number;
|
|
203
|
+
featuresHashArray: string[];
|
|
204
|
+
attributeStorageInfo?: AttributeStorageInfo[];
|
|
205
|
+
draco: boolean;
|
|
206
|
+
workerSource: {[key: string]: string};
|
|
207
|
+
}): Promise<I3SConvertedResources> {
|
|
125
208
|
const boundingVolumes = convertedAttributes.boundingVolumes;
|
|
126
209
|
const vertexCount = convertedAttributes.positions.length / VALUES_PER_VERTEX;
|
|
127
|
-
const triangleCount = vertexCount / 3;
|
|
128
210
|
const {faceRange, featureIds, positions, normals, colors, texCoords, featureCount} =
|
|
129
|
-
generateAttributes(
|
|
211
|
+
generateAttributes(convertedAttributes);
|
|
130
212
|
|
|
131
213
|
if (tileContent.batchTableJson) {
|
|
132
214
|
makeFeatureIdsUnique(
|
|
@@ -153,14 +235,19 @@ async function _makeNodeResources({
|
|
|
153
235
|
)
|
|
154
236
|
);
|
|
155
237
|
const compressedGeometry = draco
|
|
156
|
-
?
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
238
|
+
? generateCompressedGeometry(
|
|
239
|
+
vertexCount,
|
|
240
|
+
convertedAttributes,
|
|
241
|
+
{
|
|
242
|
+
positions,
|
|
243
|
+
normals,
|
|
244
|
+
texCoords: texture ? texCoords : new Float32Array(0),
|
|
245
|
+
colors,
|
|
246
|
+
featureIds,
|
|
247
|
+
faceRange
|
|
248
|
+
},
|
|
249
|
+
workerSource.draco
|
|
250
|
+
)
|
|
164
251
|
: null;
|
|
165
252
|
|
|
166
253
|
const attributes = convertBatchTableToAttributeBuffers(
|
|
@@ -173,7 +260,7 @@ async function _makeNodeResources({
|
|
|
173
260
|
geometry: fileBuffer,
|
|
174
261
|
compressedGeometry,
|
|
175
262
|
texture,
|
|
176
|
-
sharedResources: getSharedResources(tileContent, nodeId),
|
|
263
|
+
sharedResources: getSharedResources(tileContent.gltf?.materials || [], nodeId),
|
|
177
264
|
meshMaterial: material,
|
|
178
265
|
vertexCount,
|
|
179
266
|
attributes,
|
|
@@ -184,40 +271,53 @@ async function _makeNodeResources({
|
|
|
184
271
|
|
|
185
272
|
/**
|
|
186
273
|
* Convert attributes from the gltf nodes tree to i3s plain geometry
|
|
187
|
-
* @param
|
|
188
|
-
* @
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
for (const material of tileContent.gltf.materials || [{id: 'default'}]) {
|
|
274
|
+
* @param tileContent - 3d tile content
|
|
275
|
+
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
276
|
+
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
277
|
+
* @returns map of converted geometry attributes
|
|
278
|
+
*/
|
|
279
|
+
export async function convertAttributes(
|
|
280
|
+
attributesData: B3DMAttributesData,
|
|
281
|
+
useCartesianPositions: boolean
|
|
282
|
+
): Promise<Map<string, ConvertedAttributes>> {
|
|
283
|
+
const {gltfMaterials, nodes, cartographicOrigin, cartesianModelMatrix} = attributesData;
|
|
284
|
+
const attributesMap = new Map<string, ConvertedAttributes>();
|
|
285
|
+
|
|
286
|
+
for (const material of gltfMaterials || [{id: 'default'}]) {
|
|
201
287
|
attributesMap.set(material.id, {
|
|
202
288
|
positions: new Float32Array(0),
|
|
203
289
|
normals: new Float32Array(0),
|
|
204
290
|
texCoords: new Float32Array(0),
|
|
205
291
|
colors: new Uint8Array(0),
|
|
292
|
+
featureIndicesGroups: [],
|
|
206
293
|
featureIndices: [],
|
|
207
294
|
boundingVolumes: null
|
|
208
295
|
});
|
|
209
296
|
}
|
|
210
297
|
|
|
211
|
-
|
|
212
|
-
|
|
298
|
+
convertNodes(
|
|
299
|
+
nodes,
|
|
300
|
+
cartographicOrigin,
|
|
301
|
+
cartesianModelMatrix,
|
|
302
|
+
attributesMap,
|
|
303
|
+
useCartesianPositions
|
|
304
|
+
);
|
|
213
305
|
|
|
214
306
|
for (const attrKey of attributesMap.keys()) {
|
|
215
307
|
const attributes = attributesMap.get(attrKey);
|
|
308
|
+
if (!attributes) {
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
216
311
|
if (attributes.positions.length === 0) {
|
|
217
312
|
attributesMap.delete(attrKey);
|
|
218
313
|
continue; // eslint-disable-line no-continue
|
|
219
314
|
}
|
|
220
|
-
|
|
315
|
+
if (attributes.featureIndicesGroups) {
|
|
316
|
+
attributes.featureIndices = attributes.featureIndicesGroups.reduce((acc, value) =>
|
|
317
|
+
acc.concat(value)
|
|
318
|
+
);
|
|
319
|
+
delete attributes.featureIndicesGroups;
|
|
320
|
+
}
|
|
221
321
|
}
|
|
222
322
|
|
|
223
323
|
return attributesMap;
|
|
@@ -226,23 +326,32 @@ function convertAttributes(tileContent, useCartesianPositions) {
|
|
|
226
326
|
/**
|
|
227
327
|
* Gltf has hierarchical structure of nodes. This function converts nodes starting from those which are in gltf scene object.
|
|
228
328
|
* The goal is applying tranformation matrix for all children. Functions "convertNodes" and "convertNode" work together recursively.
|
|
229
|
-
* @param
|
|
230
|
-
* @param
|
|
231
|
-
* @param
|
|
232
|
-
*
|
|
233
|
-
*
|
|
329
|
+
* @param nodes - gltf nodes array
|
|
330
|
+
* @param tileContent - 3d tile content
|
|
331
|
+
* @param attributesMap - for recursive concatenation of attributes
|
|
332
|
+
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
333
|
+
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
334
|
+
* @param matrix - transformation matrix - cumulative transformation matrix formed from all parent node matrices
|
|
234
335
|
* @returns {void}
|
|
235
336
|
*/
|
|
236
337
|
function convertNodes(
|
|
237
|
-
nodes,
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
338
|
+
nodes: GLTFNodePostprocessed[],
|
|
339
|
+
cartographicOrigin: Vector3,
|
|
340
|
+
cartesianModelMatrix: Matrix4,
|
|
341
|
+
attributesMap: Map<string, ConvertedAttributes>,
|
|
342
|
+
useCartesianPositions: boolean,
|
|
343
|
+
matrix: Matrix4 = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
|
|
242
344
|
) {
|
|
243
345
|
if (nodes) {
|
|
244
346
|
for (const node of nodes) {
|
|
245
|
-
convertNode(
|
|
347
|
+
convertNode(
|
|
348
|
+
node,
|
|
349
|
+
cartographicOrigin,
|
|
350
|
+
cartesianModelMatrix,
|
|
351
|
+
attributesMap,
|
|
352
|
+
useCartesianPositions,
|
|
353
|
+
matrix
|
|
354
|
+
);
|
|
246
355
|
}
|
|
247
356
|
}
|
|
248
357
|
}
|
|
@@ -262,6 +371,10 @@ function getCompositeTransformationMatrix(node, matrix) {
|
|
|
262
371
|
transformationMatrix = matrix.multiplyRight(nodeMatrix);
|
|
263
372
|
}
|
|
264
373
|
|
|
374
|
+
if (translation) {
|
|
375
|
+
transformationMatrix = transformationMatrix.translate(translation);
|
|
376
|
+
}
|
|
377
|
+
|
|
265
378
|
if (rotation) {
|
|
266
379
|
transformationMatrix = transformationMatrix.rotateXYZ(rotation);
|
|
267
380
|
}
|
|
@@ -270,26 +383,24 @@ function getCompositeTransformationMatrix(node, matrix) {
|
|
|
270
383
|
transformationMatrix = transformationMatrix.scale(scale);
|
|
271
384
|
}
|
|
272
385
|
|
|
273
|
-
if (translation) {
|
|
274
|
-
transformationMatrix = transformationMatrix.translate(translation);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
386
|
return transformationMatrix;
|
|
278
387
|
}
|
|
279
388
|
|
|
280
389
|
/**
|
|
281
390
|
* Convert all primitives of node and all children nodes
|
|
282
|
-
* @param
|
|
391
|
+
* @param node - gltf node
|
|
283
392
|
* @param {Object} tileContent - 3d tile content
|
|
284
393
|
* @param {Map} attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
|
|
285
394
|
* attributes
|
|
395
|
+
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
396
|
+
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
286
397
|
* @param {Matrix4} matrix - transformation matrix - cumulative transformation matrix formed from all parent node matrices
|
|
287
|
-
* @todo: optimize arrays concatenation
|
|
288
398
|
*/
|
|
289
399
|
function convertNode(
|
|
290
|
-
node,
|
|
291
|
-
|
|
292
|
-
|
|
400
|
+
node: GLTFNodePostprocessed,
|
|
401
|
+
cartographicOrigin: Vector3,
|
|
402
|
+
cartesianModelMatrix: Matrix4,
|
|
403
|
+
attributesMap: Map<string, ConvertedAttributes>,
|
|
293
404
|
useCartesianPositions,
|
|
294
405
|
matrix = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
|
|
295
406
|
) {
|
|
@@ -297,12 +408,20 @@ function convertNode(
|
|
|
297
408
|
|
|
298
409
|
const mesh = node.mesh;
|
|
299
410
|
if (mesh) {
|
|
300
|
-
convertMesh(
|
|
411
|
+
convertMesh(
|
|
412
|
+
mesh,
|
|
413
|
+
cartographicOrigin,
|
|
414
|
+
cartesianModelMatrix,
|
|
415
|
+
attributesMap,
|
|
416
|
+
useCartesianPositions,
|
|
417
|
+
transformationMatrix
|
|
418
|
+
);
|
|
301
419
|
}
|
|
302
420
|
|
|
303
421
|
convertNodes(
|
|
304
|
-
node.children,
|
|
305
|
-
|
|
422
|
+
node.children || [],
|
|
423
|
+
cartographicOrigin,
|
|
424
|
+
cartesianModelMatrix,
|
|
306
425
|
attributesMap,
|
|
307
426
|
useCartesianPositions,
|
|
308
427
|
transformationMatrix
|
|
@@ -311,22 +430,25 @@ function convertNode(
|
|
|
311
430
|
|
|
312
431
|
/**
|
|
313
432
|
* Convert all primitives of node and all children nodes
|
|
314
|
-
* @param
|
|
315
|
-
* @param
|
|
316
|
-
* @param
|
|
433
|
+
* @param mesh - gltf node
|
|
434
|
+
* @param content - 3d tile content
|
|
435
|
+
* @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
|
|
436
|
+
* Cartesian coordinates will be required for creating bounding voulmest from geometry positions
|
|
437
|
+
* @param attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
|
|
317
438
|
* attributes
|
|
439
|
+
|
|
318
440
|
* @param {Matrix4} matrix - transformation matrix - cumulative transformation matrix formed from all parent node matrices
|
|
319
|
-
* @todo: optimize arrays concatenation
|
|
320
441
|
*/
|
|
321
442
|
function convertMesh(
|
|
322
|
-
mesh,
|
|
323
|
-
|
|
324
|
-
|
|
443
|
+
mesh: GLTFMeshPostprocessed,
|
|
444
|
+
cartographicOrigin: Vector3,
|
|
445
|
+
cartesianModelMatrix: Matrix4,
|
|
446
|
+
attributesMap: Map<string, ConvertedAttributes>,
|
|
325
447
|
useCartesianPositions = false,
|
|
326
448
|
matrix = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
|
|
327
449
|
) {
|
|
328
450
|
for (const primitive of mesh.primitives) {
|
|
329
|
-
let outputAttributes = null;
|
|
451
|
+
let outputAttributes: ConvertedAttributes | null | undefined = null;
|
|
330
452
|
if (primitive.material) {
|
|
331
453
|
outputAttributes = attributesMap.get(primitive.material.id);
|
|
332
454
|
} else if (attributesMap.has('default')) {
|
|
@@ -334,15 +456,17 @@ function convertMesh(
|
|
|
334
456
|
}
|
|
335
457
|
assert(outputAttributes !== null, 'Primitive - material mapping failed');
|
|
336
458
|
const attributes = primitive.attributes;
|
|
337
|
-
|
|
459
|
+
if (!outputAttributes) {
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
338
462
|
outputAttributes.positions = concatenateTypedArrays(
|
|
339
463
|
outputAttributes.positions,
|
|
340
464
|
transformVertexArray({
|
|
341
465
|
vertices: attributes.POSITION.value,
|
|
342
|
-
cartographicOrigin
|
|
343
|
-
cartesianModelMatrix
|
|
466
|
+
cartographicOrigin,
|
|
467
|
+
cartesianModelMatrix,
|
|
344
468
|
nodeMatrix: matrix,
|
|
345
|
-
indices: primitive.indices
|
|
469
|
+
indices: primitive.indices?.value,
|
|
346
470
|
attributeSpecificTransformation: transformVertexPositions,
|
|
347
471
|
useCartesianPositions
|
|
348
472
|
})
|
|
@@ -351,10 +475,10 @@ function convertMesh(
|
|
|
351
475
|
outputAttributes.normals,
|
|
352
476
|
transformVertexArray({
|
|
353
477
|
vertices: attributes.NORMAL && attributes.NORMAL.value,
|
|
354
|
-
cartographicOrigin
|
|
355
|
-
cartesianModelMatrix
|
|
478
|
+
cartographicOrigin,
|
|
479
|
+
cartesianModelMatrix,
|
|
356
480
|
nodeMatrix: matrix,
|
|
357
|
-
indices: primitive.indices
|
|
481
|
+
indices: primitive.indices?.value,
|
|
358
482
|
attributeSpecificTransformation: transformVertexNormals,
|
|
359
483
|
useCartesianPositions: false
|
|
360
484
|
})
|
|
@@ -363,34 +487,43 @@ function convertMesh(
|
|
|
363
487
|
outputAttributes.texCoords,
|
|
364
488
|
flattenTexCoords(
|
|
365
489
|
attributes.TEXCOORD_0 && attributes.TEXCOORD_0.value,
|
|
366
|
-
primitive.indices
|
|
490
|
+
primitive.indices?.value
|
|
367
491
|
)
|
|
368
492
|
);
|
|
369
493
|
|
|
370
494
|
outputAttributes.colors = concatenateTypedArrays(
|
|
371
495
|
outputAttributes.colors,
|
|
372
|
-
flattenColors(attributes.COLOR_0, primitive.indices
|
|
496
|
+
flattenColors(attributes.COLOR_0, primitive.indices?.value)
|
|
373
497
|
);
|
|
374
498
|
|
|
375
|
-
outputAttributes.
|
|
376
|
-
|
|
499
|
+
outputAttributes.featureIndicesGroups = outputAttributes.featureIndicesGroups || [];
|
|
500
|
+
outputAttributes.featureIndicesGroups.push(
|
|
501
|
+
flattenBatchIds(getBatchIdsByAttributeName(attributes), primitive.indices?.value)
|
|
377
502
|
);
|
|
378
503
|
}
|
|
379
504
|
}
|
|
380
505
|
|
|
381
506
|
/**
|
|
382
507
|
* Convert vertices attributes (POSITIONS or NORMALS) to i3s compatible format
|
|
383
|
-
* @param
|
|
384
|
-
* @param
|
|
385
|
-
* @param
|
|
386
|
-
* @param
|
|
387
|
-
* @param
|
|
388
|
-
* @param
|
|
389
|
-
* @param
|
|
390
|
-
* @param
|
|
508
|
+
* @param args
|
|
509
|
+
* @param args.vertices - gltf primitive POSITION or NORMAL attribute
|
|
510
|
+
* @param args.cartographicOrigin - cartographic origin coordinates
|
|
511
|
+
* @param args.cartesianModelMatrix - a cartesian model matrix to transform coordnates from cartesian to cartographic format
|
|
512
|
+
* @param args.nodeMatrix - a gltf node transformation matrix - cumulative transformation matrix formed from all parent node matrices
|
|
513
|
+
* @param args.indices - gltf primitive indices
|
|
514
|
+
* @param args.attributeSpecificTransformation - function to do attribute - specific transformations
|
|
515
|
+
* @param args.useCartesianPositions - use coordinates as it is.
|
|
391
516
|
* @returns {Float32Array}
|
|
392
517
|
*/
|
|
393
|
-
function transformVertexArray(args
|
|
518
|
+
function transformVertexArray(args: {
|
|
519
|
+
vertices: Float32Array;
|
|
520
|
+
cartographicOrigin: number[];
|
|
521
|
+
cartesianModelMatrix: number[];
|
|
522
|
+
nodeMatrix: Matrix4;
|
|
523
|
+
indices: Uint8Array;
|
|
524
|
+
attributeSpecificTransformation: Function;
|
|
525
|
+
useCartesianPositions: boolean;
|
|
526
|
+
}) {
|
|
394
527
|
const {vertices, indices, attributeSpecificTransformation} = args;
|
|
395
528
|
const newVertices = new Float32Array(indices.length * VALUES_PER_VERTEX);
|
|
396
529
|
if (!vertices) {
|
|
@@ -410,7 +543,17 @@ function transformVertexArray(args) {
|
|
|
410
543
|
return newVertices;
|
|
411
544
|
}
|
|
412
545
|
|
|
413
|
-
|
|
546
|
+
/**
|
|
547
|
+
* Trasform positions vector with the attribute specific transformations
|
|
548
|
+
* @param vertexVector - source positions vector to transform
|
|
549
|
+
* @param calleeArgs
|
|
550
|
+
* @param calleeArgs.cartesianModelMatrix - a cartesian model matrix to transform coordnates from cartesian to cartographic format
|
|
551
|
+
* @param calleeArgs.cartographicOrigin - cartographic origin coordinates
|
|
552
|
+
* @param calleeArgs.nodeMatrix - a gltf node transformation matrix - cumulative transformation matrix formed from all parent node matrices
|
|
553
|
+
* @param calleeArgs.useCartesianPositions - use coordinates as it is.
|
|
554
|
+
* @returns transformed positions vector
|
|
555
|
+
*/
|
|
556
|
+
function transformVertexPositions(vertexVector, calleeArgs): number[] {
|
|
414
557
|
const {cartesianModelMatrix, cartographicOrigin, nodeMatrix, useCartesianPositions} = calleeArgs;
|
|
415
558
|
|
|
416
559
|
if (nodeMatrix) {
|
|
@@ -431,7 +574,15 @@ function transformVertexPositions(vertexVector, calleeArgs) {
|
|
|
431
574
|
return vertexVector;
|
|
432
575
|
}
|
|
433
576
|
|
|
434
|
-
|
|
577
|
+
/**
|
|
578
|
+
* Trasform normals vector with the attribute specific transformations
|
|
579
|
+
* @param vertexVector - source normals vector to transform
|
|
580
|
+
* @param calleeArgs
|
|
581
|
+
* @param calleeArgs.cartesianModelMatrix - a cartesian model matrix to transform coordnates from cartesian to cartographic format
|
|
582
|
+
* @param calleeArgs.nodeMatrix - a gltf node transformation matrix - cumulative transformation matrix formed from all parent node matrices
|
|
583
|
+
* @returns transformed normals vector
|
|
584
|
+
*/
|
|
585
|
+
function transformVertexNormals(vertexVector, calleeArgs): number[] {
|
|
435
586
|
const {cartesianModelMatrix, nodeMatrix} = calleeArgs;
|
|
436
587
|
|
|
437
588
|
if (nodeMatrix) {
|
|
@@ -444,11 +595,11 @@ function transformVertexNormals(vertexVector, calleeArgs) {
|
|
|
444
595
|
|
|
445
596
|
/**
|
|
446
597
|
* Convert uv0 (texture coordinates) from coords based on indices to plain arrays, compatible with i3s
|
|
447
|
-
* @param
|
|
448
|
-
* @param
|
|
449
|
-
* @returns
|
|
598
|
+
* @param texCoords - gltf primitive TEXCOORD_0 attribute
|
|
599
|
+
* @param indices - gltf primitive indices
|
|
600
|
+
* @returns flattened texture coordinates
|
|
450
601
|
*/
|
|
451
|
-
function flattenTexCoords(texCoords, indices) {
|
|
602
|
+
function flattenTexCoords(texCoords: Float32Array, indices: Uint8Array): Float32Array {
|
|
452
603
|
const newTexCoords = new Float32Array(indices.length * VALUES_PER_TEX_COORD);
|
|
453
604
|
if (!texCoords) {
|
|
454
605
|
// We need dummy UV0s because it is required in 1.6
|
|
@@ -467,11 +618,14 @@ function flattenTexCoords(texCoords, indices) {
|
|
|
467
618
|
|
|
468
619
|
/**
|
|
469
620
|
* Convert color from COLOR_0 based on indices to plain arrays, compatible with i3s
|
|
470
|
-
* @param
|
|
471
|
-
* @param
|
|
472
|
-
* @returns
|
|
621
|
+
* @param colorsAttribute - gltf primitive COLOR_0 attribute
|
|
622
|
+
* @param indices - gltf primitive indices
|
|
623
|
+
* @returns flattened colors attribute
|
|
473
624
|
*/
|
|
474
|
-
function flattenColors(
|
|
625
|
+
function flattenColors(
|
|
626
|
+
colorsAttribute: GLTFAccessorPostprocessed,
|
|
627
|
+
indices: Uint8Array
|
|
628
|
+
): Uint8Array {
|
|
475
629
|
const components = colorsAttribute?.components || VALUES_PER_COLOR_ELEMENT;
|
|
476
630
|
const newColors = new Uint8Array(indices.length * components);
|
|
477
631
|
if (!colorsAttribute) {
|
|
@@ -494,28 +648,31 @@ function flattenColors(colorsAttribute, indices) {
|
|
|
494
648
|
|
|
495
649
|
/**
|
|
496
650
|
* Flatten batchedIds list based on indices to right ordered array, compatible with i3s
|
|
497
|
-
* @param
|
|
498
|
-
* @param
|
|
499
|
-
* @returns
|
|
651
|
+
* @param batchedIds - gltf primitive
|
|
652
|
+
* @param indices - gltf primitive indices
|
|
653
|
+
* @returns flattened batch ids
|
|
500
654
|
*/
|
|
501
|
-
function flattenBatchIds(batchedIds, indices) {
|
|
655
|
+
function flattenBatchIds(batchedIds: number[], indices: Uint8Array): number[] {
|
|
502
656
|
if (!batchedIds.length || !indices.length) {
|
|
503
657
|
return [];
|
|
504
658
|
}
|
|
505
|
-
const newBatchIds = [];
|
|
659
|
+
const newBatchIds: number[] = [];
|
|
506
660
|
for (let i = 0; i < indices.length; i++) {
|
|
507
661
|
const coordIndex = indices[i];
|
|
508
662
|
newBatchIds.push(batchedIds[coordIndex]);
|
|
509
663
|
}
|
|
510
664
|
return newBatchIds;
|
|
511
665
|
}
|
|
666
|
+
|
|
512
667
|
/**
|
|
513
668
|
* Return batchIds based on possible attribute names for different kind of maps.
|
|
514
|
-
* @param
|
|
515
|
-
* @returns
|
|
669
|
+
* @param attributes - the gltf primitive attributes
|
|
670
|
+
* @returns batch ids attribute
|
|
516
671
|
*/
|
|
517
|
-
function getBatchIdsByAttributeName(attributes
|
|
518
|
-
|
|
672
|
+
function getBatchIdsByAttributeName(attributes: {
|
|
673
|
+
[key: string]: GLTFAccessorPostprocessed;
|
|
674
|
+
}): number[] {
|
|
675
|
+
let batchIds: number[] = [];
|
|
519
676
|
|
|
520
677
|
for (let index = 0; index < BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES.length; index++) {
|
|
521
678
|
const possibleBatchIdAttributeName = BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES[index];
|
|
@@ -531,9 +688,15 @@ function getBatchIdsByAttributeName(attributes) {
|
|
|
531
688
|
return batchIds;
|
|
532
689
|
}
|
|
533
690
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
691
|
+
/**
|
|
692
|
+
* Convert GLTF material to I3S material definitions and textures
|
|
693
|
+
* @param sourceMaterials Source GLTF materials
|
|
694
|
+
* @returns Array of Couples I3SMaterialDefinition + texture content
|
|
695
|
+
*/
|
|
696
|
+
function convertMaterials(
|
|
697
|
+
sourceMaterials: GLTFMaterialPostprocessed[] = []
|
|
698
|
+
): I3SMaterialWithTexture[] {
|
|
699
|
+
const result: I3SMaterialWithTexture[] = [];
|
|
537
700
|
for (const sourceMaterial of sourceMaterials) {
|
|
538
701
|
result.push(convertMaterial(sourceMaterial));
|
|
539
702
|
}
|
|
@@ -542,16 +705,20 @@ function convertMaterials(tileContent) {
|
|
|
542
705
|
|
|
543
706
|
/**
|
|
544
707
|
* Convert texture and material from gltf 2.0 material object
|
|
545
|
-
* @param
|
|
546
|
-
* @returns
|
|
708
|
+
* @param sourceMaterial - material object
|
|
709
|
+
* @returns I3S material definition and texture
|
|
547
710
|
*/
|
|
548
|
-
function convertMaterial(sourceMaterial) {
|
|
549
|
-
const material = {
|
|
711
|
+
function convertMaterial(sourceMaterial: GLTFMaterialPostprocessed): I3SMaterialWithTexture {
|
|
712
|
+
const material: I3SMaterialDefinition = {
|
|
550
713
|
doubleSided: sourceMaterial.doubleSided,
|
|
551
|
-
emissiveFactor: sourceMaterial.emissiveFactor
|
|
714
|
+
emissiveFactor: sourceMaterial.emissiveFactor?.map((c) => Math.round(c * 255)) as [
|
|
715
|
+
number,
|
|
716
|
+
number,
|
|
717
|
+
number
|
|
718
|
+
],
|
|
552
719
|
// It is in upper case in GLTF: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#alpha-coverage
|
|
553
720
|
// But it is in lower case in I3S: https://github.com/Esri/i3s-spec/blob/master/docs/1.7/materialDefinitions.cmn.md
|
|
554
|
-
alphaMode: (sourceMaterial.alphaMode
|
|
721
|
+
alphaMode: convertAlphaMode(sourceMaterial.alphaMode),
|
|
555
722
|
pbrMetallicRoughness: {
|
|
556
723
|
roughnessFactor:
|
|
557
724
|
sourceMaterial?.pbrMetallicRoughness?.roughnessFactor || DEFAULT_ROUGHNESS_FACTOR,
|
|
@@ -579,28 +746,63 @@ function convertMaterial(sourceMaterial) {
|
|
|
579
746
|
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#reference-pbrmetallicroughness
|
|
580
747
|
const baseColorFactor = sourceMaterial?.pbrMetallicRoughness?.baseColorFactor;
|
|
581
748
|
material.pbrMetallicRoughness.baseColorFactor =
|
|
582
|
-
(baseColorFactor && baseColorFactor.map((c) => Math.round(c * 255)))
|
|
749
|
+
((baseColorFactor && baseColorFactor.map((c) => Math.round(c * 255))) as [
|
|
750
|
+
number,
|
|
751
|
+
number,
|
|
752
|
+
number,
|
|
753
|
+
number
|
|
754
|
+
]) || undefined;
|
|
583
755
|
}
|
|
584
756
|
|
|
585
757
|
return {material, texture};
|
|
586
758
|
}
|
|
587
759
|
|
|
588
|
-
|
|
760
|
+
/**
|
|
761
|
+
* Converts from `alphaMode` material property from GLTF to I3S format
|
|
762
|
+
* @param gltfAlphaMode Gltf material `alphaMode` property
|
|
763
|
+
* @returns I3SMaterialDefinition.alphaMode property
|
|
764
|
+
*/
|
|
765
|
+
function convertAlphaMode(
|
|
766
|
+
gltfAlphaMode?: 'OPAQUE' | 'MASK' | 'BLEND' | string
|
|
767
|
+
): 'opaque' | 'mask' | 'blend' {
|
|
768
|
+
switch (gltfAlphaMode) {
|
|
769
|
+
case 'OPAQUE':
|
|
770
|
+
return 'opaque';
|
|
771
|
+
case 'MASK':
|
|
772
|
+
return 'mask';
|
|
773
|
+
case 'BLEND':
|
|
774
|
+
return 'blend';
|
|
775
|
+
default:
|
|
776
|
+
return 'opaque';
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Form default I3SMaterialDefinition
|
|
782
|
+
* @returns I3S material definition
|
|
783
|
+
*/
|
|
784
|
+
function getDefaultMaterial(): I3SMaterialDefinition {
|
|
589
785
|
return {
|
|
590
786
|
alphaMode: 'opaque',
|
|
591
|
-
pbrMetallicRoughness: {
|
|
787
|
+
pbrMetallicRoughness: {
|
|
788
|
+
metallicFactor: 1,
|
|
789
|
+
roughnessFactor: 1
|
|
790
|
+
}
|
|
592
791
|
};
|
|
593
792
|
}
|
|
594
793
|
|
|
595
794
|
/**
|
|
596
795
|
* Form "sharedResources" from gltf materials array
|
|
597
|
-
* @param
|
|
598
|
-
* @
|
|
796
|
+
* @param gltfMaterials - GLTF materials array
|
|
797
|
+
* @param nodeId - I3S node ID
|
|
798
|
+
* @returns {materialDefinitionInfos: Object[], textureDefinitionInfos: Object[]} -
|
|
599
799
|
* 2 arrays in format of i3s sharedResources data https://github.com/Esri/i3s-spec/blob/master/docs/1.7/sharedResource.cmn.md
|
|
600
800
|
*/
|
|
601
|
-
function getSharedResources(
|
|
602
|
-
|
|
603
|
-
|
|
801
|
+
function getSharedResources(
|
|
802
|
+
gltfMaterials: GLTFMaterialPostprocessed[],
|
|
803
|
+
nodeId: number
|
|
804
|
+
): SharedResourcesArrays {
|
|
805
|
+
const i3sResources: SharedResourcesArrays = {};
|
|
604
806
|
|
|
605
807
|
if (!gltfMaterials || !gltfMaterials.length) {
|
|
606
808
|
return i3sResources;
|
|
@@ -623,13 +825,20 @@ function getSharedResources(tileContent, nodeId) {
|
|
|
623
825
|
|
|
624
826
|
/**
|
|
625
827
|
* Convert gltf material into I3S sharedResources data
|
|
626
|
-
* @param
|
|
627
|
-
* @
|
|
828
|
+
* @param gltfMaterial - gltf material data
|
|
829
|
+
* @param nodeId - I3S node ID
|
|
830
|
+
* @returns - Couple {materialDefinitionInfo, textureDefinitionInfo} extracted from gltf material data
|
|
628
831
|
*/
|
|
629
|
-
function convertGLTFMaterialToI3sSharedResources(
|
|
832
|
+
function convertGLTFMaterialToI3sSharedResources(
|
|
833
|
+
gltfMaterial: GLTFMaterialPostprocessed,
|
|
834
|
+
nodeId: number
|
|
835
|
+
): {
|
|
836
|
+
materialDefinitionInfo: MaterialDefinitionInfo;
|
|
837
|
+
textureDefinitionInfo: TextureDefinitionInfo | null;
|
|
838
|
+
} {
|
|
630
839
|
const texture =
|
|
631
840
|
gltfMaterial?.pbrMetallicRoughness?.baseColorTexture || gltfMaterial.emissiveTexture;
|
|
632
|
-
let textureDefinitionInfo = null;
|
|
841
|
+
let textureDefinitionInfo: TextureDefinitionInfo | null = null;
|
|
633
842
|
if (texture) {
|
|
634
843
|
textureDefinitionInfo = extractSharedResourcesTextureInfo(texture.texture, nodeId);
|
|
635
844
|
}
|
|
@@ -642,7 +851,10 @@ function convertGLTFMaterialToI3sSharedResources(gltfMaterial, nodeId) {
|
|
|
642
851
|
}
|
|
643
852
|
|
|
644
853
|
return {
|
|
645
|
-
materialDefinitionInfo: extractSharedResourcesMaterialInfo(
|
|
854
|
+
materialDefinitionInfo: extractSharedResourcesMaterialInfo(
|
|
855
|
+
colorFactor || [1, 1, 1, 1],
|
|
856
|
+
metallicFactor
|
|
857
|
+
),
|
|
646
858
|
textureDefinitionInfo
|
|
647
859
|
};
|
|
648
860
|
}
|
|
@@ -658,11 +870,14 @@ function convertGLTFMaterialToI3sSharedResources(gltfMaterial, nodeId) {
|
|
|
658
870
|
*
|
|
659
871
|
* Assumption: F0 - specular in i3s ("specular reflection" <-> "reflectance value at normal incidence")
|
|
660
872
|
* cdiff - diffuse in i3s ("Diffuse color" <-> "'c' diffuse" (c means color?))
|
|
661
|
-
* @param
|
|
662
|
-
* @param
|
|
663
|
-
* @returns
|
|
873
|
+
* @param baseColorFactor - RGBA color in 0..1 format
|
|
874
|
+
* @param metallicFactor - "metallicFactor" attribute of gltf material object
|
|
875
|
+
* @returns material definition info for I3S shared resource
|
|
664
876
|
*/
|
|
665
|
-
function extractSharedResourcesMaterialInfo(
|
|
877
|
+
function extractSharedResourcesMaterialInfo(
|
|
878
|
+
baseColorFactor: number[],
|
|
879
|
+
metallicFactor: number = 1
|
|
880
|
+
): MaterialDefinitionInfo {
|
|
666
881
|
const matDielectricColorComponent = 0.04 / 255; // Color from rgb (255) to 0..1 resolution
|
|
667
882
|
// All color resolutions are 0..1
|
|
668
883
|
const black = new Vector4(0, 0, 0, 1);
|
|
@@ -681,38 +896,47 @@ function extractSharedResourcesMaterialInfo(baseColorFactor, metallicFactor = 1)
|
|
|
681
896
|
dielectricSpecular[3] = 1;
|
|
682
897
|
const specular = dielectricSpecular.lerp(dielectricSpecular, baseColorVector, metallicFactor);
|
|
683
898
|
return {
|
|
684
|
-
|
|
685
|
-
|
|
899
|
+
params: {
|
|
900
|
+
diffuse: diffuse.toArray(),
|
|
901
|
+
specular: specular.toArray(),
|
|
902
|
+
renderMode: 'solid'
|
|
903
|
+
}
|
|
686
904
|
};
|
|
687
905
|
}
|
|
688
906
|
|
|
689
907
|
/**
|
|
690
908
|
* Form "textureDefinition" which is part of "sharedResouces"
|
|
691
|
-
* @param
|
|
692
|
-
* @
|
|
909
|
+
* @param texture - texture image info
|
|
910
|
+
* @param nodeId - I3S node ID
|
|
911
|
+
* @returns texture definition infor for shared resource
|
|
693
912
|
*/
|
|
694
|
-
function extractSharedResourcesTextureInfo(
|
|
913
|
+
function extractSharedResourcesTextureInfo(
|
|
914
|
+
texture: GLTFTexturePostprocessed,
|
|
915
|
+
nodeId: number
|
|
916
|
+
): TextureDefinitionInfo {
|
|
695
917
|
return {
|
|
696
|
-
encoding: [texture.source.mimeType],
|
|
918
|
+
encoding: texture?.source?.mimeType ? [texture.source.mimeType] : undefined,
|
|
697
919
|
images: [
|
|
698
920
|
{
|
|
699
921
|
// 'i3s' has just size which is width of the image. Images are supposed to be square.
|
|
700
922
|
// https://github.com/Esri/i3s-spec/blob/master/docs/1.7/image.cmn.md
|
|
701
923
|
id: generateImageId(texture, nodeId),
|
|
702
|
-
size: texture.source
|
|
703
|
-
length: [texture.source
|
|
924
|
+
size: texture.source?.image.width,
|
|
925
|
+
length: [texture.source?.image.data.length]
|
|
704
926
|
}
|
|
705
927
|
]
|
|
706
928
|
};
|
|
707
929
|
}
|
|
708
|
-
|
|
930
|
+
|
|
931
|
+
/**
|
|
709
932
|
* Formula for counting imageId:
|
|
710
933
|
* https://github.com/Esri/i3s-spec/blob/0a6366a9249b831db8436c322f8d27521e86cf07/format/Indexed%203d%20Scene%20Layer%20Format%20Specification.md#generating-image-ids
|
|
711
|
-
* @param
|
|
712
|
-
* @
|
|
934
|
+
* @param texture - texture image info
|
|
935
|
+
* @param nodeId - I3S node ID
|
|
936
|
+
* @returns calculate image ID according to the spec
|
|
713
937
|
*/
|
|
714
|
-
function generateImageId(texture, nodeId) {
|
|
715
|
-
const {width, height} = texture.source
|
|
938
|
+
function generateImageId(texture: GLTFTexturePostprocessed, nodeId) {
|
|
939
|
+
const {width, height} = texture.source?.image;
|
|
716
940
|
const levelCountOfTexture = 1;
|
|
717
941
|
const indexOfLevel = 0;
|
|
718
942
|
const indexOfTextureInStore = nodeId + 1;
|
|
@@ -732,13 +956,18 @@ function generateImageId(texture, nodeId) {
|
|
|
732
956
|
|
|
733
957
|
/**
|
|
734
958
|
* Make all feature ids unique through all nodes in layout.
|
|
735
|
-
* @param
|
|
736
|
-
* @param
|
|
737
|
-
* @param
|
|
738
|
-
* @param
|
|
959
|
+
* @param featureIds
|
|
960
|
+
* @param featureIndices
|
|
961
|
+
* @param featuresHashArray
|
|
962
|
+
* @param batchTable
|
|
739
963
|
* @returns {void}
|
|
740
964
|
*/
|
|
741
|
-
function makeFeatureIdsUnique(
|
|
965
|
+
function makeFeatureIdsUnique(
|
|
966
|
+
featureIds: number[],
|
|
967
|
+
featureIndices: number[],
|
|
968
|
+
featuresHashArray: string[],
|
|
969
|
+
batchTable: {[key: string]: any}
|
|
970
|
+
) {
|
|
742
971
|
const replaceMap = getFeaturesReplaceMap(featureIds, batchTable, featuresHashArray);
|
|
743
972
|
replaceIndicesByUnique(featureIndices, replaceMap);
|
|
744
973
|
replaceIndicesByUnique(featureIds, replaceMap);
|
|
@@ -814,7 +1043,7 @@ function replaceIndicesByUnique(indicesArray, featureMap) {
|
|
|
814
1043
|
* @returns {Array} - Array of file buffers.
|
|
815
1044
|
*/
|
|
816
1045
|
function convertBatchTableToAttributeBuffers(batchTable, featureIds, attributeStorageInfo) {
|
|
817
|
-
const attributeBuffers = [];
|
|
1046
|
+
const attributeBuffers: ArrayBuffer[] = [];
|
|
818
1047
|
|
|
819
1048
|
if (batchTable) {
|
|
820
1049
|
const batchTableWithFeatureIds = {
|
|
@@ -825,7 +1054,7 @@ function convertBatchTableToAttributeBuffers(batchTable, featureIds, attributeSt
|
|
|
825
1054
|
for (const key in batchTableWithFeatureIds) {
|
|
826
1055
|
const type = getAttributeType(key, attributeStorageInfo);
|
|
827
1056
|
|
|
828
|
-
let attributeBuffer = null;
|
|
1057
|
+
let attributeBuffer: ArrayBuffer | null = null;
|
|
829
1058
|
|
|
830
1059
|
switch (type) {
|
|
831
1060
|
case OBJECT_ID_TYPE:
|
|
@@ -842,7 +1071,9 @@ function convertBatchTableToAttributeBuffers(batchTable, featureIds, attributeSt
|
|
|
842
1071
|
attributeBuffer = generateStringAttributeBuffer(batchTableWithFeatureIds[key]);
|
|
843
1072
|
}
|
|
844
1073
|
|
|
845
|
-
|
|
1074
|
+
if (attributeBuffer) {
|
|
1075
|
+
attributeBuffers.push(attributeBuffer);
|
|
1076
|
+
}
|
|
846
1077
|
}
|
|
847
1078
|
}
|
|
848
1079
|
|
|
@@ -864,7 +1095,7 @@ function getAttributeType(key, attributeStorageInfo) {
|
|
|
864
1095
|
* @param {Array} featureIds
|
|
865
1096
|
* @returns {ArrayBuffer} - Buffer with objectId data.
|
|
866
1097
|
*/
|
|
867
|
-
function generateShortIntegerAttributeBuffer(featureIds) {
|
|
1098
|
+
function generateShortIntegerAttributeBuffer(featureIds): ArrayBuffer {
|
|
868
1099
|
const count = new Uint32Array([featureIds.length]);
|
|
869
1100
|
const valuesArray = new Uint32Array(featureIds);
|
|
870
1101
|
return concatenateArrayBuffers(count.buffer, valuesArray.buffer);
|
|
@@ -875,7 +1106,7 @@ function generateShortIntegerAttributeBuffer(featureIds) {
|
|
|
875
1106
|
* @param {Array} featureIds
|
|
876
1107
|
* @returns {ArrayBuffer} - Buffer with objectId data.
|
|
877
1108
|
*/
|
|
878
|
-
function generateDoubleAttributeBuffer(featureIds) {
|
|
1109
|
+
function generateDoubleAttributeBuffer(featureIds): ArrayBuffer {
|
|
879
1110
|
const count = new Uint32Array([featureIds.length]);
|
|
880
1111
|
const padding = new Uint8Array(4);
|
|
881
1112
|
const valuesArray = new Float64Array(featureIds);
|
|
@@ -888,11 +1119,11 @@ function generateDoubleAttributeBuffer(featureIds) {
|
|
|
888
1119
|
* @param {Array} batchAttributes
|
|
889
1120
|
* @returns {ArrayBuffer} - Buffer with batch table data.
|
|
890
1121
|
*/
|
|
891
|
-
function generateStringAttributeBuffer(batchAttributes) {
|
|
1122
|
+
function generateStringAttributeBuffer(batchAttributes): ArrayBuffer {
|
|
892
1123
|
const stringCountArray = new Uint32Array([batchAttributes.length]);
|
|
893
1124
|
let totalNumberOfBytes = 0;
|
|
894
1125
|
const stringSizesArray = new Uint32Array(batchAttributes.length);
|
|
895
|
-
const stringBufferArray = [];
|
|
1126
|
+
const stringBufferArray: ArrayBuffer[] = [];
|
|
896
1127
|
|
|
897
1128
|
for (let index = 0; index < batchAttributes.length; index++) {
|
|
898
1129
|
const currentString = `${String(batchAttributes[index])}\0`;
|
|
@@ -929,10 +1160,17 @@ function generateBigUint64Array(featureIds) {
|
|
|
929
1160
|
/**
|
|
930
1161
|
* Generates draco compressed geometry
|
|
931
1162
|
* @param {Number} vertexCount
|
|
932
|
-
* @param {Object} convertedAttributes
|
|
1163
|
+
* @param {Object} convertedAttributes - get rid of this argument here
|
|
1164
|
+
* @param {Object} attributes - geometry attributes to compress
|
|
1165
|
+
* @param {string} dracoWorkerSoure - draco worker source code
|
|
933
1166
|
* @returns {Promise<object>} - COmpressed geometry.
|
|
934
1167
|
*/
|
|
935
|
-
async function generateCompressedGeometry(
|
|
1168
|
+
async function generateCompressedGeometry(
|
|
1169
|
+
vertexCount,
|
|
1170
|
+
convertedAttributes,
|
|
1171
|
+
attributes,
|
|
1172
|
+
dracoWorkerSoure
|
|
1173
|
+
) {
|
|
936
1174
|
const {positions, normals, texCoords, colors, featureIds, faceRange} = attributes;
|
|
937
1175
|
const indices = new Uint32Array(vertexCount);
|
|
938
1176
|
|
|
@@ -946,7 +1184,13 @@ async function generateCompressedGeometry(vertexCount, convertedAttributes, attr
|
|
|
946
1184
|
|
|
947
1185
|
const featureIndex = generateFeatureIndexAttribute(featureIndices, faceRange);
|
|
948
1186
|
|
|
949
|
-
const compressedAttributes
|
|
1187
|
+
const compressedAttributes: {
|
|
1188
|
+
positions: TypedArray;
|
|
1189
|
+
normals: TypedArray;
|
|
1190
|
+
colors: TypedArray;
|
|
1191
|
+
'feature-index': TypedArray;
|
|
1192
|
+
texCoords?: TypedArray;
|
|
1193
|
+
} = {
|
|
950
1194
|
positions,
|
|
951
1195
|
normals,
|
|
952
1196
|
colors,
|
|
@@ -964,14 +1208,16 @@ async function generateCompressedGeometry(vertexCount, convertedAttributes, attr
|
|
|
964
1208
|
}
|
|
965
1209
|
};
|
|
966
1210
|
|
|
967
|
-
return
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1211
|
+
return encode({attributes: compressedAttributes, indices}, DracoWriterWorker, {
|
|
1212
|
+
...DracoWriterWorker.options,
|
|
1213
|
+
source: dracoWorkerSoure,
|
|
1214
|
+
reuseWorkers: true,
|
|
1215
|
+
_nodeWorkers: true,
|
|
1216
|
+
draco: {
|
|
1217
|
+
method: 'MESH_SEQUENTIAL_ENCODING',
|
|
1218
|
+
attributesMetadata
|
|
1219
|
+
}
|
|
1220
|
+
});
|
|
975
1221
|
}
|
|
976
1222
|
|
|
977
1223
|
/**
|