@itwin/core-frontend 3.0.0-dev.157 → 3.0.0-dev.159

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