@loaders.gl/tile-converter 5.0.0-alpha.12 → 5.0.0-alpha.14

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 (132) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +4 -4
  3. package/dist/converter.min.cjs +149 -158
  4. package/dist/i3s-server/bin/i3s-server.min.cjs +113 -158
  5. package/dist/index.cjs +17486 -17479
  6. package/dist/index.js +25572 -25560
  7. package/dist/v5/adapters.cjs +540 -190
  8. package/dist/v5/adapters.d.ts +4 -0
  9. package/dist/v5/adapters.js +501 -151
  10. package/dist/v5/archive-source.d.ts +1 -1
  11. package/dist/v5/browser.d.ts +1 -1
  12. package/dist/v5/conversion-api.d.ts +25 -0
  13. package/dist/v5/converter-cli.js +23 -7
  14. package/dist/v5/core.cjs +76 -17
  15. package/dist/v5/core.d.ts +1 -1
  16. package/dist/v5/core.js +69 -10
  17. package/dist/v5/feature-arrow.d.ts +1 -1
  18. package/dist/v5/i3s-mesh-conversion.d.ts +1 -1
  19. package/dist/v5/i3s-mesh-source-features.d.ts +2 -2
  20. package/dist/v5/i3s-mesh-source-material.d.ts +1 -1
  21. package/dist/v5/i3s-mesh-source.d.ts +2 -2
  22. package/dist/v5/i3s-selection-source.d.ts +3 -3
  23. package/dist/v5/index.cjs +11 -6
  24. package/dist/v5/index.d.ts +5 -1
  25. package/dist/v5/index.js +8 -0
  26. package/dist/v5/mesh-conversion.d.ts +3 -3
  27. package/dist/v5/mesh-draco.d.ts +2 -2
  28. package/dist/v5/mesh-features.d.ts +2 -2
  29. package/dist/v5/mesh-source-features.d.ts +4 -4
  30. package/dist/v5/mesh-source-schema.d.ts +2 -2
  31. package/dist/v5/mesh-source-texture.d.ts +3 -3
  32. package/dist/v5/mesh-source.d.ts +5 -5
  33. package/dist/v5/mesh-tileset-sink.d.ts +1 -1
  34. package/dist/v5/mesh.d.ts +1 -1
  35. package/dist/v5/node-conversion.d.ts +2 -0
  36. package/dist/v5/node-i3s-source.d.ts +3 -3
  37. package/dist/v5/node-source.d.ts +1 -1
  38. package/dist/v5/node.cjs +19 -6
  39. package/dist/v5/node.js +19 -6
  40. package/dist/v5/point-cloud-attributes.d.ts +19 -0
  41. package/dist/v5/point-cloud-conversion.d.ts +1 -1
  42. package/dist/v5/point-cloud-copc.d.ts +44 -0
  43. package/dist/v5/point-cloud-file.d.ts +4 -4
  44. package/dist/v5/point-cloud-potree.d.ts +3 -3
  45. package/dist/v5/point-cloud-source-encoder.d.ts +1 -1
  46. package/dist/v5/point-cloud-source.d.ts +1 -1
  47. package/dist/v5/point-cloud-tileset.d.ts +3 -3
  48. package/dist/v5/point-cloud.d.ts +1 -1
  49. package/dist/v5/spatial-conversion.d.ts +1 -1
  50. package/dist/v5/tileset-source.d.ts +1 -1
  51. package/package.json +17 -32
  52. package/src/v4/3d-tiles-converter/3d-tiles-converter.ts +11 -12
  53. package/src/v4/3d-tiles-converter/helpers/3d-tiles-content-converter.ts +7 -3
  54. package/src/v4/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.ts +2 -2
  55. package/src/v4/3d-tiles-converter/helpers/load-i3s.ts +3 -3
  56. package/src/v4/3d-tiles-converter/helpers/texture-atlas.ts +1 -1
  57. package/src/v4/3d-tiles-converter/helpers/validate-i3s-spatial-reference.ts +2 -2
  58. package/src/v4/3d-tiles-converter/json-templates/tileset.ts +58 -39
  59. package/src/v4/converter-cli.ts +3 -3
  60. package/src/v4/deps-installer/deps-installer.ts +3 -3
  61. package/src/v4/i3s-converter/helpers/attribute-metadata-info.ts +1 -1
  62. package/src/v4/i3s-converter/helpers/batch-ids-extensions.ts +9 -10
  63. package/src/v4/i3s-converter/helpers/conversion-gltf.ts +108 -0
  64. package/src/v4/i3s-converter/helpers/coordinate-converter.ts +6 -5
  65. package/src/v4/i3s-converter/helpers/create-scene-server-path.ts +5 -6
  66. package/src/v4/i3s-converter/helpers/feature-attributes.ts +4 -4
  67. package/src/v4/i3s-converter/helpers/geometry-attributes.ts +1 -1
  68. package/src/v4/i3s-converter/helpers/geometry-converter.ts +69 -77
  69. package/src/v4/i3s-converter/helpers/gltf-attributes.ts +58 -74
  70. package/src/v4/i3s-converter/helpers/load-3d-tiles.ts +5 -5
  71. package/src/v4/i3s-converter/helpers/node-debug.ts +7 -3
  72. package/src/v4/i3s-converter/helpers/node-index-document.ts +6 -7
  73. package/src/v4/i3s-converter/helpers/node-pages.ts +3 -4
  74. package/src/v4/i3s-converter/helpers/preprocess-3d-tiles.ts +1 -1
  75. package/src/v4/i3s-converter/helpers/tileset-traversal.ts +1 -1
  76. package/src/v4/i3s-converter/i3s-converter.ts +29 -31
  77. package/src/v4/i3s-converter/json-templates/geometry-definitions.ts +71 -66
  78. package/src/v4/i3s-converter/json-templates/layers.ts +97 -132
  79. package/src/v4/i3s-converter/json-templates/metadata.ts +31 -21
  80. package/src/v4/i3s-converter/json-templates/node.ts +60 -74
  81. package/src/v4/i3s-converter/json-templates/scene-server.ts +36 -27
  82. package/src/v4/i3s-converter/json-templates/shared-resources.ts +62 -123
  83. package/src/v4/i3s-converter/json-templates/store.ts +39 -58
  84. package/src/v4/i3s-converter/types.ts +4 -4
  85. package/src/v4/i3s-server/controllers/slpk-controller.ts +3 -3
  86. package/src/v4/i3s-server/utils/create-scene-server.ts +3 -3
  87. package/src/v4/lib/utils/builder-input.ts +8 -0
  88. package/src/v4/lib/utils/conversion-dump.ts +5 -1
  89. package/src/v4/lib/utils/file-utils.ts +1 -1
  90. package/src/v4/lib/utils/hash-string.ts +21 -0
  91. package/src/v4/lib/utils/lod-conversion-utils.ts +3 -3
  92. package/src/v4/pgm-loader.ts +2 -2
  93. package/src/v5/adapters.ts +5 -0
  94. package/src/v5/archive-source.ts +4 -4
  95. package/src/v5/browser.ts +1 -0
  96. package/src/v5/conversion-api.ts +115 -8
  97. package/src/v5/conversion-archive.ts +2 -2
  98. package/src/v5/core.ts +1 -0
  99. package/src/v5/feature-arrow.ts +2 -2
  100. package/src/v5/i3s-mesh-conversion.ts +2 -2
  101. package/src/v5/i3s-mesh-source-features.ts +3 -3
  102. package/src/v5/i3s-mesh-source-material.ts +18 -11
  103. package/src/v5/i3s-mesh-source.ts +2 -2
  104. package/src/v5/i3s-selection-source.ts +4 -4
  105. package/src/v5/index.ts +15 -0
  106. package/src/v5/mesh-conversion.ts +4 -4
  107. package/src/v5/mesh-draco.ts +2 -2
  108. package/src/v5/mesh-features.ts +3 -3
  109. package/src/v5/mesh-hierarchy.ts +1 -1
  110. package/src/v5/mesh-source-features.ts +137 -55
  111. package/src/v5/mesh-source-schema.ts +10 -4
  112. package/src/v5/mesh-source-texture.ts +49 -19
  113. package/src/v5/mesh-source.ts +65 -46
  114. package/src/v5/mesh-tileset-archive.ts +1 -1
  115. package/src/v5/mesh-tileset-sink.ts +1 -1
  116. package/src/v5/mesh.ts +1 -1
  117. package/src/v5/node-cli.ts +4 -0
  118. package/src/v5/node-conversion.ts +19 -2
  119. package/src/v5/node-source.ts +2 -2
  120. package/src/v5/point-cloud-attributes.ts +113 -0
  121. package/src/v5/point-cloud-conversion.ts +1 -1
  122. package/src/v5/point-cloud-copc.ts +289 -0
  123. package/src/v5/point-cloud-file.ts +8 -8
  124. package/src/v5/point-cloud-potree.ts +8 -4
  125. package/src/v5/point-cloud-source-encoder.ts +1 -1
  126. package/src/v5/point-cloud-source.ts +1 -1
  127. package/src/v5/point-cloud-spatial.ts +2 -2
  128. package/src/v5/point-cloud-tileset.ts +4 -4
  129. package/src/v5/point-cloud.ts +3 -3
  130. package/src/v5/selected-mesh-source.ts +4 -4
  131. package/src/v5/spatial-conversion.ts +2 -2
  132. package/src/v5/tileset-source.ts +2 -2
@@ -25,6 +25,7 @@ __export(adapters_exports, {
25
25
  convertPointCloudSource: () => convertPointCloudSource,
26
26
  convertPointCloudToPotree: () => convertPointCloudToPotree,
27
27
  convertPointCloudToTileset: () => convertPointCloudToTileset,
28
+ createCOPCConversionCodec: () => createCOPCConversionCodec,
28
29
  createI3SMeshConversionCodec: () => createI3SMeshConversionCodec,
29
30
  createI3SMeshSink: () => createI3SMeshSink,
30
31
  createI3SMeshTilesetConversionSource: () => createI3SMeshTilesetConversionSource,
@@ -43,6 +44,7 @@ __export(adapters_exports, {
43
44
  createTileConversionArchiveTransport: () => createTileConversionArchiveTransport,
44
45
  createTileConversionResourceFetcher: () => createTileConversionResourceFetcher,
45
46
  encodeMeshTile: () => encodeMeshTile,
47
+ encodePointCloudCOPC: () => encodePointCloudCOPC,
46
48
  encodePointCloudSource: () => encodePointCloudSource,
47
49
  encodePointCloudSourceTile: () => encodePointCloudSourceTile,
48
50
  encodePointCloudTile: () => encodePointCloudTile,
@@ -51,6 +53,7 @@ __export(adapters_exports, {
51
53
  encodeTileConversionArchiveInBatches: () => encodeTileConversionArchiveInBatches,
52
54
  extractMeshVertices: () => extractMeshVertices,
53
55
  inspectI3SMeshConversionSource: () => inspectI3SMeshConversionSource,
56
+ mapPointCloudAttributes: () => mapPointCloudAttributes,
54
57
  measureMeshBytes: () => measureMeshBytes,
55
58
  openPointCloudFile: () => openPointCloudFile,
56
59
  openTileConversionArchive: () => openTileConversionArchive,
@@ -59,7 +62,7 @@ __export(adapters_exports, {
59
62
  module.exports = __toCommonJS(adapters_exports);
60
63
 
61
64
  // src/v5/feature-arrow.ts
62
- var import_schema_utils = require("@loaders.gl/schema-utils");
65
+ var import_schema_utils = require("@loaders.gl/core/schema-utils");
63
66
  var import_core = require("@loaders.gl/tile-converter/v5/core");
64
67
  var DEFAULT_FEATURE_ID_FIELD = "feature_id";
65
68
  var FEATURE_CLASS_METADATA_KEY = "loaders.gl:feature-class";
@@ -381,8 +384,8 @@ function isBinaryType(dataType) {
381
384
  }
382
385
 
383
386
  // src/v5/point-cloud.ts
384
- var import_d_tiles = require("@loaders.gl/3d-tiles");
385
- var import_schema_utils2 = require("@loaders.gl/schema-utils");
387
+ var import_d_tiles = require("@loaders.gl/tiles-3d/3d-tiles");
388
+ var import_schema_utils2 = require("@loaders.gl/core/schema-utils");
386
389
  var import_core2 = require("@loaders.gl/tile-converter/v5/core");
387
390
  function encodePointCloudTile(pointBatch, options = {}) {
388
391
  return encodePointCloudTileWithMetadata(pointBatch, options).pnts;
@@ -645,8 +648,8 @@ function validateBatchTable(batchTableJson, batchIds) {
645
648
 
646
649
  // src/v5/point-cloud-spatial.ts
647
650
  var import_core3 = require("@math.gl/core");
648
- var import_tiles = require("@loaders.gl/tiles");
649
- var import_schema_utils3 = require("@loaders.gl/schema-utils");
651
+ var import_tiles_3d = require("@loaders.gl/tiles-3d");
652
+ var import_schema_utils3 = require("@loaders.gl/core/schema-utils");
650
653
  var import_core4 = require("@loaders.gl/tile-converter/v5/core");
651
654
  async function transformPointCloudSourceTile(sourceTile, options) {
652
655
  options.signal?.throwIfAborted();
@@ -655,7 +658,7 @@ async function transformPointCloudSourceTile(sourceTile, options) {
655
658
  const reference = options.spatialContext.spatialReference;
656
659
  const contentReference = content.spatialReference;
657
660
  const retainTransformedEcef = contentReference?.status === "transformed" && (contentReference.targetCrs || contentReference.sourceCrs) === "EPSG:4978" && reference.status === "native" && reference.sourceCrs === "EPSG:4978" && reference.verticalUnitScale === 1 && (reference.units?.every((unit) => unit === "meter") ?? true);
658
- const sourceReference = retainTransformedEcef ? (0, import_tiles.createTilesetSpatialReference)({
661
+ const sourceReference = retainTransformedEcef ? (0, import_tiles_3d.createTilesetSpatialReference)({
659
662
  sourceCrs: "EPSG:4978",
660
663
  coordinateFrame: "geocentric",
661
664
  axisOrder: "xyz",
@@ -669,7 +672,7 @@ async function transformPointCloudSourceTile(sourceTile, options) {
669
672
  "Point content and context must agree on the input CRS, units, height reference and epoch"
670
673
  );
671
674
  }
672
- const sourceFrame = reference.coordinateFrame === "unknown" && reference.sourceCrs ? (0, import_tiles.getSpatialCoordinateFrame)(reference.sourceCrs) : reference.coordinateFrame;
675
+ const sourceFrame = reference.coordinateFrame === "unknown" && reference.sourceCrs ? (0, import_tiles_3d.getSpatialCoordinateFrame)(reference.sourceCrs) : reference.coordinateFrame;
673
676
  const geographic = sourceFrame === "geographic";
674
677
  if (!["xy", "xyz", "unknown"].includes(reference.axisOrder) || (geographic ? !["lnglat", "lnglat-offsets"].includes(content.coordinateSystem) : content.coordinateSystem !== "cartesian" || !["projected", "geocentric", "cartesian", "local"].includes(sourceFrame))) {
675
678
  throw new import_core4.TileConversionError(
@@ -780,7 +783,7 @@ async function transformPointCloudSourceTile(sourceTile, options) {
780
783
  maximum[axis] = Math.max(maximum[axis], value);
781
784
  }
782
785
  const center = minimum.map((value, axis) => value / 2 + maximum[axis] / 2);
783
- const targetFrame = reference.status === "native" ? sourceFrame : (0, import_tiles.getSpatialCoordinateFrame)(reference.targetCrs || reference.sourceCrs);
786
+ const targetFrame = reference.status === "native" ? sourceFrame : (0, import_tiles_3d.getSpatialCoordinateFrame)(reference.targetCrs || reference.sourceCrs);
784
787
  const targetIsGeographic = targetFrame === "geographic";
785
788
  const attributes = {
786
789
  ...mesh.attributes,
@@ -904,7 +907,7 @@ var import_gltf = require("@loaders.gl/gltf");
904
907
  var import_images = require("@loaders.gl/images");
905
908
 
906
909
  // src/v5/mesh-features.ts
907
- var import_schema_utils4 = require("@loaders.gl/schema-utils");
910
+ var import_schema_utils4 = require("@loaders.gl/core/schema-utils");
908
911
  var import_core8 = require("@loaders.gl/tile-converter/v5/core");
909
912
  function prepareMeshFeatureGeometry(mesh, features) {
910
913
  if (!features) return mesh;
@@ -1458,7 +1461,7 @@ function validateMeshTextureTransform(transform) {
1458
1461
  }
1459
1462
 
1460
1463
  // src/v5/mesh-conversion.ts
1461
- var import_tiles2 = require("@loaders.gl/tiles");
1464
+ var import_tiles_3d2 = require("@loaders.gl/tiles-3d");
1462
1465
  var import_core11 = require("@loaders.gl/tile-converter/v5/core");
1463
1466
 
1464
1467
  // src/v5/mesh-draco.ts
@@ -1601,7 +1604,7 @@ function createMeshConversionCodec(options) {
1601
1604
  }
1602
1605
  const spatialReference = spatialContext.spatialReference;
1603
1606
  const outputCrs = spatialReference.targetCrs || spatialReference.sourceCrs;
1604
- const outputFrame = spatialReference.status === "native" ? spatialReference.coordinateFrame : outputCrs ? (0, import_tiles2.getSpatialCoordinateFrame)(outputCrs) : "unknown";
1607
+ const outputFrame = spatialReference.status === "native" ? spatialReference.coordinateFrame : outputCrs ? (0, import_tiles_3d2.getSpatialCoordinateFrame)(outputCrs) : "unknown";
1605
1608
  if (!["native", "transformed"].includes(spatialReference.status) || !["projected", "geocentric", "local", "cartesian"].includes(outputFrame)) {
1606
1609
  throw new import_core11.TileConversionError(
1607
1610
  "MESH_OUTPUT_FRAME_UNSUPPORTED",
@@ -1945,8 +1948,8 @@ function createMeshTilesetSink(options) {
1945
1948
  }
1946
1949
 
1947
1950
  // src/v5/conversion-archive.ts
1948
- var import_d_tiles_archive_writer = require("@loaders.gl/3d-tiles/3d-tiles-archive-writer");
1949
- var import_i3s_slpk_writer = require("@loaders.gl/i3s/i3s-slpk-writer");
1951
+ var import_d_tiles_archive_writer = require("@loaders.gl/tiles-3d/3d-tiles/3d-tiles-archive-writer");
1952
+ var import_i3s_slpk_writer = require("@loaders.gl/tiles-3d/i3s/i3s-slpk-writer");
1950
1953
  var import_core14 = require("@loaders.gl/tile-converter/v5/core");
1951
1954
  async function createTileConversionArchive(files, options) {
1952
1955
  const { resources, format, maxArchiveBytes, signal } = prepareArchiveInput(files, options);
@@ -1981,7 +1984,7 @@ function prepareArchiveInput(files, options) {
1981
1984
  }
1982
1985
 
1983
1986
  // src/v5/mesh-tileset-archive.ts
1984
- var import_d_tiles_archive_writer2 = require("@loaders.gl/3d-tiles/3d-tiles-archive-writer");
1987
+ var import_d_tiles_archive_writer2 = require("@loaders.gl/tiles-3d/3d-tiles/3d-tiles-archive-writer");
1985
1988
  var import_core15 = require("@loaders.gl/tile-converter/v5/core");
1986
1989
  async function createSingleMeshTilesetArchive(files, options) {
1987
1990
  const { maxArchiveBytes, signal } = options;
@@ -2004,16 +2007,18 @@ async function createSingleMeshTilesetArchive(files, options) {
2004
2007
 
2005
2008
  // src/v5/mesh-source.ts
2006
2009
  var import_core19 = require("@math.gl/core");
2010
+ var import_gltf4 = require("@loaders.gl/gltf");
2007
2011
  var import_core20 = require("@loaders.gl/tile-converter/v5/core");
2008
2012
  var import_core21 = require("@loaders.gl/tile-converter/v5/core");
2009
2013
 
2010
2014
  // src/v5/mesh-source-texture.ts
2011
2015
  var import_images2 = require("@loaders.gl/images");
2016
+ var import_gltf2 = require("@loaders.gl/gltf");
2012
2017
  var import_core16 = require("@loaders.gl/tile-converter/v5/core");
2013
- function mapMeshSourceTexture(textureInfo) {
2014
- const texture = textureInfo?.texture;
2015
- const image = texture?.source;
2016
- const sampler = texture?.sampler;
2018
+ function mapMeshSourceTexture(gltf, textureInfo) {
2019
+ const texture = textureInfo ? gltf.json.textures?.[textureInfo.index] : void 0;
2020
+ const image = texture?.source === void 0 ? void 0 : gltf.json.images?.[texture.source];
2021
+ const sampler = texture?.sampler === void 0 ? void 0 : gltf.json.samplers?.[texture.sampler];
2017
2022
  const extensions = textureInfo?.extensions || {};
2018
2023
  const hasTransform = Object.hasOwn(extensions, "KHR_texture_transform");
2019
2024
  const transform = extensions.KHR_texture_transform;
@@ -2023,7 +2028,7 @@ function mapMeshSourceTexture(textureInfo) {
2023
2028
  (name) => !["id", "index", "texture", "texCoord", "extensions", "extras"].includes(name)
2024
2029
  ) || !texture || Object.keys(texture).some(
2025
2030
  (name) => !["id", "source", "sampler", "name", "extensions", "extras"].includes(name)
2026
- ) || Object.keys(texture.extensions || {}).length || !image || image.uri !== void 0 && image.bufferView !== void 0 || Object.keys(image.extensions || {}).length || image.uri === void 0 && (!(image.bufferView?.data instanceof Uint8Array) || Object.keys(image.bufferView.extensions || {}).length || !["image/png", "image/jpeg"].includes(image.mimeType || "")) || sampler && (Object.keys(sampler.extensions || {}).length || Object.keys(sampler).some(
2031
+ ) || Object.keys(texture.extensions || {}).length || !image || image.uri !== void 0 && image.bufferView !== void 0 || Object.keys(image.extensions || {}).length || image.uri === void 0 && (image.bufferView === void 0 || !gltf.json.bufferViews?.[image.bufferView] || Object.keys(gltf.json.bufferViews?.[image.bufferView]?.extensions || {}).length || !["image/png", "image/jpeg"].includes(image.mimeType || "")) || sampler && (Object.keys(sampler.extensions || {}).length || Object.keys(sampler).some(
2027
2032
  (name) => ![
2028
2033
  "id",
2029
2034
  "parameters",
@@ -2048,7 +2053,7 @@ function mapMeshSourceTexture(textureInfo) {
2048
2053
  minFilter: sampler.minFilter
2049
2054
  } : void 0;
2050
2055
  return {
2051
- ...mapMeshSourceImage(image),
2056
+ ...mapMeshSourceImage(gltf, image),
2052
2057
  ...hasTransform ? {
2053
2058
  transform: {
2054
2059
  offset: transform.offset,
@@ -2059,9 +2064,12 @@ function mapMeshSourceTexture(textureInfo) {
2059
2064
  ...selectedSampler && Object.values(selectedSampler).some((value) => value !== void 0) ? { sampler: selectedSampler } : {}
2060
2065
  };
2061
2066
  }
2062
- function mapMeshSourceImage(image) {
2067
+ function mapMeshSourceImage(gltf, image) {
2063
2068
  if (image.uri === void 0) {
2064
- return { data: image.bufferView.data, mimeType: image.mimeType };
2069
+ return {
2070
+ data: new import_gltf2.GLTFScenegraph(gltf).getTypedArrayForBufferView(image.bufferView),
2071
+ mimeType: image.mimeType
2072
+ };
2065
2073
  }
2066
2074
  const match = typeof image.uri === "string" ? /^data:(image\/(?:png|jpeg));base64,([A-Za-z0-9+/]+={0,2})$/.exec(image.uri) : null;
2067
2075
  if (!match || image.mimeType !== void 0 && image.mimeType !== match[1]) {
@@ -2081,10 +2089,11 @@ function mapMeshSourceImage(image) {
2081
2089
  mimeType: match[1]
2082
2090
  };
2083
2091
  }
2084
- async function resolveMeshSourceTexture(textureInfo, readExternalResource, contentUri, signal) {
2085
- const image = textureInfo?.texture?.source;
2092
+ async function resolveMeshSourceTexture(gltf, textureInfo, readExternalResource, contentUri, signal) {
2093
+ const texture = textureInfo ? gltf.json.textures?.[textureInfo.index] : void 0;
2094
+ const image = texture?.source === void 0 ? void 0 : gltf.json.images?.[texture.source];
2086
2095
  if (!image || image.uri === void 0 || image.uri.startsWith("data:"))
2087
- return mapMeshSourceTexture(textureInfo);
2096
+ return mapMeshSourceTexture(gltf, textureInfo);
2088
2097
  if (!readExternalResource || image.bufferView !== void 0)
2089
2098
  throw new import_core16.TileConversionError(
2090
2099
  "MESH_SOURCE_TEXTURE_UNSUPPORTED",
@@ -2103,16 +2112,39 @@ async function resolveMeshSourceTexture(textureInfo, readExternalResource, conte
2103
2112
  "MESH_SOURCE_TEXTURE_UNSUPPORTED",
2104
2113
  "External images require matching PNG/JPEG headers"
2105
2114
  );
2115
+ const resolvedImage = {
2116
+ ...image,
2117
+ uri: void 0,
2118
+ mimeType: metadata.mimeType,
2119
+ bufferView: (gltf.json.bufferViews || []).length
2120
+ };
2106
2121
  const resolved = {
2107
- ...textureInfo,
2108
- texture: {
2109
- ...textureInfo.texture,
2110
- source: { ...image, uri: void 0, mimeType: metadata.mimeType, bufferView: { data } }
2122
+ ...gltf,
2123
+ buffers: [
2124
+ ...gltf.buffers,
2125
+ {
2126
+ arrayBuffer: data.buffer,
2127
+ byteOffset: data.byteOffset,
2128
+ byteLength: data.byteLength
2129
+ }
2130
+ ],
2131
+ json: {
2132
+ ...gltf.json,
2133
+ images: gltf.json.images.map(
2134
+ (entry, index) => index === texture.source ? resolvedImage : entry
2135
+ ),
2136
+ bufferViews: [
2137
+ ...gltf.json.bufferViews || [],
2138
+ { buffer: gltf.buffers.length, byteLength: data.byteLength }
2139
+ ]
2111
2140
  }
2112
2141
  };
2113
- return mapMeshSourceTexture(resolved);
2142
+ return mapMeshSourceTexture(resolved, textureInfo);
2114
2143
  }
2115
2144
 
2145
+ // src/v5/mesh-source-features.ts
2146
+ var import_gltf3 = require("@loaders.gl/gltf");
2147
+
2116
2148
  // src/v5/mesh-source-schema.ts
2117
2149
  var import_core17 = require("@loaders.gl/tile-converter/v5/core");
2118
2150
  var SCALAR_TYPES = {
@@ -2198,9 +2230,9 @@ function createMeshSourceFeatureOptions(gltf, options) {
2198
2230
  var import_core18 = require("@loaders.gl/tile-converter/v5/core");
2199
2231
  function extractMeshFeatures(gltf, primitive, payload, mesh, options) {
2200
2232
  const declarations = primitive.extensions?.EXT_mesh_features?.featureIds;
2201
- const metadata = gltf.extensions?.EXT_structural_metadata;
2233
+ const metadata = gltf.json.extensions?.EXT_structural_metadata;
2202
2234
  const legacy = primitive.attributes._BATCHID;
2203
- if (!declarations && !legacy && !metadata && !Object.keys(payload.batchTableJson || {}).length && !payload.header?.batchLength) {
2235
+ if (!declarations && legacy === void 0 && !metadata && !Object.keys(payload.batchTableJson || {}).length && !payload.header?.batchLength) {
2204
2236
  if (Object.keys(primitive.attributes).some((name) => /^_FEATURE_ID_\d+$/.test(name)))
2205
2237
  throw new import_core18.TileConversionError(
2206
2238
  "MESH_FEATURE_MAPPING_REQUIRED",
@@ -2218,37 +2250,38 @@ function extractMeshFeatures(gltf, primitive, payload, mesh, options) {
2218
2250
  "MESH_FEATURE_CLASS_REQUIRED",
2219
2251
  "Feature metadata class must be explicit"
2220
2252
  );
2221
- const mapping = "schema" in options ? options : createMeshSourceFeatureOptions(gltf, options);
2253
+ const mapping = "schema" in options ? options : createMeshSourceFeatureOptions(gltf.json, options);
2254
+ const propertyMappings = /* @__PURE__ */ new Map();
2222
2255
  let count;
2223
- let attribute = legacy;
2256
+ let attributeReference = legacy;
2224
2257
  let properties;
2225
2258
  if (declarations) {
2226
- if (legacy || declarations.length !== 1 || metadata?.propertyTables?.length !== 1 || metadata.propertyTextures?.length || metadata.propertyAttributes?.length)
2259
+ if (legacy !== void 0 || declarations.length !== 1 || metadata?.propertyTables?.length !== 1 || metadata.propertyTextures?.length || metadata.propertyAttributes?.length)
2227
2260
  throw new import_core18.TileConversionError(
2228
2261
  "MESH_FEATURE_MAPPING_UNSUPPORTED",
2229
2262
  "Only one attribute-backed feature set and one property table are supported"
2230
2263
  );
2231
2264
  const declaration = declarations[0];
2232
- if (!Number.isInteger(declaration.attribute) || declaration.attribute < 0 || declaration.propertyTable !== 0 || declaration.texture || declaration.implicit || declaration.nullFeatureId !== void 0)
2265
+ if (typeof declaration.attribute !== "number" || !Number.isInteger(declaration.attribute) || declaration.attribute < 0 || declaration.propertyTable !== 0 || declaration.texture || declaration.implicit || declaration.nullFeatureId !== void 0)
2233
2266
  throw new import_core18.TileConversionError(
2234
2267
  "MESH_FEATURE_MAPPING_UNSUPPORTED",
2235
2268
  "Features require an attribute and property table 0 without null/texture/implicit IDs"
2236
2269
  );
2237
- attribute = primitive.attributes[`_FEATURE_ID_${declaration.attribute}`];
2270
+ attributeReference = primitive.attributes[`_FEATURE_ID_${declaration.attribute}`];
2238
2271
  const table = metadata.propertyTables[0];
2239
- if (table.class !== options.metadataClass || table.count !== declaration.featureCount)
2272
+ if (table.class !== options.metadataClass || !Number.isSafeInteger(declaration.featureCount) || declaration.featureCount <= 0 || declaration.featureCount > table.count)
2240
2273
  throw new import_core18.TileConversionError(
2241
2274
  "MESH_FEATURE_CLASS_MISMATCH",
2242
- "Feature class and declared table counts must agree"
2275
+ "Feature class must agree and declared feature count must fit the property table"
2243
2276
  );
2244
2277
  count = table.count;
2245
- if (!Number.isSafeInteger(count) || count <= 0 || count > mesh.attributes.POSITION.value.length / 3) {
2278
+ if (!Number.isSafeInteger(count) || count <= 0 || count > 4294967295) {
2246
2279
  throw new import_core18.TileConversionError(
2247
2280
  "MESH_FEATURE_IDS_INVALID",
2248
- "Feature row count exceeds the available mesh vertices"
2281
+ "Feature row count must fit uint32 indices"
2249
2282
  );
2250
2283
  }
2251
- properties = {};
2284
+ properties = /* @__PURE__ */ Object.create(null);
2252
2285
  const classProperties = metadata.schema?.classes?.[table.class]?.properties;
2253
2286
  if (!classProperties)
2254
2287
  throw new import_core18.TileConversionError(
@@ -2281,9 +2314,10 @@ function extractMeshFeatures(gltf, primitive, payload, mesh, options) {
2281
2314
  );
2282
2315
  }
2283
2316
  const defaultValue = integer64 && property.default !== void 0 ? BigInt(property.default) : property.default ?? null;
2284
- const decoded = data ?? Array.from({ length: count }, () => defaultValue);
2317
+ const decoded = data;
2285
2318
  if (property.noData === void 0 || data === void 0) {
2286
- properties[name] = decoded;
2319
+ if (decoded !== void 0) properties[name] = decoded;
2320
+ else propertyMappings.set(name, { defaultValue });
2287
2321
  continue;
2288
2322
  }
2289
2323
  const sentinel = property.noData;
@@ -2293,10 +2327,9 @@ function extractMeshFeatures(gltf, primitive, payload, mesh, options) {
2293
2327
  `Property ${name} requires a valid decoded noData mapping`
2294
2328
  );
2295
2329
  const comparable = integer64 ? BigInt(sentinel) : sentinel;
2296
- properties[name] = Array.from(
2297
- decoded,
2298
- (value) => value === comparable ? defaultValue : value
2299
- );
2330
+ const values = decoded;
2331
+ properties[name] = values;
2332
+ propertyMappings.set(name, { noData: comparable, defaultValue });
2300
2333
  }
2301
2334
  } else {
2302
2335
  if (metadata)
@@ -2307,14 +2340,32 @@ function extractMeshFeatures(gltf, primitive, payload, mesh, options) {
2307
2340
  count = payload.header?.batchLength ?? Number(payload.featureTableJson?.BATCH_LENGTH);
2308
2341
  properties = payload.batchTableJson || {};
2309
2342
  }
2343
+ const accessor = attributeReference === void 0 ? void 0 : (0, import_gltf3.getGLTFAccessor)(gltf, attributeReference);
2344
+ const attribute = accessor ? {
2345
+ ...accessor,
2346
+ components: accessor.type === "SCALAR" ? 1 : Number(accessor.type.slice(3)),
2347
+ value: (0, import_gltf3.getGLTFAccessorValue)(gltf, accessor)
2348
+ } : void 0;
2310
2349
  const vertexCount = mesh.attributes.POSITION.value.length / 3;
2311
- if (!Number.isSafeInteger(count) || count <= 0 || !attribute || attribute.components !== 1 || attribute.normalized || attribute.value.length !== vertexCount || Array.from(attribute.value).some(
2312
- (value) => !Number.isSafeInteger(value) || value < 0 || value >= count
2313
- ))
2350
+ if (!Number.isSafeInteger(count) || count <= 0 || !attribute || attribute.components !== 1 || attribute.normalized || attribute.value.length !== vertexCount)
2314
2351
  throw new import_core18.TileConversionError(
2315
2352
  "MESH_FEATURE_IDS_INVALID",
2316
2353
  "Feature IDs must be one valid property-table row index per vertex"
2317
2354
  );
2355
+ const vertexRows = declarations ? /* @__PURE__ */ new Set() : void 0;
2356
+ for (const value of attribute.value) {
2357
+ if (!Number.isSafeInteger(value) || value < 0 || value >= count)
2358
+ throw new import_core18.TileConversionError(
2359
+ "MESH_FEATURE_IDS_INVALID",
2360
+ "Feature IDs must reference valid property-table rows"
2361
+ );
2362
+ vertexRows?.add(Number(value));
2363
+ }
2364
+ if (declarations && vertexRows.size !== declarations[0].featureCount)
2365
+ throw new import_core18.TileConversionError(
2366
+ "MESH_FEATURE_IDS_INVALID",
2367
+ "Declared feature count must match distinct vertex feature IDs"
2368
+ );
2318
2369
  const selectedAttribute = declarations ? `_FEATURE_ID_${declarations[0].attribute}` : "_BATCHID";
2319
2370
  if (Object.keys(primitive.attributes).some(
2320
2371
  (name) => (name === "_BATCHID" || /^_FEATURE_ID_\d+$/.test(name)) && name !== selectedAttribute
@@ -2327,39 +2378,70 @@ function extractMeshFeatures(gltf, primitive, payload, mesh, options) {
2327
2378
  if (!values || !Array.isArray(values) && !ArrayBuffer.isView(values) || values.length !== count)
2328
2379
  throw new import_core18.TileConversionError(
2329
2380
  "MESH_FEATURE_PROPERTY_UNAVAILABLE",
2330
- `Property ${name} must be a decoded column matching the table count`
2381
+ `Property ${name} must be a decoded column matching the feature row count`
2331
2382
  );
2332
2383
  }
2333
2384
  const sourceIdentifier = options.sourceFeatureIdProperty;
2334
- if (sourceIdentifier && !properties[sourceIdentifier])
2385
+ if (sourceIdentifier && !properties[sourceIdentifier] && !propertyMappings.has(sourceIdentifier))
2335
2386
  throw new import_core18.TileConversionError(
2336
2387
  "MESH_FEATURE_ID_PROPERTY_REQUIRED",
2337
2388
  "Stable source identifier property is missing"
2338
2389
  );
2339
- const batches = convertFeatureAttributesToArrowBatches(
2340
- Array.from({ length: count }, (_, index) => ({
2341
- featureId: sourceIdentifier ? properties[sourceIdentifier][index] : index,
2342
- metadataClass: options.metadataClass,
2343
- properties: Object.fromEntries(
2344
- Object.entries(properties).filter(([name]) => name !== sourceIdentifier).map(([name, values]) => [name, values[index]])
2345
- )
2346
- })),
2347
- mapping
2348
- );
2349
2390
  const indices = mesh.indices?.value;
2350
- const triangleFeatureIndices = new Uint32Array((indices?.length ?? vertexCount) / 3);
2351
- for (let triangle = 0; triangle < triangleFeatureIndices.length; triangle++) {
2352
- const corners = [0, 1, 2].map(
2353
- (corner) => indices?.[triangle * 3 + corner] ?? triangle * 3 + corner
2391
+ const cornerCount = indices?.length ?? vertexCount;
2392
+ if (cornerCount % 3)
2393
+ throw new import_core18.TileConversionError(
2394
+ "MESH_FEATURE_IDS_INVALID",
2395
+ "Triangle geometry requires complete triples"
2354
2396
  );
2355
- const rows = corners.map((corner) => attribute.value[corner]);
2356
- if (rows.some((row) => row !== rows[0]) && new Set(corners).size === 3)
2397
+ const triangleFeatureIndices = new Uint32Array(cornerCount / 3);
2398
+ const referencedRows = /* @__PURE__ */ new Set();
2399
+ const readFeatureRow = (corner) => {
2400
+ if (!Number.isSafeInteger(corner) || corner < 0 || corner >= vertexCount)
2401
+ throw new import_core18.TileConversionError(
2402
+ "MESH_FEATURE_IDS_INVALID",
2403
+ "Triangle indices must reference valid mesh vertices"
2404
+ );
2405
+ return Number(attribute.value[corner]);
2406
+ };
2407
+ for (let triangle = 0; triangle < triangleFeatureIndices.length; triangle++) {
2408
+ const firstCorner = indices?.[triangle * 3] ?? triangle * 3;
2409
+ const secondCorner = indices?.[triangle * 3 + 1] ?? triangle * 3 + 1;
2410
+ const thirdCorner = indices?.[triangle * 3 + 2] ?? triangle * 3 + 2;
2411
+ const firstRow = readFeatureRow(firstCorner);
2412
+ const secondRow = readFeatureRow(secondCorner);
2413
+ const thirdRow = readFeatureRow(thirdCorner);
2414
+ if ((firstRow !== secondRow || firstRow !== thirdRow) && firstCorner !== secondCorner && firstCorner !== thirdCorner && secondCorner !== thirdCorner)
2357
2415
  throw new import_core18.TileConversionError(
2358
2416
  "MESH_FEATURE_TRIANGLE_MIXED",
2359
2417
  "All vertices of a nondegenerate triangle must reference the same feature row"
2360
2418
  );
2361
- triangleFeatureIndices[triangle] = Number(rows[0]);
2419
+ triangleFeatureIndices[triangle] = firstRow;
2420
+ referencedRows.add(firstRow);
2362
2421
  }
2422
+ const selectedRows = [...referencedRows].sort((left, right) => left - right);
2423
+ const denseRows = new Map(selectedRows.map((row, index) => [row, index]));
2424
+ for (let triangle = 0; triangle < triangleFeatureIndices.length; triangle++) {
2425
+ triangleFeatureIndices[triangle] = denseRows.get(triangleFeatureIndices[triangle]);
2426
+ }
2427
+ const readProperty = (name, row) => {
2428
+ const values = properties[name];
2429
+ const propertyMapping = propertyMappings.get(name);
2430
+ if (!values) return propertyMapping?.defaultValue;
2431
+ const value = values[row];
2432
+ return propertyMapping && value === propertyMapping.noData ? propertyMapping.defaultValue : value;
2433
+ };
2434
+ const propertyNames = [
2435
+ .../* @__PURE__ */ new Set([...Object.keys(properties), ...propertyMappings.keys()])
2436
+ ].filter((name) => name !== sourceIdentifier);
2437
+ const batches = convertFeatureAttributesToArrowBatches(
2438
+ selectedRows.map((row) => ({
2439
+ featureId: sourceIdentifier ? readProperty(sourceIdentifier, row) : row,
2440
+ metadataClass: options.metadataClass,
2441
+ properties: Object.fromEntries(propertyNames.map((name) => [name, readProperty(name, row)]))
2442
+ })),
2443
+ mapping
2444
+ );
2363
2445
  return {
2364
2446
  batches,
2365
2447
  triangleFeatureIndices,
@@ -2418,7 +2500,8 @@ function createMeshTilesetConversionSource(tileset, options = {}) {
2418
2500
  "Mesh extraction requires decoded GLB/glTF or B3DM content"
2419
2501
  );
2420
2502
  }
2421
- const gltf = payload.gltf;
2503
+ const gltfWithBuffers = payload.gltf;
2504
+ const gltf = gltfWithBuffers.json;
2422
2505
  if (gltf.animations?.length || gltf.skins?.length || Object.keys(gltf.extensions || {}).some(
2423
2506
  (name) => !["EXT_structural_metadata", "CESIUM_RTC"].includes(name)
2424
2507
  )) {
@@ -2444,19 +2527,20 @@ function createMeshTilesetConversionSource(tileset, options = {}) {
2444
2527
  placement.multiplyRight(new import_core19.Matrix4([1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1]));
2445
2528
  if (axis === "X")
2446
2529
  placement.multiplyRight(new import_core19.Matrix4([0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1]));
2447
- const roots = gltf.scene?.nodes || (gltf.scenes?.length === 1 ? gltf.scenes[0].nodes : void 0);
2530
+ const roots = (gltf.scene !== void 0 ? gltf.scenes?.[gltf.scene]?.nodes : void 0) || (gltf.scenes?.length === 1 ? gltf.scenes[0].nodes : void 0);
2448
2531
  if (!roots?.length)
2449
2532
  throw new import_core20.TileConversionError(
2450
2533
  "MESH_SOURCE_SCENE_UNSUPPORTED",
2451
2534
  "A default scene or exactly one scene is required"
2452
2535
  );
2453
2536
  let primitiveIndex = 0;
2454
- const primitives = traverseMeshNodes(roots, placement);
2537
+ const primitives = traverseMeshNodes(gltfWithBuffers, roots, placement);
2455
2538
  let current = primitives.next();
2456
2539
  while (!current.done) {
2457
2540
  const selected = current.value;
2458
2541
  const next = primitives.next();
2459
2542
  const resource = await extractPrimitive(
2543
+ gltfWithBuffers,
2460
2544
  selected.primitive,
2461
2545
  selected.transform,
2462
2546
  `${item.tile.id}/${content.index}/${primitiveIndex++}`,
@@ -2465,7 +2549,7 @@ function createMeshTilesetConversionSource(tileset, options = {}) {
2465
2549
  signal
2466
2550
  );
2467
2551
  const features = extractMeshFeatures(
2468
- gltf,
2552
+ gltfWithBuffers,
2469
2553
  selected.primitive,
2470
2554
  payload,
2471
2555
  resource.mesh,
@@ -2488,9 +2572,10 @@ function createMeshTilesetConversionSource(tileset, options = {}) {
2488
2572
  }
2489
2573
  };
2490
2574
  }
2491
- function* traverseMeshNodes(nodes, parent, ancestors = /* @__PURE__ */ new Set()) {
2492
- for (const node of nodes) {
2493
- if (ancestors.has(node) || node.skin || node.weights || Object.keys(node.extensions || {}).length)
2575
+ function* traverseMeshNodes(gltf, nodes, parent, ancestors = /* @__PURE__ */ new Set()) {
2576
+ for (const nodeIndex of nodes) {
2577
+ const node = gltf.json.nodes[nodeIndex];
2578
+ if (!node || ancestors.has(nodeIndex) || node.skin !== void 0 || node.weights || Object.keys(node.extensions || {}).length)
2494
2579
  throw new import_core20.TileConversionError(
2495
2580
  "MESH_SOURCE_NODE_UNSUPPORTED",
2496
2581
  "Cyclic, skinned, morphed, or extended nodes are unsupported"
@@ -2498,18 +2583,24 @@ function* traverseMeshNodes(nodes, parent, ancestors = /* @__PURE__ */ new Set()
2498
2583
  const transform = new import_core19.Matrix4(parent).multiplyRight(
2499
2584
  node.matrix ? new import_core19.Matrix4(node.matrix) : new import_core19.Matrix4().translate(node.translation || [0, 0, 0]).multiplyRight(new import_core19.Matrix4().fromQuaternion(node.rotation || [0, 0, 0, 1])).scale(node.scale || [1, 1, 1])
2500
2585
  );
2501
- if (node.mesh) {
2502
- if (node.mesh.weights || Object.keys(node.mesh.extensions || {}).length)
2586
+ if (node.mesh !== void 0) {
2587
+ const mesh = gltf.json.meshes[node.mesh];
2588
+ if (mesh.weights || Object.keys(mesh.extensions || {}).length)
2503
2589
  throw new import_core20.TileConversionError(
2504
2590
  "MESH_SOURCE_NODE_UNSUPPORTED",
2505
2591
  "Morph weights and mesh extensions are unsupported"
2506
2592
  );
2507
- for (const primitive of node.mesh.primitives) yield { primitive, transform };
2593
+ for (const primitive of mesh.primitives) yield { primitive, transform };
2508
2594
  }
2509
- yield* traverseMeshNodes(node.children || [], transform, /* @__PURE__ */ new Set([...ancestors, node]));
2595
+ yield* traverseMeshNodes(
2596
+ gltf,
2597
+ node.children || [],
2598
+ transform,
2599
+ /* @__PURE__ */ new Set([...ancestors, nodeIndex])
2600
+ );
2510
2601
  }
2511
2602
  }
2512
- async function extractPrimitive(primitive, transform, id, readExternalResource, contentUri, signal) {
2603
+ async function extractPrimitive(gltf, primitive, transform, id, readExternalResource, contentUri, signal) {
2513
2604
  if (primitive.targets?.length || Object.keys(primitive.extensions || {}).some((name) => name !== "EXT_mesh_features"))
2514
2605
  throw new import_core20.TileConversionError(
2515
2606
  "MESH_SOURCE_PRIMITIVE_UNSUPPORTED",
@@ -2521,7 +2612,8 @@ async function extractPrimitive(primitive, transform, id, readExternalResource,
2521
2612
  "Mesh placement requires a finite invertible affine transform with positive determinant"
2522
2613
  );
2523
2614
  const attributes = {};
2524
- for (const [name, accessor] of Object.entries(primitive.attributes)) {
2615
+ for (const [name, reference] of Object.entries(primitive.attributes)) {
2616
+ const accessor = (0, import_gltf4.getGLTFAccessor)(gltf, reference);
2525
2617
  if (name === "_BATCHID" || /^_FEATURE_ID_\d+$/.test(name)) continue;
2526
2618
  if (!["POSITION", "NORMAL", "COLOR_0", "TEXCOORD_0"].includes(name))
2527
2619
  throw new import_core20.TileConversionError(
@@ -2529,17 +2621,17 @@ async function extractPrimitive(primitive, transform, id, readExternalResource,
2529
2621
  `Unsupported mesh attribute ${name}`
2530
2622
  );
2531
2623
  attributes[name] = {
2532
- value: accessor.value,
2533
- size: accessor.components,
2624
+ value: (0, import_gltf4.getGLTFAccessorValue)(gltf, reference),
2625
+ size: accessor.type === "SCALAR" ? 1 : Number(accessor.type.slice(3)),
2534
2626
  ...accessor.normalized ? { normalized: true } : {}
2535
2627
  };
2536
2628
  }
2537
2629
  const mesh = validateMeshGeometry(
2538
2630
  {
2539
2631
  topology: "triangle-list",
2540
- mode: primitive.mode === 5 ? 4 : primitive.mode ?? 4,
2632
+ mode: [5, 6].includes(primitive.mode ?? 4) ? 4 : primitive.mode ?? 4,
2541
2633
  attributes,
2542
- indices: createTriangleIndices(primitive, (attributes.POSITION?.value.length ?? 0) / 3)
2634
+ indices: createTriangleIndices(gltf, primitive, (attributes.POSITION?.value.length ?? 0) / 3)
2543
2635
  },
2544
2636
  true
2545
2637
  );
@@ -2577,14 +2669,15 @@ async function extractPrimitive(primitive, transform, id, readExternalResource,
2577
2669
  mesh,
2578
2670
  origin: minimum.map((value, axis) => value / 2 + maximum[axis] / 2),
2579
2671
  material: await mapMeshSourceMaterial(
2580
- primitive.material,
2672
+ primitive.material === void 0 ? void 0 : gltf.json.materials?.[primitive.material],
2581
2673
  readExternalResource,
2582
2674
  contentUri,
2583
- signal
2675
+ signal,
2676
+ gltf
2584
2677
  )
2585
2678
  };
2586
2679
  }
2587
- async function mapMeshSourceMaterial(material, readExternalResource, contentUri, signal) {
2680
+ async function mapMeshSourceMaterial(material, readExternalResource, contentUri, signal, gltf) {
2588
2681
  if (!material) return void 0;
2589
2682
  const pbr = material.pbrMetallicRoughness;
2590
2683
  if (Object.entries(material).some(
@@ -2609,6 +2702,7 @@ async function mapMeshSourceMaterial(material, readExternalResource, contentUri,
2609
2702
  baseColorFactor: pbr?.baseColorFactor,
2610
2703
  ..."baseColorTexture" in (pbr || {}) ? {
2611
2704
  baseColorTexture: await resolveMeshSourceTexture(
2705
+ gltf,
2612
2706
  pbr.baseColorTexture,
2613
2707
  readExternalResource,
2614
2708
  contentUri,
@@ -2622,13 +2716,14 @@ async function mapMeshSourceMaterial(material, readExternalResource, contentUri,
2622
2716
  doubleSided: material.doubleSided
2623
2717
  };
2624
2718
  }
2625
- function createTriangleIndices(primitive, vertexCount) {
2626
- const attribute = primitive.indices ? {
2627
- value: primitive.indices.value,
2628
- size: primitive.indices.components,
2629
- normalized: primitive.indices.normalized
2719
+ function createTriangleIndices(gltf, primitive, vertexCount) {
2720
+ const accessor = primitive.indices === void 0 ? void 0 : (0, import_gltf4.getGLTFAccessor)(gltf, primitive.indices);
2721
+ const attribute = accessor ? {
2722
+ value: (0, import_gltf4.getGLTFAccessorValue)(gltf, accessor),
2723
+ size: 1,
2724
+ normalized: accessor.normalized
2630
2725
  } : void 0;
2631
- if (primitive.mode !== 5) return attribute;
2726
+ if (primitive.mode !== 5 && primitive.mode !== 6) return attribute;
2632
2727
  const sourceIndices = validateMeshIndices(attribute, vertexCount, 5);
2633
2728
  const indexCount = sourceIndices?.length ?? vertexCount;
2634
2729
  if (!Number.isSafeInteger(indexCount) || indexCount < 3) {
@@ -2640,9 +2735,10 @@ function createTriangleIndices(primitive, vertexCount) {
2640
2735
  const IndexArray = vertexCount < 65536 ? Uint16Array : Uint32Array;
2641
2736
  const indices = new IndexArray((indexCount - 2) * 3);
2642
2737
  for (let triangle = 0; triangle < indexCount - 2; triangle++) {
2643
- const second = triangle + 1 + triangle % 2;
2644
- const third = triangle + 2 - triangle % 2;
2645
- indices[triangle * 3] = sourceIndices?.[triangle] ?? triangle;
2738
+ const second = primitive.mode === 6 ? triangle + 1 : triangle + 1 + triangle % 2;
2739
+ const third = primitive.mode === 6 ? triangle + 2 : triangle + 2 - triangle % 2;
2740
+ const first = primitive.mode === 6 ? 0 : triangle;
2741
+ indices[triangle * 3] = sourceIndices?.[first] ?? first;
2646
2742
  indices[triangle * 3 + 1] = sourceIndices?.[second] ?? second;
2647
2743
  indices[triangle * 3 + 2] = sourceIndices?.[third] ?? third;
2648
2744
  }
@@ -2650,7 +2746,7 @@ function createTriangleIndices(primitive, vertexCount) {
2650
2746
  }
2651
2747
 
2652
2748
  // src/v5/i3s-mesh-conversion.ts
2653
- var import_i3s = require("@loaders.gl/i3s");
2749
+ var import_i3s = require("@loaders.gl/tiles-3d/i3s");
2654
2750
  var import_core22 = require("@loaders.gl/tile-converter/v5/core");
2655
2751
  var import_core23 = require("@loaders.gl/tile-converter/v5/core");
2656
2752
  function createI3SMeshConversionCodec(options) {
@@ -3264,6 +3360,7 @@ var import_core28 = require("@loaders.gl/tile-converter/v5/core");
3264
3360
  var import_images3 = require("@loaders.gl/images");
3265
3361
  var import_core26 = require("@loaders.gl/tile-converter/v5/core");
3266
3362
  async function mapI3SMeshSourceMaterial(content, header, readExternalResource, contentUri, signal) {
3363
+ const gltf = { json: { asset: { version: "2.0" } }, buffers: [] };
3267
3364
  const material = Object.fromEntries(
3268
3365
  Object.entries(content.material || {}).filter(([, value]) => value !== void 0)
3269
3366
  );
@@ -3330,7 +3427,7 @@ async function mapI3SMeshSourceMaterial(content, header, readExternalResource, c
3330
3427
  }
3331
3428
  }
3332
3429
  const declaredFormat = resources[0]?.textureFormat;
3333
- if (!image || !["image/png", "image/jpeg"].includes(image.mimeType) || declaredFormat && (declaredFormat === "png" ? image.mimeType !== "image/png" : declaredFormat === "jpg" ? image.mimeType !== "image/jpeg" : true)) {
3430
+ if (!(data instanceof Uint8Array) || !image || !["image/png", "image/jpeg"].includes(image.mimeType) || declaredFormat && (declaredFormat === "png" ? image.mimeType !== "image/png" : declaredFormat === "jpg" ? image.mimeType !== "image/jpeg" : true)) {
3334
3431
  throw new import_core26.TileConversionError(
3335
3432
  "I3S_MESH_SOURCE_TEXTURE_UNSUPPORTED",
3336
3433
  "I3S base-color bytes must have matching PNG/JPEG headers"
@@ -3339,19 +3436,24 @@ async function mapI3SMeshSourceMaterial(content, header, readExternalResource, c
3339
3436
  const sampler = Object.fromEntries(
3340
3437
  ["wrapS", "wrapT"].filter((name) => textureInfo[name] !== void 0).map((name) => [name, wrappingModes[textureInfo[name]]])
3341
3438
  );
3342
- metallicRoughness.baseColorTexture = {
3343
- texCoord: 0,
3344
- texture: {
3345
- source: { mimeType: image.mimeType, bufferView: { data } },
3346
- ...Object.keys(sampler).length ? { sampler } : {}
3347
- }
3348
- };
3439
+ gltf.buffers.push({
3440
+ arrayBuffer: data.buffer,
3441
+ byteOffset: data.byteOffset,
3442
+ byteLength: data.byteLength
3443
+ });
3444
+ gltf.json.buffers = [{ byteLength: data.byteLength }];
3445
+ gltf.json.bufferViews = [{ buffer: 0, byteLength: data.byteLength }];
3446
+ gltf.json.images = [{ mimeType: image.mimeType, bufferView: 0 }];
3447
+ gltf.json.samplers = [sampler];
3448
+ gltf.json.textures = [{ source: 0, sampler: 0 }];
3449
+ metallicRoughness.baseColorTexture = { texCoord: 0, index: 0 };
3349
3450
  }
3350
3451
  const mapped = await mapMeshSourceMaterial(
3351
3452
  material,
3352
3453
  void 0,
3353
3454
  contentUri,
3354
- signal
3455
+ signal,
3456
+ gltf
3355
3457
  );
3356
3458
  if (mapped?.baseColorTexture && !content.sourceAttributes?.uv0) {
3357
3459
  throw new import_core26.TileConversionError(
@@ -3363,7 +3465,7 @@ async function mapI3SMeshSourceMaterial(content, header, readExternalResource, c
3363
3465
  }
3364
3466
 
3365
3467
  // src/v5/i3s-mesh-source-features.ts
3366
- var import_i3s2 = require("@loaders.gl/i3s");
3468
+ var import_i3s2 = require("@loaders.gl/tiles-3d/i3s");
3367
3469
  var import_core27 = require("@loaders.gl/tile-converter/v5/core");
3368
3470
  async function extractI3SMeshFeatures(content, item, metadata, options, readExternalResource, contentUri, signal) {
3369
3471
  const maximumAttributeBytes = options.maxAttributeBytes;
@@ -3691,19 +3793,267 @@ function createI3SMeshTilesetConversionSource(tileset, options = {}) {
3691
3793
  };
3692
3794
  }
3693
3795
 
3694
- // src/v5/point-cloud-tileset.ts
3695
- var import_point_cloud_tile_source = require("@loaders.gl/tiles/point-cloud-tile-source");
3796
+ // src/v5/point-cloud-attributes.ts
3797
+ var import_schema_utils5 = require("@loaders.gl/core/schema-utils");
3696
3798
  var import_core29 = require("@loaders.gl/tile-converter/v5/core");
3799
+ function mapPointCloudAttributes(input, mapping) {
3800
+ const mesh = getPointCloudMesh(input);
3801
+ const attributes = /* @__PURE__ */ Object.create(null);
3802
+ const selected = /* @__PURE__ */ new Set();
3803
+ for (const [target, source] of Object.entries(mapping.attributes)) {
3804
+ if (!target || ["__proto__", "constructor", "prototype"].includes(target) || !Object.hasOwn(mesh.attributes, source))
3805
+ throw new import_core29.TileConversionError(
3806
+ "POINT_CLOUD_MAPPING_INVALID",
3807
+ `Invalid point attribute mapping ${target}: ${source}`
3808
+ );
3809
+ if (Object.hasOwn(mapping.drop || {}, source))
3810
+ throw new import_core29.TileConversionError(
3811
+ "POINT_CLOUD_MAPPING_INVALID",
3812
+ `Point attribute ${source} is both selected and dropped`
3813
+ );
3814
+ attributes[target] = { ...mesh.attributes[source] };
3815
+ selected.add(source);
3816
+ }
3817
+ const droppedAttributes = /* @__PURE__ */ Object.create(null);
3818
+ for (const [source, reason] of Object.entries(mapping.drop || {}).sort(
3819
+ ([left], [right]) => left < right ? -1 : left > right ? 1 : 0
3820
+ )) {
3821
+ if (!Object.hasOwn(mesh.attributes, source) || typeof reason !== "string" || !reason.trim())
3822
+ throw new import_core29.TileConversionError(
3823
+ "POINT_CLOUD_MAPPING_INVALID",
3824
+ `Invalid loss declaration for ${source}`
3825
+ );
3826
+ droppedAttributes[source] = reason;
3827
+ }
3828
+ const unmapped = Object.keys(mesh.attributes).filter(
3829
+ (name) => !selected.has(name) && !Object.hasOwn(droppedAttributes, name)
3830
+ );
3831
+ if (unmapped.length || !attributes.POSITION)
3832
+ throw new import_core29.TileConversionError(
3833
+ "POINT_CLOUD_MAPPING_REQUIRED",
3834
+ `Map POSITION and explicitly retain or drop every attribute: ${unmapped.join(", ")}`
3835
+ );
3836
+ return {
3837
+ mesh: { ...mesh, attributes, schema: { fields: [], metadata: { ...mesh.schema?.metadata } } },
3838
+ droppedAttributes
3839
+ };
3840
+ }
3841
+ function getPointCloudMesh(input, maxInputBytes = Infinity) {
3842
+ const buffers = /* @__PURE__ */ new Set();
3843
+ let bytes = 0;
3844
+ const countBuffer = (buffer) => {
3845
+ if (!buffers.has(buffer)) {
3846
+ buffers.add(buffer);
3847
+ bytes += buffer.byteLength;
3848
+ }
3849
+ if (bytes > maxInputBytes)
3850
+ throw new import_core29.TileConversionError("POINT_CLOUD_INPUT_BUDGET", "Point input byte budget exceeded");
3851
+ };
3852
+ if ("shape" in input) {
3853
+ const checkColumn = (column) => {
3854
+ if (column.nullCount)
3855
+ throw new import_core29.TileConversionError(
3856
+ "POINT_CLOUD_NULL_UNSUPPORTED",
3857
+ "Null point values require an explicit preprocessing step"
3858
+ );
3859
+ for (const buffer of Object.values(column.buffers)) if (buffer) countBuffer(buffer.buffer);
3860
+ for (const view of column.variadicBuffers) countBuffer(view.buffer);
3861
+ for (const child of column.children) checkColumn(child);
3862
+ for (const dictionary of column.dictionary?.data || []) checkColumn(dictionary);
3863
+ };
3864
+ for (const batch of input.data.batches) checkColumn(batch.data);
3865
+ } else
3866
+ for (const attribute of Object.values(input.attributes)) countBuffer(attribute.value.buffer);
3867
+ const mesh = "shape" in input ? (0, import_schema_utils5.convertTableToMesh)(input) : input;
3868
+ if (mesh.topology !== "point-list" || mesh.indices)
3869
+ throw new import_core29.TileConversionError(
3870
+ "POINT_CLOUD_INPUT_INVALID",
3871
+ "Decoded unindexed point-list input is required"
3872
+ );
3873
+ return mesh;
3874
+ }
3875
+
3876
+ // src/v5/point-cloud-copc.ts
3877
+ var import_copc = require("@loaders.gl/tiles-3d/copc");
3878
+ var import_core30 = require("@loaders.gl/tile-converter/v5/core");
3879
+ var SCALAR_RANGES = {
3880
+ intensity: [0, 65535],
3881
+ classification: [0, 255],
3882
+ nir: [0, 65535],
3883
+ gpsTime: [-Infinity, Infinity],
3884
+ scanAngle: [-32768, 32767],
3885
+ userData: [0, 255],
3886
+ pointSourceId: [0, 65535],
3887
+ returnNumber: [1, 15],
3888
+ numberOfReturns: [1, 15],
3889
+ scannerChannel: [0, 3],
3890
+ scanDirectionFlag: [0, 1],
3891
+ edgeOfFlightLine: [0, 1],
3892
+ synthetic: [0, 1],
3893
+ keyPoint: [0, 1],
3894
+ withheld: [0, 1],
3895
+ overlap: [0, 1]
3896
+ };
3897
+ async function encodePointCloudCOPC(input, options) {
3898
+ const maxInputBytes = options.maxInputBytes ?? 64 * 1024 * 1024;
3899
+ const maxPoints = options.maxPoints ?? 1e6;
3900
+ const maxOutputBytes = options.maxOutputBytes ?? 128 * 1024 * 1024;
3901
+ if ([maxInputBytes, maxPoints, maxOutputBytes].some(
3902
+ (value) => !Number.isSafeInteger(value) || value < 1
3903
+ ) || options.scale.length !== 3 || options.scale.some((value) => !Number.isFinite(value) || value <= 0) || options.offset.length !== 3 || options.offset.some((value) => !Number.isFinite(value)) || typeof options.wkt !== "string" || !options.wkt.trim() || !Number.isFinite(options.maxPositionError) || options.maxPositionError < 0)
3904
+ throw new import_core30.TileConversionError(
3905
+ "POINT_CLOUD_COPC_OPTIONS_INVALID",
3906
+ "COPC requires explicit finite scale, offset, CRS, precision and positive budgets"
3907
+ );
3908
+ options.signal?.throwIfAborted();
3909
+ const source = getPointCloudMesh(input, maxInputBytes);
3910
+ const { mesh, droppedAttributes } = mapPointCloudAttributes(source, options.mapping);
3911
+ const position = mesh.attributes.POSITION;
3912
+ const pointCount = mesh.header?.vertexCount ?? position.value.length / 3;
3913
+ if (!Number.isSafeInteger(pointCount) || pointCount < 1 || pointCount > maxPoints)
3914
+ throw new import_core30.TileConversionError(
3915
+ "POINT_CLOUD_POINT_BUDGET",
3916
+ "COPC requires a nonempty batch within the point limit"
3917
+ );
3918
+ if (!(position.value instanceof Float32Array || position.value instanceof Float64Array) || position.size !== 3 || position.normalized)
3919
+ throw new import_core30.TileConversionError(
3920
+ "POINT_CLOUD_POSITION_INVALID",
3921
+ "COPC requires decoded floating XYZ"
3922
+ );
3923
+ const extraNames = new Set(options.extraBytes?.map((field) => field.attribute) || []);
3924
+ const descriptorNames = new Set(
3925
+ options.extraBytes?.map((field) => field.name || field.attribute) || []
3926
+ );
3927
+ if (extraNames.size !== (options.extraBytes?.length || 0) || descriptorNames.size !== extraNames.size || options.extraBytes?.some((field) => {
3928
+ const name = field.name || field.attribute;
3929
+ const description = field.description || "";
3930
+ return !mesh.attributes[field.attribute] || !field.attribute || !name.length || name.length > 32 || description.length > 32 || /[^\x20-\x7e]/.test(name) || /[^\x20-\x7e]/.test(description);
3931
+ }))
3932
+ throw new import_core30.TileConversionError(
3933
+ "POINT_CLOUD_EXTRA_BYTES_INVALID",
3934
+ "Extra Bytes descriptors require unique mapped attributes and names/descriptions within 32 printable ASCII bytes"
3935
+ );
3936
+ for (const name of extraNames)
3937
+ if (name === "POSITION" || name === "COLOR_0" || Object.hasOwn(SCALAR_RANGES, name))
3938
+ throw new import_core30.TileConversionError(
3939
+ "POINT_CLOUD_EXTRA_BYTES_INVALID",
3940
+ "Map standard attributes directly instead of duplicating them as Extra Bytes"
3941
+ );
3942
+ for (const [name, attribute] of Object.entries(mesh.attributes)) {
3943
+ const color2 = name === "COLOR_0";
3944
+ const extra = extraNames.has(name);
3945
+ if (name !== "POSITION" && !color2 && !extra && !Object.hasOwn(SCALAR_RANGES, name))
3946
+ throw new import_core30.TileConversionError(
3947
+ "POINT_CLOUD_ATTRIBUTE_UNSUPPORTED",
3948
+ `COPC cannot preserve ${name}; supply an explicit supported mapping or drop reason`
3949
+ );
3950
+ if (attribute.transform || attribute.byteOffset || attribute.byteStride || attribute.componentType === "float16" || attribute.value.length !== pointCount * attribute.size || !color2 && attribute.normalized || name !== "POSITION" && !color2 && (extra ? ![1, 3].includes(attribute.size) : attribute.size !== 1))
3951
+ throw new import_core30.TileConversionError(
3952
+ "POINT_CLOUD_ATTRIBUTE_INVALID",
3953
+ `COPC requires packed decoded attributes: ${name}`
3954
+ );
3955
+ if (color2) {
3956
+ if (attribute.size !== 3 || !(attribute.value instanceof Uint8Array || attribute.value instanceof Uint16Array))
3957
+ throw new import_core30.TileConversionError(
3958
+ "POINT_CLOUD_COLOR_INVALID",
3959
+ "COPC requires explicitly mapped uint8/uint16 RGB"
3960
+ );
3961
+ } else if (extra) {
3962
+ for (const value of attribute.value)
3963
+ if (typeof value !== "bigint" && !Number.isFinite(value))
3964
+ throw new import_core30.TileConversionError(
3965
+ "POINT_CLOUD_ATTRIBUTE_RANGE",
3966
+ `Nonfinite Extra Bytes value: ${name}`
3967
+ );
3968
+ } else if (name !== "POSITION") {
3969
+ const [minimum2, maximum2] = SCALAR_RANGES[name];
3970
+ for (const value of attribute.value) {
3971
+ if (typeof value !== "number" || !Number.isFinite(value) || value < minimum2 || value > maximum2 || name !== "gpsTime" && !Number.isInteger(value))
3972
+ throw new import_core30.TileConversionError(
3973
+ "POINT_CLOUD_ATTRIBUTE_RANGE",
3974
+ `COPC value outside the qualified range: ${name}`
3975
+ );
3976
+ }
3977
+ }
3978
+ }
3979
+ let maximumPositionError = 0;
3980
+ const minimum = [Infinity, Infinity, Infinity];
3981
+ const maximum = [-Infinity, -Infinity, -Infinity];
3982
+ const errors = [0, 0, 0];
3983
+ for (let row = 0; row < pointCount; row++) {
3984
+ for (let axis = 0; axis < 3; axis++) {
3985
+ const value = position.value[row * 3 + axis];
3986
+ const encoded = Math.round((value - options.offset[axis]) / options.scale[axis]);
3987
+ if (!Number.isFinite(value) || !Number.isSafeInteger(encoded) || encoded < -2147483648 || encoded > 2147483647)
3988
+ throw new import_core30.TileConversionError(
3989
+ "POINT_CLOUD_POSITION_RANGE",
3990
+ "COPC position exceeds signed int32 quantization"
3991
+ );
3992
+ minimum[axis] = Math.min(minimum[axis], value);
3993
+ maximum[axis] = Math.max(maximum[axis], value);
3994
+ errors[axis] = encoded * options.scale[axis] + options.offset[axis] - value;
3995
+ }
3996
+ maximumPositionError = Math.max(maximumPositionError, Math.hypot(...errors));
3997
+ if (maximumPositionError > options.maxPositionError)
3998
+ throw new import_core30.TileConversionError(
3999
+ "POINT_CLOUD_PRECISION_EXCEEDED",
4000
+ "COPC position rounding exceeds the declared error gate"
4001
+ );
4002
+ if (row % 16384 === 0) {
4003
+ await new Promise((resolve) => setTimeout(resolve, 0));
4004
+ options.signal?.throwIfAborted();
4005
+ }
4006
+ }
4007
+ const width = Math.max(...maximum.map((value, axis) => value - minimum[axis]), ...options.scale);
4008
+ const radius = width / 2;
4009
+ if (!Number.isFinite(Math.hypot(radius, radius, radius)) || minimum.some((value, axis) => {
4010
+ const center = value + (maximum[axis] - value) / 2;
4011
+ return !Number.isFinite(value + maximum[axis]) || !Number.isFinite(center - radius) || !Number.isFinite(center + radius);
4012
+ }))
4013
+ throw new import_core30.TileConversionError("POINT_CLOUD_BOUNDS_INVALID", "COPC coordinate extent overflow");
4014
+ options.signal?.throwIfAborted();
4015
+ const color = mesh.attributes.COLOR_0;
4016
+ const copc = import_copc.COPCWriter.encodeSync(mesh, {
4017
+ copc: {
4018
+ ...options.organization,
4019
+ scale: [...options.scale],
4020
+ offset: [...options.offset],
4021
+ wkt: options.wkt,
4022
+ pointDataRecordFormat: mesh.attributes.nir ? 8 : color ? 7 : 6,
4023
+ colorDepth: color?.value instanceof Uint16Array ? 16 : 8,
4024
+ extraBytes: options.extraBytes
4025
+ }
4026
+ });
4027
+ options.signal?.throwIfAborted();
4028
+ if (copc.byteLength > maxOutputBytes)
4029
+ throw new import_core30.TileConversionError(
4030
+ "POINT_CLOUD_OUTPUT_BUDGET",
4031
+ "Completed COPC output exceeds the byte budget"
4032
+ );
4033
+ return { copc, pointCount, maximumPositionError, droppedAttributes };
4034
+ }
4035
+ function createCOPCConversionCodec(options) {
4036
+ return {
4037
+ async *convert(input, _inspection, signal) {
4038
+ const combinedSignal = options.signal && signal ? AbortSignal.any([options.signal, signal]) : options.signal || signal;
4039
+ yield await encodePointCloudCOPC(input, { ...options, signal: combinedSignal });
4040
+ }
4041
+ };
4042
+ }
4043
+
4044
+ // src/v5/point-cloud-tileset.ts
4045
+ var import_point_cloud_tile_source = require("@loaders.gl/tiles-3d/point-cloud-tile-source");
4046
+ var import_core31 = require("@loaders.gl/tile-converter/v5/core");
3697
4047
  async function convertPointCloudToTileset(input, options) {
3698
4048
  const reference = options.spatialReference;
3699
4049
  if (!reference || reference.status !== "native" || reference.sourceCrs !== "EPSG:4978" || reference.targetCrs && reference.targetCrs !== "EPSG:4978" || reference.coordinateFrame !== "geocentric" || reference.axisOrder !== "xyz" || reference.heightReference !== "ellipsoidal" || reference.verticalUnitScale !== 1 || reference.units?.some((unit) => unit !== "meter")) {
3700
- throw new import_core29.TileConversionError(
4050
+ throw new import_core31.TileConversionError(
3701
4051
  "POINT_CLOUD_TILESET_FRAME_UNSUPPORTED",
3702
4052
  "Point authoring requires explicit native EPSG:4978 xyz meters and ellipsoidal heights"
3703
4053
  );
3704
4054
  }
3705
4055
  if (options.archive && (!Number.isSafeInteger(options.archive.maxArchiveBytes) || options.archive.maxArchiveBytes < 0)) {
3706
- throw new import_core29.TileConversionError(
4056
+ throw new import_core31.TileConversionError(
3707
4057
  "INVALID_ARCHIVE_BYTE_LIMIT",
3708
4058
  "Archive byte limit must be a non-negative safe integer"
3709
4059
  );
@@ -3754,10 +4104,10 @@ async function convertPointCloudToTileset(input, options) {
3754
4104
  }
3755
4105
 
3756
4106
  // src/v5/point-cloud-file.ts
3757
- var import_copc = require("@loaders.gl/copc");
3758
- var import_potree = require("@loaders.gl/potree");
3759
- var import_schema_utils5 = require("@loaders.gl/schema-utils");
3760
- var import_zip = require("@loaders.gl/zip");
4107
+ var import_copc2 = require("@loaders.gl/tiles-3d/copc");
4108
+ var import_potree = require("@loaders.gl/tiles-3d/potree");
4109
+ var import_schema_utils6 = require("@loaders.gl/core/schema-utils");
4110
+ var import_zip = require("@loaders.gl/archives/zip");
3761
4111
  async function encodePotreeArchive(input, options) {
3762
4112
  validateLimit(options.maxArchiveBytes);
3763
4113
  const dataset = await (0, import_potree.encodePotreeDataset)(input, { potree: options.potree });
@@ -3782,7 +4132,7 @@ async function openPointCloudFile(input, options) {
3782
4132
  if (input.size > options.maxFileBytes) throw new RangeError("Point file input budget exceeded");
3783
4133
  options.signal?.throwIfAborted();
3784
4134
  if (options.format === "copc") {
3785
- const source2 = import_copc.COPCSourceLoader.createDataSource(input, options.sourceOptions || {});
4135
+ const source2 = import_copc2.COPCSourceLoader.createDataSource(input, options.sourceOptions || {});
3786
4136
  try {
3787
4137
  await source2.metadata;
3788
4138
  options.signal?.throwIfAborted();
@@ -3899,7 +4249,7 @@ function extractMeshVertices(mesh, options) {
3899
4249
  throw new Error(`Invalid selected mesh vertex attribute: ${name}`);
3900
4250
  attributes[name] = attribute;
3901
4251
  }
3902
- return { topology: "point-list", mode: 0, attributes, schema: (0, import_schema_utils5.deduceMeshSchema)(attributes) };
4252
+ return { topology: "point-list", mode: 0, attributes, schema: (0, import_schema_utils6.deduceMeshSchema)(attributes) };
3903
4253
  }
3904
4254
  function validatePath(path) {
3905
4255
  if (!path || !/^[A-Za-z0-9_.\/-]+$/.test(path) || path.split("/").some((part) => !part || part === "." || part === ".."))
@@ -3911,8 +4261,8 @@ function validateLimit(value) {
3911
4261
  }
3912
4262
 
3913
4263
  // src/v5/point-cloud-potree.ts
3914
- var import_schema_utils6 = require("@loaders.gl/schema-utils");
3915
- var import_potree2 = require("@loaders.gl/potree");
4264
+ var import_schema_utils7 = require("@loaders.gl/core/schema-utils");
4265
+ var import_potree2 = require("@loaders.gl/tiles-3d/potree");
3916
4266
  async function convertPointCloudToPotree(input, options) {
3917
4267
  if (typeof options.projection !== "string" || !options.projection.trim()) {
3918
4268
  throw new Error("Potree authoring requires an explicit native CRS declaration");
@@ -3930,7 +4280,7 @@ async function convertPointCloudToPotree(input, options) {
3930
4280
  throw new RangeError("Potree authoring requires gathered and encoded byte limits");
3931
4281
  }
3932
4282
  options.signal?.throwIfAborted();
3933
- const tiler = new import_schema_utils6.PointCloudTiler(input, {
4283
+ const tiler = new import_schema_utils7.PointCloudTiler(input, {
3934
4284
  ...options.tiling,
3935
4285
  maxNodes: Math.min(options.tiling?.maxNodes ?? 1e5, options.potree?.maxNodes ?? 1e5),
3936
4286
  maxTileBytes: Math.min(
@@ -3982,12 +4332,12 @@ async function convertPointCloudToPotree(input, options) {
3982
4332
  }
3983
4333
 
3984
4334
  // src/v5/mesh-hierarchy.ts
3985
- var import_core30 = require("@math.gl/core");
3986
- var import_tiles3 = require("@loaders.gl/tiles");
3987
- var import_core31 = require("@loaders.gl/tile-converter/v5/core");
4335
+ var import_core32 = require("@math.gl/core");
4336
+ var import_tiles_3d3 = require("@loaders.gl/tiles-3d");
4337
+ var import_core33 = require("@loaders.gl/tile-converter/v5/core");
3988
4338
  function prepareMeshHierarchy(inspection, resourceIds) {
3989
4339
  const rejectHierarchy = (message) => {
3990
- throw new import_core31.TileConversionError("MESH_HIERARCHY_UNSUPPORTED", message);
4340
+ throw new import_core33.TileConversionError("MESH_HIERARCHY_UNSUPPORTED", message);
3991
4341
  };
3992
4342
  if (!inspection.documents?.length || inspection.documents.length > 32)
3993
4343
  rejectHierarchy(
@@ -3997,7 +4347,7 @@ function prepareMeshHierarchy(inspection, resourceIds) {
3997
4347
  rejectHierarchy(
3998
4348
  "Hierarchy preservation requires every content placement, without duplicates (at most 64)"
3999
4349
  );
4000
- const entryTransform = new import_core30.Matrix4();
4350
+ const entryTransform = new import_core32.Matrix4();
4001
4351
  if (inspection.documents[0].parentResourceId !== void 0 || !Array.isArray(inspection.documents[0].parentTransform) || inspection.documents[0].parentTransform.length !== 16 || inspection.documents[0].parentTransform.some((value, index) => value !== entryTransform[index]))
4002
4352
  rejectHierarchy("The entry document must have identity parent placement");
4003
4353
  const documents = inspection.documents.map((placement) => placement.tileset);
@@ -4022,9 +4372,9 @@ function prepareMeshHierarchy(inspection, resourceIds) {
4022
4372
  rejectHierarchy("Dataset geometricError must be finite nonnegative meters");
4023
4373
  }
4024
4374
  const spatialReferences = documents.map(
4025
- (document2) => (0, import_tiles3.get3DTilesSpatialReference)(document2)
4375
+ (document2) => (0, import_tiles_3d3.get3DTilesSpatialReference)(document2)
4026
4376
  );
4027
- const spatialReference = (0, import_core31.createTiles3DConversionSpatialContext)(
4377
+ const spatialReference = (0, import_core33.createTiles3DConversionSpatialContext)(
4028
4378
  spatialReferences[0]
4029
4379
  ).spatialReference;
4030
4380
  if (spatialReference.status !== "native" || spatialReference.sourceCrs !== "EPSG:4978" || spatialReference.heightReference !== "ellipsoidal" || spatialReference.axisOrder !== "xyz" || spatialReference.verticalUnitScale !== 1 || spatialReference.units?.some((unit) => unit !== "meter"))
@@ -4033,7 +4383,7 @@ function prepareMeshHierarchy(inspection, resourceIds) {
4033
4383
  );
4034
4384
  for (const reference of spatialReferences.slice(1)) {
4035
4385
  const inherited = reference.crs.state === "absent" && reference.coordinateEpoch === void 0 && !reference.verticalCrs && !reference.warnings.length;
4036
- const context = (0, import_core31.createTiles3DConversionSpatialContext)(inherited ? spatialReference : reference);
4386
+ const context = (0, import_core33.createTiles3DConversionSpatialContext)(inherited ? spatialReference : reference);
4037
4387
  if (context.spatialReference.status !== "native" || context.spatialReference.sourceCrs !== spatialReference.sourceCrs || context.spatialReference.heightReference !== spatialReference.heightReference || context.spatialReference.axisOrder !== spatialReference.axisOrder || context.spatialReference.verticalUnitScale !== 1 || context.spatialReference.units?.some((unit) => unit !== "meter") || context.spatialReference.coordinateEpoch !== spatialReference.coordinateEpoch)
4038
4388
  rejectHierarchy("External document CRS and coordinate epoch must match the entry frame");
4039
4389
  }
@@ -4046,7 +4396,7 @@ function prepareMeshHierarchy(inspection, resourceIds) {
4046
4396
  prefix: "",
4047
4397
  path: [],
4048
4398
  parent: -1,
4049
- transform: new import_core30.Matrix4(),
4399
+ transform: new import_core32.Matrix4(),
4050
4400
  refine: void 0
4051
4401
  }
4052
4402
  ];
@@ -4072,7 +4422,7 @@ function prepareMeshHierarchy(inspection, resourceIds) {
4072
4422
  const matrix = tile.transform;
4073
4423
  if (matrix !== void 0 && (!Array.isArray(matrix) || matrix.length !== 16 || matrix.some((value) => typeof value !== "number" || !Number.isFinite(value)) || matrix[3] !== 0 || matrix[7] !== 0 || matrix[11] !== 0 || matrix[15] !== 1))
4074
4424
  rejectHierarchy("Hierarchy transforms must be finite affine matrices");
4075
- const transform = new import_core30.Matrix4(parentTransform).multiplyRight(matrix ?? new import_core30.Matrix4());
4425
+ const transform = new import_core32.Matrix4(parentTransform).multiplyRight(matrix ?? new import_core32.Matrix4());
4076
4426
  const columns = [0, 1, 2].map(
4077
4427
  (column) => [0, 1, 2].reduce((sum, row) => sum + Math.abs(transform[column * 4 + row]), 0)
4078
4428
  );
@@ -4167,11 +4517,11 @@ function createMeshHierarchyTilesetSink(options) {
4167
4517
  );
4168
4518
  const { maxPositionError } = options;
4169
4519
  if (!Number.isFinite(maxPositionError) || maxPositionError < 0 || hierarchy.nodes.some((node) => !Number.isFinite(node.geometricError + maxPositionError)) || !Number.isFinite(hierarchy.geometricError + maxPositionError))
4170
- throw new import_core31.TileConversionError(
4520
+ throw new import_core33.TileConversionError(
4171
4521
  "MESH_GEOMETRIC_ERROR_INVALID",
4172
4522
  "Hierarchy position allowance and resulting errors must be finite nonnegative meters"
4173
4523
  );
4174
- const memory = (0, import_core31.createBoundedMemoryTileConversionSink)(options);
4524
+ const memory = (0, import_core33.createBoundedMemoryTileConversionSink)(options);
4175
4525
  const placements = /* @__PURE__ */ new Map();
4176
4526
  const completedContents = /* @__PURE__ */ new Set();
4177
4527
  const primitiveIdentifiers = /* @__PURE__ */ new Set();
@@ -4189,12 +4539,12 @@ function createMeshHierarchyTilesetSink(options) {
4189
4539
  last: true
4190
4540
  };
4191
4541
  if (state !== "open" || !identifier || completedContents.has(identifier) || primitiveIdentifiers.has(resource.id) || primitiveIdentifiers.size >= 64 || !Number.isSafeInteger(primitiveIndex) || primitiveIndex !== (placements.get(identifier)?.length ?? 0) || typeof lastPrimitive !== "boolean" || !hierarchy.nodes.some((node2) => node2.resourceIds.includes(identifier)))
4192
- throw new import_core31.TileConversionError(
4542
+ throw new import_core33.TileConversionError(
4193
4543
  "MESH_HIERARCHY_PLACEMENT_INVALID",
4194
4544
  "Hierarchy writes require ordered, distinct primitives for declared contents before close (at most 64)"
4195
4545
  );
4196
4546
  if (resource.spatialReference.coordinateEpoch !== hierarchy.coordinateEpoch)
4197
- throw new import_core31.TileConversionError(
4547
+ throw new import_core33.TileConversionError(
4198
4548
  "MESH_SOURCE_EPOCH_MISMATCH",
4199
4549
  "Hierarchy output coordinate epoch must match its source"
4200
4550
  );
@@ -4203,7 +4553,7 @@ function createMeshHierarchyTilesetSink(options) {
4203
4553
  const node = hierarchy.nodes[nodeIndex];
4204
4554
  const sibling = node.resourceIds.map((identifier2) => placements.get(identifier2)?.[0]).find(Boolean);
4205
4555
  if (sibling && sibling.origin.some((value, axis) => value !== resource.origin[axis]))
4206
- throw new import_core31.TileConversionError(
4556
+ throw new import_core33.TileConversionError(
4207
4557
  "MESH_HIERARCHY_PLACEMENT_INVALID",
4208
4558
  "Contents on one tile must share an encoded origin"
4209
4559
  );
@@ -4230,7 +4580,7 @@ function createMeshHierarchyTilesetSink(options) {
4230
4580
  /** Publishes original topology only after every source content has completed. */
4231
4581
  async finalize(report) {
4232
4582
  if (state !== "open" || completedContents.size !== hierarchy.nodes.reduce((count, node) => count + node.resourceIds.length, 0))
4233
- throw new import_core31.TileConversionError(
4583
+ throw new import_core33.TileConversionError(
4234
4584
  "MESH_HIERARCHY_INCOMPLETE",
4235
4585
  "Finalization requires every declared hierarchy content"
4236
4586
  );
@@ -4239,7 +4589,7 @@ function createMeshHierarchyTilesetSink(options) {
4239
4589
  const bounds = new Array(hierarchy.nodes.length);
4240
4590
  const transforms = hierarchy.nodes.map((node) => {
4241
4591
  const placement = placements.get(node.resourceIds[0])?.[0];
4242
- return placement ? new import_core30.Matrix4(placement.transform) : new import_core30.Matrix4();
4592
+ return placement ? new import_core32.Matrix4(placement.transform) : new import_core32.Matrix4();
4243
4593
  });
4244
4594
  for (let index = hierarchy.nodes.length - 1; index >= 0; index--) {
4245
4595
  const node = hierarchy.nodes[index];
@@ -4268,12 +4618,12 @@ function createMeshHierarchyTilesetSink(options) {
4268
4618
  maximum[axis] = Math.max(maximum[axis], upper[axis]);
4269
4619
  }
4270
4620
  if ([...minimum, ...maximum].some((value) => !Number.isFinite(value)))
4271
- throw new import_core31.TileConversionError(
4621
+ throw new import_core33.TileConversionError(
4272
4622
  "MESH_TILESET_BOUNDS_INVALID",
4273
4623
  "Hierarchy absolute bounds must remain finite"
4274
4624
  );
4275
4625
  bounds[index] = [minimum, maximum];
4276
- const inverse = new import_core30.Matrix4(transforms[index]).invert();
4626
+ const inverse = new import_core32.Matrix4(transforms[index]).invert();
4277
4627
  const center = Array.from(
4278
4628
  inverse.transformAsPoint(minimum.map((value, axis) => value / 2 + maximum[axis] / 2))
4279
4629
  );
@@ -4286,7 +4636,7 @@ function createMeshHierarchyTilesetSink(options) {
4286
4636
  )
4287
4637
  );
4288
4638
  if ([...center, ...halfAxes].some((value) => !Number.isFinite(value)))
4289
- throw new import_core31.TileConversionError(
4639
+ throw new import_core33.TileConversionError(
4290
4640
  "MESH_TILESET_BOUNDS_INVALID",
4291
4641
  "Hierarchy local bounds must remain finite"
4292
4642
  );
@@ -4299,10 +4649,10 @@ function createMeshHierarchyTilesetSink(options) {
4299
4649
  ...node.children.length ? {
4300
4650
  children: node.children.map((child) => {
4301
4651
  tiles[child].transform = Array.from(
4302
- new import_core30.Matrix4(inverse).multiplyRight(transforms[child])
4652
+ new import_core32.Matrix4(inverse).multiplyRight(transforms[child])
4303
4653
  );
4304
4654
  if (tiles[child].transform.some((value) => !Number.isFinite(value)))
4305
- throw new import_core31.TileConversionError(
4655
+ throw new import_core33.TileConversionError(
4306
4656
  "MESH_TILESET_BOUNDS_INVALID",
4307
4657
  "Relative hierarchy transforms must remain finite"
4308
4658
  );
@@ -4340,10 +4690,10 @@ function createMeshHierarchyTilesetSink(options) {
4340
4690
  }
4341
4691
 
4342
4692
  // src/v5/selected-mesh-source.ts
4343
- var import_core32 = require("@loaders.gl/core");
4344
- var import_d_tiles2 = require("@loaders.gl/3d-tiles");
4345
- var import_tiles4 = require("@loaders.gl/tiles");
4346
- var import_core33 = require("@loaders.gl/tile-converter/v5/core");
4693
+ var import_core34 = require("@loaders.gl/core");
4694
+ var import_d_tiles2 = require("@loaders.gl/tiles-3d/3d-tiles");
4695
+ var import_tiles_3d4 = require("@loaders.gl/tiles-3d");
4696
+ var import_core35 = require("@loaders.gl/tile-converter/v5/core");
4347
4697
  var import_adapters = require("@loaders.gl/tile-converter/v5/adapters");
4348
4698
  var SELECTED_MESH_LIMITS = {
4349
4699
  /** Root JSON plus selected content transport bytes; also the decoded geometry/image/feature byte gate. */
@@ -4372,7 +4722,7 @@ async function createSelectedMeshConversionSource(inspection, options) {
4372
4722
  } = options;
4373
4723
  const maxInputBytes = options.maxInputBytes ?? SELECTED_MESH_LIMITS.maxInputBytes;
4374
4724
  if (!Number.isSafeInteger(maxInputBytes) || maxInputBytes < 1 || maxInputBytes > SELECTED_MESH_LIMITS.maxInputBytes)
4375
- throw new import_core33.TileConversionError(
4725
+ throw new import_core35.TileConversionError(
4376
4726
  "INVALID_SELECTED_MESH_OPTIONS",
4377
4727
  "Selected mesh input budget must be a positive safe integer at most 16 MiB"
4378
4728
  );
@@ -4381,7 +4731,7 @@ async function createSelectedMeshConversionSource(inspection, options) {
4381
4731
  ))
4382
4732
  throw new Error("Select between 1 and 64 distinct content placements.");
4383
4733
  if (preserveHierarchy !== void 0 && typeof preserveHierarchy !== "boolean")
4384
- throw new import_core33.TileConversionError(
4734
+ throw new import_core35.TileConversionError(
4385
4735
  "MESH_HIERARCHY_UNSUPPORTED",
4386
4736
  "preserveHierarchy must be a boolean"
4387
4737
  );
@@ -4390,7 +4740,7 @@ async function createSelectedMeshConversionSource(inspection, options) {
4390
4740
  (resource) => resourceIds.includes(resource.resourceId)
4391
4741
  );
4392
4742
  const selections = descriptors.map(
4393
- (descriptor) => (0, import_core33.selectBrowserTilesetContent)(inspection, descriptor)
4743
+ (descriptor) => (0, import_core35.selectBrowserTilesetContent)(inspection, descriptor)
4394
4744
  );
4395
4745
  const selectedContents = new Map(
4396
4746
  descriptors.map((descriptor, index) => [descriptor.resourceId, selections[index]])
@@ -4418,11 +4768,11 @@ async function createSelectedMeshConversionSource(inspection, options) {
4418
4768
  try {
4419
4769
  await qualification.tilesetInitializationPromise;
4420
4770
  const metadata = await (0, import_adapters.createMeshTilesetConversionSource)(qualification).inspect(signal);
4421
- spatialContext = (0, import_core33.createTiles3DConversionSpatialContext)(metadata.spatialReference);
4771
+ spatialContext = (0, import_core35.createTiles3DConversionSpatialContext)(metadata.spatialReference);
4422
4772
  } finally {
4423
4773
  qualification.destroy();
4424
4774
  }
4425
- const rawSource = options.source ?? (0, import_core33.createBrowserTilesetConversionSource)({
4775
+ const rawSource = options.source ?? (0, import_core35.createBrowserTilesetConversionSource)({
4426
4776
  input: inspection.rootUrl,
4427
4777
  ...SELECTED_MESH_LIMITS,
4428
4778
  maxInputBytes,
@@ -4446,7 +4796,7 @@ async function createSelectedMeshConversionSource(inspection, options) {
4446
4796
  for await (const raw of rawSource.read(selectedInspection, signal2)) {
4447
4797
  const selection = selectedContents.get(raw.resourceId);
4448
4798
  if (!selection)
4449
- throw new import_core33.TileConversionError(
4799
+ throw new import_core35.TileConversionError(
4450
4800
  "INVALID_BROWSER_SELECTION",
4451
4801
  "Source yielded an uninspected content placement"
4452
4802
  );
@@ -4473,9 +4823,9 @@ async function createSelectedMeshConversionSource(inspection, options) {
4473
4823
  }
4474
4824
  });
4475
4825
  const metadata = await meshSource.inspect(signal2);
4476
- const selectedContext = (0, import_core33.createTiles3DConversionSpatialContext)(metadata.spatialReference);
4826
+ const selectedContext = (0, import_core35.createTiles3DConversionSpatialContext)(metadata.spatialReference);
4477
4827
  if (selectedContext.spatialReference.coordinateEpoch !== spatialContext.spatialReference.coordinateEpoch)
4478
- throw new import_core33.TileConversionError(
4828
+ throw new import_core35.TileConversionError(
4479
4829
  "MESH_SOURCE_EPOCH_MISMATCH",
4480
4830
  "Selected content coordinate epoch must match the root; epoch transformations are unsupported"
4481
4831
  );
@@ -4486,7 +4836,7 @@ async function createSelectedMeshConversionSource(inspection, options) {
4486
4836
  throw new Error("Selected contents exceed the mesh primitive placement limit.");
4487
4837
  decodedBytes += measureMeshBytes(resource);
4488
4838
  if (decodedBytes > maxInputBytes)
4489
- throw new import_core33.TileConversionError(
4839
+ throw new import_core35.TileConversionError(
4490
4840
  "INPUT_RESOURCE_TOO_LARGE",
4491
4841
  "Selected decoded geometry and encoded images exceed the aggregate input byte limit."
4492
4842
  );
@@ -4513,7 +4863,7 @@ async function createSelectedMeshConversionSource(inspection, options) {
4513
4863
  geometricError: Math.max(...selections.map((selection) => selection.geometricError)) + SELECTED_MESH_LIMITS.maxPositionError
4514
4864
  };
4515
4865
  }
4516
- var SelectedTiles3DSource = class extends import_tiles4.Tiles3DSource {
4866
+ var SelectedTiles3DSource = class extends import_tiles_3d4.Tiles3DSource {
4517
4867
  /** Parent frame; explicit, unknown or unresolved child declarations are never replaced. */
4518
4868
  inheritedSpatialReference;
4519
4869
  /** Creates a selected source with optional external-document frame inheritance. */
@@ -4560,23 +4910,23 @@ function createSelectedRuntime(document, data, signal, boundedFetcher, contentUr
4560
4910
  },
4561
4911
  "3d-tiles": { loadGLTF: true }
4562
4912
  };
4563
- return new import_tiles4.Tileset3D(
4913
+ return new import_tiles_3d4.Tileset3D(
4564
4914
  new SelectedTiles3DSource(
4565
4915
  {
4566
4916
  url: contentUrl,
4567
4917
  loader: import_d_tiles2.Tiles3DLoader,
4568
4918
  resolver: {
4569
4919
  /** Normalizes the selected hierarchy through the format loader, retaining ancestor transforms. */
4570
- loadRoot: async (_url, loader, options) => (0, import_core32.parse)(new TextEncoder().encode(JSON.stringify(document)), loader, options),
4920
+ loadRoot: async (_url, loader, options) => (0, import_core34.parse)(new TextEncoder().encode(JSON.stringify(document)), loader, options),
4571
4921
  /** Decodes only the selected bounded payload; no sibling content can be requested. */
4572
4922
  loadResource: async (_url, loader, options) => {
4573
4923
  signal.throwIfAborted();
4574
- return (0, import_core32.parse)(data, loader, options, {
4924
+ return (0, import_core34.parse)(data, loader, options, {
4575
4925
  url: contentUrl,
4576
4926
  baseUrl: contentUrl.startsWith("blob:") ? contentUrl : new URL(".", contentUrl).href,
4577
4927
  fetch: boundedFetcher,
4578
- coreApi: import_core32.coreApi,
4579
- _parse: import_core32.parse
4928
+ coreApi: import_core34.coreApi,
4929
+ _parse: import_core34.parse
4580
4930
  });
4581
4931
  }
4582
4932
  }
@@ -4601,14 +4951,14 @@ function measureMeshBytes(resource) {
4601
4951
  }
4602
4952
 
4603
4953
  // src/v5/archive-source.ts
4604
- var import_loader_utils = require("@loaders.gl/loader-utils");
4605
- var import_i3s3 = require("@loaders.gl/i3s");
4606
- var import_d_tiles3 = require("@loaders.gl/3d-tiles");
4607
- var import_core34 = require("@loaders.gl/tile-converter/v5/core");
4954
+ var import_loader_utils = require("@loaders.gl/core/loader-utils");
4955
+ var import_i3s3 = require("@loaders.gl/tiles-3d/i3s");
4956
+ var import_d_tiles3 = require("@loaders.gl/tiles-3d/3d-tiles");
4957
+ var import_core36 = require("@loaders.gl/tile-converter/v5/core");
4608
4958
  async function openTileConversionArchive(descriptor, maxInputBytes, signal, fetcher = fetch) {
4609
4959
  signal.throwIfAborted();
4610
4960
  if (!["slpk", "3tz"].includes(descriptor.format))
4611
- throw new import_core34.TileConversionError("INVALID_ARCHIVE_SOURCE", "Select SLPK or 3TZ archive input");
4961
+ throw new import_core36.TileConversionError("INVALID_ARCHIVE_SOURCE", "Select SLPK or 3TZ archive input");
4612
4962
  validateArchiveEntityTag(descriptor.identity?.etag);
4613
4963
  const transport = createTileConversionResourceFetcher({
4614
4964
  maxInputBytes,
@@ -4675,12 +5025,12 @@ async function createTileConversionArchiveTransport(file, format, maxInputBytes,
4675
5025
  const checkOpen = () => {
4676
5026
  signal.throwIfAborted();
4677
5027
  if (closed)
4678
- throw new import_core34.TileConversionError("ARCHIVE_SOURCE_CLOSED", "Conversion archive is closed");
5028
+ throw new import_core36.TileConversionError("ARCHIVE_SOURCE_CLOSED", "Conversion archive is closed");
4679
5029
  };
4680
5030
  try {
4681
5031
  checkOpen();
4682
5032
  if (!["slpk", "3tz"].includes(format) || !Number.isSafeInteger(maxInputBytes) || maxInputBytes < 1)
4683
- throw new import_core34.TileConversionError(
5033
+ throw new import_core36.TileConversionError(
4684
5034
  "INVALID_ARCHIVE_SOURCE",
4685
5035
  "Archive source requires a supported format and positive safe byte budget"
4686
5036
  );
@@ -4698,7 +5048,7 @@ async function createTileConversionArchiveTransport(file, format, maxInputBytes,
4698
5048
  read: async (start, length) => {
4699
5049
  checkOpen();
4700
5050
  if (!Number.isSafeInteger(length) || length < 0 || length > maxInputBytes - readBytes)
4701
- throw new import_core34.TileConversionError(
5051
+ throw new import_core36.TileConversionError(
4702
5052
  "INPUT_RESOURCE_TOO_LARGE",
4703
5053
  "Archive indexed reads exceed the input budget"
4704
5054
  );
@@ -4747,7 +5097,7 @@ async function createTileConversionArchiveTransport(file, format, maxInputBytes,
4747
5097
  }
4748
5098
  function validateArchiveEntityTag(entityTag) {
4749
5099
  if (entityTag !== void 0 && entityTag !== null && !/^"[\x21\x23-\x7e\x80-\xff]*"$/.test(entityTag))
4750
- throw new import_core34.TileConversionError(
5100
+ throw new import_core36.TileConversionError(
4751
5101
  "ARCHIVE_VALIDATOR_UNSUPPORTED",
4752
5102
  "Remote archives require a strong quoted ETag, or Last-Modified without an ETag; weak/malformed ETags are unsupported"
4753
5103
  );
@@ -4761,7 +5111,7 @@ function validateArchiveResponseValidator(headers) {
4761
5111
  const modifiedTime = parseArchiveHttpDate(lastModified);
4762
5112
  const responseTime = parseArchiveHttpDate(responseDate);
4763
5113
  if (!Number.isFinite(modifiedTime) || !Number.isFinite(responseTime) || responseTime - modifiedTime < 6e4)
4764
- throw new import_core34.TileConversionError(
5114
+ throw new import_core36.TileConversionError(
4765
5115
  "ARCHIVE_VALIDATOR_UNSUPPORTED",
4766
5116
  "Last-Modified archive identity requires a valid Date at least 60 seconds later; otherwise supply a strong ETag"
4767
5117
  );
@@ -4772,10 +5122,10 @@ function parseArchiveHttpDate(value) {
4772
5122
  }
4773
5123
 
4774
5124
  // src/v5/i3s-selection-source.ts
4775
- var import_core35 = require("@loaders.gl/core");
4776
- var import_i3s4 = require("@loaders.gl/i3s");
4777
- var import_tiles5 = require("@loaders.gl/tiles");
4778
- var import_core36 = require("@loaders.gl/tile-converter/v5/core");
5125
+ var import_core37 = require("@loaders.gl/core");
5126
+ var import_i3s4 = require("@loaders.gl/tiles-3d/i3s");
5127
+ var import_tiles_3d5 = require("@loaders.gl/tiles-3d");
5128
+ var import_core38 = require("@loaders.gl/tile-converter/v5/core");
4779
5129
  function createRuntime(transport, layer, header) {
4780
5130
  const libraries = transport.dracoLibraryOptions;
4781
5131
  const sourceUrl = new URL(transport.rootUrl);
@@ -4798,14 +5148,14 @@ function createRuntime(transport, layer, header) {
4798
5148
  const contextUrl = new URL(url);
4799
5149
  contextUrl.search = "";
4800
5150
  contextUrl.hash = "";
4801
- return (0, import_core35.parse)(await response.arrayBuffer(), loader, loadOptions, {
5151
+ return (0, import_core37.parse)(await response.arrayBuffer(), loader, loadOptions, {
4802
5152
  url: contextUrl.href,
4803
5153
  fetch: transport.fetcher,
4804
- coreApi: import_core35.coreApi,
4805
- _parse: import_core35.parse
5154
+ coreApi: import_core37.coreApi,
5155
+ _parse: import_core37.parse
4806
5156
  });
4807
5157
  };
4808
- const source = new import_tiles5.I3SSource(
5158
+ const source = new import_tiles_3d5.I3SSource(
4809
5159
  header && layer ? {
4810
5160
  ...layer,
4811
5161
  root: { ...header, children: [] },
@@ -4813,17 +5163,17 @@ function createRuntime(transport, layer, header) {
4813
5163
  url: sourceUrl.href,
4814
5164
  basePath: sourceUrl.href,
4815
5165
  loader: import_i3s4.I3SLoader,
4816
- coreApi: import_core35.coreApi
5166
+ coreApi: import_core37.coreApi
4817
5167
  } : {
4818
5168
  url: sourceUrl.href,
4819
5169
  loader: import_i3s4.I3SLoader,
4820
- coreApi: import_core35.coreApi,
5170
+ coreApi: import_core37.coreApi,
4821
5171
  resolver: { loadRoot: loadResource, loadResource }
4822
5172
  },
4823
5173
  options
4824
5174
  );
4825
- source.coreApi = { ...import_core35.coreApi, load: loadResource };
4826
- return new import_tiles5.Tileset3D(source, { i3s: options.i3s });
5175
+ source.coreApi = { ...import_core37.coreApi, load: loadResource };
5176
+ return new import_tiles_3d5.Tileset3D(source, { i3s: options.i3s });
4827
5177
  }
4828
5178
  async function inspectI3SMeshConversionSource(options) {
4829
5179
  const { signal } = options;
@@ -4886,7 +5236,7 @@ async function createSelectedI3SMeshConversionSource(inspection, options) {
4886
5236
  validateSelectionOptions(options);
4887
5237
  signal.throwIfAborted();
4888
5238
  if (inspection.rootUrl !== options.rootUrl)
4889
- throw new import_core36.TileConversionError(
5239
+ throw new import_core38.TileConversionError(
4890
5240
  "INVALID_I3S_SELECTION",
4891
5241
  "Selection transport must match the inspected layer"
4892
5242
  );
@@ -4910,7 +5260,7 @@ async function createSelectedI3SMeshConversionSource(inspection, options) {
4910
5260
  try {
4911
5261
  await qualification.tilesetInitializationPromise;
4912
5262
  const metadata = await createI3SMeshTilesetConversionSource(qualification).inspect(signal);
4913
- spatialContext = (0, import_core36.createI3SConversionSpatialContext)(metadata.spatialReference, {
5263
+ spatialContext = (0, import_core38.createI3SConversionSpatialContext)(metadata.spatialReference, {
4914
5264
  targetCrs: "EPSG:4978"
4915
5265
  });
4916
5266
  } finally {
@@ -4936,7 +5286,7 @@ async function createSelectedI3SMeshConversionSource(inspection, options) {
4936
5286
  for await (const resource of meshSource.read(metadata, signal)) {
4937
5287
  decodedBytes += measureMeshBytes(resource);
4938
5288
  if (++meshCount > SELECTED_MESH_LIMITS.maxMeshResources || decodedBytes > (options.maxInputBytes ?? SELECTED_MESH_LIMITS.maxInputBytes))
4939
- throw new import_core36.TileConversionError(
5289
+ throw new import_core38.TileConversionError(
4940
5290
  "INPUT_RESOURCE_TOO_LARGE",
4941
5291
  "Selected I3S decoded resources exceed the input/mesh budget"
4942
5292
  );
@@ -4963,7 +5313,7 @@ function validateSelectionOptions(options) {
4963
5313
  ]
4964
5314
  ])
4965
5315
  if (!Number.isSafeInteger(value) || value < 1 || value > maximum)
4966
- throw new import_core36.TileConversionError(
5316
+ throw new import_core38.TileConversionError(
4967
5317
  "INVALID_I3S_SELECTION_LIMIT",
4968
5318
  "I3S selection limits must be positive safe integers within the bounded profile"
4969
5319
  );