@loaders.gl/tile-converter 4.0.0-alpha.7 → 4.0.0-alpha.9

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.
Files changed (149) hide show
  1. package/dist/3d-tiles-attributes-worker.js +2 -2
  2. package/dist/3d-tiles-attributes-worker.js.map +2 -2
  3. package/dist/converter.min.js +67 -67
  4. package/dist/deps-installer/deps-installer.d.ts.map +1 -1
  5. package/dist/deps-installer/deps-installer.js +3 -2
  6. package/dist/dist.min.js +698 -340
  7. package/dist/es5/3d-tiles-attributes-worker.js +1 -1
  8. package/dist/es5/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  9. package/dist/es5/deps-installer/deps-installer.js +4 -3
  10. package/dist/es5/deps-installer/deps-installer.js.map +1 -1
  11. package/dist/es5/i3s-attributes-worker.js +1 -1
  12. package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js +2 -2
  13. package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  14. package/dist/es5/i3s-converter/helpers/coordinate-converter.js +6 -7
  15. package/dist/es5/i3s-converter/helpers/coordinate-converter.js.map +1 -1
  16. package/dist/es5/i3s-converter/helpers/geometry-converter.js +25 -14
  17. package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
  18. package/dist/es5/i3s-converter/helpers/gltf-attributes.js +45 -12
  19. package/dist/es5/i3s-converter/helpers/gltf-attributes.js.map +1 -1
  20. package/dist/es5/i3s-converter/helpers/load-3d-tiles.js +82 -0
  21. package/dist/es5/i3s-converter/helpers/load-3d-tiles.js.map +1 -0
  22. package/dist/es5/i3s-converter/helpers/node-index-document.js +74 -45
  23. package/dist/es5/i3s-converter/helpers/node-index-document.js.map +1 -1
  24. package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js +111 -0
  25. package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -0
  26. package/dist/es5/i3s-converter/helpers/tileset-traversal.js +82 -0
  27. package/dist/es5/i3s-converter/helpers/tileset-traversal.js.map +1 -0
  28. package/dist/es5/i3s-converter/i3s-converter.js +545 -516
  29. package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
  30. package/dist/es5/i3s-converter/types.js +16 -0
  31. package/dist/es5/i3s-converter/types.js.map +1 -1
  32. package/dist/es5/i3s-server/README.md +19 -0
  33. package/dist/es5/i3s-server/app.js +10 -1
  34. package/dist/es5/i3s-server/app.js.map +1 -1
  35. package/dist/es5/i3s-server/controllers/slpk-controller.js +84 -0
  36. package/dist/es5/i3s-server/controllers/slpk-controller.js.map +1 -0
  37. package/dist/es5/i3s-server/routes/slpk-router.js +71 -0
  38. package/dist/es5/i3s-server/routes/slpk-router.js.map +1 -0
  39. package/dist/es5/i3s-server/utils/create-scene-server.js +17 -0
  40. package/dist/es5/i3s-server/utils/create-scene-server.js.map +1 -0
  41. package/dist/es5/lib/utils/file-utils.js +1 -1
  42. package/dist/es5/lib/utils/file-utils.js.map +1 -1
  43. package/dist/es5/lib/utils/lod-conversion-utils.js.map +1 -1
  44. package/dist/es5/pgm-loader.js +1 -1
  45. package/dist/esm/3d-tiles-attributes-worker.js +1 -1
  46. package/dist/esm/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  47. package/dist/esm/deps-installer/deps-installer.js +4 -3
  48. package/dist/esm/deps-installer/deps-installer.js.map +1 -1
  49. package/dist/esm/i3s-attributes-worker.js +1 -1
  50. package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js +2 -2
  51. package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  52. package/dist/esm/i3s-converter/helpers/coordinate-converter.js +6 -7
  53. package/dist/esm/i3s-converter/helpers/coordinate-converter.js.map +1 -1
  54. package/dist/esm/i3s-converter/helpers/geometry-converter.js +19 -8
  55. package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
  56. package/dist/esm/i3s-converter/helpers/gltf-attributes.js +49 -12
  57. package/dist/esm/i3s-converter/helpers/gltf-attributes.js.map +1 -1
  58. package/dist/esm/i3s-converter/helpers/load-3d-tiles.js +35 -0
  59. package/dist/esm/i3s-converter/helpers/load-3d-tiles.js.map +1 -0
  60. package/dist/esm/i3s-converter/helpers/node-index-document.js +14 -1
  61. package/dist/esm/i3s-converter/helpers/node-index-document.js.map +1 -1
  62. package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js +48 -0
  63. package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -0
  64. package/dist/esm/i3s-converter/helpers/tileset-traversal.js +14 -0
  65. package/dist/esm/i3s-converter/helpers/tileset-traversal.js.map +1 -0
  66. package/dist/esm/i3s-converter/i3s-converter.js +134 -120
  67. package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
  68. package/dist/esm/i3s-converter/types.js +10 -1
  69. package/dist/esm/i3s-converter/types.js.map +1 -1
  70. package/dist/esm/i3s-server/README.md +19 -0
  71. package/dist/esm/i3s-server/app.js +11 -1
  72. package/dist/esm/i3s-server/app.js.map +1 -1
  73. package/dist/esm/i3s-server/controllers/slpk-controller.js +36 -0
  74. package/dist/esm/i3s-server/controllers/slpk-controller.js.map +1 -0
  75. package/dist/esm/i3s-server/routes/slpk-router.js +33 -0
  76. package/dist/esm/i3s-server/routes/slpk-router.js.map +1 -0
  77. package/dist/esm/i3s-server/utils/create-scene-server.js +16 -0
  78. package/dist/esm/i3s-server/utils/create-scene-server.js.map +1 -0
  79. package/dist/esm/lib/utils/file-utils.js +1 -1
  80. package/dist/esm/lib/utils/file-utils.js.map +1 -1
  81. package/dist/esm/lib/utils/lod-conversion-utils.js.map +1 -1
  82. package/dist/esm/pgm-loader.js +1 -1
  83. package/dist/i3s-attributes-worker.js +2 -2
  84. package/dist/i3s-attributes-worker.js.map +2 -2
  85. package/dist/i3s-converter/helpers/batch-ids-extensions.js +2 -5
  86. package/dist/i3s-converter/helpers/coordinate-converter.d.ts +3 -4
  87. package/dist/i3s-converter/helpers/coordinate-converter.d.ts.map +1 -1
  88. package/dist/i3s-converter/helpers/coordinate-converter.js +8 -9
  89. package/dist/i3s-converter/helpers/geometry-converter.d.ts +9 -4
  90. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
  91. package/dist/i3s-converter/helpers/geometry-converter.js +34 -12
  92. package/dist/i3s-converter/helpers/gltf-attributes.d.ts +22 -3
  93. package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -1
  94. package/dist/i3s-converter/helpers/gltf-attributes.js +61 -18
  95. package/dist/i3s-converter/helpers/load-3d-tiles.d.ts +18 -0
  96. package/dist/i3s-converter/helpers/load-3d-tiles.d.ts.map +1 -0
  97. package/dist/i3s-converter/helpers/load-3d-tiles.js +53 -0
  98. package/dist/i3s-converter/helpers/node-index-document.d.ts +8 -0
  99. package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -1
  100. package/dist/i3s-converter/helpers/node-index-document.js +20 -2
  101. package/dist/i3s-converter/helpers/node-pages.js +1 -1
  102. package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts +23 -0
  103. package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts.map +1 -0
  104. package/dist/i3s-converter/helpers/preprocess-3d-tiles.js +76 -0
  105. package/dist/i3s-converter/helpers/tileset-traversal.d.ts +25 -0
  106. package/dist/i3s-converter/helpers/tileset-traversal.d.ts.map +1 -0
  107. package/dist/i3s-converter/helpers/tileset-traversal.js +29 -0
  108. package/dist/i3s-converter/i3s-converter.d.ts +40 -40
  109. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  110. package/dist/i3s-converter/i3s-converter.js +150 -126
  111. package/dist/i3s-converter/types.d.ts +18 -0
  112. package/dist/i3s-converter/types.d.ts.map +1 -1
  113. package/dist/i3s-converter/types.js +15 -0
  114. package/dist/i3s-server/app.d.ts.map +1 -1
  115. package/dist/i3s-server/app.js +9 -1
  116. package/dist/i3s-server/controllers/slpk-controller.d.ts +3 -0
  117. package/dist/i3s-server/controllers/slpk-controller.d.ts.map +1 -0
  118. package/dist/i3s-server/controllers/slpk-controller.js +32 -0
  119. package/dist/i3s-server/routes/slpk-router.d.ts +3 -0
  120. package/dist/i3s-server/routes/slpk-router.d.ts.map +1 -0
  121. package/dist/i3s-server/routes/slpk-router.js +33 -0
  122. package/dist/i3s-server/utils/create-scene-server.d.ts +11 -0
  123. package/dist/i3s-server/utils/create-scene-server.d.ts.map +1 -0
  124. package/dist/i3s-server/utils/create-scene-server.js +14 -0
  125. package/dist/lib/utils/file-utils.d.ts.map +1 -1
  126. package/dist/lib/utils/file-utils.js +2 -1
  127. package/dist/lib/utils/lod-conversion-utils.d.ts +3 -2
  128. package/dist/lib/utils/lod-conversion-utils.d.ts.map +1 -1
  129. package/dist/lib/utils/lod-conversion-utils.js +1 -1
  130. package/package.json +15 -15
  131. package/src/3d-tiles-converter/3d-tiles-converter.ts +5 -5
  132. package/src/deps-installer/deps-installer.ts +3 -2
  133. package/src/i3s-converter/helpers/batch-ids-extensions.ts +2 -5
  134. package/src/i3s-converter/helpers/coordinate-converter.ts +11 -10
  135. package/src/i3s-converter/helpers/geometry-converter.ts +51 -19
  136. package/src/i3s-converter/helpers/gltf-attributes.ts +84 -21
  137. package/src/i3s-converter/helpers/load-3d-tiles.ts +68 -0
  138. package/src/i3s-converter/helpers/node-index-document.ts +22 -2
  139. package/src/i3s-converter/helpers/preprocess-3d-tiles.ts +81 -0
  140. package/src/i3s-converter/helpers/tileset-traversal.ts +51 -0
  141. package/src/i3s-converter/i3s-converter.ts +228 -178
  142. package/src/i3s-converter/types.ts +20 -0
  143. package/src/i3s-server/README.md +19 -0
  144. package/src/i3s-server/app.js +8 -1
  145. package/src/i3s-server/controllers/slpk-controller.js +38 -0
  146. package/src/i3s-server/routes/slpk-router.js +33 -0
  147. package/src/i3s-server/utils/create-scene-server.js +15 -0
  148. package/src/lib/utils/file-utils.ts +2 -1
  149. package/src/lib/utils/lod-conversion-utils.ts +6 -2
@@ -1,3 +1,4 @@
1
+ import { Tiles3DTileJSONPostprocessed } from '@loaders.gl/3d-tiles';
1
2
  import { BoundingVolumes } from '@loaders.gl/i3s';
2
3
  import { Tile3D } from '@loaders.gl/tiles';
3
4
  /**
@@ -13,7 +14,7 @@ import { Tile3D } from '@loaders.gl/tiles';
13
14
  * To avoid infinity values when we do calculations of maxError we shold replace 0 with value which allows us
14
15
  * to make child maxError bigger than his parent maxError.
15
16
  *
16
- * @param tile - 3d-tiles tile Object
17
+ * @param tile - 3d-tiles tile JSON
17
18
  * @param coordinates - node converted coordinates
18
19
  * @returns An array of LOD metrics in format compatible with i3s 3DNodeIndexDocument.lodSelection
19
20
  * @example
@@ -28,7 +29,7 @@ import { Tile3D } from '@loaders.gl/tiles';
28
29
  }
29
30
  ]
30
31
  */
31
- export declare function convertGeometricErrorToScreenThreshold(tile: Tile3D, coordinates: BoundingVolumes): {
32
+ export declare function convertGeometricErrorToScreenThreshold(tile: Tiles3DTileJSONPostprocessed, coordinates: BoundingVolumes): {
32
33
  metricType: string;
33
34
  maxError: number;
34
35
  }[];
@@ -1 +1 @@
1
- {"version":3,"file":"lod-conversion-utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/lod-conversion-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAIzC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,sCAAsC,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe;gBAC9D,MAAM;cAAY,MAAM;IAqB1D;AAED;;;;GAIG;AACH,wBAAgB,sCAAsC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe3E"}
1
+ {"version":3,"file":"lod-conversion-utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/lod-conversion-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,4BAA4B,EAAC,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAIzC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,sCAAsC,CACpD,IAAI,EAAE,4BAA4B,EAClC,WAAW,EAAE,eAAe;gBAEK,MAAM;cAAY,MAAM;IAqB1D;AAED;;;;GAIG;AACH,wBAAgB,sCAAsC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe3E"}
@@ -16,7 +16,7 @@ const DEFAULT_MAXIMUM_SCREEN_SPACE_ERROR = 16;
16
16
  * To avoid infinity values when we do calculations of maxError we shold replace 0 with value which allows us
17
17
  * to make child maxError bigger than his parent maxError.
18
18
  *
19
- * @param tile - 3d-tiles tile Object
19
+ * @param tile - 3d-tiles tile JSON
20
20
  * @param coordinates - node converted coordinates
21
21
  * @returns An array of LOD metrics in format compatible with i3s 3DNodeIndexDocument.lodSelection
22
22
  * @example
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loaders.gl/tile-converter",
3
- "version": "4.0.0-alpha.7",
3
+ "version": "4.0.0-alpha.9",
4
4
  "description": "Converter",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -44,18 +44,18 @@
44
44
  "build-3d-tiles-attributes-worker": "esbuild src/workers/3d-tiles-attributes-worker.ts --outfile=dist/3d-tiles-attributes-worker.js --platform=node --target=esnext,node14 --external:join-images --minify --bundle --sourcemap --define:__VERSION__=\\\"$npm_package_version\\\""
45
45
  },
46
46
  "dependencies": {
47
- "@loaders.gl/3d-tiles": "4.0.0-alpha.7",
48
- "@loaders.gl/crypto": "4.0.0-alpha.7",
49
- "@loaders.gl/draco": "4.0.0-alpha.7",
50
- "@loaders.gl/gltf": "4.0.0-alpha.7",
51
- "@loaders.gl/i3s": "4.0.0-alpha.7",
52
- "@loaders.gl/images": "4.0.0-alpha.7",
53
- "@loaders.gl/loader-utils": "4.0.0-alpha.7",
54
- "@loaders.gl/polyfills": "4.0.0-alpha.7",
55
- "@loaders.gl/textures": "4.0.0-alpha.7",
56
- "@loaders.gl/tiles": "4.0.0-alpha.7",
57
- "@loaders.gl/worker-utils": "4.0.0-alpha.7",
58
- "@loaders.gl/zip": "4.0.0-alpha.7",
47
+ "@loaders.gl/3d-tiles": "4.0.0-alpha.9",
48
+ "@loaders.gl/crypto": "4.0.0-alpha.9",
49
+ "@loaders.gl/draco": "4.0.0-alpha.9",
50
+ "@loaders.gl/gltf": "4.0.0-alpha.9",
51
+ "@loaders.gl/i3s": "4.0.0-alpha.9",
52
+ "@loaders.gl/images": "4.0.0-alpha.9",
53
+ "@loaders.gl/loader-utils": "4.0.0-alpha.9",
54
+ "@loaders.gl/polyfills": "4.0.0-alpha.9",
55
+ "@loaders.gl/textures": "4.0.0-alpha.9",
56
+ "@loaders.gl/tiles": "4.0.0-alpha.9",
57
+ "@loaders.gl/worker-utils": "4.0.0-alpha.9",
58
+ "@loaders.gl/zip": "4.0.0-alpha.9",
59
59
  "@math.gl/core": "^3.5.1",
60
60
  "@math.gl/culling": "^3.5.1",
61
61
  "@math.gl/geoid": "^3.5.1",
@@ -72,11 +72,11 @@
72
72
  "uuid": "^8.1.0"
73
73
  },
74
74
  "peerDependencies": {
75
- "@loaders.gl/core": "4.0.0-alpha.6"
75
+ "@loaders.gl/core": "^4.0.0-alpha.8"
76
76
  },
77
77
  "quarantinedDependencies": {
78
78
  "join-images": "^1.1.3",
79
79
  "sharp": "^0.31.3"
80
80
  },
81
- "gitHead": "afb59c4d8e5d8ebb9c28f111cb0c96c5527d0ffd"
81
+ "gitHead": "03ff81ab468f20f3bddeec787aa88d477a7e1c72"
82
82
  }
@@ -1,5 +1,5 @@
1
1
  import type {AttributeStorageInfo, FeatureAttribute, NodeReference} from '@loaders.gl/i3s';
2
- import type {Node3D} from '@loaders.gl/3d-tiles';
2
+ import type {Tiles3DTileJSON} from '@loaders.gl/3d-tiles';
3
3
 
4
4
  import {join} from 'path';
5
5
  import process from 'process';
@@ -109,7 +109,7 @@ export default class Tiles3DConverter {
109
109
  // do nothing
110
110
  }
111
111
 
112
- const rootTile: Node3D = {
112
+ const rootTile: Tiles3DTileJSON = {
113
113
  boundingVolume: {
114
114
  box: i3sObbTo3dTilesObb(rootNode.header.obb, this.geoidHeightModel)
115
115
  },
@@ -138,7 +138,7 @@ export default class Tiles3DConverter {
138
138
  */
139
139
  private async convertChildNode(
140
140
  parentSourceNode: Tile3D,
141
- parentNode: Node3D,
141
+ parentNode: Tiles3DTileJSON,
142
142
  level: number,
143
143
  childNodeInfo: NodeReference
144
144
  ): Promise<void> {
@@ -160,7 +160,7 @@ export default class Tiles3DConverter {
160
160
  const boundingVolume = {
161
161
  box: i3sObbTo3dTilesObb(sourceChild.header.obb, this.geoidHeightModel)
162
162
  };
163
- const child: Node3D = {
163
+ const child: Tiles3DTileJSON = {
164
164
  boundingVolume,
165
165
  geometricError: convertScreenThresholdToGeometricError(sourceChild),
166
166
  children: []
@@ -198,7 +198,7 @@ export default class Tiles3DConverter {
198
198
  */
199
199
  private async _addChildren(
200
200
  parentSourceNode: Tile3D,
201
- parentNode: Node3D,
201
+ parentNode: Tiles3DTileJSON,
202
202
  level: number
203
203
  ): Promise<void> {
204
204
  if (this.options.maxDepth && level > this.options.maxDepth) {
@@ -50,8 +50,9 @@ export class DepsInstaller {
50
50
  // `npm install sharp join-images` works unstable. It fails because installed `sharp` version
51
51
  // may be different from the version required by `join-images`. Pointing to specific versions
52
52
  // resolve this issue
53
- arguments: ['install', 'sharp@^0.30.4', 'join-images@^1.1.3'],
54
- wait: 0
53
+ arguments: ['install', 'sharp@0.30.4', 'join-images@1.1.3'],
54
+ wait: 0,
55
+ ignoreStderr: true
55
56
  });
56
57
 
57
58
  console.log('All dependencies were installed succesfully.'); // eslint-disable-line no-console
@@ -97,12 +97,9 @@ function handleExtFeatureMetadataExtension(
97
97
  const featureTexture =
98
98
  extFeatureMetadata?.featureTextures && extFeatureMetadata?.featureTextures[0];
99
99
 
100
- /**
101
- * TODO need to get batchIds from root extension
102
- */
103
100
  if (featureTexture) {
104
- console.warn("EXT_feature_metadata doesn't yet support featureTextures in primitive");
105
- return [];
101
+ const batchIdsAttribute = attributes[featureTexture];
102
+ return batchIdsAttribute.value;
106
103
  }
107
104
 
108
105
  return [];
@@ -8,34 +8,35 @@ import {
8
8
  makeBoundingSphereFromPoints,
9
9
  BoundingSphere
10
10
  } from '@math.gl/culling';
11
- import {Tile3D} from '@loaders.gl/tiles';
12
11
  import {Geoid} from '@math.gl/geoid';
13
12
 
14
13
  /**
15
14
  * Create bounding volumes object from tile and geoid height model.
16
- * @param tile
17
- * @param geoidHeightModel
15
+ * @param sourceBoundingVolume - initialized bounding volume of the source tile
16
+ * @param geoidHeightModel - instance of Geoid class that converts elevation from geoidal to ellipsoidal and back
18
17
  * @returns - Bounding volumes object
19
18
  */
20
- export function createBoundingVolumes(tile: Tile3D, geoidHeightModel: Geoid): BoundingVolumes {
19
+ export function createBoundingVolumes(
20
+ sourceBoundingVolume: OrientedBoundingBox | BoundingSphere,
21
+ geoidHeightModel: Geoid
22
+ ): BoundingVolumes {
21
23
  let radius;
22
24
  let halfSize;
23
25
  let quaternion;
24
26
 
25
- const boundingVolume = tile.boundingVolume;
26
27
  const cartographicCenter = Ellipsoid.WGS84.cartesianToCartographic(
27
- boundingVolume.center,
28
+ sourceBoundingVolume.center,
28
29
  new Vector3()
29
30
  );
30
31
  cartographicCenter[2] =
31
32
  cartographicCenter[2] -
32
33
  geoidHeightModel.getHeight(cartographicCenter[1], cartographicCenter[0]);
33
- if (boundingVolume instanceof OrientedBoundingBox) {
34
- halfSize = boundingVolume.halfSize;
34
+ if (sourceBoundingVolume instanceof OrientedBoundingBox) {
35
+ halfSize = sourceBoundingVolume.halfSize;
35
36
  radius = new Vector3(halfSize[0], halfSize[1], halfSize[2]).len();
36
- quaternion = boundingVolume.quaternion;
37
+ quaternion = sourceBoundingVolume.quaternion;
37
38
  } else {
38
- radius = tile.boundingVolume.radius;
39
+ radius = sourceBoundingVolume.radius;
39
40
  halfSize = [radius, radius, radius];
40
41
  quaternion = new Quaternion()
41
42
  .fromMatrix3(new Matrix3([halfSize[0], 0, 0, 0, halfSize[1], 0, 0, 0, halfSize[2]]))
@@ -1,4 +1,4 @@
1
- import type {B3DMContent, FeatureTableJson} from '@loaders.gl/3d-tiles';
1
+ import type {FeatureTableJson, Tiles3DTileContent} from '@loaders.gl/3d-tiles';
2
2
  import type {
3
3
  GLTF_EXT_feature_metadata,
4
4
  GLTF_EXT_mesh_features,
@@ -52,6 +52,7 @@ import {GL} from '@loaders.gl/math';
52
52
  */
53
53
  import type {TypedArrayConstructor} from '../types';
54
54
  import {generateSyntheticIndices} from '../../lib/utils/geometry-utils';
55
+ import {BoundingSphere, OrientedBoundingBox} from '@math.gl/culling';
55
56
 
56
57
  // Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.7/pbrMetallicRoughness.cmn.md
57
58
  const DEFAULT_ROUGHNESS_FACTOR = 1;
@@ -81,6 +82,9 @@ let scratchVector = new Vector3();
81
82
  * Convert binary data from b3dm file to i3s resources
82
83
  *
83
84
  * @param tileContent - 3d tile content
85
+ * @param tileTransform - transformation matrix of the tile, calculated recursively multiplying
86
+ * transform of all parent tiles and transform of the current tile
87
+ * @param tileBoundingVolume - initialized bounding volume of the source tile
84
88
  * @param addNodeToNodePage - function to add new node to node pages
85
89
  * @param propertyTable - batch table (corresponding to feature attributes data)
86
90
  * @param featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
@@ -93,7 +97,9 @@ let scratchVector = new Vector3();
93
97
  * @returns Array of node resources to create one or more i3s nodes
94
98
  */
95
99
  export default async function convertB3dmToI3sGeometry(
96
- tileContent: B3DMContent,
100
+ tileContent: Tiles3DTileContent,
101
+ tileTransform: Matrix4,
102
+ tileBoundingVolume: OrientedBoundingBox | BoundingSphere,
97
103
  addNodeToNodePage: () => Promise<number>,
98
104
  propertyTable: FeatureTableJson | null,
99
105
  featuresHashArray: string[],
@@ -110,7 +116,11 @@ export default async function convertB3dmToI3sGeometry(
110
116
  shouldMergeMaterials
111
117
  );
112
118
 
113
- const dataForAttributesConversion = prepareDataForAttributesConversion(tileContent);
119
+ const dataForAttributesConversion = prepareDataForAttributesConversion(
120
+ tileContent,
121
+ tileTransform,
122
+ tileBoundingVolume
123
+ );
114
124
  const convertedAttributesMap: Map<string, ConvertedAttributes> = await convertAttributes(
115
125
  dataForAttributesConversion,
116
126
  materialAndTextureList,
@@ -198,7 +208,7 @@ function _generateBoundingVolumesFromGeometry(
198
208
  * @param params.convertedAttributes - Converted geometry attributes
199
209
  * @param params.material - I3S PBR-like material definition
200
210
  * @param params.texture - texture content
201
- * @param params.tileContent - B3DM decoded content
211
+ * @param params.tileContent - 3DTiles decoded content
202
212
  * @param params.nodeId - new node ID
203
213
  * @param params.featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
204
214
  * @param params.propertyTable - batch table (corresponding to feature attributes data)
@@ -222,7 +232,7 @@ async function _makeNodeResources({
222
232
  convertedAttributes: ConvertedAttributes;
223
233
  material: I3SMaterialDefinition;
224
234
  texture?: {};
225
- tileContent: B3DMContent;
235
+ tileContent: Tiles3DTileContent;
226
236
  nodeId: number;
227
237
  featuresHashArray: string[];
228
238
  propertyTable: FeatureTableJson | null;
@@ -515,8 +525,12 @@ function convertMesh(
515
525
  outputAttributes = attributesMap.get('default');
516
526
  }
517
527
  assert(outputAttributes !== null, 'Primitive - material mapping failed');
528
+ // Per the spec https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_mode
529
+ // GL.TRIANGLES is default. So in case `mode` is `undefined`, it is 'TRIANGLES'
518
530
  assert(
519
- primitive.mode === GL.TRIANGLES || primitive.mode === GL.TRIANGLE_STRIP,
531
+ primitive.mode === undefined ||
532
+ primitive.mode === GL.TRIANGLES ||
533
+ primitive.mode === GL.TRIANGLE_STRIP,
520
534
  `Primitive - unsupported mode ${primitive.mode}`
521
535
  );
522
536
  const attributes = primitive.attributes;
@@ -1541,10 +1555,14 @@ function generateFeatureIndexAttribute(
1541
1555
  /**
1542
1556
  * Find property table in tile
1543
1557
  * For example it can be batchTable for b3dm files or property table in gLTF extension.
1544
- * @param sourceTile
1558
+ * @param tileContent - 3DTiles tile content
1545
1559
  * @return batch table from b3dm / feature properties from EXT_FEATURE_METADATA
1546
1560
  */
1547
- export function getPropertyTable(tileContent: B3DMContent): FeatureTableJson | null {
1561
+ export function getPropertyTable(tileContent: Tiles3DTileContent | null): FeatureTableJson | null {
1562
+ if (!tileContent) {
1563
+ return null;
1564
+ }
1565
+
1548
1566
  const batchTableJson = tileContent?.batchTableJson;
1549
1567
 
1550
1568
  if (batchTableJson) {
@@ -1568,10 +1586,10 @@ export function getPropertyTable(tileContent: B3DMContent): FeatureTableJson | n
1568
1586
 
1569
1587
  /**
1570
1588
  * Check extensions which can be with property table inside.
1571
- * @param sourceTile
1589
+ * @param tileContent - 3DTiles tile content
1572
1590
  */
1573
1591
  function getPropertyTableExtension(
1574
- tileContent: B3DMContent
1592
+ tileContent: Tiles3DTileContent
1575
1593
  ): GLTF_EXT_feature_metadata | GLTF_EXT_mesh_features {
1576
1594
  const extensionsWithPropertyTables = [EXT_FEATURE_METADATA, EXT_MESH_FEATURES];
1577
1595
  const extensionsUsed = tileContent?.gltf?.extensionsUsed;
@@ -1597,18 +1615,10 @@ function getPropertyTableExtension(
1597
1615
  /**
1598
1616
  * Handle EXT_feature_metadata to get property table
1599
1617
  * @param extension
1600
- * TODO add EXT_feature_metadata feature textures support.
1601
1618
  */
1602
1619
  function getPropertyTableFromExtFeatureMetadata(
1603
1620
  extension: GLTF_EXT_feature_metadata
1604
1621
  ): FeatureTableJson | null {
1605
- if (extension?.featureTextures) {
1606
- console.warn(
1607
- 'The I3S converter does not yet support the EXT_feature_metadata feature textures'
1608
- );
1609
- return null;
1610
- }
1611
-
1612
1622
  if (extension?.featureTables) {
1613
1623
  /**
1614
1624
  * Take only first feature table to generate attributes storage info object.
@@ -1630,6 +1640,28 @@ function getPropertyTableFromExtFeatureMetadata(
1630
1640
  }
1631
1641
  }
1632
1642
 
1633
- console.warn("The I3S converter couldn't handle EXT_feature_metadata extension");
1643
+ if (extension?.featureTextures) {
1644
+ /**
1645
+ * Take only first feature texture to generate attributes storage info object.
1646
+ * TODO: Think about getting data from all feature textures?
1647
+ * It can be tricky just because 3dTiles is able to have multiple featureTextures.
1648
+ * In I3S we should decide which featureTextures will be passed to geometry data.
1649
+ */
1650
+ const firstTextureName = Object.keys(extension.featureTextures)?.[0];
1651
+ if (firstTextureName) {
1652
+ const featureTable = extension?.featureTextures[firstTextureName];
1653
+ const propertyTable = {};
1654
+
1655
+ for (const propertyName in featureTable.properties) {
1656
+ propertyTable[propertyName] = featureTable.properties[propertyName].data;
1657
+ }
1658
+
1659
+ return propertyTable;
1660
+ }
1661
+ }
1662
+
1663
+ console.warn(
1664
+ "The I3S converter couldn't handle EXT_feature_metadata extension: There is neither featureTables, no featureTextures in the extension."
1665
+ );
1634
1666
  return null;
1635
1667
  }
@@ -1,33 +1,27 @@
1
- import type {B3DMContent} from '@loaders.gl/3d-tiles';
1
+ import type {Tiles3DTileContent} from '@loaders.gl/3d-tiles';
2
2
  import type {GLTFAccessorPostprocessed, GLTFNodePostprocessed} from '@loaders.gl/gltf';
3
3
  import type {B3DMAttributesData} from '../../i3s-attributes-worker';
4
+ import {Matrix4, Vector3} from '@math.gl/core';
5
+ import {BoundingSphere, OrientedBoundingBox} from '@math.gl/culling';
6
+ import {Ellipsoid} from '@math.gl/geospatial';
4
7
 
5
8
  type AttributesObject = {
6
9
  [k: string]: GLTFAccessorPostprocessed;
7
10
  };
8
11
 
9
- /**
10
- * Keep only values for B3DM attributes to pass data to worker thread.
11
- * @param attributes
12
- */
13
- function getB3DMAttributesWithoutBufferView(attributes: AttributesObject): AttributesObject {
14
- const attributesWithoutBufferView = {};
15
-
16
- for (const attributeName in attributes) {
17
- attributesWithoutBufferView[attributeName] = {
18
- value: attributes[attributeName].value
19
- };
20
- }
21
-
22
- return attributesWithoutBufferView;
23
- }
24
-
25
12
  /**
26
13
  * Prepare attributes for conversion to avoid binary data breaking in worker thread.
27
- * @param tileContent
14
+ * @param tileContent - 3DTiles tile content
15
+ * @param tileTransform - transformation matrix of the tile, calculated recursively multiplying
16
+ * transform of all parent tiles and transform of the current tile
17
+ * @param boundingVolume - initialized bounding volume of the source tile
28
18
  * @returns
29
19
  */
30
- export function prepareDataForAttributesConversion(tileContent: B3DMContent): B3DMAttributesData {
20
+ export function prepareDataForAttributesConversion(
21
+ tileContent: Tiles3DTileContent,
22
+ tileTransform: Matrix4,
23
+ boundingVolume: OrientedBoundingBox | BoundingSphere
24
+ ): B3DMAttributesData {
31
25
  let nodes =
32
26
  tileContent.gltf?.scene?.nodes ||
33
27
  tileContent.gltf?.scenes?.[0]?.nodes ||
@@ -56,8 +50,11 @@ export function prepareDataForAttributesConversion(tileContent: B3DMContent): B3
56
50
 
57
51
  prepareNodes(nodes);
58
52
 
59
- const cartographicOrigin = tileContent.cartographicOrigin;
60
- const cartesianModelMatrix = tileContent.cartesianModelMatrix;
53
+ const {cartographicOrigin, modelMatrix: cartesianModelMatrix} = calculateTransformProps(
54
+ tileContent,
55
+ tileTransform,
56
+ boundingVolume
57
+ );
61
58
 
62
59
  return {
63
60
  nodes,
@@ -67,6 +64,72 @@ export function prepareDataForAttributesConversion(tileContent: B3DMContent): B3
67
64
  };
68
65
  }
69
66
 
67
+ /**
68
+ * Keep only values for glTF attributes to pass data to worker thread.
69
+ * @param attributes - geometry attributes
70
+ */
71
+ function getB3DMAttributesWithoutBufferView(attributes: AttributesObject): AttributesObject {
72
+ const attributesWithoutBufferView = {};
73
+
74
+ for (const attributeName in attributes) {
75
+ attributesWithoutBufferView[attributeName] = {
76
+ value: attributes[attributeName].value
77
+ };
78
+ }
79
+
80
+ return attributesWithoutBufferView;
81
+ }
82
+
83
+ /**
84
+ * Calculate transformation properties to transform vertex attributes (POSITION, NORMAL, etc.)
85
+ * from METER_OFFSET coorditantes to LNGLAT_OFFSET coordinates
86
+ * @param tileContent - 3DTiles tile content
87
+ * @param tileTransform - transformation matrix of the tile, calculated recursively multiplying
88
+ * transform of all parent tiles and transform of the current tile
89
+ * @param boundingVolume - initialized bounding volume of the source tile
90
+ * @returns modelMatrix - transformation matrix to transform coordinates to cartographic coordinates
91
+ * cartographicOrigin - tile origin coordinates to calculate offsets
92
+ */
93
+ export function calculateTransformProps(
94
+ tileContent: Tiles3DTileContent,
95
+ tileTransform: Matrix4,
96
+ boundingVolume: OrientedBoundingBox | BoundingSphere
97
+ ): {modelMatrix: Matrix4; cartographicOrigin: Vector3} {
98
+ const {rtcCenter, gltfUpAxis} = tileContent;
99
+ const {center} = boundingVolume;
100
+
101
+ let modelMatrix = new Matrix4(tileTransform);
102
+
103
+ // Translate if appropriate
104
+ if (rtcCenter) {
105
+ modelMatrix.translate(rtcCenter);
106
+ }
107
+
108
+ // glTF models need to be rotated from Y to Z up
109
+ // https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/specification#y-up-to-z-up
110
+ switch (gltfUpAxis) {
111
+ case 'Z':
112
+ break;
113
+ case 'Y':
114
+ const rotationY = new Matrix4().rotateX(Math.PI / 2);
115
+ modelMatrix = modelMatrix.multiplyRight(rotationY);
116
+ break;
117
+ case 'X':
118
+ const rotationX = new Matrix4().rotateY(-Math.PI / 2);
119
+ modelMatrix = modelMatrix.multiplyRight(rotationX);
120
+ break;
121
+ default:
122
+ break;
123
+ }
124
+
125
+ const cartesianOrigin = new Vector3(center);
126
+ const cartographicOrigin = Ellipsoid.WGS84.cartesianToCartographic(
127
+ cartesianOrigin,
128
+ new Vector3()
129
+ );
130
+ return {modelMatrix, cartographicOrigin};
131
+ }
132
+
70
133
  /**
71
134
  * Traverse all nodes to replace all sensible data with copy to avoid data corruption in worker.
72
135
  * @param nodes
@@ -0,0 +1,68 @@
1
+ import type {
2
+ Tiles3DLoaderOptions,
3
+ Tiles3DTileContent,
4
+ Tiles3DTileJSONPostprocessed,
5
+ Tiles3DTilesetJSONPostprocessed
6
+ } from '@loaders.gl/3d-tiles';
7
+ import {load} from '@loaders.gl/core';
8
+
9
+ /**
10
+ * Load nested 3DTiles tileset. If the sourceTile is not nested tileset - do nothing
11
+ * @param sourceTileset - source root tileset JSON
12
+ * @param sourceTile - source tile JSON that is supposed to has link to nested tileset
13
+ * @param tilesetLoadOptions - load options for Tiles3DLoader
14
+ * @returns nothing
15
+ */
16
+ export const loadNestedTileset = async (
17
+ sourceTileset: Tiles3DTilesetJSONPostprocessed | null,
18
+ sourceTile: Tiles3DTileJSONPostprocessed,
19
+ tilesetLoadOptions: Tiles3DLoaderOptions
20
+ ): Promise<void> => {
21
+ const isTileset = sourceTile.type === 'json';
22
+ if (!sourceTileset || !sourceTile.contentUrl || !isTileset) {
23
+ return;
24
+ }
25
+
26
+ const loadOptions = {
27
+ ...tilesetLoadOptions,
28
+ [sourceTileset.loader.id]: {
29
+ isTileset,
30
+ assetGltfUpAxis: (sourceTileset.asset && sourceTileset.asset.gltfUpAxis) || 'Y'
31
+ }
32
+ };
33
+ const tileContent = await load(sourceTile.contentUrl, sourceTileset.loader, loadOptions);
34
+
35
+ if (tileContent.root) {
36
+ sourceTile.children = [tileContent.root];
37
+ }
38
+ };
39
+
40
+ /**
41
+ * Load 3DTiles tile content, that includes glTF object
42
+ * @param sourceTileset - source root tileset JSON
43
+ * @param sourceTile - source tile JSON that has link to content data
44
+ * @param tilesetLoadOptions - load options for Tiles3DLoader
45
+ * @returns - 3DTiles tile content or null
46
+ */
47
+ export const loadTile3DContent = async (
48
+ sourceTileset: Tiles3DTilesetJSONPostprocessed | null,
49
+ sourceTile: Tiles3DTileJSONPostprocessed,
50
+ tilesetLoadOptions: Tiles3DLoaderOptions
51
+ ): Promise<Tiles3DTileContent | null> => {
52
+ const isTileset = sourceTile.type === 'json';
53
+ if (!sourceTileset || !sourceTile.contentUrl || isTileset) {
54
+ return null;
55
+ }
56
+
57
+ const loadOptions = {
58
+ ...tilesetLoadOptions,
59
+ [sourceTileset.loader.id]: {
60
+ ...(tilesetLoadOptions[sourceTileset.loader.id] || {}),
61
+ isTileset,
62
+ assetGltfUpAxis: (sourceTileset.asset && sourceTileset.asset.gltfUpAxis) || 'Y'
63
+ }
64
+ };
65
+ const tileContent = await load(sourceTile.contentUrl, sourceTileset.loader, loadOptions);
66
+
67
+ return tileContent;
68
+ };
@@ -31,6 +31,15 @@ export class NodeIndexDocument {
31
31
  /** converter instance */
32
32
  private converter: I3SConverter;
33
33
 
34
+ /**
35
+ * Finalized property. It means that all child nodes are saved and their data
36
+ * is unloaded
37
+ */
38
+ private _finalized: boolean = false;
39
+ get finalized(): boolean {
40
+ return this._finalized;
41
+ }
42
+
34
43
  /**
35
44
  * Constructor
36
45
  * @param id - id of the node in node pages
@@ -90,6 +99,9 @@ export class NodeIndexDocument {
90
99
  * Add neighbors to child nodes of this node
91
100
  */
92
101
  public async addNeighbors(): Promise<void> {
102
+ if (this.finalized) {
103
+ return;
104
+ }
93
105
  const nodeData = await this.load();
94
106
  for (const childNode of this.children) {
95
107
  const childNodeData = await childNode.load();
@@ -116,9 +128,9 @@ export class NodeIndexDocument {
116
128
  await childNode.write(childNodeData);
117
129
  }
118
130
  await childNode.save();
119
- // The save after adding neighbors is the last one. Flush the the node
120
- childNode.flush();
121
131
  }
132
+ // The save after adding neighbors is the last one. Finalize the the node
133
+ this.finalize();
122
134
  }
123
135
 
124
136
  /** Save 3DNodeIndexDocument in file on disk */
@@ -128,6 +140,14 @@ export class NodeIndexDocument {
128
140
  }
129
141
  }
130
142
 
143
+ /** Finalize the node */
144
+ private finalize(): void {
145
+ this._finalized = true;
146
+ for (const child of this.children) {
147
+ child.flush();
148
+ }
149
+ }
150
+
131
151
  /**
132
152
  * Write 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md
133
153
  * @param node - Node3DIndexDocument object