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