@itwin/core-frontend 3.0.0-dev.156 → 3.0.0-dev.161

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 (49) hide show
  1. package/lib/cjs/Viewport.js +2 -2
  2. package/lib/cjs/Viewport.js.map +1 -1
  3. package/lib/cjs/render/GraphicBuilder.d.ts +1 -1
  4. package/lib/cjs/render/GraphicBuilder.js.map +1 -1
  5. package/lib/cjs/tile/B3dmReader.d.ts +1 -0
  6. package/lib/cjs/tile/B3dmReader.d.ts.map +1 -1
  7. package/lib/cjs/tile/B3dmReader.js +7 -3
  8. package/lib/cjs/tile/B3dmReader.js.map +1 -1
  9. package/lib/cjs/tile/GltfReader.d.ts +466 -34
  10. package/lib/cjs/tile/GltfReader.d.ts.map +1 -1
  11. package/lib/cjs/tile/GltfReader.js +425 -180
  12. package/lib/cjs/tile/GltfReader.js.map +1 -1
  13. package/lib/cjs/tile/I3dmReader.d.ts +1 -0
  14. package/lib/cjs/tile/I3dmReader.d.ts.map +1 -1
  15. package/lib/cjs/tile/I3dmReader.js +6 -2
  16. package/lib/cjs/tile/I3dmReader.js.map +1 -1
  17. package/lib/cjs/tile/ImdlReader.d.ts +334 -10
  18. package/lib/cjs/tile/ImdlReader.d.ts.map +1 -1
  19. package/lib/cjs/tile/ImdlReader.js +84 -44
  20. package/lib/cjs/tile/ImdlReader.js.map +1 -1
  21. package/lib/cjs/tile/map/MapTiledGraphicsProvider.d.ts +3 -3
  22. package/lib/cjs/tile/map/MapTiledGraphicsProvider.d.ts.map +1 -1
  23. package/lib/cjs/tile/map/MapTiledGraphicsProvider.js +4 -6
  24. package/lib/cjs/tile/map/MapTiledGraphicsProvider.js.map +1 -1
  25. package/lib/esm/Viewport.js +2 -2
  26. package/lib/esm/Viewport.js.map +1 -1
  27. package/lib/esm/render/GraphicBuilder.d.ts +1 -1
  28. package/lib/esm/render/GraphicBuilder.js.map +1 -1
  29. package/lib/esm/tile/B3dmReader.d.ts +1 -0
  30. package/lib/esm/tile/B3dmReader.d.ts.map +1 -1
  31. package/lib/esm/tile/B3dmReader.js +8 -4
  32. package/lib/esm/tile/B3dmReader.js.map +1 -1
  33. package/lib/esm/tile/GltfReader.d.ts +466 -34
  34. package/lib/esm/tile/GltfReader.d.ts.map +1 -1
  35. package/lib/esm/tile/GltfReader.js +400 -157
  36. package/lib/esm/tile/GltfReader.js.map +1 -1
  37. package/lib/esm/tile/I3dmReader.d.ts +1 -0
  38. package/lib/esm/tile/I3dmReader.d.ts.map +1 -1
  39. package/lib/esm/tile/I3dmReader.js +7 -3
  40. package/lib/esm/tile/I3dmReader.js.map +1 -1
  41. package/lib/esm/tile/ImdlReader.d.ts +334 -10
  42. package/lib/esm/tile/ImdlReader.d.ts.map +1 -1
  43. package/lib/esm/tile/ImdlReader.js +86 -46
  44. package/lib/esm/tile/ImdlReader.js.map +1 -1
  45. package/lib/esm/tile/map/MapTiledGraphicsProvider.d.ts +3 -3
  46. package/lib/esm/tile/map/MapTiledGraphicsProvider.d.ts.map +1 -1
  47. package/lib/esm/tile/map/MapTiledGraphicsProvider.js +4 -6
  48. package/lib/esm/tile/map/MapTiledGraphicsProvider.js.map +1 -1
  49. package/package.json +22 -22
@@ -7,34 +7,175 @@
7
7
  * @module Tiles
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.GltfReader = exports.GltfMeshData = exports.GltfReaderProps = void 0;
10
+ exports.readGltfGraphics = exports.GltfReader = exports.GltfMeshData = exports.GltfReaderProps = exports.GltfBufferData = exports.GltfDataType = void 0;
11
11
  const core_bentley_1 = require("@itwin/core-bentley");
12
12
  const core_geometry_1 = require("@itwin/core-geometry");
13
13
  const core_common_1 = require("@itwin/core-common");
14
14
  const ImageUtil_1 = require("../ImageUtil");
15
+ const IModelApp_1 = require("../IModelApp");
15
16
  const GraphicBranch_1 = require("../render/GraphicBranch");
16
17
  const DisplayParams_1 = require("../render/primitives/DisplayParams");
17
18
  const MeshPrimitives_1 = require("../render/primitives/mesh/MeshPrimitives");
18
19
  const RealityMeshPrimitive_1 = require("../render/primitives/mesh/RealityMeshPrimitive");
19
20
  const RenderTexture_1 = require("../render/RenderTexture");
20
- // eslint-disable-next-line prefer-const
21
- let forceLUT = false;
21
+ /* eslint-disable no-restricted-syntax */
22
+ /** Enumerates the types of [[GltfMeshPrimitive]] topologies. */
23
+ var GltfMeshMode;
24
+ (function (GltfMeshMode) {
25
+ GltfMeshMode[GltfMeshMode["Points"] = 0] = "Points";
26
+ GltfMeshMode[GltfMeshMode["Lines"] = 1] = "Lines";
27
+ GltfMeshMode[GltfMeshMode["LineStrip"] = 3] = "LineStrip";
28
+ GltfMeshMode[GltfMeshMode["Triangles"] = 4] = "Triangles";
29
+ /** Not currently supported. */
30
+ GltfMeshMode[GltfMeshMode["TriangleStrip"] = 5] = "TriangleStrip";
31
+ /** Not currently supported. */
32
+ GltfMeshMode[GltfMeshMode["TriangleFan"] = 6] = "TriangleFan";
33
+ })(GltfMeshMode || (GltfMeshMode = {}));
34
+ /** Enumerates the basic data types supported by accessors, material values, technique uniforms, etc.
35
+ * @internal
36
+ */
37
+ var GltfDataType;
38
+ (function (GltfDataType) {
39
+ GltfDataType[GltfDataType["SignedByte"] = 5120] = "SignedByte";
40
+ GltfDataType[GltfDataType["UnsignedByte"] = 5121] = "UnsignedByte";
41
+ GltfDataType[GltfDataType["SignedShort"] = 5122] = "SignedShort";
42
+ GltfDataType[GltfDataType["UnsignedShort"] = 5123] = "UnsignedShort";
43
+ GltfDataType[GltfDataType["UInt32"] = 5125] = "UInt32";
44
+ GltfDataType[GltfDataType["Float"] = 5126] = "Float";
45
+ GltfDataType[GltfDataType["Rgb"] = 6407] = "Rgb";
46
+ GltfDataType[GltfDataType["Rgba"] = 6408] = "Rgba";
47
+ GltfDataType[GltfDataType["IntVec2"] = 35667] = "IntVec2";
48
+ GltfDataType[GltfDataType["IntVec3"] = 35668] = "IntVec3";
49
+ GltfDataType[GltfDataType["FloatVec2"] = 35664] = "FloatVec2";
50
+ GltfDataType[GltfDataType["FloatVec3"] = 35665] = "FloatVec3";
51
+ GltfDataType[GltfDataType["FloatVec4"] = 35666] = "FloatVec4";
52
+ GltfDataType[GltfDataType["FloatMat3"] = 35675] = "FloatMat3";
53
+ GltfDataType[GltfDataType["FloatMat4"] = 35676] = "FloatMat4";
54
+ GltfDataType[GltfDataType["Sampler2d"] = 35678] = "Sampler2d";
55
+ })(GltfDataType = exports.GltfDataType || (exports.GltfDataType = {}));
56
+ /** @internal */
57
+ var GltfMagFilter;
58
+ (function (GltfMagFilter) {
59
+ GltfMagFilter[GltfMagFilter["Nearest"] = 9728] = "Nearest";
60
+ GltfMagFilter[GltfMagFilter["Linear"] = 9729] = "Linear";
61
+ })(GltfMagFilter || (GltfMagFilter = {}));
62
+ /** @internal */
63
+ var GltfMinFilter;
64
+ (function (GltfMinFilter) {
65
+ GltfMinFilter[GltfMinFilter["Nearest"] = 9728] = "Nearest";
66
+ GltfMinFilter[GltfMinFilter["Linear"] = 9729] = "Linear";
67
+ GltfMinFilter[GltfMinFilter["NearestMipMapNearest"] = 9984] = "NearestMipMapNearest";
68
+ GltfMinFilter[GltfMinFilter["LinearMipMapNearest"] = 9985] = "LinearMipMapNearest";
69
+ GltfMinFilter[GltfMinFilter["NearestMipMapLinear"] = 9986] = "NearestMipMapLinear";
70
+ GltfMinFilter[GltfMinFilter["LinearMipMapLinear"] = 9987] = "LinearMipMapLinear";
71
+ })(GltfMinFilter || (GltfMinFilter = {}));
72
+ /** Describes how texture coordinates outside of the range [0..1] are handled. */
73
+ var GltfWrapMode;
74
+ (function (GltfWrapMode) {
75
+ GltfWrapMode[GltfWrapMode["ClampToEdge"] = 33071] = "ClampToEdge";
76
+ GltfWrapMode[GltfWrapMode["MirroredRepeat"] = 33648] = "MirroredRepeat";
77
+ GltfWrapMode[GltfWrapMode["Repeat"] = 10497] = "Repeat";
78
+ })(GltfWrapMode || (GltfWrapMode = {}));
79
+ /** Describes the intended target of a [[GltfBufferViewProps]]. */
80
+ var GltfBufferTarget;
81
+ (function (GltfBufferTarget) {
82
+ GltfBufferTarget[GltfBufferTarget["ArrayBuffer"] = 34962] = "ArrayBuffer";
83
+ GltfBufferTarget[GltfBufferTarget["ElementArrayBuffer"] = 24963] = "ElementArrayBuffer";
84
+ })(GltfBufferTarget || (GltfBufferTarget = {}));
85
+ function getNodeMeshIds(node) {
86
+ if (undefined !== node.meshes)
87
+ return typeof node.meshes === "string" ? [node.meshes] : node.meshes;
88
+ else if (undefined !== node.mesh)
89
+ return [node.mesh];
90
+ return [];
91
+ }
92
+ function isGltf1Material(material) {
93
+ const mat1 = material;
94
+ return undefined !== mat1.technique || undefined !== mat1.values;
95
+ }
96
+ /**
97
+ * A chunk of binary data exposed as a typed array.
98
+ * The count member indicates how many elements exist. This may be less than this.buffer.length due to padding added to the
99
+ * binary stream to ensure correct alignment.
100
+ * @internal
101
+ */
102
+ class GltfBufferData {
103
+ constructor(buffer, count) {
104
+ this.buffer = buffer;
105
+ this.count = count;
106
+ }
107
+ /**
108
+ * Create a GltfBufferData of the desired type. The actual type may differ from the desired type - for example, small 32-bit integers
109
+ * may be represented as 8-bit or 16-bit integers instead.
110
+ * If the actual data type is not convertible to the desired type, this function returns undefined.
111
+ */
112
+ static create(bytes, actualType, expectedType, count) {
113
+ if (expectedType !== actualType) {
114
+ // Some data is stored in smaller data types to save space if no values exceed the maximum of the smaller type.
115
+ switch (expectedType) {
116
+ case GltfDataType.Float:
117
+ case GltfDataType.UnsignedByte:
118
+ return undefined;
119
+ case GltfDataType.UnsignedShort:
120
+ if (GltfDataType.UnsignedByte !== actualType)
121
+ return undefined;
122
+ break;
123
+ case GltfDataType.UInt32:
124
+ if (GltfDataType.UnsignedByte !== actualType && GltfDataType.UnsignedShort !== actualType)
125
+ return undefined;
126
+ break;
127
+ }
128
+ }
129
+ const data = this.createDataBuffer(bytes, actualType);
130
+ return undefined !== data ? new GltfBufferData(data, count) : undefined;
131
+ }
132
+ static createDataBuffer(bytes, actualType) {
133
+ // NB: Endianness of typed array data is determined by the 'platform byte order'. Actual data is always little-endian.
134
+ // We are assuming little-endian platform. If we find a big-endian platform, we'll need to use a DataView instead.
135
+ switch (actualType) {
136
+ case GltfDataType.UnsignedByte:
137
+ return bytes;
138
+ case GltfDataType.UnsignedShort:
139
+ return new Uint16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2);
140
+ case GltfDataType.UInt32:
141
+ return new Uint32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 4);
142
+ case GltfDataType.Float:
143
+ return new Float32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 4);
144
+ default:
145
+ return undefined;
146
+ }
147
+ }
148
+ }
149
+ exports.GltfBufferData = GltfBufferData;
150
+ /**
151
+ * A view of a chunk of glTF binary data containing an array of elements of a specific data type.
152
+ * The count member indicates how many elements exist; this may be smaller than this.data.length.
153
+ * The count member may also indicate the number of elements of a type containing more than one value of the
154
+ * underlying type. For example, a buffer of 4 32-bit floating point 'vec2' elements will have a count of 4,
155
+ * but its data member will contain 8 32-bit floating point values (2 per vec2).
156
+ * The accessor member may contain additional JSON data specific to a particular buffer.
157
+ * @internal
158
+ */
159
+ class GltfBufferView {
160
+ constructor(data, count, type, accessor, stride) {
161
+ this.data = data;
162
+ this.count = count;
163
+ this.type = type;
164
+ this.accessor = accessor;
165
+ this.stride = stride;
166
+ }
167
+ get byteLength() { return this.data.length; }
168
+ toBufferData(desiredType) {
169
+ return GltfBufferData.create(this.data, this.type, desiredType, this.count);
170
+ }
171
+ }
22
172
  /** Data required for creating a [[GltfReader]] capable of deserializing [glTF](https://www.khronos.org/gltf/).
23
173
  * @internal
24
174
  */
25
175
  class GltfReaderProps {
26
- constructor(buffer, binaryData, accessors, bufferViews, scene, nodes, meshes, materials, extensions, samplers, techniques, yAxisUp) {
27
- this.buffer = buffer;
176
+ constructor(binaryData, glTF, yAxisUp) {
28
177
  this.binaryData = binaryData;
29
- this.accessors = accessors;
30
- this.bufferViews = bufferViews;
31
- this.scene = scene;
32
- this.nodes = nodes;
33
- this.meshes = meshes;
34
- this.materials = materials;
35
- this.extensions = extensions;
36
- this.samplers = samplers;
37
- this.techniques = techniques;
178
+ this.glTF = glTF;
38
179
  this.yAxisUp = yAxisUp;
39
180
  }
40
181
  /** Attempt to construct a new GltfReaderProps from the binary data beginning at the supplied stream's current read position. */
@@ -44,23 +185,34 @@ class GltfReaderProps {
44
185
  return undefined;
45
186
  const binaryData = new Uint8Array(buffer.arrayBuffer, header.binaryPosition);
46
187
  buffer.curPos = header.scenePosition;
47
- const sceneStrData = buffer.nextBytes(header.sceneStrLength);
48
- const sceneStr = (0, core_bentley_1.utf8ToString)(sceneStrData);
49
- if (undefined === sceneStr)
188
+ const jsonStrData = buffer.nextBytes(header.sceneStrLength);
189
+ const jsonStr = (0, core_bentley_1.utf8ToString)(jsonStrData);
190
+ if (undefined === jsonStr)
50
191
  return undefined;
51
192
  try {
52
- const sceneValue = JSON.parse(sceneStr);
53
- const nodes = core_bentley_1.JsonUtils.asObject(sceneValue.nodes);
54
- const meshes = core_bentley_1.JsonUtils.asObject(sceneValue.meshes);
55
- const materialValues = core_bentley_1.JsonUtils.asObject(sceneValue.materials);
56
- const accessors = core_bentley_1.JsonUtils.asObject(sceneValue.accessors);
57
- const bufferViews = core_bentley_1.JsonUtils.asObject(sceneValue.bufferViews);
58
- const extensions = core_bentley_1.JsonUtils.asObject(sceneValue.extensions);
59
- const samplers = core_bentley_1.JsonUtils.asObject(sceneValue.samplers);
60
- const techniques = core_bentley_1.JsonUtils.asObject(sceneValue.techniques);
61
- if (undefined === meshes)
62
- return undefined;
63
- return new GltfReaderProps(buffer, binaryData, accessors, bufferViews, sceneValue, nodes, meshes, materialValues, extensions, samplers, techniques, yAxisUp);
193
+ const json = JSON.parse(jsonStr);
194
+ const asset = core_bentley_1.JsonUtils.asObject(json.asset);
195
+ if (header.version === 2 && !asset)
196
+ return undefined; // asset is required in glTF 2.0
197
+ const glTF = {
198
+ asset,
199
+ scene: core_bentley_1.JsonUtils.asString(json.scene),
200
+ extensions: core_bentley_1.JsonUtils.asObject(json.extensions),
201
+ extensionsUsed: core_bentley_1.JsonUtils.asArray(json.extensionsUsed),
202
+ extensionsRequired: core_bentley_1.JsonUtils.asArray(json.extensionsRequired),
203
+ accessors: core_bentley_1.JsonUtils.asObject(json.accessors),
204
+ buffers: core_bentley_1.JsonUtils.asObject(json.buffers),
205
+ bufferViews: core_bentley_1.JsonUtils.asObject(json.bufferViews),
206
+ images: core_bentley_1.JsonUtils.asObject(json.images),
207
+ materials: core_bentley_1.JsonUtils.asObject(json.materials),
208
+ meshes: core_bentley_1.JsonUtils.asObject(json.meshes),
209
+ nodes: core_bentley_1.JsonUtils.asObject(json.nodes),
210
+ samplers: core_bentley_1.JsonUtils.asObject(json.samplers),
211
+ scenes: core_bentley_1.JsonUtils.asObject(json.scenes),
212
+ textures: core_bentley_1.JsonUtils.asObject(json.textures),
213
+ techniques: core_bentley_1.JsonUtils.asObject(json.techniques),
214
+ };
215
+ return glTF.meshes ? new GltfReaderProps(binaryData, glTF, yAxisUp) : undefined;
64
216
  }
65
217
  catch (e) {
66
218
  return undefined;
@@ -90,57 +242,123 @@ exports.GltfMeshData = GltfMeshData;
90
242
  }
91
243
  }
92
244
  -------------------------------------- */
245
+ const emptyDict = {};
246
+ function colorFromJson(values) {
247
+ return core_common_1.ColorDef.from(values[0] * 255, values[1] * 255, values[2] * 255, (1.0 - values[3]) * 255);
248
+ }
249
+ function colorFromMaterial(material) {
250
+ var _a, _b, _c, _d, _e;
251
+ if (material) {
252
+ if (isGltf1Material(material)) {
253
+ if (((_a = material.values) === null || _a === void 0 ? void 0 : _a.color) && Array.isArray(material.values.color))
254
+ return colorFromJson(material.values.color);
255
+ }
256
+ 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) {
257
+ return colorFromJson(material.extensions.KHR_techniques_webgl.values.u_color);
258
+ }
259
+ else if ((_e = material.pbrMetallicRoughness) === null || _e === void 0 ? void 0 : _e.baseColorFactor) {
260
+ return colorFromJson(material.pbrMetallicRoughness.baseColorFactor);
261
+ }
262
+ }
263
+ return core_common_1.ColorDef.white;
264
+ }
265
+ class TransformStack {
266
+ constructor() {
267
+ this._stack = [];
268
+ }
269
+ get transform() {
270
+ return this._stack.length > 0 ? this._stack[this._stack.length - 1] : undefined;
271
+ }
272
+ get isEmpty() {
273
+ return 0 === this._stack.length;
274
+ }
275
+ push(node) {
276
+ let nodeTransform;
277
+ if (node.matrix) {
278
+ const origin = core_geometry_1.Point3d.create(node.matrix[12], node.matrix[13], node.matrix[14]);
279
+ const matrix = core_geometry_1.Matrix3d.createRowValues(node.matrix[0], node.matrix[4], node.matrix[8], node.matrix[1], node.matrix[5], node.matrix[9], node.matrix[2], node.matrix[6], node.matrix[10]);
280
+ nodeTransform = core_geometry_1.Transform.createOriginAndMatrix(origin, matrix);
281
+ }
282
+ else if (node.rotation || node.scale || node.translation) {
283
+ // SPEC: To compose the local transformation matrix, TRS properties MUST be converted to matrices and postmultiplied in the T * R * S order;
284
+ // first the scale is applied to the vertices, then the rotation, and then the translation.
285
+ const scale = core_geometry_1.Transform.createRefs(undefined, node.scale ? core_geometry_1.Matrix3d.createScale(node.scale[0], node.scale[1], node.scale[2]) : core_geometry_1.Matrix3d.identity);
286
+ const rot = core_geometry_1.Transform.createRefs(undefined, node.rotation ? core_geometry_1.Matrix3d.createFromQuaternion(core_geometry_1.Point4d.create(node.rotation[0], node.rotation[1], node.rotation[2], node.rotation[3])) : core_geometry_1.Matrix3d.identity);
287
+ rot.matrix.transposeInPlace(); // See comment on Matrix3d.createFromQuaternion
288
+ const trans = core_geometry_1.Transform.createTranslation(node.translation ? new core_geometry_1.Point3d(node.translation[0], node.translation[1], node.translation[2]) : core_geometry_1.Point3d.createZero());
289
+ nodeTransform = scale.multiplyTransformTransform(rot);
290
+ trans.multiplyTransformTransform(nodeTransform, nodeTransform);
291
+ }
292
+ const top = this.transform;
293
+ if (!top)
294
+ this._stack.push(nodeTransform);
295
+ else
296
+ this._stack.push(nodeTransform ? top.multiplyTransformTransform(nodeTransform) : top);
297
+ }
298
+ pop() {
299
+ (0, core_bentley_1.assert)(this._stack.length > 0);
300
+ this._stack.pop();
301
+ }
302
+ }
93
303
  /** Deserializes [glTF](https://www.khronos.org/gltf/).
94
304
  * @internal
95
305
  */
96
306
  class GltfReader {
97
- constructor(props, iModel, modelId, is3d, system, type = core_common_1.BatchType.Primary, isCanceled, deduplicateVertices = false) {
98
- this._buffer = props.buffer;
99
- this._scene = props.scene;
100
- this._binaryData = props.binaryData;
101
- this._accessors = props.accessors;
102
- this._bufferViews = props.bufferViews;
103
- this._meshes = props.meshes;
104
- this._nodes = props.nodes;
105
- this._materialValues = props.materials;
106
- this._samplers = props.samplers;
107
- this._techniques = props.techniques;
108
- this._extensions = props.extensions;
109
- this._yAxisUp = props.yAxisUp;
110
- this._returnToCenter = this.extractReturnToCenter(props.extensions);
111
- this._textures = props.scene.textures;
112
- this._images = props.scene.images;
113
- this._renderMaterials = props.scene.renderMaterials;
114
- this._namedTextures = props.scene.namedTextures;
115
- this._iModel = iModel;
116
- this._modelId = modelId;
117
- this._is3d = is3d;
118
- this._system = system;
119
- this._type = type;
120
- this._canceled = isCanceled;
121
- this._deduplicateVertices = deduplicateVertices;
307
+ constructor(args) {
308
+ var _a, _b, _c, _d, _e, _f, _g;
309
+ this._binaryData = args.props.binaryData;
310
+ this._glTF = args.props.glTF;
311
+ this._yAxisUp = args.props.yAxisUp;
312
+ const rtcCenter = (_b = (_a = args.props.glTF.extensions) === null || _a === void 0 ? void 0 : _a.CESIUM_RTC) === null || _b === void 0 ? void 0 : _b.center;
313
+ if (rtcCenter && 3 === rtcCenter.length)
314
+ if (0 !== rtcCenter[0] || 0 !== rtcCenter[1] || 0 !== rtcCenter[2])
315
+ this._returnToCenter = core_geometry_1.Point3d.fromJSON(rtcCenter);
316
+ this._iModel = args.iModel;
317
+ this._is3d = true !== args.is2d;
318
+ this._system = (_c = args.system) !== null && _c !== void 0 ? _c : IModelApp_1.IModelApp.renderSystem;
319
+ this._type = (_d = args.type) !== null && _d !== void 0 ? _d : core_common_1.BatchType.Primary;
320
+ this._canceled = args.shouldAbort;
321
+ this._deduplicateVertices = (_e = args.deduplicateVertices) !== null && _e !== void 0 ? _e : false;
322
+ this._vertexTableRequired = (_f = args.vertexTableRequired) !== null && _f !== void 0 ? _f : false;
323
+ // The original implementation of GltfReader would process and produce graphics for every node in glTF.nodes.
324
+ // What it's *supposed* to do is process the nodes in glTF.scenes[glTF.scene].nodes
325
+ // Some nodes may not be referenced by the configured scene, or only indirectly via GltfNode.children.
326
+ // Perhaps some faulty tiles existed that didn't define their scenes properly?
327
+ let sceneNodes;
328
+ if (this._glTF.scenes && undefined !== this._glTF.scene)
329
+ sceneNodes = (_g = this._glTF.scenes[this._glTF.scene]) === null || _g === void 0 ? void 0 : _g.nodes;
330
+ if (!sceneNodes)
331
+ sceneNodes = Object.keys(this._nodes);
332
+ this._sceneNodes = sceneNodes;
122
333
  }
334
+ get _nodes() { var _a; return (_a = this._glTF.nodes) !== null && _a !== void 0 ? _a : emptyDict; }
335
+ get _meshes() { var _a; return (_a = this._glTF.meshes) !== null && _a !== void 0 ? _a : emptyDict; }
336
+ get _accessors() { var _a; return (_a = this._glTF.accessors) !== null && _a !== void 0 ? _a : emptyDict; }
337
+ get _bufferViews() { var _a; return (_a = this._glTF.bufferViews) !== null && _a !== void 0 ? _a : emptyDict; }
338
+ get _materialValues() { var _a; return (_a = this._glTF.materials) !== null && _a !== void 0 ? _a : emptyDict; }
123
339
  get _isCanceled() { return undefined !== this._canceled && this._canceled(this); }
124
340
  get _isVolumeClassifier() { return core_common_1.BatchType.VolumeClassifier === this._type; }
125
341
  readGltfAndCreateGraphics(isLeaf, featureTable, contentRange, transformToRoot, pseudoRtcBias, instances) {
126
342
  var _a;
127
343
  if (this._isCanceled)
128
344
  return { readStatus: core_common_1.TileReadStatus.Canceled, isLeaf };
129
- if (this._returnToCenter !== undefined || ((_a = this._nodes[0]) === null || _a === void 0 ? void 0 : _a.matrix) !== undefined || (pseudoRtcBias !== undefined && pseudoRtcBias.magnitude() < 1.0E5))
345
+ // If contentRange was not supplied, we will compute it as we read the meshes.
346
+ if (!contentRange)
347
+ this._computedContentRange = contentRange = core_geometry_1.Range3d.createNull();
348
+ else
349
+ this._computedContentRange = undefined;
350
+ // ###TODO this looks like a hack? Why does it assume the first node's transform is special, or that the transform will be specified as a matrix instead of translation+rot+scale?
351
+ if (this._returnToCenter || ((_a = this._nodes[0]) === null || _a === void 0 ? void 0 : _a.matrix) || (pseudoRtcBias && pseudoRtcBias.magnitude() < 1.0E5))
130
352
  pseudoRtcBias = undefined;
131
- const childNodes = new Set();
132
- for (const key of Object.keys(this._nodes)) {
133
- const node = this._nodes[key];
134
- if (node.children)
135
- for (const child of node.children)
136
- childNodes.add(child.toString());
137
- }
353
+ const transformStack = new TransformStack();
138
354
  const renderGraphicList = [];
139
355
  let readStatus = core_common_1.TileReadStatus.InvalidTileData;
140
- for (const nodeKey of Object.keys(this._nodes))
141
- if (!childNodes.has(nodeKey))
142
- if (core_common_1.TileReadStatus.Success !== (readStatus = this.readNodeAndCreateGraphics(renderGraphicList, this._nodes[nodeKey], featureTable, undefined, instances, pseudoRtcBias)))
143
- return { readStatus, isLeaf };
356
+ for (const nodeKey of this._sceneNodes) {
357
+ (0, core_bentley_1.assert)(transformStack.isEmpty);
358
+ const node = this._nodes[nodeKey];
359
+ if (node && core_common_1.TileReadStatus.Success !== (readStatus = this.readNodeAndCreateGraphics(renderGraphicList, node, featureTable, transformStack, instances, pseudoRtcBias)))
360
+ return { readStatus, isLeaf };
361
+ }
144
362
  if (0 === renderGraphicList.length)
145
363
  return { readStatus: core_common_1.TileReadStatus.InvalidTileData, isLeaf };
146
364
  let renderGraphic;
@@ -150,20 +368,21 @@ class GltfReader {
150
368
  renderGraphic = this._system.createGraphicList(renderGraphicList);
151
369
  let transform;
152
370
  let range = contentRange;
153
- if (undefined !== this._returnToCenter || undefined !== pseudoRtcBias || this._yAxisUp || undefined !== transformToRoot) {
154
- if (undefined !== this._returnToCenter)
155
- transform = core_geometry_1.Transform.createTranslationXYZ(this._returnToCenter[0], this._returnToCenter[1], this._returnToCenter[2]);
156
- else if (undefined !== pseudoRtcBias)
371
+ if (this._returnToCenter || pseudoRtcBias || this._yAxisUp || transformToRoot) {
372
+ if (this._returnToCenter)
373
+ transform = core_geometry_1.Transform.createTranslation(this._returnToCenter.clone());
374
+ else if (pseudoRtcBias)
157
375
  transform = core_geometry_1.Transform.createTranslationXYZ(pseudoRtcBias.x, pseudoRtcBias.y, pseudoRtcBias.z);
158
376
  else
159
377
  transform = core_geometry_1.Transform.createIdentity();
160
378
  if (this._yAxisUp)
161
379
  transform = transform.multiplyTransformMatrix3d(core_geometry_1.Matrix3d.createRotationAroundVector(core_geometry_1.Vector3d.create(1.0, 0.0, 0.0), core_geometry_1.Angle.createRadians(core_geometry_1.Angle.piOver2Radians)));
162
- if (undefined !== transformToRoot)
380
+ if (transformToRoot)
163
381
  transform = transformToRoot.multiplyTransformTransform(transform);
164
382
  range = transform.inverse().multiplyRange(contentRange);
165
383
  }
166
- renderGraphic = this._system.createBatch(renderGraphic, core_common_1.PackedFeatureTable.pack(featureTable), range);
384
+ if (featureTable)
385
+ renderGraphic = this._system.createBatch(renderGraphic, core_common_1.PackedFeatureTable.pack(featureTable), range);
167
386
  if (transform) {
168
387
  const branch = new GraphicBranch_1.GraphicBranch(true);
169
388
  branch.add(renderGraphic);
@@ -177,11 +396,9 @@ class GltfReader {
177
396
  };
178
397
  }
179
398
  graphicFromMeshData(gltfMesh, meshGraphicArgs, instances) {
180
- if (!gltfMesh.points || !gltfMesh.pointRange) {
181
- (0, core_bentley_1.assert)(false);
399
+ if (!gltfMesh.points || !gltfMesh.pointRange)
182
400
  return;
183
- }
184
- const realityMeshPrimitive = (forceLUT || instances) ? undefined : RealityMeshPrimitive_1.RealityMeshPrimitive.createFromGltfMesh(gltfMesh);
401
+ const realityMeshPrimitive = (this._vertexTableRequired || instances) ? undefined : RealityMeshPrimitive_1.RealityMeshPrimitive.createFromGltfMesh(gltfMesh);
185
402
  if (realityMeshPrimitive) {
186
403
  const realityMesh = this._system.createRealityMesh(realityMeshPrimitive);
187
404
  if (realityMesh)
@@ -202,16 +419,12 @@ class GltfReader {
202
419
  mesh.normals.push(new core_common_1.OctEncodedNormal(normal));
203
420
  return mesh.getGraphics(meshGraphicArgs, this._system, instances);
204
421
  }
205
- readNodeAndCreateGraphics(renderGraphicList, node, featureTable, parentTransform, instances, pseudoRtcBias) {
422
+ readNodeAndCreateGraphics(renderGraphicList, node, featureTable, transformStack, instances, pseudoRtcBias) {
206
423
  if (undefined === node)
207
424
  return core_common_1.TileReadStatus.InvalidTileData;
208
- let thisTransform = parentTransform;
209
- let thisBias;
210
- if (Array.isArray(node.matrix)) {
211
- const jTrans = node.matrix;
212
- const nodeTransform = core_geometry_1.Transform.createOriginAndMatrix(core_geometry_1.Point3d.create(jTrans[12], jTrans[13], jTrans[14]), core_geometry_1.Matrix3d.createRowValues(jTrans[0], jTrans[4], jTrans[8], jTrans[1], jTrans[5], jTrans[9], jTrans[2], jTrans[6], jTrans[10]));
213
- thisTransform = thisTransform ? thisTransform.multiplyTransformTransform(nodeTransform) : nodeTransform;
214
- }
425
+ // IMPORTANT: Do not return without popping this node from the stack.
426
+ transformStack.push(node);
427
+ const thisTransform = transformStack.transform;
215
428
  /**
216
429
  * This is a workaround for tiles generated by
217
430
  * context capture which have a large offset from the tileset origin that exceeds the
@@ -220,19 +433,24 @@ class GltfReader {
220
433
  * as the vertices are supplied in a quantized format, applying the RTC bias to
221
434
  * quantization origin will make these tiles work correctly.
222
435
  */
223
- if (undefined !== pseudoRtcBias) {
436
+ let thisBias;
437
+ if (undefined !== pseudoRtcBias)
224
438
  thisBias = (undefined === thisTransform) ? pseudoRtcBias : thisTransform.matrix.multiplyInverse(pseudoRtcBias);
225
- }
226
- const meshKey = node.meshes ? node.meshes : node.mesh;
227
- if (undefined !== meshKey) {
439
+ for (const meshKey of getNodeMeshIds(node)) {
228
440
  const nodeMesh = this._meshes[meshKey];
229
- if (nodeMesh) {
441
+ if (nodeMesh === null || nodeMesh === void 0 ? void 0 : nodeMesh.primitives) {
230
442
  const meshGraphicArgs = new MeshPrimitives_1.MeshGraphicArgs();
231
443
  const meshes = [];
232
444
  for (const primitive of nodeMesh.primitives) {
233
445
  const geometry = this.readMeshPrimitive(primitive, featureTable, thisBias);
234
- if (undefined !== geometry)
446
+ if (geometry) {
235
447
  meshes.push(geometry);
448
+ if (this._computedContentRange && geometry.pointRange) {
449
+ const invTransform = thisTransform === null || thisTransform === void 0 ? void 0 : thisTransform.inverse();
450
+ const meshRange = invTransform ? invTransform.multiplyRange(geometry.pointRange) : geometry.pointRange;
451
+ this._computedContentRange.extendRange(meshRange);
452
+ }
453
+ }
236
454
  }
237
455
  let renderGraphic;
238
456
  if (0 !== meshes.length) {
@@ -261,11 +479,16 @@ class GltfReader {
261
479
  }
262
480
  }
263
481
  if (node.children) {
264
- for (const child of node.children)
265
- this.readNodeAndCreateGraphics(renderGraphicList, this._nodes[child], featureTable, thisTransform, instances);
482
+ for (const childId of node.children) {
483
+ const child = this._nodes[childId];
484
+ if (child)
485
+ this.readNodeAndCreateGraphics(renderGraphicList, child, featureTable, transformStack, instances);
486
+ }
266
487
  }
488
+ transformStack.pop();
267
489
  return core_common_1.TileReadStatus.Success;
268
490
  }
491
+ // ###TODO what is the actual type of `json`?
269
492
  getBufferView(json, accessorName) {
270
493
  try {
271
494
  const accessorValue = core_bentley_1.JsonUtils.asString(json[accessorName]);
@@ -277,14 +500,14 @@ class GltfReader {
277
500
  const type = accessor.componentType;
278
501
  let dataSize = 0;
279
502
  switch (type) {
280
- case core_common_1.GltfDataType.UnsignedByte:
503
+ case GltfDataType.UnsignedByte:
281
504
  dataSize = 1;
282
505
  break;
283
- case core_common_1.GltfDataType.UnsignedShort:
506
+ case GltfDataType.UnsignedShort:
284
507
  dataSize = 2;
285
508
  break;
286
- case core_common_1.GltfDataType.UInt32:
287
- case core_common_1.GltfDataType.Float:
509
+ case GltfDataType.UInt32:
510
+ case GltfDataType.Float:
288
511
  dataSize = 4;
289
512
  break;
290
513
  default:
@@ -305,36 +528,24 @@ class GltfReader {
305
528
  // If the data is misaligned (Scalable mesh tile publisher) use slice to copy -- else use subarray.
306
529
  // assert(0 === offset % dataSize);
307
530
  const bytes = (0 === (this._binaryData.byteOffset + offset) % dataSize) ? this._binaryData.subarray(offset, offset + length) : this._binaryData.slice(offset, offset + length);
308
- return new core_common_1.GltfBufferView(bytes, accessor.count, type, accessor, byteStride / dataSize);
531
+ return new GltfBufferView(bytes, accessor.count, type, accessor, byteStride / dataSize);
309
532
  }
310
533
  catch (e) {
311
534
  return undefined;
312
535
  }
313
536
  }
314
- readBufferData32(json, accessorName) { return this.readBufferData(json, accessorName, core_common_1.GltfDataType.UInt32); }
315
- readBufferData16(json, accessorName) { return this.readBufferData(json, accessorName, core_common_1.GltfDataType.UnsignedShort); }
316
- readBufferData8(json, accessorName) { return this.readBufferData(json, accessorName, core_common_1.GltfDataType.UnsignedByte); }
317
- readBufferDataFloat(json, accessorName) { return this.readBufferData(json, accessorName, core_common_1.GltfDataType.Float); }
537
+ readBufferData32(json, accessorName) { return this.readBufferData(json, accessorName, GltfDataType.UInt32); }
538
+ readBufferData16(json, accessorName) { return this.readBufferData(json, accessorName, GltfDataType.UnsignedShort); }
539
+ readBufferData8(json, accessorName) { return this.readBufferData(json, accessorName, GltfDataType.UnsignedByte); }
540
+ readBufferDataFloat(json, accessorName) { return this.readBufferData(json, accessorName, GltfDataType.Float); }
318
541
  readBufferData(json, accessorName, type) {
319
542
  const view = this.getBufferView(json, accessorName);
320
543
  return undefined !== view ? view.toBufferData(type) : undefined;
321
544
  }
322
545
  readFeatureIndices(_json) { return undefined; }
323
- colorFromJson(values) { return core_common_1.ColorDef.from(values[0] * 255, values[1] * 255, values[2] * 255, (1.0 - values[3]) * 255); }
324
- colorFromMaterial(materialJson) {
325
- if (materialJson) {
326
- if (materialJson.values && Array.isArray(materialJson.values.color))
327
- return this.colorFromJson(materialJson.values.color);
328
- else if (materialJson.pbrMetallicRoughness && Array.isArray(materialJson.pbrMetallicRoughness.baseColorFactor))
329
- return this.colorFromJson(materialJson.pbrMetallicRoughness.baseColorFactor);
330
- else if (materialJson.extensions && materialJson.extensions.KHR_techniques_webgl && materialJson.extensions.KHR_techniques_webgl.values && materialJson.extensions.KHR_techniques_webgl.values.u_color)
331
- return this.colorFromJson(materialJson.extensions.KHR_techniques_webgl.values.u_color);
332
- }
333
- return core_common_1.ColorDef.white;
334
- }
335
- extractTextureId(materialJson) {
546
+ extractTextureId(material) {
336
547
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
337
- if (typeof materialJson !== "object")
548
+ if (typeof material !== "object")
338
549
  return undefined;
339
550
  const extractId = (value) => {
340
551
  switch (typeof value) {
@@ -347,60 +558,48 @@ class GltfReader {
347
558
  }
348
559
  };
349
560
  // Bimium's shader value...almost certainly obsolete at this point.
350
- let id = extractId((_a = materialJson.values) === null || _a === void 0 ? void 0 : _a.tex);
351
- if (undefined !== id)
352
- return id;
561
+ if (isGltf1Material(material))
562
+ return (_a = material.diffuse) !== null && _a !== void 0 ? _a : extractId((_b = material.values) === null || _b === void 0 ? void 0 : _b.tex);
353
563
  // KHR_techniques_webgl extension
354
- const techniques = (_c = (_b = this._extensions) === null || _b === void 0 ? void 0 : _b.KHR_techniques_webgl) === null || _c === void 0 ? void 0 : _c.techniques;
355
- const ext = Array.isArray(techniques) ? (_d = materialJson.extensions) === null || _d === void 0 ? void 0 : _d.KHR_techniques_webgl : undefined;
356
- if (undefined !== ext && typeof ext.values === "object") {
564
+ const techniques = (_d = (_c = this._glTF.extensions) === null || _c === void 0 ? void 0 : _c.KHR_techniques_webgl) === null || _d === void 0 ? void 0 : _d.techniques;
565
+ const ext = Array.isArray(techniques) ? (_e = material.extensions) === null || _e === void 0 ? void 0 : _e.KHR_techniques_webgl : undefined;
566
+ if (techniques && undefined !== ext && typeof (ext.values) === "object") {
357
567
  const uniforms = typeof ext.technique === "number" ? techniques[ext.technique].uniforms : undefined;
358
568
  if (typeof uniforms === "object") {
359
569
  for (const uniformName of Object.keys(uniforms)) {
360
570
  const uniform = uniforms[uniformName];
361
- if (typeof uniform === "object" && uniform.type === core_common_1.GltfDataType.Sampler2d)
362
- return extractId((_e = ext.values[uniformName]) === null || _e === void 0 ? void 0 : _e.index);
571
+ if (typeof uniform === "object" && uniform.type === GltfDataType.Sampler2d)
572
+ return extractId((_f = ext.values[uniformName]) === null || _f === void 0 ? void 0 : _f.index);
363
573
  }
364
574
  }
365
575
  }
366
- id = extractId((_f = materialJson.diffuseTexture) === null || _f === void 0 ? void 0 : _f.index);
367
- id = id !== null && id !== void 0 ? id : extractId((_g = materialJson.emissiveTexture) === null || _g === void 0 ? void 0 : _g.index);
368
- return id !== null && id !== void 0 ? id : extractId((_j = (_h = materialJson.pbrMetallicRoughness) === null || _h === void 0 ? void 0 : _h.baseColorTexture) === null || _j === void 0 ? void 0 : _j.index);
576
+ const id = extractId((_g = material.emissiveTexture) === null || _g === void 0 ? void 0 : _g.index);
577
+ 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);
369
578
  }
370
579
  createDisplayParams(materialJson, hasBakedLighting) {
371
580
  const textureId = this.extractTextureId(materialJson);
372
581
  const textureMapping = undefined !== textureId ? this.findTextureMapping(textureId) : undefined;
373
- const color = this.colorFromMaterial(materialJson);
582
+ const color = colorFromMaterial(materialJson);
374
583
  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);
375
584
  }
376
- extractReturnToCenter(extensions) {
377
- if (extensions === undefined) {
378
- return undefined;
379
- }
380
- const cesiumRtc = core_bentley_1.JsonUtils.asObject(extensions.CESIUM_RTC);
381
- if (cesiumRtc === undefined)
382
- return undefined;
383
- const rtc = core_bentley_1.JsonUtils.asArray(cesiumRtc.center);
384
- return (rtc[0] === 0.0 && rtc[1] === 0.0 && rtc[2] === 0.0) ? undefined : rtc;
385
- }
386
585
  readMeshPrimitive(primitive, featureTable, pseudoRtcBias) {
387
- var _a, _b;
586
+ var _a, _b, _c, _d, _e, _f;
388
587
  const materialName = core_bentley_1.JsonUtils.asString(primitive.material);
389
588
  const hasBakedLighting = undefined === primitive.attributes.NORMAL;
390
- const materialValue = 0 < materialName.length ? core_bentley_1.JsonUtils.asObject(this._materialValues[materialName]) : undefined;
391
- const displayParams = this.createDisplayParams(materialValue, hasBakedLighting);
589
+ const material = 0 < materialName.length ? this._materialValues[materialName] : undefined;
590
+ const displayParams = this.createDisplayParams(material, hasBakedLighting);
392
591
  if (undefined === displayParams)
393
592
  return undefined;
394
593
  let primitiveType = -1;
395
- const meshMode = core_bentley_1.JsonUtils.asInt(primitive.mode, core_common_1.GltfMeshMode.Triangles);
594
+ const meshMode = core_bentley_1.JsonUtils.asInt(primitive.mode, GltfMeshMode.Triangles);
396
595
  switch (meshMode) {
397
- case core_common_1.GltfMeshMode.Lines:
596
+ case GltfMeshMode.Lines:
398
597
  primitiveType = MeshPrimitives_1.Mesh.PrimitiveType.Polyline;
399
598
  break;
400
- case core_common_1.GltfMeshMode.Points:
599
+ case GltfMeshMode.Points:
401
600
  primitiveType = MeshPrimitives_1.Mesh.PrimitiveType.Point;
402
601
  break;
403
- case core_common_1.GltfMeshMode.Triangles:
602
+ case GltfMeshMode.Triangles:
404
603
  primitiveType = MeshPrimitives_1.Mesh.PrimitiveType.Mesh;
405
604
  break;
406
605
  default:
@@ -425,12 +624,12 @@ class GltfReader {
425
624
  // uv parameters to pick the colors out of the color map texture.
426
625
  meshPrimitive.colorMap.insert(displayParams.fillColor.tbgr); // White...
427
626
  const colorIndices = this.readBufferData16(primitive.attributes, "_COLORINDEX");
428
- if (undefined !== colorIndices) {
627
+ if (undefined !== colorIndices && material) {
429
628
  let texStep;
430
- if (materialValue.values !== undefined && Array.isArray(materialValue.values.texStep))
431
- texStep = materialValue.values.texStep;
432
- else if (materialValue.extensions && materialValue.extensions.KHR_techniques_webgl && materialValue.extensions.KHR_techniques_webgl.values && Array.isArray(materialValue.extensions.KHR_techniques_webgl.values.u_texStep))
433
- texStep = materialValue.extensions.KHR_techniques_webgl.values.u_texStep;
629
+ if (isGltf1Material(material))
630
+ texStep = (_a = material.values) === null || _a === void 0 ? void 0 : _a.texStep;
631
+ else
632
+ 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;
434
633
  if (texStep) {
435
634
  const uvParams = [];
436
635
  for (let i = 0; i < colorIndices.count; i++)
@@ -440,7 +639,7 @@ class GltfReader {
440
639
  mesh.uvQParams = paramList.params;
441
640
  }
442
641
  }
443
- if ((_a = primitive.extensions) === null || _a === void 0 ? void 0 : _a.KHR_draco_mesh_compression) {
642
+ if ((_e = primitive.extensions) === null || _e === void 0 ? void 0 : _e.KHR_draco_mesh_compression) {
444
643
  return undefined; // Defer Draco decompression until web workers implementation.
445
644
  /*
446
645
  const dracoExtension = primitive.extensions.KHR_draco_mesh_compression;
@@ -478,7 +677,7 @@ class GltfReader {
478
677
  }
479
678
  if (displayParams.textureMapping && !mesh.uvs)
480
679
  return undefined;
481
- if ((_b = primitive.extensions) === null || _b === void 0 ? void 0 : _b.CESIUM_primitive_outline) {
680
+ if ((_f = primitive.extensions) === null || _f === void 0 ? void 0 : _f.CESIUM_primitive_outline) {
482
681
  const data = this.readBufferData32(primitive.extensions.CESIUM_primitive_outline, "indices");
483
682
  if (data !== undefined) {
484
683
  (0, core_bentley_1.assert)(0 === data.count % 2);
@@ -530,8 +729,8 @@ class GltfReader {
530
729
  const view = this.getBufferView(primitive.attributes, "POSITION");
531
730
  if (undefined === view)
532
731
  return false;
533
- if (core_common_1.GltfDataType.Float === view.type) {
534
- const buffer = view.toBufferData(core_common_1.GltfDataType.Float);
732
+ if (GltfDataType.Float === view.type) {
733
+ const buffer = view.toBufferData(GltfDataType.Float);
535
734
  if (undefined === buffer)
536
735
  return false;
537
736
  const strideSkip = view.stride - 3;
@@ -550,7 +749,7 @@ class GltfReader {
550
749
  mesh.points = positions.toTypedArray();
551
750
  }
552
751
  else {
553
- if (core_common_1.GltfDataType.UnsignedShort !== view.type)
752
+ if (GltfDataType.UnsignedShort !== view.type)
554
753
  return false;
555
754
  const extensions = core_bentley_1.JsonUtils.asObject(view.accessor.extensions);
556
755
  const quantized = undefined !== extensions ? core_bentley_1.JsonUtils.asObject(extensions.WEB3D_quantized_attributes) : undefined;
@@ -560,7 +759,7 @@ class GltfReader {
560
759
  const rangeMax = core_bentley_1.JsonUtils.asArray(quantized.decodedMax);
561
760
  if (undefined === rangeMin || undefined === rangeMax)
562
761
  return false;
563
- const buffer = view.toBufferData(core_common_1.GltfDataType.UnsignedShort);
762
+ const buffer = view.toBufferData(GltfDataType.UnsignedShort);
564
763
  if (undefined === buffer || !(buffer.buffer instanceof Uint16Array))
565
764
  return false;
566
765
  (0, core_bentley_1.assert)(buffer.buffer instanceof Uint16Array);
@@ -608,8 +807,8 @@ class GltfReader {
608
807
  if (undefined === view)
609
808
  return false;
610
809
  switch (view.type) {
611
- case core_common_1.GltfDataType.Float: {
612
- const data = view.toBufferData(core_common_1.GltfDataType.Float);
810
+ case GltfDataType.Float: {
811
+ const data = view.toBufferData(GltfDataType.Float);
613
812
  if (undefined === data)
614
813
  return false;
615
814
  mesh.normals = new Uint16Array(data.count);
@@ -621,8 +820,8 @@ class GltfReader {
621
820
  }
622
821
  return true;
623
822
  }
624
- case core_common_1.GltfDataType.UnsignedByte: {
625
- const data = view.toBufferData(core_common_1.GltfDataType.UnsignedByte);
823
+ case GltfDataType.UnsignedByte: {
824
+ const data = view.toBufferData(GltfDataType.UnsignedByte);
626
825
  if (undefined === data)
627
826
  return false;
628
827
  // ###TODO: we shouldn't have to allocate OctEncodedNormal objects...just use uint16s / numbers...
@@ -645,7 +844,7 @@ class GltfReader {
645
844
  if (view === undefined)
646
845
  return false;
647
846
  switch (view.type) {
648
- case core_common_1.GltfDataType.Float: {
847
+ case GltfDataType.Float: {
649
848
  data = this.readBufferDataFloat(json, accessorName);
650
849
  mesh.uvRange = core_geometry_1.Range2d.createNull();
651
850
  for (let i = 0; i < data.count; i++) {
@@ -661,7 +860,7 @@ class GltfReader {
661
860
  }
662
861
  return true;
663
862
  }
664
- case core_common_1.GltfDataType.UnsignedShort: {
863
+ case GltfDataType.UnsignedShort: {
665
864
  const extensions = core_bentley_1.JsonUtils.asObject(view.accessor.extensions);
666
865
  const quantized = undefined !== extensions ? core_bentley_1.JsonUtils.asObject(extensions.WEB3D_quantized_attributes) : undefined;
667
866
  if (undefined === quantized)
@@ -670,7 +869,7 @@ class GltfReader {
670
869
  const rangeMax = core_bentley_1.JsonUtils.asArray(quantized.decodedMax);
671
870
  if (undefined === rangeMin || undefined === rangeMax)
672
871
  return false;
673
- const qData = view.toBufferData(core_common_1.GltfDataType.UnsignedShort);
872
+ const qData = view.toBufferData(GltfDataType.UnsignedShort);
674
873
  if (undefined === qData || !(qData.buffer instanceof Uint16Array))
675
874
  return false;
676
875
  mesh.uvRange = core_geometry_1.Range2d.createXYXY(rangeMin[0], rangeMin[1], rangeMax[0], rangeMax[1]);
@@ -722,33 +921,39 @@ class GltfReader {
722
921
  return true;
723
922
  }
724
923
  async loadTextures() {
725
- if (undefined === this._textures)
924
+ var _a, _b;
925
+ if (undefined === this._glTF.textures)
726
926
  return;
727
927
  const transparentTextures = new Set();
728
- for (const name of Object.keys(this._materialValues)) {
729
- const materialValue = this._materialValues[name];
730
- let technique;
731
- if (undefined !== materialValue.values &&
732
- undefined !== materialValue.values.tex &&
733
- undefined !== materialValue.technique &&
734
- undefined !== (technique = this._techniques[materialValue.technique]) &&
735
- undefined !== technique.states &&
736
- Array.isArray(technique.states.enable)) {
737
- for (const enable of technique.states.enable)
738
- if (enable === 3042)
739
- transparentTextures.add(materialValue.values.tex);
928
+ if (this._glTF.techniques) {
929
+ for (const name of Object.keys(this._materialValues)) {
930
+ const material = this._materialValues[name];
931
+ if (material && isGltf1Material(material) && undefined !== material.technique && undefined !== ((_a = material.values) === null || _a === void 0 ? void 0 : _a.tex)) {
932
+ const technique = this._glTF.techniques[material.technique];
933
+ if ((_b = technique === null || technique === void 0 ? void 0 : technique.states) === null || _b === void 0 ? void 0 : _b.enable) {
934
+ for (const enable of technique.states.enable) {
935
+ if (3042 === enable) { // 3042 = BLEND
936
+ transparentTextures.add(material.values.tex.toString());
937
+ break;
938
+ }
939
+ }
940
+ }
941
+ }
740
942
  }
741
943
  }
742
944
  const promises = new Array();
743
- for (const name of Object.keys(this._textures))
945
+ for (const name of Object.keys(this._glTF.textures))
744
946
  promises.push(this.loadTexture(name, transparentTextures.has(name)));
745
947
  if (promises.length > 0)
746
948
  await Promise.all(promises);
747
949
  }
748
950
  async loadTextureImage(imageJson, samplerJson, isTransparent) {
951
+ var _a;
749
952
  try {
750
953
  const binaryImageJson = (imageJson.extensions && imageJson.extensions.KHR_binary_glTF) ? core_bentley_1.JsonUtils.asObject(imageJson.extensions.KHR_binary_glTF) : imageJson;
751
954
  const bufferView = this._bufferViews[binaryImageJson.bufferView];
955
+ if (!bufferView || undefined === bufferView.byteLength || bufferView.byteLength <= 0)
956
+ return undefined;
752
957
  const mimeType = core_bentley_1.JsonUtils.asString(binaryImageJson.mimeType);
753
958
  const format = (0, ImageUtil_1.getImageSourceFormatForMimeType)(mimeType);
754
959
  if (undefined === format)
@@ -757,7 +962,7 @@ class GltfReader {
757
962
  if (undefined !== samplerJson &&
758
963
  (undefined !== samplerJson.wrapS || undefined !== samplerJson.wrapT))
759
964
  textureType = core_common_1.RenderTexture.Type.TileSection;
760
- const offset = bufferView.byteOffset;
965
+ const offset = (_a = bufferView.byteOffset) !== null && _a !== void 0 ? _a : 0;
761
966
  /* -----------------------------------
762
967
  const jpegArray = this._binaryData.slice(offset, offset + bufferView.byteLength);
763
968
  const jpegArrayBuffer = jpegArray.buffer;
@@ -792,17 +997,57 @@ class GltfReader {
792
997
  }
793
998
  }
794
999
  async loadTexture(textureId, isTransparent) {
795
- const textureJson = core_bentley_1.JsonUtils.asObject(this._textures[textureId]);
1000
+ if (!this._glTF.textures || !this._glTF.images)
1001
+ return;
1002
+ const textureJson = core_bentley_1.JsonUtils.asObject(this._glTF.textures[textureId]);
796
1003
  if (undefined === textureJson)
797
1004
  return;
798
- const texture = await this.loadTextureImage(this._images[textureJson.source], undefined === this._samplers ? undefined : this._samplers[textureJson.sampler], isTransparent);
1005
+ const texture = await this.loadTextureImage(this._glTF.images[textureJson.source], this._glTF.samplers ? this._glTF.samplers[textureJson.sampler] : undefined, isTransparent);
799
1006
  textureJson.renderTexture = texture;
800
1007
  }
801
1008
  findTextureMapping(textureId) {
802
- const textureJson = core_bentley_1.JsonUtils.asObject(this._textures[textureId]);
1009
+ const textureJson = this._glTF.textures ? core_bentley_1.JsonUtils.asObject(this._glTF.textures[textureId]) : undefined;
803
1010
  const texture = undefined !== textureJson ? textureJson.renderTexture : undefined;
804
1011
  return undefined !== texture ? new core_common_1.TextureMapping(texture, new core_common_1.TextureMapping.Params()) : undefined;
805
1012
  }
806
1013
  }
807
1014
  exports.GltfReader = GltfReader;
1015
+ /** Produce a [[RenderGraphic]] from a [glTF](https://www.khronos.org/gltf/) asset suitable for use in [view decorations]($docs/learning/frontend/ViewDecorations).
1016
+ * @returns a graphic produced from the glTF asset's default scene, or `undefined` if a graphic could not be produced from the asset.
1017
+ * @note Support for the full [glTF 2.0 specification](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html) is currently a work in progress.
1018
+ * If a particular glTF asset fails to load and/or display properly, please
1019
+ * [submit an issue](https://github.com/iTwin/itwinjs-core/issues).
1020
+ * @see [Example decorator]($docs/learning/frontend/ViewDecorations#gltf-decorations) for an example of a decorator that reads and displays a glTF asset.
1021
+ * @public
1022
+ */
1023
+ async function readGltfGraphics(args) {
1024
+ const stream = new core_bentley_1.ByteStream(args.gltf.buffer);
1025
+ const props = GltfReaderProps.create(stream, true); // glTF supports exactly one coordinate system with y axis up.
1026
+ const reader = props ? new Reader(props, args) : undefined;
1027
+ if (!reader)
1028
+ return undefined;
1029
+ const result = await reader.read();
1030
+ return result.graphic;
1031
+ }
1032
+ exports.readGltfGraphics = readGltfGraphics;
1033
+ /** Implements [[readGltfGraphics]]. */
1034
+ class Reader extends GltfReader {
1035
+ constructor(props, args) {
1036
+ var _a, _b, _c;
1037
+ super({
1038
+ props,
1039
+ iModel: args.iModel,
1040
+ vertexTableRequired: true,
1041
+ });
1042
+ const pickableId = (_a = args.pickableOptions) === null || _a === void 0 ? void 0 : _a.id;
1043
+ if (pickableId) {
1044
+ this._featureTable = new core_common_1.FeatureTable(1, (_c = (_b = args.pickableOptions) === null || _b === void 0 ? void 0 : _b.modelId) !== null && _c !== void 0 ? _c : pickableId, core_common_1.BatchType.Primary);
1045
+ this._featureTable.insert(new core_common_1.Feature(pickableId));
1046
+ }
1047
+ }
1048
+ async read() {
1049
+ await this.loadTextures();
1050
+ return this.readGltfAndCreateGraphics(true, this._featureTable, undefined);
1051
+ }
1052
+ }
808
1053
  //# sourceMappingURL=GltfReader.js.map