@itwin/core-frontend 3.0.0-dev.170 → 3.0.0-dev.175

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.
@@ -102,6 +102,12 @@ function getNodeMeshIds(node) {
102
102
  return [node.mesh];
103
103
  return [];
104
104
  }
105
+ /** GL states that can be enabled by a [[GltfTechnique]]. Only those queried by this implementation are enumerated. */
106
+ var GltfTechniqueState;
107
+ (function (GltfTechniqueState) {
108
+ /** Enables alpha blending. */
109
+ GltfTechniqueState[GltfTechniqueState["Blend"] = 3042] = "Blend";
110
+ })(GltfTechniqueState || (GltfTechniqueState = {}));
105
111
  function isGltf1Material(material) {
106
112
  const mat1 = material;
107
113
  return undefined !== mat1.technique || undefined !== mat1.values;
@@ -289,21 +295,23 @@ const emptyDict = {};
289
295
  function colorFromJson(values) {
290
296
  return core_common_1.ColorDef.from(values[0] * 255, values[1] * 255, values[2] * 255, (1.0 - values[3]) * 255);
291
297
  }
292
- function colorFromMaterial(material) {
298
+ function colorFromMaterial(material, isTransparent) {
293
299
  var _a, _b, _c, _d, _e;
294
- if (material) {
295
- if (isGltf1Material(material)) {
296
- if (((_a = material.values) === null || _a === void 0 ? void 0 : _a.color) && Array.isArray(material.values.color))
297
- return colorFromJson(material.values.color);
298
- }
299
- else if ((_d = (_c = (_b = material.extensions) === null || _b === void 0 ? void 0 : _b.KHR_techniques_webgl) === null || _c === void 0 ? void 0 : _c.values) === null || _d === void 0 ? void 0 : _d.u_color) {
300
- return colorFromJson(material.extensions.KHR_techniques_webgl.values.u_color);
301
- }
302
- else if ((_e = material.pbrMetallicRoughness) === null || _e === void 0 ? void 0 : _e.baseColorFactor) {
303
- return colorFromJson(material.pbrMetallicRoughness.baseColorFactor);
304
- }
300
+ let color = core_common_1.ColorDef.white;
301
+ if (isGltf1Material(material)) {
302
+ if (((_a = material.values) === null || _a === void 0 ? void 0 : _a.color) && Array.isArray(material.values.color))
303
+ color = colorFromJson(material.values.color);
304
+ }
305
+ else if ((_d = (_c = (_b = material.extensions) === null || _b === void 0 ? void 0 : _b.KHR_techniques_webgl) === null || _c === void 0 ? void 0 : _c.values) === null || _d === void 0 ? void 0 : _d.u_color) {
306
+ color = colorFromJson(material.extensions.KHR_techniques_webgl.values.u_color);
307
+ }
308
+ else if ((_e = material.pbrMetallicRoughness) === null || _e === void 0 ? void 0 : _e.baseColorFactor) {
309
+ color = colorFromJson(material.pbrMetallicRoughness.baseColorFactor);
305
310
  }
306
- return core_common_1.ColorDef.white;
311
+ // SPEC: Opaque materials ignore any alpha channel.
312
+ if (!isTransparent)
313
+ color = color.withTransparency(0);
314
+ return color;
307
315
  }
308
316
  class TransformStack {
309
317
  constructor() {
@@ -357,12 +365,25 @@ function* traverseNodes(ids, nodes, traversed) {
357
365
  yield child;
358
366
  }
359
367
  }
368
+ function compareTextureKeys(lhs, rhs) {
369
+ const cmp = (0, core_bentley_1.compareBooleans)(lhs.isTransparent, rhs.isTransparent);
370
+ if (0 !== cmp)
371
+ return cmp;
372
+ (0, core_bentley_1.assert)(typeof lhs.id === typeof rhs.id);
373
+ if ("string" === typeof lhs.id) {
374
+ (0, core_bentley_1.assert)("string" === typeof rhs.id);
375
+ return (0, core_bentley_1.compareStrings)(lhs.id, rhs.id);
376
+ }
377
+ (0, core_bentley_1.assert)("number" === typeof lhs.id && "number" === typeof rhs.id);
378
+ return (0, core_bentley_1.compareNumbers)(lhs.id, rhs.id);
379
+ }
360
380
  /** Deserializes [glTF](https://www.khronos.org/gltf/).
361
381
  * @internal
362
382
  */
363
383
  class GltfReader {
364
384
  constructor(args) {
365
385
  var _a, _b, _c, _d, _e, _f, _g;
386
+ this._resolvedTextures = new core_bentley_1.Dictionary((lhs, rhs) => compareTextureKeys(lhs, rhs));
366
387
  this._glTF = args.props.glTF;
367
388
  this._version = args.props.version;
368
389
  this._yAxisUp = args.props.yAxisUp;
@@ -660,22 +681,41 @@ class GltfReader {
660
681
  }
661
682
  }
662
683
  }
663
- const id = extractId((_g = material.emissiveTexture) === null || _g === void 0 ? void 0 : _g.index);
664
- return id !== null && id !== void 0 ? id : extractId((_j = (_h = material.pbrMetallicRoughness) === null || _h === void 0 ? void 0 : _h.baseColorTexture) === null || _j === void 0 ? void 0 : _j.index);
684
+ const id = extractId((_h = (_g = material.pbrMetallicRoughness) === null || _g === void 0 ? void 0 : _g.baseColorTexture) === null || _h === void 0 ? void 0 : _h.index);
685
+ return id !== null && id !== void 0 ? id : extractId((_j = material.emissiveTexture) === null || _j === void 0 ? void 0 : _j.index);
686
+ }
687
+ isMaterialTransparent(material) {
688
+ var _a, _b;
689
+ if (isGltf1Material(material)) {
690
+ if (this._glTF.techniques && undefined !== material.technique) {
691
+ const technique = this._glTF.techniques[material.technique];
692
+ if ((_b = (_a = technique === null || technique === void 0 ? void 0 : technique.states) === null || _a === void 0 ? void 0 : _a.enable) === null || _b === void 0 ? void 0 : _b.some((state) => state === GltfTechniqueState.Blend))
693
+ return true;
694
+ }
695
+ return false;
696
+ }
697
+ else {
698
+ // Default: OPAQUE.
699
+ // ###TODO support MASK. For now treat as opaque.
700
+ return "BLEND" === material.alphaMode;
701
+ }
665
702
  }
666
- createDisplayParams(materialJson, hasBakedLighting) {
667
- const textureId = this.extractTextureId(materialJson);
668
- const textureMapping = undefined !== textureId ? this.findTextureMapping(textureId) : undefined;
669
- const color = colorFromMaterial(materialJson);
703
+ createDisplayParams(material, hasBakedLighting) {
704
+ const isTransparent = this.isMaterialTransparent(material);
705
+ const textureId = this.extractTextureId(material);
706
+ const textureMapping = undefined !== textureId ? this.findTextureMapping(textureId, isTransparent) : undefined;
707
+ const color = colorFromMaterial(material, isTransparent);
670
708
  return new DisplayParams_1.DisplayParams(DisplayParams_1.DisplayParams.Type.Mesh, color, color, 1, core_common_1.LinePixels.Solid, core_common_1.FillFlags.Always, undefined, undefined, hasBakedLighting, textureMapping);
671
709
  }
672
710
  readMeshPrimitive(primitive, featureTable, pseudoRtcBias) {
673
- var _a, _b, _c, _d, _e, _f;
711
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
674
712
  const materialName = core_bentley_1.JsonUtils.asString(primitive.material);
675
- const hasBakedLighting = undefined === primitive.attributes.NORMAL;
676
713
  const material = 0 < materialName.length ? this._materials[materialName] : undefined;
714
+ if (!material)
715
+ return undefined;
716
+ const hasBakedLighting = undefined === primitive.attributes.NORMAL || undefined !== ((_a = material.extensions) === null || _a === void 0 ? void 0 : _a.KHR_materials_unlit);
677
717
  const displayParams = material ? this.createDisplayParams(material, hasBakedLighting) : undefined;
678
- if (undefined === displayParams)
718
+ if (!displayParams)
679
719
  return undefined;
680
720
  let primitiveType = -1;
681
721
  const meshMode = core_bentley_1.JsonUtils.asInt(primitive.mode, GltfMeshMode.Triangles);
@@ -713,9 +753,9 @@ class GltfReader {
713
753
  if (undefined !== colorIndices && material) {
714
754
  let texStep;
715
755
  if (isGltf1Material(material))
716
- texStep = (_a = material.values) === null || _a === void 0 ? void 0 : _a.texStep;
756
+ texStep = (_b = material.values) === null || _b === void 0 ? void 0 : _b.texStep;
717
757
  else
718
- texStep = (_d = (_c = (_b = material.extensions) === null || _b === void 0 ? void 0 : _b.KHR_techniques_webgl) === null || _c === void 0 ? void 0 : _c.values) === null || _d === void 0 ? void 0 : _d.u_texStep;
758
+ texStep = (_e = (_d = (_c = material.extensions) === null || _c === void 0 ? void 0 : _c.KHR_techniques_webgl) === null || _d === void 0 ? void 0 : _d.values) === null || _e === void 0 ? void 0 : _e.u_texStep;
719
759
  if (texStep) {
720
760
  const uvParams = [];
721
761
  for (let i = 0; i < colorIndices.count; i++)
@@ -725,7 +765,7 @@ class GltfReader {
725
765
  mesh.uvQParams = paramList.params;
726
766
  }
727
767
  }
728
- if ((_e = primitive.extensions) === null || _e === void 0 ? void 0 : _e.KHR_draco_mesh_compression) {
768
+ if ((_f = primitive.extensions) === null || _f === void 0 ? void 0 : _f.KHR_draco_mesh_compression) {
729
769
  return undefined; // Defer Draco decompression until web workers implementation.
730
770
  /*
731
771
  const dracoExtension = primitive.extensions.KHR_draco_mesh_compression;
@@ -744,8 +784,12 @@ class GltfReader {
744
784
  return undefined;
745
785
  if (!displayParams.ignoreLighting && !this.readNormals(mesh, primitive.attributes, "NORMAL"))
746
786
  return undefined;
747
- if (!mesh.uvs)
748
- this.readUVParams(mesh, primitive.attributes, "TEXCOORD_0");
787
+ if (!mesh.uvs) {
788
+ let texCoordIndex = 0;
789
+ if (!isGltf1Material(material) && undefined !== ((_h = (_g = material.pbrMetallicRoughness) === null || _g === void 0 ? void 0 : _g.baseColorTexture) === null || _h === void 0 ? void 0 : _h.texCoord))
790
+ texCoordIndex = core_bentley_1.JsonUtils.asInt(material.pbrMetallicRoughness.baseColorTexture.texCoord);
791
+ this.readUVParams(mesh, primitive.attributes, `TEXCOORD_${texCoordIndex}`);
792
+ }
749
793
  if (this._deduplicateVertices && !this.deduplicateVertices(mesh))
750
794
  return undefined;
751
795
  break;
@@ -763,7 +807,7 @@ class GltfReader {
763
807
  }
764
808
  if (displayParams.textureMapping && !mesh.uvs)
765
809
  return undefined;
766
- if ((_f = primitive.extensions) === null || _f === void 0 ? void 0 : _f.CESIUM_primitive_outline) {
810
+ if ((_j = primitive.extensions) === null || _j === void 0 ? void 0 : _j.CESIUM_primitive_outline) {
767
811
  const data = this.readBufferData32(primitive.extensions.CESIUM_primitive_outline, "indices");
768
812
  if (data !== undefined) {
769
813
  (0, core_bentley_1.assert)(0 === data.count % 2);
@@ -782,6 +826,8 @@ class GltfReader {
782
826
  const indices = mesh.indices;
783
827
  if (indices instanceof Uint16Array && numPoints > 0xffff)
784
828
  mesh.indices = new Uint32Array(numPoints);
829
+ else if (indices instanceof Uint8Array && numPoints > 0xff)
830
+ mesh.indices = new Uint32Array(numPoints);
785
831
  const points = new Uint16Array(3 * numPoints);
786
832
  const normals = mesh.normals ? new Uint16Array(numPoints) : undefined;
787
833
  const uvs = mesh.uvs ? new Uint16Array(2 * numPoints) : undefined;
@@ -882,10 +928,22 @@ class GltfReader {
882
928
  readBatchTable(_mesh, _json) {
883
929
  }
884
930
  readMeshIndices(mesh, json) {
885
- const data = this.readBufferData16(json, "indices") || this.readBufferData32(json, "indices");
886
- if (undefined === data || (!(data.buffer instanceof (Uint16Array)) && !(data.buffer instanceof (Uint32Array))))
931
+ var _a;
932
+ if (undefined !== json.indices) {
933
+ const data = this.readBufferData16(json, "indices") || this.readBufferData32(json, "indices");
934
+ if (data && (data.buffer instanceof Uint8Array || data.buffer instanceof Uint16Array || data.buffer instanceof Uint32Array)) {
935
+ mesh.indices = data.buffer;
936
+ return true;
937
+ }
938
+ return false;
939
+ }
940
+ // Non-indexed geometry. Manufacture triangle indices from points.
941
+ const numPoints = (_a = mesh.points) === null || _a === void 0 ? void 0 : _a.length;
942
+ if (undefined === numPoints || 0 !== numPoints % 3)
887
943
  return false;
888
- mesh.indices = data.buffer;
944
+ mesh.indices = numPoints < 255 ? new Uint8Array(numPoints) : (numPoints < 0xffff ? new Uint16Array(numPoints) : new Uint32Array(numPoints));
945
+ for (let i = 0; i < numPoints; i++)
946
+ mesh.indices[i] = i;
889
947
  return true;
890
948
  }
891
949
  readNormals(mesh, json, accessorName) {
@@ -1023,9 +1081,6 @@ class GltfReader {
1023
1081
  if (!image.resolvedImage)
1024
1082
  promises.push(this.resolveImage(image));
1025
1083
  await Promise.all(promises);
1026
- if (this._isCanceled)
1027
- return;
1028
- this.resolveTextures();
1029
1084
  }
1030
1085
  catch (_) {
1031
1086
  }
@@ -1083,64 +1138,33 @@ class GltfReader {
1083
1138
  if (undefined !== url)
1084
1139
  image.resolvedImage = await (0, ImageUtil_1.tryImageElementFromUrl)(url);
1085
1140
  }
1086
- resolveTextures() {
1087
- var _a, _b;
1088
- if (undefined === this._glTF.textures)
1089
- return;
1090
- // ###TODO this seems pretty hacky, and won't work for glTF 2.0 even if the KHR_techniques_webgl extension is used...
1091
- const transparentTextures = new Set();
1092
- if (this._glTF.techniques) {
1093
- for (const name of Object.keys(this._materials)) {
1094
- const material = this._materials[name];
1095
- if (material && isGltf1Material(material) && undefined !== material.technique && undefined !== ((_a = material.values) === null || _a === void 0 ? void 0 : _a.tex)) {
1096
- const technique = this._glTF.techniques[material.technique];
1097
- if ((_b = technique === null || technique === void 0 ? void 0 : technique.states) === null || _b === void 0 ? void 0 : _b.enable) {
1098
- for (const enable of technique.states.enable) {
1099
- if (3042 === enable) { // 3042 = BLEND
1100
- transparentTextures.add(material.values.tex.toString());
1101
- break;
1102
- }
1103
- }
1104
- }
1105
- }
1106
- }
1107
- }
1108
- for (const node of this.traverseScene()) {
1109
- for (const meshId of getNodeMeshIds(node)) {
1110
- const mesh = this._meshes[meshId];
1111
- if (!(mesh === null || mesh === void 0 ? void 0 : mesh.primitives))
1112
- continue;
1113
- for (const primitive of mesh.primitives) {
1114
- const material = undefined !== primitive.material ? this._materials[primitive.material] : undefined;
1115
- const textureId = material ? this.extractTextureId(material) : undefined;
1116
- if (undefined !== textureId)
1117
- this.resolveTexture(textureId, transparentTextures.has(textureId));
1118
- }
1119
- }
1120
- }
1121
- }
1122
1141
  resolveTexture(textureId, isTransparent) {
1123
1142
  var _a;
1124
1143
  const texture = this._textures[textureId];
1125
- if (!texture || texture.resolvedTexture || undefined === texture.source)
1126
- return;
1144
+ if (!texture || undefined === texture.source)
1145
+ return false;
1127
1146
  const image = (_a = this._images[texture.source]) === null || _a === void 0 ? void 0 : _a.resolvedImage;
1128
1147
  if (!image)
1129
- return;
1148
+ return false;
1130
1149
  const samplerId = texture.sampler;
1131
1150
  const sampler = undefined !== samplerId ? this._samplers[samplerId] : undefined;
1132
- const textureType = undefined !== (sampler === null || sampler === void 0 ? void 0 : sampler.wrapS) || undefined !== (sampler === null || sampler === void 0 ? void 0 : sampler.wrapT) ? core_common_1.RenderTexture.Type.TileSection : core_common_1.RenderTexture.Type.Normal;
1133
- texture.resolvedTexture = this._system.createTexture({
1151
+ // ###TODO: RenderTexture should support different wrapping behavior for U vs V, and support mirrored repeat.
1152
+ // For now, repeat unless either explicitly clamps.
1153
+ const textureType = GltfWrapMode.ClampToEdge === (sampler === null || sampler === void 0 ? void 0 : sampler.wrapS) || GltfWrapMode.ClampToEdge === (sampler === null || sampler === void 0 ? void 0 : sampler.wrapT) ? core_common_1.RenderTexture.Type.TileSection : core_common_1.RenderTexture.Type.Normal;
1154
+ const renderTexture = this._system.createTexture({
1134
1155
  type: textureType,
1135
1156
  image: {
1136
1157
  source: image,
1137
1158
  transparency: isTransparent ? RenderTexture_1.TextureTransparency.Translucent : RenderTexture_1.TextureTransparency.Opaque,
1138
1159
  },
1139
1160
  });
1161
+ return renderTexture !== null && renderTexture !== void 0 ? renderTexture : false;
1140
1162
  }
1141
- findTextureMapping(textureId) {
1142
- const texture = this._textures[textureId];
1143
- return (texture === null || texture === void 0 ? void 0 : texture.resolvedTexture) ? new core_common_1.TextureMapping(texture.resolvedTexture, new core_common_1.TextureMapping.Params()) : undefined;
1163
+ findTextureMapping(id, isTransparent) {
1164
+ let texture = this._resolvedTextures.get({ id, isTransparent });
1165
+ if (undefined === texture)
1166
+ this._resolvedTextures.set({ id, isTransparent }, texture = this.resolveTexture(id, isTransparent));
1167
+ return texture ? new core_common_1.TextureMapping(texture, new core_common_1.TextureMapping.Params()) : undefined;
1144
1168
  }
1145
1169
  }
1146
1170
  exports.GltfReader = GltfReader;