@itwin/core-frontend 4.6.0-dev.3 → 4.6.0-dev.6

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 (32) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/lib/cjs/common/gltf/GltfSchema.d.ts +24 -0
  3. package/lib/cjs/common/gltf/GltfSchema.d.ts.map +1 -1
  4. package/lib/cjs/common/gltf/GltfSchema.js.map +1 -1
  5. package/lib/cjs/tile/GltfReader.d.ts +4 -2
  6. package/lib/cjs/tile/GltfReader.d.ts.map +1 -1
  7. package/lib/cjs/tile/GltfReader.js +92 -20
  8. package/lib/cjs/tile/GltfReader.js.map +1 -1
  9. package/lib/cjs/tile/MeshoptCompression.d.ts +16 -0
  10. package/lib/cjs/tile/MeshoptCompression.d.ts.map +1 -0
  11. package/lib/cjs/tile/MeshoptCompression.js +93 -0
  12. package/lib/cjs/tile/MeshoptCompression.js.map +1 -0
  13. package/lib/cjs/tile/internal.d.ts +1 -0
  14. package/lib/cjs/tile/internal.d.ts.map +1 -1
  15. package/lib/cjs/tile/internal.js +1 -0
  16. package/lib/cjs/tile/internal.js.map +1 -1
  17. package/lib/esm/common/gltf/GltfSchema.d.ts +24 -0
  18. package/lib/esm/common/gltf/GltfSchema.d.ts.map +1 -1
  19. package/lib/esm/common/gltf/GltfSchema.js.map +1 -1
  20. package/lib/esm/tile/GltfReader.d.ts +4 -2
  21. package/lib/esm/tile/GltfReader.d.ts.map +1 -1
  22. package/lib/esm/tile/GltfReader.js +92 -20
  23. package/lib/esm/tile/GltfReader.js.map +1 -1
  24. package/lib/esm/tile/MeshoptCompression.d.ts +16 -0
  25. package/lib/esm/tile/MeshoptCompression.d.ts.map +1 -0
  26. package/lib/esm/tile/MeshoptCompression.js +66 -0
  27. package/lib/esm/tile/MeshoptCompression.js.map +1 -0
  28. package/lib/esm/tile/internal.d.ts +1 -0
  29. package/lib/esm/tile/internal.d.ts.map +1 -1
  30. package/lib/esm/tile/internal.js +1 -0
  31. package/lib/esm/tile/internal.js.map +1 -1
  32. package/package.json +19 -18
@@ -13,6 +13,7 @@ import { GraphicBranch } from "../render/GraphicBranch";
13
13
  import { RealityMeshParams } from "../render/RealityMeshParams";
14
14
  import { Mesh } from "../render/primitives/mesh/MeshPrimitives";
15
15
  import { Triangle } from "../render/primitives/Primitives";
16
+ import { decodeMeshoptBuffer } from "./internal";
16
17
  import { DisplayParams } from "../common/render/primitives/DisplayParams";
17
18
  import { FrontendLoggerCategory } from "../common/FrontendLoggerCategory";
18
19
  import { getImageSourceFormatForMimeType, imageBitmapFromImageSource, imageElementFromImageSource, tryImageElementFromUrl } from "../common/ImageUtil";
@@ -581,10 +582,15 @@ export class GltfReader {
581
582
  return undefined;
582
583
  const bufferViewAccessorValue = accessor.bufferView;
583
584
  const bufferView = undefined !== bufferViewAccessorValue ? this._bufferViews[bufferViewAccessorValue] : undefined;
584
- if (!bufferView || undefined === bufferView.buffer)
585
+ if (!bufferView)
585
586
  return undefined;
586
- const buffer = this._buffers[bufferView.buffer];
587
- const bufferData = buffer?.resolvedBuffer;
587
+ let bufferData = bufferView.resolvedBuffer;
588
+ if (!bufferData) {
589
+ if (undefined === bufferView.buffer)
590
+ return undefined;
591
+ const buffer = this._buffers[bufferView.buffer];
592
+ bufferData = buffer?.resolvedBuffer;
593
+ }
588
594
  if (!bufferData)
589
595
  return undefined;
590
596
  const type = accessor.componentType;
@@ -791,7 +797,7 @@ export class GltfReader {
791
797
  readMeshPrimitive(primitive, featureTable, pseudoRtcBias) {
792
798
  const meshMode = JsonUtils.asInt(primitive.mode, GltfMeshMode.Triangles);
793
799
  if (meshMode === GltfMeshMode.Points /* && !this._vertexTableRequired */) {
794
- const pointCloud = this.readPointCloud(primitive, undefined !== featureTable);
800
+ const pointCloud = this.readPointCloud2(primitive, undefined !== featureTable);
795
801
  if (pointCloud)
796
802
  return pointCloud;
797
803
  }
@@ -909,23 +915,60 @@ export class GltfReader {
909
915
  }
910
916
  return mesh;
911
917
  }
912
- readPointCloud(primitive, hasFeatures) {
918
+ readPointCloud2(primitive, hasFeatures) {
919
+ let pointRange;
920
+ let positions;
921
+ let qparams;
913
922
  const posView = this.getBufferView(primitive.attributes, "POSITION");
914
- if (!posView || GltfDataType.Float !== posView.type)
915
- return undefined;
916
- const posData = posView.toBufferData(GltfDataType.Float);
917
- if (!(posData?.buffer instanceof Float32Array))
918
- return undefined;
923
+ switch (posView?.type) {
924
+ case GltfDataType.Float: {
925
+ const posData = posView.toBufferData(GltfDataType.Float);
926
+ if (!(posData?.buffer instanceof Float32Array)) {
927
+ return undefined;
928
+ }
929
+ positions = posData.buffer;
930
+ const strideSkip = posView.stride - 3;
931
+ pointRange = new Range3d();
932
+ for (let i = 0; i < positions.length; i += strideSkip) {
933
+ pointRange.extendXYZ(positions[i++], positions[i++], positions[i++]);
934
+ }
935
+ qparams = QParams3d.fromOriginAndScale(new Point3d(0, 0, 0), new Point3d(1, 1, 1));
936
+ break;
937
+ }
938
+ case GltfDataType.UnsignedByte:
939
+ case GltfDataType.UnsignedShort: {
940
+ const posData = posView.toBufferData(posView.type);
941
+ if (!(posData?.buffer instanceof Uint8Array || posData?.buffer instanceof Uint16Array)) {
942
+ return undefined;
943
+ }
944
+ positions = posData.buffer;
945
+ let min, max;
946
+ const ext = posView.accessor.extensions?.WEB3D_quantized_attributes;
947
+ if (ext) {
948
+ min = ext.decodedMin;
949
+ max = ext.decodedMax;
950
+ }
951
+ else {
952
+ // Assume KHR_mesh_quantization...
953
+ min = posView.accessor.min;
954
+ max = posView.accessor.max;
955
+ }
956
+ if (undefined === min || undefined === max) {
957
+ return undefined;
958
+ }
959
+ pointRange = Range3d.createXYZXYZ(min[0], min[1], min[2], max[0], max[1], max[2]);
960
+ qparams = QParams3d.fromRange(pointRange);
961
+ break;
962
+ }
963
+ default:
964
+ return undefined;
965
+ }
919
966
  const colorView = this.getBufferView(primitive.attributes, "COLOR_0");
920
967
  if (!colorView || GltfDataType.UnsignedByte !== colorView.type)
921
968
  return undefined;
922
969
  const colorData = colorView.toBufferData(GltfDataType.UnsignedByte);
923
970
  if (!(colorData?.buffer instanceof Uint8Array))
924
971
  return undefined;
925
- const strideSkip = posView.stride - 3;
926
- const pointRange = new Range3d();
927
- for (let i = 0; i < posData.buffer.length; i += strideSkip)
928
- pointRange.extendXYZ(posData.buffer[i++], posData.buffer[i++], posData.buffer[i++]);
929
972
  let colors = colorData.buffer;
930
973
  if ("VEC4" === colorView.accessor.type) {
931
974
  // ###TODO support transparent point clouds
@@ -938,13 +981,14 @@ export class GltfReader {
938
981
  }
939
982
  }
940
983
  const features = new FeatureIndex();
941
- if (hasFeatures)
984
+ if (hasFeatures) {
942
985
  features.type = FeatureIndexType.Uniform;
986
+ }
943
987
  this._containsPointCloud = true;
944
988
  return {
945
989
  type: "pointcloud",
946
- positions: posData.buffer,
947
- qparams: QParams3d.fromOriginAndScale(new Point3d(0, 0, 0), new Point3d(1, 1, 1)),
990
+ positions,
991
+ qparams,
948
992
  pointRange,
949
993
  colors,
950
994
  colorFormat: "rgb",
@@ -1073,10 +1117,18 @@ export class GltfReader {
1073
1117
  else {
1074
1118
  if (GltfDataType.UnsignedShort !== view.type)
1075
1119
  return false;
1120
+ let rangeMin, rangeMax;
1076
1121
  const quantized = view.accessor.extensions?.WEB3D_quantized_attributes;
1077
- const rangeMin = quantized?.decodedMin;
1078
- const rangeMax = quantized?.decodedMax;
1079
- if (!rangeMin || !rangeMax) // required by spec...
1122
+ if (quantized) {
1123
+ rangeMin = quantized.decodedMin;
1124
+ rangeMax = quantized.decodedMax;
1125
+ }
1126
+ else {
1127
+ // Assume KHR_mesh_quantization...
1128
+ rangeMin = view.accessor.min;
1129
+ rangeMax = view.accessor.max;
1130
+ }
1131
+ if (undefined === rangeMin || undefined === rangeMax) // required by spec...
1080
1132
  return false;
1081
1133
  // ###TODO apply WEB3D_quantized_attributes.decodeMatrix? Have not encountered in the wild; glTF 1.0 only.
1082
1134
  const buffer = view.toBufferData(GltfDataType.UnsignedShort);
@@ -1276,6 +1328,26 @@ export class GltfReader {
1276
1328
  async resolveResources() {
1277
1329
  // Load any external images and buffers.
1278
1330
  await this._resolveResources();
1331
+ // Decompress any meshopt-compressed buffer views
1332
+ const decodeMeshoptBuffers = [];
1333
+ for (const bv of gltfDictionaryIterator(this._bufferViews)) {
1334
+ const ext = bv.extensions?.EXT_meshopt_compression;
1335
+ if (ext) {
1336
+ const bufferData = this._buffers[ext.buffer]?.resolvedBuffer;
1337
+ if (bufferData) {
1338
+ const source = new Uint8Array(bufferData.buffer, bufferData.byteOffset + (ext.byteOffset ?? 0), ext.byteLength ?? 0);
1339
+ const decode = async () => {
1340
+ bv.resolvedBuffer = await decodeMeshoptBuffer(source, ext);
1341
+ if (bv.resolvedBuffer) {
1342
+ bv.byteLength = bv.resolvedBuffer.byteLength;
1343
+ bv.byteOffset = 0;
1344
+ }
1345
+ };
1346
+ decodeMeshoptBuffers.push(decode());
1347
+ }
1348
+ }
1349
+ }
1350
+ await Promise.all(decodeMeshoptBuffers);
1279
1351
  // If any meshes are draco-compressed, dynamically load the decoder module and then decode the meshes.
1280
1352
  const dracoMeshes = [];
1281
1353
  for (const node of this.traverseScene()) {