@loaders.gl/3d-tiles 4.2.0-alpha.4 → 4.2.0-alpha.5

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 (141) hide show
  1. package/dist/3d-tiles-archive/3d-tiles-archive-archive.js +66 -41
  2. package/dist/3d-tiles-archive/3d-tiles-archive-parser.d.ts +1 -1
  3. package/dist/3d-tiles-archive/3d-tiles-archive-parser.d.ts.map +1 -1
  4. package/dist/3d-tiles-archive/3d-tiles-archive-parser.js +26 -16
  5. package/dist/3d-tiles-archive-loader.js +25 -14
  6. package/dist/cesium-ion-loader.js +34 -30
  7. package/dist/dist.dev.js +1963 -1037
  8. package/dist/dist.min.js +32 -0
  9. package/dist/index.cjs +122 -337
  10. package/dist/index.cjs.map +7 -0
  11. package/dist/index.d.ts +13 -13
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +7 -1
  14. package/dist/lib/classes/helpers/tile-3d-accessor-utils.js +103 -87
  15. package/dist/lib/classes/tile-3d-batch-table-hierarchy.js +179 -155
  16. package/dist/lib/classes/tile-3d-batch-table.js +232 -217
  17. package/dist/lib/classes/tile-3d-feature-table.js +62 -59
  18. package/dist/lib/constants.js +19 -15
  19. package/dist/lib/encoders/encode-3d-tile-batched-model.js +40 -35
  20. package/dist/lib/encoders/encode-3d-tile-composite.js +19 -17
  21. package/dist/lib/encoders/encode-3d-tile-instanced-model.js +32 -31
  22. package/dist/lib/encoders/encode-3d-tile-point-cloud.js +31 -32
  23. package/dist/lib/encoders/encode-3d-tile.js +23 -19
  24. package/dist/lib/encoders/helpers/encode-3d-tile-header.js +23 -23
  25. package/dist/lib/ion/ion.js +55 -54
  26. package/dist/lib/parsers/helpers/normalize-3d-tile-colors.d.ts +1 -1
  27. package/dist/lib/parsers/helpers/normalize-3d-tile-colors.d.ts.map +1 -1
  28. package/dist/lib/parsers/helpers/normalize-3d-tile-colors.js +57 -51
  29. package/dist/lib/parsers/helpers/normalize-3d-tile-normals.d.ts +1 -1
  30. package/dist/lib/parsers/helpers/normalize-3d-tile-normals.d.ts.map +1 -1
  31. package/dist/lib/parsers/helpers/normalize-3d-tile-normals.js +21 -18
  32. package/dist/lib/parsers/helpers/normalize-3d-tile-positions.js +35 -20
  33. package/dist/lib/parsers/helpers/parse-3d-implicit-tiles.d.ts +4 -4
  34. package/dist/lib/parsers/helpers/parse-3d-implicit-tiles.d.ts.map +1 -1
  35. package/dist/lib/parsers/helpers/parse-3d-implicit-tiles.js +269 -234
  36. package/dist/lib/parsers/helpers/parse-3d-tile-gltf-view.d.ts +2 -2
  37. package/dist/lib/parsers/helpers/parse-3d-tile-gltf-view.d.ts.map +1 -1
  38. package/dist/lib/parsers/helpers/parse-3d-tile-gltf-view.js +83 -55
  39. package/dist/lib/parsers/helpers/parse-3d-tile-header.d.ts +1 -1
  40. package/dist/lib/parsers/helpers/parse-3d-tile-header.d.ts.map +1 -1
  41. package/dist/lib/parsers/helpers/parse-3d-tile-header.js +23 -14
  42. package/dist/lib/parsers/helpers/parse-3d-tile-subtree.d.ts +1 -1
  43. package/dist/lib/parsers/helpers/parse-3d-tile-subtree.d.ts.map +1 -1
  44. package/dist/lib/parsers/helpers/parse-3d-tile-subtree.js +82 -54
  45. package/dist/lib/parsers/helpers/parse-3d-tile-tables.d.ts +2 -2
  46. package/dist/lib/parsers/helpers/parse-3d-tile-tables.d.ts.map +1 -1
  47. package/dist/lib/parsers/helpers/parse-3d-tile-tables.js +79 -68
  48. package/dist/lib/parsers/helpers/parse-utils.js +19 -14
  49. package/dist/lib/parsers/parse-3d-tile-batched-model.d.ts +2 -2
  50. package/dist/lib/parsers/parse-3d-tile-batched-model.d.ts.map +1 -1
  51. package/dist/lib/parsers/parse-3d-tile-batched-model.js +21 -17
  52. package/dist/lib/parsers/parse-3d-tile-composite.d.ts +2 -2
  53. package/dist/lib/parsers/parse-3d-tile-composite.d.ts.map +1 -1
  54. package/dist/lib/parsers/parse-3d-tile-composite.js +18 -14
  55. package/dist/lib/parsers/parse-3d-tile-gltf.d.ts +2 -2
  56. package/dist/lib/parsers/parse-3d-tile-gltf.d.ts.map +1 -1
  57. package/dist/lib/parsers/parse-3d-tile-gltf.js +22 -14
  58. package/dist/lib/parsers/parse-3d-tile-header.d.ts +2 -2
  59. package/dist/lib/parsers/parse-3d-tile-header.d.ts.map +1 -1
  60. package/dist/lib/parsers/parse-3d-tile-header.js +168 -159
  61. package/dist/lib/parsers/parse-3d-tile-instanced-model.d.ts +2 -2
  62. package/dist/lib/parsers/parse-3d-tile-instanced-model.d.ts.map +1 -1
  63. package/dist/lib/parsers/parse-3d-tile-instanced-model.js +153 -123
  64. package/dist/lib/parsers/parse-3d-tile-point-cloud.d.ts +2 -2
  65. package/dist/lib/parsers/parse-3d-tile-point-cloud.d.ts.map +1 -1
  66. package/dist/lib/parsers/parse-3d-tile-point-cloud.js +380 -174
  67. package/dist/lib/parsers/parse-3d-tile.d.ts +2 -2
  68. package/dist/lib/parsers/parse-3d-tile.d.ts.map +1 -1
  69. package/dist/lib/parsers/parse-3d-tile.js +24 -24
  70. package/dist/lib/utils/obb/s2-corners-to-obb.js +29 -16
  71. package/dist/lib/utils/s2/converters/s2-to-boundary.d.ts +1 -1
  72. package/dist/lib/utils/s2/converters/s2-to-boundary.d.ts.map +1 -1
  73. package/dist/lib/utils/s2/converters/s2-to-boundary.js +55 -35
  74. package/dist/lib/utils/s2/converters/s2-to-obb-points.js +31 -20
  75. package/dist/lib/utils/s2/converters/s2-to-region.d.ts +1 -1
  76. package/dist/lib/utils/s2/converters/s2-to-region.d.ts.map +1 -1
  77. package/dist/lib/utils/s2/converters/s2-to-region.js +51 -35
  78. package/dist/lib/utils/s2/index.d.ts +7 -7
  79. package/dist/lib/utils/s2/index.d.ts.map +1 -1
  80. package/dist/lib/utils/s2/index.js +3 -1
  81. package/dist/lib/utils/s2/s2-geometry-functions.js +19 -5
  82. package/dist/lib/utils/s2/s2-token-functions.js +51 -22
  83. package/dist/lib/utils/s2/s2geometry/s2-cell-utils.d.ts +1 -1
  84. package/dist/lib/utils/s2/s2geometry/s2-cell-utils.d.ts.map +1 -1
  85. package/dist/lib/utils/s2/s2geometry/s2-cell-utils.js +23 -9
  86. package/dist/lib/utils/s2/s2geometry/s2-geometry.js +218 -157
  87. package/dist/lib/utils/version.js +3 -1
  88. package/dist/tile-3d-subtree-loader.d.ts +1 -1
  89. package/dist/tile-3d-subtree-loader.d.ts.map +1 -1
  90. package/dist/tile-3d-subtree-loader.js +15 -10
  91. package/dist/tile-3d-writer.js +19 -14
  92. package/dist/tiles-3d-loader.js +65 -55
  93. package/dist/types.js +3 -1
  94. package/package.json +11 -10
  95. package/dist/3d-tiles-archive/3d-tiles-archive-archive.js.map +0 -1
  96. package/dist/3d-tiles-archive/3d-tiles-archive-parser.js.map +0 -1
  97. package/dist/3d-tiles-archive-loader.js.map +0 -1
  98. package/dist/cesium-ion-loader.js.map +0 -1
  99. package/dist/index.js.map +0 -1
  100. package/dist/lib/classes/helpers/tile-3d-accessor-utils.js.map +0 -1
  101. package/dist/lib/classes/tile-3d-batch-table-hierarchy.js.map +0 -1
  102. package/dist/lib/classes/tile-3d-batch-table.js.map +0 -1
  103. package/dist/lib/classes/tile-3d-feature-table.js.map +0 -1
  104. package/dist/lib/constants.js.map +0 -1
  105. package/dist/lib/encoders/encode-3d-tile-batched-model.js.map +0 -1
  106. package/dist/lib/encoders/encode-3d-tile-composite.js.map +0 -1
  107. package/dist/lib/encoders/encode-3d-tile-instanced-model.js.map +0 -1
  108. package/dist/lib/encoders/encode-3d-tile-point-cloud.js.map +0 -1
  109. package/dist/lib/encoders/encode-3d-tile.js.map +0 -1
  110. package/dist/lib/encoders/helpers/encode-3d-tile-header.js.map +0 -1
  111. package/dist/lib/ion/ion.js.map +0 -1
  112. package/dist/lib/parsers/helpers/normalize-3d-tile-colors.js.map +0 -1
  113. package/dist/lib/parsers/helpers/normalize-3d-tile-normals.js.map +0 -1
  114. package/dist/lib/parsers/helpers/normalize-3d-tile-positions.js.map +0 -1
  115. package/dist/lib/parsers/helpers/parse-3d-implicit-tiles.js.map +0 -1
  116. package/dist/lib/parsers/helpers/parse-3d-tile-gltf-view.js.map +0 -1
  117. package/dist/lib/parsers/helpers/parse-3d-tile-header.js.map +0 -1
  118. package/dist/lib/parsers/helpers/parse-3d-tile-subtree.js.map +0 -1
  119. package/dist/lib/parsers/helpers/parse-3d-tile-tables.js.map +0 -1
  120. package/dist/lib/parsers/helpers/parse-utils.js.map +0 -1
  121. package/dist/lib/parsers/parse-3d-tile-batched-model.js.map +0 -1
  122. package/dist/lib/parsers/parse-3d-tile-composite.js.map +0 -1
  123. package/dist/lib/parsers/parse-3d-tile-gltf.js.map +0 -1
  124. package/dist/lib/parsers/parse-3d-tile-header.js.map +0 -1
  125. package/dist/lib/parsers/parse-3d-tile-instanced-model.js.map +0 -1
  126. package/dist/lib/parsers/parse-3d-tile-point-cloud.js.map +0 -1
  127. package/dist/lib/parsers/parse-3d-tile.js.map +0 -1
  128. package/dist/lib/utils/obb/s2-corners-to-obb.js.map +0 -1
  129. package/dist/lib/utils/s2/converters/s2-to-boundary.js.map +0 -1
  130. package/dist/lib/utils/s2/converters/s2-to-obb-points.js.map +0 -1
  131. package/dist/lib/utils/s2/converters/s2-to-region.js.map +0 -1
  132. package/dist/lib/utils/s2/index.js.map +0 -1
  133. package/dist/lib/utils/s2/s2-geometry-functions.js.map +0 -1
  134. package/dist/lib/utils/s2/s2-token-functions.js.map +0 -1
  135. package/dist/lib/utils/s2/s2geometry/s2-cell-utils.js.map +0 -1
  136. package/dist/lib/utils/s2/s2geometry/s2-geometry.js.map +0 -1
  137. package/dist/lib/utils/version.js.map +0 -1
  138. package/dist/tile-3d-subtree-loader.js.map +0 -1
  139. package/dist/tile-3d-writer.js.map +0 -1
  140. package/dist/tiles-3d-loader.js.map +0 -1
  141. package/dist/types.js.map +0 -1
@@ -1,3 +1,6 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright vis.gl contributors
1
4
  import { Tile3DSubtreeLoader } from "../../../tile-3d-subtree-loader.js";
2
5
  import { load } from '@loaders.gl/core';
3
6
  import { default as log } from '@probe.gl/log';
@@ -6,260 +9,292 @@ import { convertS2BoundingVolumetoOBB } from "../../utils/obb/s2-corners-to-obb.
6
9
  const QUADTREE_DIVISION_COUNT = 4;
7
10
  const OCTREE_DIVISION_COUNT = 8;
8
11
  const SUBDIVISION_COUNT_MAP = {
9
- QUADTREE: QUADTREE_DIVISION_COUNT,
10
- OCTREE: OCTREE_DIVISION_COUNT
12
+ QUADTREE: QUADTREE_DIVISION_COUNT,
13
+ OCTREE: OCTREE_DIVISION_COUNT
11
14
  };
12
15
  function getChildS2VolumeBox(s2VolumeBox, index, subdivisionScheme) {
13
- if (s2VolumeBox !== null && s2VolumeBox !== void 0 && s2VolumeBox.box) {
14
- const cellId = getS2CellIdFromToken(s2VolumeBox.s2VolumeInfo.token);
15
- const childCellId = getS2ChildCellId(cellId, index);
16
- const childToken = getS2TokenFromCellId(childCellId);
17
- const s2ChildVolumeInfo = {
18
- ...s2VolumeBox.s2VolumeInfo
19
- };
20
- s2ChildVolumeInfo.token = childToken;
21
- switch (subdivisionScheme) {
22
- case 'OCTREE':
23
- const s2VolumeInfo = s2VolumeBox.s2VolumeInfo;
24
- const delta = s2VolumeInfo.maximumHeight - s2VolumeInfo.minimumHeight;
25
- const sizeZ = delta / 2.0;
26
- const midZ = s2VolumeInfo.minimumHeight + delta / 2.0;
27
- s2VolumeInfo.minimumHeight = midZ - sizeZ;
28
- s2VolumeInfo.maximumHeight = midZ + sizeZ;
29
- break;
30
- default:
31
- break;
16
+ if (s2VolumeBox?.box) {
17
+ // Check if the BoundingVolume is of type "box"
18
+ const cellId = getS2CellIdFromToken(s2VolumeBox.s2VolumeInfo.token);
19
+ const childCellId = getS2ChildCellId(cellId, index);
20
+ const childToken = getS2TokenFromCellId(childCellId);
21
+ // Clone object. Note, s2VolumeInfo is a plain object that doesn't contain any nested object.
22
+ // So, we can use the Spread Operator to make a shallow copy of the object.
23
+ const s2ChildVolumeInfo = { ...s2VolumeBox.s2VolumeInfo };
24
+ s2ChildVolumeInfo.token = childToken; // replace the token with the child's one
25
+ // In case of QUADTREE the sizeZ should NOT be changed!
26
+ // https://portal.ogc.org/files/102132
27
+ // A quadtree divides space only on the x and y dimensions.
28
+ // It divides each tile into 4 smaller tiles where the x and y dimensions are halved.
29
+ // The quadtree z minimum and maximum remain unchanged.
30
+ switch (subdivisionScheme) {
31
+ case 'OCTREE':
32
+ const s2VolumeInfo = s2VolumeBox.s2VolumeInfo;
33
+ const delta = s2VolumeInfo.maximumHeight - s2VolumeInfo.minimumHeight;
34
+ const sizeZ = delta / 2.0; // It's a next level (a child)
35
+ const midZ = s2VolumeInfo.minimumHeight + delta / 2.0;
36
+ s2VolumeInfo.minimumHeight = midZ - sizeZ;
37
+ s2VolumeInfo.maximumHeight = midZ + sizeZ;
38
+ break;
39
+ default:
40
+ break;
41
+ }
42
+ const box = convertS2BoundingVolumetoOBB(s2ChildVolumeInfo);
43
+ const childS2VolumeBox = {
44
+ box,
45
+ s2VolumeInfo: s2ChildVolumeInfo
46
+ };
47
+ return childS2VolumeBox;
32
48
  }
33
- const box = convertS2BoundingVolumetoOBB(s2ChildVolumeInfo);
34
- const childS2VolumeBox = {
35
- box,
36
- s2VolumeInfo: s2ChildVolumeInfo
37
- };
38
- return childS2VolumeBox;
39
- }
40
- return undefined;
49
+ return undefined;
41
50
  }
51
+ /**
52
+ * Recursively parse implicit tiles tree
53
+ * Spec - https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_implicit_tiling
54
+ * TODO Check out do we able to use Tile3D class as return type here.
55
+ * @param subtree
56
+ * @param lodMetricValue
57
+ * @param options
58
+ * @param parentData
59
+ * @param childIndex
60
+ * @param level
61
+ * @param globalData
62
+ */
63
+ // eslint-disable-next-line max-statements
42
64
  export async function parseImplicitTiles(params) {
43
- const {
44
- implicitOptions,
45
- parentData = {
46
- mortonIndex: 0,
47
- x: 0,
48
- y: 0,
49
- z: 0
50
- },
51
- childIndex = 0,
52
- s2VolumeBox,
53
- loaderOptions
54
- } = params;
55
- let {
56
- subtree,
57
- level = 0,
58
- globalData = {
59
- level: 0,
60
- mortonIndex: 0,
61
- x: 0,
62
- y: 0,
63
- z: 0
65
+ const { implicitOptions, parentData = {
66
+ mortonIndex: 0,
67
+ x: 0,
68
+ y: 0,
69
+ z: 0
70
+ }, childIndex = 0, s2VolumeBox, loaderOptions } = params;
71
+ let { subtree, level = 0, globalData = {
72
+ level: 0,
73
+ mortonIndex: 0,
74
+ x: 0,
75
+ y: 0,
76
+ z: 0
77
+ } } = params;
78
+ const { subdivisionScheme, subtreeLevels, maximumLevel, contentUrlTemplate, subtreesUriTemplate, basePath } = implicitOptions;
79
+ const tile = { children: [], lodMetricValue: 0, contentUrl: '' };
80
+ if (!maximumLevel) {
81
+ // eslint-disable-next-line no-console
82
+ log.once(`Missing 'maximumLevel' or 'availableLevels' property. The subtree ${contentUrlTemplate} won't be loaded...`);
83
+ return tile;
64
84
  }
65
- } = params;
66
- const {
67
- subdivisionScheme,
68
- subtreeLevels,
69
- maximumLevel,
70
- contentUrlTemplate,
71
- subtreesUriTemplate,
72
- basePath
73
- } = implicitOptions;
74
- const tile = {
75
- children: [],
76
- lodMetricValue: 0,
77
- contentUrl: ''
78
- };
79
- if (!maximumLevel) {
80
- log.once(`Missing 'maximumLevel' or 'availableLevels' property. The subtree ${contentUrlTemplate} won't be loaded...`);
81
- return tile;
82
- }
83
- const lev = level + globalData.level;
84
- if (lev > maximumLevel) {
85
- return tile;
86
- }
87
- const childrenPerTile = SUBDIVISION_COUNT_MAP[subdivisionScheme];
88
- const bitsPerTile = Math.log2(childrenPerTile);
89
- const childX = childIndex & 0b01;
90
- const childY = childIndex >> 1 & 0b01;
91
- const childZ = childIndex >> 2 & 0b01;
92
- const levelOffset = (childrenPerTile ** level - 1) / (childrenPerTile - 1);
93
- let childTileMortonIndex = concatBits(parentData.mortonIndex, childIndex, bitsPerTile);
94
- let tileAvailabilityIndex = levelOffset + childTileMortonIndex;
95
- let childTileX = concatBits(parentData.x, childX, 1);
96
- let childTileY = concatBits(parentData.y, childY, 1);
97
- let childTileZ = concatBits(parentData.z, childZ, 1);
98
- let isChildSubtreeAvailable = false;
99
- if (level >= subtreeLevels) {
100
- isChildSubtreeAvailable = getAvailabilityResult(subtree.childSubtreeAvailability, childTileMortonIndex);
101
- }
102
- const x = concatBits(globalData.x, childTileX, level);
103
- const y = concatBits(globalData.y, childTileY, level);
104
- const z = concatBits(globalData.z, childTileZ, level);
105
- if (isChildSubtreeAvailable) {
106
- const subtreePath = `${basePath}/${subtreesUriTemplate}`;
107
- const childSubtreeUrl = replaceContentUrlTemplate(subtreePath, lev, x, y, z);
108
- const childSubtree = await load(childSubtreeUrl, Tile3DSubtreeLoader, loaderOptions);
109
- subtree = childSubtree;
110
- globalData = {
111
- mortonIndex: childTileMortonIndex,
112
- x: childTileX,
113
- y: childTileY,
114
- z: childTileZ,
115
- level
116
- };
117
- childTileMortonIndex = 0;
118
- tileAvailabilityIndex = 0;
119
- childTileX = 0;
120
- childTileY = 0;
121
- childTileZ = 0;
122
- level = 0;
123
- }
124
- const isTileAvailable = getAvailabilityResult(subtree.tileAvailability, tileAvailabilityIndex);
125
- if (!isTileAvailable) {
126
- return tile;
127
- }
128
- const isContentAvailable = getAvailabilityResult(subtree.contentAvailability, tileAvailabilityIndex);
129
- if (isContentAvailable) {
130
- tile.contentUrl = replaceContentUrlTemplate(contentUrlTemplate, lev, x, y, z);
131
- }
132
- const childTileLevel = level + 1;
133
- const pData = {
134
- mortonIndex: childTileMortonIndex,
135
- x: childTileX,
136
- y: childTileY,
137
- z: childTileZ
138
- };
139
- for (let index = 0; index < childrenPerTile; index++) {
140
- const childS2VolumeBox = getChildS2VolumeBox(s2VolumeBox, index, subdivisionScheme);
141
- const childTileParsed = await parseImplicitTiles({
142
- subtree,
143
- implicitOptions,
144
- loaderOptions,
145
- parentData: pData,
146
- childIndex: index,
147
- level: childTileLevel,
148
- globalData: {
149
- ...globalData
150
- },
151
- s2VolumeBox: childS2VolumeBox
152
- });
153
- if (childTileParsed.contentUrl || childTileParsed.children.length) {
154
- const globalLevel = lev + 1;
155
- const childCoordinates = {
156
- childTileX,
157
- childTileY,
158
- childTileZ
159
- };
160
- const formattedTile = formatTileData(childTileParsed, globalLevel, childCoordinates, implicitOptions, s2VolumeBox);
161
- tile.children.push(formattedTile);
85
+ const lev = level + globalData.level;
86
+ if (lev > maximumLevel) {
87
+ return tile;
88
+ }
89
+ const childrenPerTile = SUBDIVISION_COUNT_MAP[subdivisionScheme];
90
+ const bitsPerTile = Math.log2(childrenPerTile);
91
+ // childIndex is in range [0,4] for quadtrees and [0, 7] for octrees
92
+ const childX = childIndex & 0b01; // Get first bit for X
93
+ const childY = (childIndex >> 1) & 0b01; // Get second bit for Y
94
+ const childZ = (childIndex >> 2) & 0b01; // Get third bit for Z
95
+ const levelOffset = (childrenPerTile ** level - 1) / (childrenPerTile - 1);
96
+ let childTileMortonIndex = concatBits(parentData.mortonIndex, childIndex, bitsPerTile);
97
+ let tileAvailabilityIndex = levelOffset + childTileMortonIndex;
98
+ // Local tile coordinates
99
+ let childTileX = concatBits(parentData.x, childX, 1);
100
+ let childTileY = concatBits(parentData.y, childY, 1);
101
+ let childTileZ = concatBits(parentData.z, childZ, 1);
102
+ let isChildSubtreeAvailable = false;
103
+ if (level >= subtreeLevels) {
104
+ isChildSubtreeAvailable = getAvailabilityResult(subtree.childSubtreeAvailability, childTileMortonIndex);
105
+ }
106
+ const x = concatBits(globalData.x, childTileX, level);
107
+ const y = concatBits(globalData.y, childTileY, level);
108
+ const z = concatBits(globalData.z, childTileZ, level);
109
+ if (isChildSubtreeAvailable) {
110
+ const subtreePath = `${basePath}/${subtreesUriTemplate}`;
111
+ const childSubtreeUrl = replaceContentUrlTemplate(subtreePath, lev, x, y, z);
112
+ const childSubtree = await load(childSubtreeUrl, Tile3DSubtreeLoader, loaderOptions);
113
+ subtree = childSubtree;
114
+ globalData = {
115
+ mortonIndex: childTileMortonIndex,
116
+ x: childTileX,
117
+ y: childTileY,
118
+ z: childTileZ,
119
+ level
120
+ };
121
+ childTileMortonIndex = 0;
122
+ tileAvailabilityIndex = 0;
123
+ childTileX = 0;
124
+ childTileY = 0;
125
+ childTileZ = 0;
126
+ level = 0;
127
+ }
128
+ const isTileAvailable = getAvailabilityResult(subtree.tileAvailability, tileAvailabilityIndex);
129
+ if (!isTileAvailable) {
130
+ return tile;
131
+ }
132
+ const isContentAvailable = getAvailabilityResult(subtree.contentAvailability, tileAvailabilityIndex);
133
+ if (isContentAvailable) {
134
+ tile.contentUrl = replaceContentUrlTemplate(contentUrlTemplate, lev, x, y, z);
135
+ }
136
+ const childTileLevel = level + 1;
137
+ const pData = { mortonIndex: childTileMortonIndex, x: childTileX, y: childTileY, z: childTileZ };
138
+ for (let index = 0; index < childrenPerTile; index++) {
139
+ const childS2VolumeBox = getChildS2VolumeBox(s2VolumeBox, index, subdivisionScheme);
140
+ // Recursive calling...
141
+ const childTileParsed = await parseImplicitTiles({
142
+ subtree,
143
+ implicitOptions,
144
+ loaderOptions,
145
+ parentData: pData,
146
+ childIndex: index,
147
+ level: childTileLevel,
148
+ globalData: { ...globalData },
149
+ s2VolumeBox: childS2VolumeBox
150
+ });
151
+ if (childTileParsed.contentUrl || childTileParsed.children.length) {
152
+ const globalLevel = lev + 1;
153
+ const childCoordinates = { childTileX, childTileY, childTileZ };
154
+ const formattedTile = formatTileData(childTileParsed, globalLevel, childCoordinates, implicitOptions, s2VolumeBox);
155
+ // @ts-ignore
156
+ tile.children.push(formattedTile);
157
+ }
162
158
  }
163
- }
164
- return tile;
159
+ return tile;
165
160
  }
161
+ /**
162
+ * Check tile availability in the bitstream array
163
+ * @param availabilityData - tileAvailability / contentAvailability / childSubtreeAvailability object
164
+ * @param index - index in the bitstream array
165
+ * @returns
166
+ */
166
167
  function getAvailabilityResult(availabilityData, index) {
167
- let availabilityObject;
168
- if (Array.isArray(availabilityData)) {
169
- availabilityObject = availabilityData[0];
170
- if (availabilityData.length > 1) {
171
- log.once('Not supported extension "3DTILES_multiple_contents" has been detected');
168
+ let availabilityObject;
169
+ if (Array.isArray(availabilityData)) {
170
+ /** TODO: we don't support `3DTILES_multiple_contents` extension at the moment.
171
+ * https://github.com/CesiumGS/3d-tiles/blob/main/extensions/3DTILES_implicit_tiling/README.md#multiple-contents
172
+ * Take first item in the array
173
+ */
174
+ availabilityObject = availabilityData[0];
175
+ if (availabilityData.length > 1) {
176
+ // eslint-disable-next-line no-console
177
+ log.once('Not supported extension "3DTILES_multiple_contents" has been detected');
178
+ }
179
+ }
180
+ else {
181
+ availabilityObject = availabilityData;
182
+ }
183
+ if ('constant' in availabilityObject) {
184
+ return Boolean(availabilityObject.constant);
172
185
  }
173
- } else {
174
- availabilityObject = availabilityData;
175
- }
176
- if ('constant' in availabilityObject) {
177
- return Boolean(availabilityObject.constant);
178
- }
179
- if (availabilityObject.explicitBitstream) {
180
- return getBooleanValueFromBitstream(index, availabilityObject.explicitBitstream);
181
- }
182
- return false;
186
+ if (availabilityObject.explicitBitstream) {
187
+ return getBooleanValueFromBitstream(index, availabilityObject.explicitBitstream);
188
+ }
189
+ return false;
183
190
  }
191
+ /**
192
+ * Do formatting of implicit tile data.
193
+ * TODO Check out do we able to use Tile3D class as type here.
194
+ * @param tile
195
+ * @param lodMetricValue
196
+ * @param options
197
+ * @returns
198
+ */
184
199
  function formatTileData(tile, level, childCoordinates, options, s2VolumeBox) {
185
- const {
186
- basePath,
187
- refine,
188
- getRefine,
189
- lodMetricType,
190
- getTileType,
191
- rootLodMetricValue,
192
- rootBoundingVolume
193
- } = options;
194
- const uri = tile.contentUrl && tile.contentUrl.replace(`${basePath}/`, '');
195
- const lodMetricValue = rootLodMetricValue / 2 ** level;
196
- const boundingVolume = s2VolumeBox !== null && s2VolumeBox !== void 0 && s2VolumeBox.box ? {
197
- box: s2VolumeBox.box
198
- } : rootBoundingVolume;
199
- const boundingVolumeForChildTile = calculateBoundingVolumeForChildTile(level, boundingVolume, childCoordinates);
200
- return {
201
- children: tile.children,
202
- contentUrl: tile.contentUrl,
203
- content: {
204
- uri
205
- },
206
- id: tile.contentUrl,
207
- refine: getRefine(refine),
208
- type: getTileType(tile),
209
- lodMetricType,
210
- lodMetricValue,
211
- geometricError: lodMetricValue,
212
- transform: tile.transform,
213
- boundingVolume: boundingVolumeForChildTile
214
- };
215
- }
216
- function calculateBoundingVolumeForChildTile(level, rootBoundingVolume, childCoordinates) {
217
- if (rootBoundingVolume.region) {
218
- const {
219
- childTileX,
220
- childTileY,
221
- childTileZ
222
- } = childCoordinates;
223
- const [west, south, east, north, minimumHeight, maximumHeight] = rootBoundingVolume.region;
224
- const boundingVolumesCount = 2 ** level;
225
- const sizeX = (east - west) / boundingVolumesCount;
226
- const sizeY = (north - south) / boundingVolumesCount;
227
- const sizeZ = (maximumHeight - minimumHeight) / boundingVolumesCount;
228
- const [childWest, childEast] = [west + sizeX * childTileX, west + sizeX * (childTileX + 1)];
229
- const [childSouth, childNorth] = [south + sizeY * childTileY, south + sizeY * (childTileY + 1)];
230
- const [childMinimumHeight, childMaximumHeight] = [minimumHeight + sizeZ * childTileZ, minimumHeight + sizeZ * (childTileZ + 1)];
200
+ const { basePath, refine, getRefine, lodMetricType, getTileType, rootLodMetricValue, rootBoundingVolume } = options;
201
+ const uri = tile.contentUrl && tile.contentUrl.replace(`${basePath}/`, '');
202
+ const lodMetricValue = rootLodMetricValue / 2 ** level;
203
+ const boundingVolume = s2VolumeBox?.box
204
+ ? { box: s2VolumeBox.box }
205
+ : rootBoundingVolume;
206
+ const boundingVolumeForChildTile = calculateBoundingVolumeForChildTile(level, boundingVolume, childCoordinates);
231
207
  return {
232
- region: [childWest, childSouth, childEast, childNorth, childMinimumHeight, childMaximumHeight]
208
+ children: tile.children,
209
+ contentUrl: tile.contentUrl,
210
+ content: { uri },
211
+ id: tile.contentUrl,
212
+ refine: getRefine(refine),
213
+ type: getTileType(tile),
214
+ lodMetricType,
215
+ lodMetricValue,
216
+ geometricError: lodMetricValue,
217
+ transform: tile.transform,
218
+ boundingVolume: boundingVolumeForChildTile
233
219
  };
234
- }
235
- if (rootBoundingVolume.box) {
236
- return rootBoundingVolume;
237
- }
238
- throw new Error(`Unsupported bounding volume type ${rootBoundingVolume}`);
239
220
  }
221
+ /**
222
+ * Calculate child bounding volume.
223
+ * Spec - https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_implicit_tiling#subdivision-rules
224
+ * @param level
225
+ * @param rootBoundingVolume
226
+ * @param childCoordinates
227
+ */
228
+ function calculateBoundingVolumeForChildTile(level, rootBoundingVolume, childCoordinates) {
229
+ if (rootBoundingVolume.region) {
230
+ const { childTileX, childTileY, childTileZ } = childCoordinates;
231
+ const [west, south, east, north, minimumHeight, maximumHeight] = rootBoundingVolume.region;
232
+ const boundingVolumesCount = 2 ** level;
233
+ const sizeX = (east - west) / boundingVolumesCount;
234
+ const sizeY = (north - south) / boundingVolumesCount;
235
+ // TODO : Why is the subdivisionScheme not being checked here?
236
+ // In case of QUADTREE the sizeZ should NOT be changed!
237
+ // https://portal.ogc.org/files/102132
238
+ // A quadtree divides space only on the x and y dimensions. It divides each tile into 4 smaller tiles where the x and y dimensions are halved. The quadtree z minimum and maximum remain unchanged.
239
+ const sizeZ = (maximumHeight - minimumHeight) / boundingVolumesCount;
240
+ const [childWest, childEast] = [west + sizeX * childTileX, west + sizeX * (childTileX + 1)];
241
+ const [childSouth, childNorth] = [south + sizeY * childTileY, south + sizeY * (childTileY + 1)];
242
+ const [childMinimumHeight, childMaximumHeight] = [
243
+ minimumHeight + sizeZ * childTileZ,
244
+ minimumHeight + sizeZ * (childTileZ + 1)
245
+ ];
246
+ return {
247
+ region: [childWest, childSouth, childEast, childNorth, childMinimumHeight, childMaximumHeight]
248
+ };
249
+ }
250
+ if (rootBoundingVolume.box) {
251
+ return rootBoundingVolume;
252
+ }
253
+ throw new Error(`Unsupported bounding volume type ${rootBoundingVolume}`);
254
+ }
255
+ /**
256
+ * Do binary concatenation
257
+ * @param higher - number to put to higher part of result
258
+ * @param lower - number to put to lower part of result
259
+ * @param shift - number of bits to shift lower number
260
+ */
240
261
  function concatBits(higher, lower, shift) {
241
- return (higher << shift) + lower;
262
+ return (higher << shift) + lower;
242
263
  }
264
+ /**
265
+ * Replace implicit tile content url with real coordinates.
266
+ * @param templateUrl
267
+ * @param level
268
+ * @param x
269
+ * @param y
270
+ * @param z
271
+ */
243
272
  export function replaceContentUrlTemplate(templateUrl, level, x, y, z) {
244
- const mapUrl = generateMapUrl({
245
- level,
246
- x,
247
- y,
248
- z
249
- });
250
- return templateUrl.replace(/{level}|{x}|{y}|{z}/gi, matched => mapUrl[matched]);
273
+ const mapUrl = generateMapUrl({ level, x, y, z });
274
+ return templateUrl.replace(/{level}|{x}|{y}|{z}/gi, (matched) => mapUrl[matched]);
251
275
  }
276
+ /**
277
+ * Get Map object for content url generation
278
+ * @param items
279
+ */
252
280
  function generateMapUrl(items) {
253
- const mapUrl = {};
254
- for (const key in items) {
255
- mapUrl[`{${key}}`] = items[key];
256
- }
257
- return mapUrl;
281
+ const mapUrl = {};
282
+ for (const key in items) {
283
+ mapUrl[`{${key}}`] = items[key];
284
+ }
285
+ return mapUrl;
258
286
  }
287
+ /**
288
+ * Get boolean value from bistream by index
289
+ * A boolean value is encoded as a single bit, either 0 (false) or 1 (true).
290
+ * Multiple boolean values are packed tightly in the same buffer.
291
+ * These buffers of tightly-packed bits are sometimes referred to as bitstreams.
292
+ * Spec - https://github.com/CesiumGS/3d-tiles/tree/implicit-revisions/specification/Metadata#booleans
293
+ * @param availabilitiIndex
294
+ */
259
295
  function getBooleanValueFromBitstream(availabilityIndex, availabilityBuffer) {
260
- const byteIndex = Math.floor(availabilityIndex / 8);
261
- const bitIndex = availabilityIndex % 8;
262
- const bitValue = availabilityBuffer[byteIndex] >> bitIndex & 1;
263
- return bitValue === 1;
296
+ const byteIndex = Math.floor(availabilityIndex / 8);
297
+ const bitIndex = availabilityIndex % 8;
298
+ const bitValue = (availabilityBuffer[byteIndex] >> bitIndex) & 1;
299
+ return bitValue === 1;
264
300
  }
265
- //# sourceMappingURL=parse-3d-implicit-tiles.js.map
@@ -1,6 +1,6 @@
1
1
  import { LoaderContext } from '@loaders.gl/loader-utils';
2
- import { Tiles3DTileContent } from '../../../types';
3
- import { Tiles3DLoaderOptions } from '../../../tiles-3d-loader';
2
+ import { Tiles3DTileContent } from "../../../types.js";
3
+ import { Tiles3DLoaderOptions } from "../../../tiles-3d-loader.js";
4
4
  export declare const GLTF_FORMAT: {
5
5
  URI: number;
6
6
  EMBEDDED: number;
@@ -1 +1 @@
1
- {"version":3,"file":"parse-3d-tile-gltf-view.d.ts","sourceRoot":"","sources":["../../../../src/lib/parsers/helpers/parse-3d-tile-gltf-view.ts"],"names":[],"mappings":"AAcA,OAAO,EAAC,aAAa,EAAqC,MAAM,0BAA0B,CAAC;AAC3F,OAAO,EAAC,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAC,oBAAoB,EAAC,MAAM,0BAA0B,CAAC;AAE9D,eAAO,MAAM,WAAW;;;CAGvB,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,kBAAkB,EACxB,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,oBAAoB,GAAG,SAAS,UAqC1C;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,kBAAkB,EACxB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,oBAAoB,EAC9B,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
1
+ {"version":3,"file":"parse-3d-tile-gltf-view.d.ts","sourceRoot":"","sources":["../../../../src/lib/parsers/helpers/parse-3d-tile-gltf-view.ts"],"names":[],"mappings":"AAcA,OAAO,EAAC,aAAa,EAAqC,MAAM,0BAA0B,CAAC;AAC3F,OAAO,EAAC,kBAAkB,EAAC,0BAAuB;AAClD,OAAO,EAAC,oBAAoB,EAAC,oCAAiC;AAE9D,eAAO,MAAM,WAAW;;;CAGvB,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,kBAAkB,EACxB,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,oBAAoB,GAAG,SAAS,UAqC1C;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,kBAAkB,EACxB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,oBAAoB,EAC9B,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}