@itwin/core-frontend 3.0.0-dev.167 → 3.0.0-dev.172
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.
- package/lib/cjs/IModelApp.d.ts +1 -1
- package/lib/cjs/IModelApp.d.ts.map +1 -1
- package/lib/cjs/IModelApp.js.map +1 -1
- package/lib/cjs/ImageUtil.d.ts.map +1 -1
- package/lib/cjs/ImageUtil.js +4 -1
- package/lib/cjs/ImageUtil.js.map +1 -1
- package/lib/cjs/ViewManager.d.ts +6 -6
- package/lib/cjs/ViewManager.js +5 -5
- package/lib/cjs/ViewManager.js.map +1 -1
- package/lib/cjs/Viewport.d.ts +5 -3
- package/lib/cjs/Viewport.d.ts.map +1 -1
- package/lib/cjs/Viewport.js +5 -3
- package/lib/cjs/Viewport.js.map +1 -1
- package/lib/cjs/render/RenderSystem.d.ts +1 -0
- package/lib/cjs/render/RenderSystem.d.ts.map +1 -1
- package/lib/cjs/render/RenderSystem.js +1 -0
- package/lib/cjs/render/RenderSystem.js.map +1 -1
- package/lib/cjs/tile/B3dmReader.js +2 -2
- package/lib/cjs/tile/B3dmReader.js.map +1 -1
- package/lib/cjs/tile/DynamicIModelTile.js +1 -1
- package/lib/cjs/tile/DynamicIModelTile.js.map +1 -1
- package/lib/cjs/tile/GltfReader.d.ts +129 -36
- package/lib/cjs/tile/GltfReader.d.ts.map +1 -1
- package/lib/cjs/tile/GltfReader.js +261 -122
- package/lib/cjs/tile/GltfReader.js.map +1 -1
- package/lib/cjs/tile/I3dmReader.js +2 -2
- package/lib/cjs/tile/I3dmReader.js.map +1 -1
- package/lib/cjs/tile/IModelTile.js +1 -1
- package/lib/cjs/tile/IModelTile.js.map +1 -1
- package/lib/cjs/tile/ImdlReader.d.ts +12 -1
- package/lib/cjs/tile/ImdlReader.d.ts.map +1 -1
- package/lib/cjs/tile/ImdlReader.js +47 -3
- package/lib/cjs/tile/ImdlReader.js.map +1 -1
- package/lib/cjs/tile/RealityTileLoader.js +1 -1
- package/lib/cjs/tile/RealityTileLoader.js.map +1 -1
- package/lib/cjs/tile/map/CesiumTerrainProvider.js +1 -1
- package/lib/cjs/tile/map/CesiumTerrainProvider.js.map +1 -1
- package/lib/esm/IModelApp.d.ts +1 -1
- package/lib/esm/IModelApp.d.ts.map +1 -1
- package/lib/esm/IModelApp.js.map +1 -1
- package/lib/esm/ImageUtil.d.ts.map +1 -1
- package/lib/esm/ImageUtil.js +4 -1
- package/lib/esm/ImageUtil.js.map +1 -1
- package/lib/esm/ViewManager.d.ts +6 -6
- package/lib/esm/ViewManager.js +5 -5
- package/lib/esm/ViewManager.js.map +1 -1
- package/lib/esm/Viewport.d.ts +5 -3
- package/lib/esm/Viewport.d.ts.map +1 -1
- package/lib/esm/Viewport.js +5 -3
- package/lib/esm/Viewport.js.map +1 -1
- package/lib/esm/render/RenderSystem.d.ts +1 -0
- package/lib/esm/render/RenderSystem.d.ts.map +1 -1
- package/lib/esm/render/RenderSystem.js +1 -0
- package/lib/esm/render/RenderSystem.js.map +1 -1
- package/lib/esm/tile/B3dmReader.js +2 -2
- package/lib/esm/tile/B3dmReader.js.map +1 -1
- package/lib/esm/tile/DynamicIModelTile.js +1 -1
- package/lib/esm/tile/DynamicIModelTile.js.map +1 -1
- package/lib/esm/tile/GltfReader.d.ts +129 -36
- package/lib/esm/tile/GltfReader.d.ts.map +1 -1
- package/lib/esm/tile/GltfReader.js +261 -123
- package/lib/esm/tile/GltfReader.js.map +1 -1
- package/lib/esm/tile/I3dmReader.js +2 -2
- package/lib/esm/tile/I3dmReader.js.map +1 -1
- package/lib/esm/tile/IModelTile.js +1 -1
- package/lib/esm/tile/IModelTile.js.map +1 -1
- package/lib/esm/tile/ImdlReader.d.ts +12 -1
- package/lib/esm/tile/ImdlReader.d.ts.map +1 -1
- package/lib/esm/tile/ImdlReader.js +45 -2
- package/lib/esm/tile/ImdlReader.js.map +1 -1
- package/lib/esm/tile/RealityTileLoader.js +1 -1
- package/lib/esm/tile/RealityTileLoader.js.map +1 -1
- package/lib/esm/tile/map/CesiumTerrainProvider.js +1 -1
- package/lib/esm/tile/map/CesiumTerrainProvider.js.map +1 -1
- package/package.json +22 -22
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { assert, ByteStream, JsonUtils, utf8ToString } from "@itwin/core-bentley";
|
|
9
9
|
import { Angle, Matrix3d, Point2d, Point3d, Point4d, Range2d, Range3d, Transform, Vector3d } from "@itwin/core-geometry";
|
|
10
|
-
import { BatchType, ColorDef, Feature, FeatureTable, FillFlags,
|
|
11
|
-
import { getImageSourceFormatForMimeType, imageElementFromImageSource } from "../ImageUtil";
|
|
10
|
+
import { BatchType, ColorDef, Feature, FeatureTable, FillFlags, GlbHeader, ImageSource, LinePixels, MeshEdge, MeshEdges, MeshPolyline, OctEncodedNormal, PackedFeatureTable, QParams2d, QParams3d, QPoint2dList, QPoint3dList, Quantization, RenderTexture, TextureMapping, TileFormat, TileReadStatus, } from "@itwin/core-common";
|
|
11
|
+
import { getImageSourceFormatForMimeType, imageElementFromImageSource, tryImageElementFromUrl } from "../ImageUtil";
|
|
12
12
|
import { IModelApp } from "../IModelApp";
|
|
13
13
|
import { GraphicBranch } from "../render/GraphicBranch";
|
|
14
14
|
import { DisplayParams } from "../render/primitives/DisplayParams";
|
|
@@ -79,6 +79,19 @@ var GltfBufferTarget;
|
|
|
79
79
|
GltfBufferTarget[GltfBufferTarget["ArrayBuffer"] = 34962] = "ArrayBuffer";
|
|
80
80
|
GltfBufferTarget[GltfBufferTarget["ElementArrayBuffer"] = 24963] = "ElementArrayBuffer";
|
|
81
81
|
})(GltfBufferTarget || (GltfBufferTarget = {}));
|
|
82
|
+
function* dictionaryIterator(dict) {
|
|
83
|
+
if (Array.isArray(dict)) {
|
|
84
|
+
for (const elem of dict)
|
|
85
|
+
yield elem;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
for (const key of Object.keys(dict)) {
|
|
89
|
+
const value = dict[key];
|
|
90
|
+
if (undefined !== value)
|
|
91
|
+
yield value;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
82
95
|
function getNodeMeshIds(node) {
|
|
83
96
|
if (undefined !== node.meshes)
|
|
84
97
|
return typeof node.meshes === "string" ? [node.meshes] : node.meshes;
|
|
@@ -169,50 +182,80 @@ class GltfBufferView {
|
|
|
169
182
|
* @internal
|
|
170
183
|
*/
|
|
171
184
|
export class GltfReaderProps {
|
|
172
|
-
constructor(
|
|
173
|
-
this.
|
|
185
|
+
constructor(glTF, version, yAxisUp, binaryData, baseUrl) {
|
|
186
|
+
this.version = version;
|
|
174
187
|
this.glTF = glTF;
|
|
188
|
+
this.binaryData = binaryData;
|
|
175
189
|
this.yAxisUp = yAxisUp;
|
|
190
|
+
this.baseUrl = baseUrl;
|
|
176
191
|
}
|
|
177
192
|
/** Attempt to construct a new GltfReaderProps from the binary data beginning at the supplied stream's current read position. */
|
|
178
|
-
static create(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
193
|
+
static create(source, yAxisUp = false, baseUrl) {
|
|
194
|
+
let version;
|
|
195
|
+
let json;
|
|
196
|
+
let binaryData;
|
|
197
|
+
if (source instanceof Uint8Array) {
|
|
198
|
+
// It may be JSON - check for magic indicating glb.
|
|
199
|
+
const buffer = ByteStream.fromUint8Array(source);
|
|
200
|
+
if (TileFormat.Gltf !== buffer.nextUint32) {
|
|
201
|
+
try {
|
|
202
|
+
const utf8Json = utf8ToString(source);
|
|
203
|
+
if (!utf8Json)
|
|
204
|
+
return undefined;
|
|
205
|
+
json = JSON.parse(utf8Json);
|
|
206
|
+
version = 2;
|
|
207
|
+
}
|
|
208
|
+
catch (_) {
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
buffer.reset();
|
|
214
|
+
const header = new GlbHeader(buffer);
|
|
215
|
+
if (!header.isValid)
|
|
216
|
+
return undefined;
|
|
217
|
+
version = header.version;
|
|
218
|
+
if (header.binaryChunk)
|
|
219
|
+
binaryData = new Uint8Array(source.buffer, source.byteOffset + header.binaryChunk.offset, header.binaryChunk.length);
|
|
220
|
+
try {
|
|
221
|
+
const jsonBytes = new Uint8Array(source.buffer, source.byteOffset + header.jsonChunk.offset, header.jsonChunk.length);
|
|
222
|
+
const jsonStr = utf8ToString(jsonBytes);
|
|
223
|
+
if (undefined === jsonStr)
|
|
224
|
+
return undefined;
|
|
225
|
+
json = JSON.parse(jsonStr);
|
|
226
|
+
}
|
|
227
|
+
catch (_) {
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
212
231
|
}
|
|
213
|
-
|
|
214
|
-
|
|
232
|
+
else {
|
|
233
|
+
version = 2; // ###TODO verify against source.asset?.version
|
|
234
|
+
json = source;
|
|
215
235
|
}
|
|
236
|
+
// asset is required in glTF 2, optional in glTF 1
|
|
237
|
+
const asset = JsonUtils.asObject(json.asset);
|
|
238
|
+
if (version === 2 && !asset)
|
|
239
|
+
return undefined;
|
|
240
|
+
const glTF = {
|
|
241
|
+
asset,
|
|
242
|
+
scene: JsonUtils.asString(json.scene),
|
|
243
|
+
extensions: JsonUtils.asObject(json.extensions),
|
|
244
|
+
extensionsUsed: JsonUtils.asArray(json.extensionsUsed),
|
|
245
|
+
extensionsRequired: JsonUtils.asArray(json.extensionsRequired),
|
|
246
|
+
accessors: JsonUtils.asObject(json.accessors),
|
|
247
|
+
buffers: JsonUtils.asObject(json.buffers),
|
|
248
|
+
bufferViews: JsonUtils.asObject(json.bufferViews),
|
|
249
|
+
images: JsonUtils.asObject(json.images),
|
|
250
|
+
materials: JsonUtils.asObject(json.materials),
|
|
251
|
+
meshes: JsonUtils.asObject(json.meshes),
|
|
252
|
+
nodes: JsonUtils.asObject(json.nodes),
|
|
253
|
+
samplers: JsonUtils.asObject(json.samplers),
|
|
254
|
+
scenes: JsonUtils.asObject(json.scenes),
|
|
255
|
+
textures: JsonUtils.asObject(json.textures),
|
|
256
|
+
techniques: JsonUtils.asObject(json.techniques),
|
|
257
|
+
};
|
|
258
|
+
return glTF.meshes ? new GltfReaderProps(glTF, version, yAxisUp, binaryData, baseUrl) : undefined;
|
|
216
259
|
}
|
|
217
260
|
}
|
|
218
261
|
/** The GltfMeshData contains the raw GLTF mesh data. If the data is suitable to create a [[RealityMesh]] directly, basically in the quantized format produced by
|
|
@@ -294,15 +337,30 @@ class TransformStack {
|
|
|
294
337
|
this._stack.pop();
|
|
295
338
|
}
|
|
296
339
|
}
|
|
340
|
+
function* traverseNodes(ids, nodes, traversed) {
|
|
341
|
+
for (const id of ids) {
|
|
342
|
+
if (traversed.has(id))
|
|
343
|
+
throw new Error("Cycle detected while traversing glTF nodes");
|
|
344
|
+
const node = nodes[id];
|
|
345
|
+
if (!node)
|
|
346
|
+
continue;
|
|
347
|
+
traversed.add(id);
|
|
348
|
+
yield node;
|
|
349
|
+
if (node.children)
|
|
350
|
+
for (const child of traverseNodes(node.children, nodes, traversed))
|
|
351
|
+
yield child;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
297
354
|
/** Deserializes [glTF](https://www.khronos.org/gltf/).
|
|
298
355
|
* @internal
|
|
299
356
|
*/
|
|
300
357
|
export class GltfReader {
|
|
301
358
|
constructor(args) {
|
|
302
359
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
303
|
-
this._binaryData = args.props.binaryData;
|
|
304
360
|
this._glTF = args.props.glTF;
|
|
361
|
+
this._version = args.props.version;
|
|
305
362
|
this._yAxisUp = args.props.yAxisUp;
|
|
363
|
+
this._baseUrl = args.props.baseUrl;
|
|
306
364
|
const rtcCenter = (_b = (_a = args.props.glTF.extensions) === null || _a === void 0 ? void 0 : _a.CESIUM_RTC) === null || _b === void 0 ? void 0 : _b.center;
|
|
307
365
|
if (rtcCenter && 3 === rtcCenter.length)
|
|
308
366
|
if (0 !== rtcCenter[0] || 0 !== rtcCenter[1] || 0 !== rtcCenter[2])
|
|
@@ -314,6 +372,12 @@ export class GltfReader {
|
|
|
314
372
|
this._canceled = args.shouldAbort;
|
|
315
373
|
this._deduplicateVertices = (_e = args.deduplicateVertices) !== null && _e !== void 0 ? _e : false;
|
|
316
374
|
this._vertexTableRequired = (_f = args.vertexTableRequired) !== null && _f !== void 0 ? _f : false;
|
|
375
|
+
const binaryData = args.props.binaryData;
|
|
376
|
+
if (binaryData) {
|
|
377
|
+
const buffer = this._buffers[this._version === 2 ? 0 : "binary_glTF"];
|
|
378
|
+
if (buffer && undefined === buffer.uri)
|
|
379
|
+
buffer.resolvedBuffer = binaryData;
|
|
380
|
+
}
|
|
317
381
|
// The original implementation of GltfReader would process and produce graphics for every node in glTF.nodes.
|
|
318
382
|
// What it's *supposed* to do is process the nodes in glTF.scenes[glTF.scene].nodes
|
|
319
383
|
// Some nodes may not be referenced by the configured scene, or only indirectly via GltfNode.children.
|
|
@@ -329,9 +393,26 @@ export class GltfReader {
|
|
|
329
393
|
get _meshes() { var _a; return (_a = this._glTF.meshes) !== null && _a !== void 0 ? _a : emptyDict; }
|
|
330
394
|
get _accessors() { var _a; return (_a = this._glTF.accessors) !== null && _a !== void 0 ? _a : emptyDict; }
|
|
331
395
|
get _bufferViews() { var _a; return (_a = this._glTF.bufferViews) !== null && _a !== void 0 ? _a : emptyDict; }
|
|
332
|
-
get
|
|
396
|
+
get _materials() { var _a; return (_a = this._glTF.materials) !== null && _a !== void 0 ? _a : emptyDict; }
|
|
397
|
+
get _samplers() { var _a; return (_a = this._glTF.samplers) !== null && _a !== void 0 ? _a : emptyDict; }
|
|
398
|
+
get _textures() { var _a; return (_a = this._glTF.textures) !== null && _a !== void 0 ? _a : emptyDict; }
|
|
399
|
+
get _images() { var _a; return (_a = this._glTF.images) !== null && _a !== void 0 ? _a : emptyDict; }
|
|
400
|
+
get _buffers() { var _a; return (_a = this._glTF.buffers) !== null && _a !== void 0 ? _a : emptyDict; }
|
|
333
401
|
get _isCanceled() { return undefined !== this._canceled && this._canceled(this); }
|
|
334
402
|
get _isVolumeClassifier() { return BatchType.VolumeClassifier === this._type; }
|
|
403
|
+
/** Traverse the nodes specified by their Ids, recursing into their child nodes.
|
|
404
|
+
* @param nodeIds The Ids of the nodes to traverse.
|
|
405
|
+
* @throws Error if a node appears more than once during traversal
|
|
406
|
+
*/
|
|
407
|
+
traverseNodes(nodeIds) {
|
|
408
|
+
return traverseNodes(nodeIds, this._nodes, new Set());
|
|
409
|
+
}
|
|
410
|
+
/** Traverse the nodes specified by their scene, recursing into their child nodes.
|
|
411
|
+
* @throws Error if a node appears more than once during traversal
|
|
412
|
+
*/
|
|
413
|
+
traverseScene() {
|
|
414
|
+
return this.traverseNodes(this._sceneNodes);
|
|
415
|
+
}
|
|
335
416
|
readGltfAndCreateGraphics(isLeaf, featureTable, contentRange, transformToRoot, pseudoRtcBias, instances) {
|
|
336
417
|
var _a;
|
|
337
418
|
if (this._isCanceled)
|
|
@@ -486,10 +567,16 @@ export class GltfReader {
|
|
|
486
567
|
getBufferView(json, accessorName) {
|
|
487
568
|
try {
|
|
488
569
|
const accessorValue = JsonUtils.asString(json[accessorName]);
|
|
489
|
-
const accessor =
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
570
|
+
const accessor = accessorValue ? this._accessors[accessorValue] : undefined;
|
|
571
|
+
if (!accessor)
|
|
572
|
+
return undefined;
|
|
573
|
+
const bufferViewAccessorValue = accessor.bufferView;
|
|
574
|
+
const bufferView = undefined !== bufferViewAccessorValue ? this._bufferViews[bufferViewAccessorValue] : undefined;
|
|
575
|
+
if (!bufferView || undefined === bufferView.buffer)
|
|
576
|
+
return undefined;
|
|
577
|
+
const buffer = this._buffers[bufferView.buffer];
|
|
578
|
+
const bufferData = buffer === null || buffer === void 0 ? void 0 : buffer.resolvedBuffer;
|
|
579
|
+
if (!bufferData)
|
|
493
580
|
return undefined;
|
|
494
581
|
const type = accessor.componentType;
|
|
495
582
|
let dataSize = 0;
|
|
@@ -520,8 +607,8 @@ export class GltfReader {
|
|
|
520
607
|
const offset = ((bufferView && bufferView.byteOffset) ? bufferView.byteOffset : 0) + (accessor.byteOffset ? accessor.byteOffset : 0);
|
|
521
608
|
const length = byteStride * accessor.count;
|
|
522
609
|
// If the data is misaligned (Scalable mesh tile publisher) use slice to copy -- else use subarray.
|
|
523
|
-
|
|
524
|
-
const bytes =
|
|
610
|
+
const aligned = 0 === (bufferData.byteOffset + offset) % dataSize;
|
|
611
|
+
const bytes = aligned ? bufferData.subarray(offset, offset + length) : bufferData.slice(offset, offset + length);
|
|
525
612
|
return new GltfBufferView(bytes, accessor.count, type, accessor, byteStride / dataSize);
|
|
526
613
|
}
|
|
527
614
|
catch (e) {
|
|
@@ -580,8 +667,8 @@ export class GltfReader {
|
|
|
580
667
|
var _a, _b, _c, _d, _e, _f;
|
|
581
668
|
const materialName = JsonUtils.asString(primitive.material);
|
|
582
669
|
const hasBakedLighting = undefined === primitive.attributes.NORMAL;
|
|
583
|
-
const material = 0 < materialName.length ? this.
|
|
584
|
-
const displayParams = this.createDisplayParams(material, hasBakedLighting);
|
|
670
|
+
const material = 0 < materialName.length ? this._materials[materialName] : undefined;
|
|
671
|
+
const displayParams = material ? this.createDisplayParams(material, hasBakedLighting) : undefined;
|
|
585
672
|
if (undefined === displayParams)
|
|
586
673
|
return undefined;
|
|
587
674
|
let primitiveType = -1;
|
|
@@ -600,7 +687,6 @@ export class GltfReader {
|
|
|
600
687
|
assert(false);
|
|
601
688
|
return undefined;
|
|
602
689
|
}
|
|
603
|
-
const isPlanar = JsonUtils.asBool(primitive.isPlanar);
|
|
604
690
|
const isVolumeClassifier = this._isVolumeClassifier;
|
|
605
691
|
const meshPrimitive = Mesh.create({
|
|
606
692
|
displayParams,
|
|
@@ -608,7 +694,7 @@ export class GltfReader {
|
|
|
608
694
|
type: primitiveType,
|
|
609
695
|
range: Range3d.createNull(),
|
|
610
696
|
is2d: !this._is3d,
|
|
611
|
-
isPlanar,
|
|
697
|
+
isPlanar: false,
|
|
612
698
|
hasBakedLighting,
|
|
613
699
|
isVolumeClassifier,
|
|
614
700
|
});
|
|
@@ -834,12 +920,13 @@ export class GltfReader {
|
|
|
834
920
|
}
|
|
835
921
|
readUVParams(mesh, json, accessorName) {
|
|
836
922
|
const view = this.getBufferView(json, accessorName);
|
|
837
|
-
let data;
|
|
838
923
|
if (view === undefined)
|
|
839
924
|
return false;
|
|
840
925
|
switch (view.type) {
|
|
841
926
|
case GltfDataType.Float: {
|
|
842
|
-
data = this.readBufferDataFloat(json, accessorName);
|
|
927
|
+
const data = this.readBufferDataFloat(json, accessorName);
|
|
928
|
+
if (!data)
|
|
929
|
+
return false;
|
|
843
930
|
mesh.uvRange = Range2d.createNull();
|
|
844
931
|
for (let i = 0; i < data.count; i++) {
|
|
845
932
|
const index = view.stride * i; // 2 float per param...
|
|
@@ -914,14 +1001,91 @@ export class GltfReader {
|
|
|
914
1001
|
polylines.push(new MeshPolyline(indices));
|
|
915
1002
|
return true;
|
|
916
1003
|
}
|
|
917
|
-
async
|
|
1004
|
+
async resolveResources() {
|
|
1005
|
+
// ###TODO traverse the scene nodes to find resources referenced by them, instead of resolving everything - some resources may not
|
|
1006
|
+
// be required for the scene.
|
|
1007
|
+
const promises = [];
|
|
1008
|
+
try {
|
|
1009
|
+
for (const buffer of dictionaryIterator(this._buffers))
|
|
1010
|
+
if (!buffer.resolvedBuffer)
|
|
1011
|
+
promises.push(this.resolveBuffer(buffer));
|
|
1012
|
+
await Promise.all(promises);
|
|
1013
|
+
if (this._isCanceled)
|
|
1014
|
+
return;
|
|
1015
|
+
promises.length = 0;
|
|
1016
|
+
for (const image of dictionaryIterator(this._images))
|
|
1017
|
+
if (!image.resolvedImage)
|
|
1018
|
+
promises.push(this.resolveImage(image));
|
|
1019
|
+
await Promise.all(promises);
|
|
1020
|
+
if (this._isCanceled)
|
|
1021
|
+
return;
|
|
1022
|
+
this.resolveTextures();
|
|
1023
|
+
}
|
|
1024
|
+
catch (_) {
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
resolveUrl(uri) {
|
|
1028
|
+
try {
|
|
1029
|
+
return new URL(uri, this._baseUrl).toString();
|
|
1030
|
+
}
|
|
1031
|
+
catch (_) {
|
|
1032
|
+
return undefined;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
async resolveBuffer(buffer) {
|
|
1036
|
+
if (buffer.resolvedBuffer || undefined === buffer.uri)
|
|
1037
|
+
return;
|
|
1038
|
+
try {
|
|
1039
|
+
const url = this.resolveUrl(buffer.uri);
|
|
1040
|
+
const response = url ? await fetch(url) : undefined;
|
|
1041
|
+
if (this._isCanceled)
|
|
1042
|
+
return;
|
|
1043
|
+
const data = await (response === null || response === void 0 ? void 0 : response.arrayBuffer());
|
|
1044
|
+
if (this._isCanceled)
|
|
1045
|
+
return;
|
|
1046
|
+
if (data)
|
|
1047
|
+
buffer.resolvedBuffer = new Uint8Array(data);
|
|
1048
|
+
}
|
|
1049
|
+
catch (_) {
|
|
1050
|
+
//
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
async resolveImage(image) {
|
|
1054
|
+
var _a, _b, _c;
|
|
1055
|
+
if (image.resolvedImage)
|
|
1056
|
+
return;
|
|
1057
|
+
const bvSrc = undefined !== image.bufferView ? image : (_a = image.extensions) === null || _a === void 0 ? void 0 : _a.KHR_binary_glTF;
|
|
1058
|
+
if (undefined !== (bvSrc === null || bvSrc === void 0 ? void 0 : bvSrc.bufferView)) {
|
|
1059
|
+
const format = undefined !== bvSrc.mimeType ? getImageSourceFormatForMimeType(bvSrc.mimeType) : undefined;
|
|
1060
|
+
const bufferView = this._bufferViews[bvSrc.bufferView];
|
|
1061
|
+
if (undefined === format || !bufferView || !bufferView.byteLength || bufferView.byteLength < 0)
|
|
1062
|
+
return;
|
|
1063
|
+
const bufferData = (_b = this._buffers[bufferView.buffer]) === null || _b === void 0 ? void 0 : _b.resolvedBuffer;
|
|
1064
|
+
if (!bufferData)
|
|
1065
|
+
return;
|
|
1066
|
+
const offset = (_c = bufferView.byteOffset) !== null && _c !== void 0 ? _c : 0;
|
|
1067
|
+
const bytes = bufferData.subarray(offset, offset + bufferView.byteLength);
|
|
1068
|
+
try {
|
|
1069
|
+
image.resolvedImage = await imageElementFromImageSource(new ImageSource(bytes, format));
|
|
1070
|
+
}
|
|
1071
|
+
catch (_) {
|
|
1072
|
+
//
|
|
1073
|
+
}
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
const url = undefined !== image.uri ? this.resolveUrl(image.uri) : undefined;
|
|
1077
|
+
if (undefined !== url)
|
|
1078
|
+
image.resolvedImage = await tryImageElementFromUrl(url);
|
|
1079
|
+
}
|
|
1080
|
+
resolveTextures() {
|
|
918
1081
|
var _a, _b;
|
|
919
1082
|
if (undefined === this._glTF.textures)
|
|
920
1083
|
return;
|
|
1084
|
+
// ###TODO this seems pretty hacky, and won't work for glTF 2.0 even if the KHR_techniques_webgl extension is used...
|
|
921
1085
|
const transparentTextures = new Set();
|
|
922
1086
|
if (this._glTF.techniques) {
|
|
923
|
-
for (const name of Object.keys(this.
|
|
924
|
-
const material = this.
|
|
1087
|
+
for (const name of Object.keys(this._materials)) {
|
|
1088
|
+
const material = this._materials[name];
|
|
925
1089
|
if (material && isGltf1Material(material) && undefined !== material.technique && undefined !== ((_a = material.values) === null || _a === void 0 ? void 0 : _a.tex)) {
|
|
926
1090
|
const technique = this._glTF.techniques[material.technique];
|
|
927
1091
|
if ((_b = technique === null || technique === void 0 ? void 0 : technique.states) === null || _b === void 0 ? void 0 : _b.enable) {
|
|
@@ -935,74 +1099,42 @@ export class GltfReader {
|
|
|
935
1099
|
}
|
|
936
1100
|
}
|
|
937
1101
|
}
|
|
938
|
-
const
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
const bufferView = this._bufferViews[binaryImageJson.bufferView];
|
|
949
|
-
if (!bufferView || undefined === bufferView.byteLength || bufferView.byteLength <= 0)
|
|
950
|
-
return undefined;
|
|
951
|
-
const mimeType = JsonUtils.asString(binaryImageJson.mimeType);
|
|
952
|
-
const format = getImageSourceFormatForMimeType(mimeType);
|
|
953
|
-
if (undefined === format)
|
|
954
|
-
return undefined;
|
|
955
|
-
let textureType = RenderTexture.Type.Normal;
|
|
956
|
-
if (undefined !== samplerJson &&
|
|
957
|
-
(undefined !== samplerJson.wrapS || undefined !== samplerJson.wrapT))
|
|
958
|
-
textureType = RenderTexture.Type.TileSection;
|
|
959
|
-
const offset = (_a = bufferView.byteOffset) !== null && _a !== void 0 ? _a : 0;
|
|
960
|
-
/* -----------------------------------
|
|
961
|
-
const jpegArray = this._binaryData.slice(offset, offset + bufferView.byteLength);
|
|
962
|
-
const jpegArrayBuffer = jpegArray.buffer;
|
|
963
|
-
const workerOp = new ImageDecodeWorkerOperation(jpegArrayBuffer, mimeType);
|
|
964
|
-
try {
|
|
965
|
-
const imageBitmap = await GltfReader.webWorkerManager.queueOperation(workerOp)
|
|
966
|
-
return this._isCanceled ? undefined : this._system.createTextureFromImage(imageBitmap, isTransparent && ImageSourceFormat.Png === format, this._iModel, textureParams))
|
|
967
|
-
} catch {
|
|
968
|
-
return undefined;
|
|
1102
|
+
for (const node of this.traverseScene()) {
|
|
1103
|
+
for (const meshId of getNodeMeshIds(node)) {
|
|
1104
|
+
const mesh = this._meshes[meshId];
|
|
1105
|
+
if (!(mesh === null || mesh === void 0 ? void 0 : mesh.primitives))
|
|
1106
|
+
continue;
|
|
1107
|
+
for (const primitive of mesh.primitives) {
|
|
1108
|
+
const material = undefined !== primitive.material ? this._materials[primitive.material] : undefined;
|
|
1109
|
+
const textureId = material ? this.extractTextureId(material) : undefined;
|
|
1110
|
+
if (undefined !== textureId)
|
|
1111
|
+
this.resolveTexture(textureId, transparentTextures.has(textureId));
|
|
969
1112
|
}
|
|
970
|
-
------------------------------------- */
|
|
971
|
-
const bytes = this._binaryData.subarray(offset, offset + bufferView.byteLength);
|
|
972
|
-
const imageSource = new ImageSource(bytes, format);
|
|
973
|
-
try {
|
|
974
|
-
const image = await imageElementFromImageSource(imageSource);
|
|
975
|
-
if (this._isCanceled)
|
|
976
|
-
return undefined;
|
|
977
|
-
return this._system.createTexture({
|
|
978
|
-
type: textureType,
|
|
979
|
-
image: {
|
|
980
|
-
source: image,
|
|
981
|
-
transparency: isTransparent && ImageSourceFormat.Png === format ? TextureTransparency.Translucent : TextureTransparency.Opaque,
|
|
982
|
-
},
|
|
983
|
-
});
|
|
984
|
-
}
|
|
985
|
-
catch {
|
|
986
|
-
return undefined;
|
|
987
1113
|
}
|
|
988
1114
|
}
|
|
989
|
-
catch (e) {
|
|
990
|
-
return undefined;
|
|
991
|
-
}
|
|
992
1115
|
}
|
|
993
|
-
|
|
994
|
-
|
|
1116
|
+
resolveTexture(textureId, isTransparent) {
|
|
1117
|
+
var _a;
|
|
1118
|
+
const texture = this._textures[textureId];
|
|
1119
|
+
if (!texture || texture.resolvedTexture || undefined === texture.source)
|
|
995
1120
|
return;
|
|
996
|
-
const
|
|
997
|
-
if (
|
|
1121
|
+
const image = (_a = this._images[texture.source]) === null || _a === void 0 ? void 0 : _a.resolvedImage;
|
|
1122
|
+
if (!image)
|
|
998
1123
|
return;
|
|
999
|
-
const
|
|
1000
|
-
|
|
1124
|
+
const samplerId = texture.sampler;
|
|
1125
|
+
const sampler = undefined !== samplerId ? this._samplers[samplerId] : undefined;
|
|
1126
|
+
const textureType = undefined !== (sampler === null || sampler === void 0 ? void 0 : sampler.wrapS) || undefined !== (sampler === null || sampler === void 0 ? void 0 : sampler.wrapT) ? RenderTexture.Type.TileSection : RenderTexture.Type.Normal;
|
|
1127
|
+
texture.resolvedTexture = this._system.createTexture({
|
|
1128
|
+
type: textureType,
|
|
1129
|
+
image: {
|
|
1130
|
+
source: image,
|
|
1131
|
+
transparency: isTransparent ? TextureTransparency.Translucent : TextureTransparency.Opaque,
|
|
1132
|
+
},
|
|
1133
|
+
});
|
|
1001
1134
|
}
|
|
1002
1135
|
findTextureMapping(textureId) {
|
|
1003
|
-
const
|
|
1004
|
-
|
|
1005
|
-
return undefined !== texture ? new TextureMapping(texture, new TextureMapping.Params()) : undefined;
|
|
1136
|
+
const texture = this._textures[textureId];
|
|
1137
|
+
return (texture === null || texture === void 0 ? void 0 : texture.resolvedTexture) ? new TextureMapping(texture.resolvedTexture, new TextureMapping.Params()) : undefined;
|
|
1006
1138
|
}
|
|
1007
1139
|
}
|
|
1008
1140
|
/** Produce a [[RenderGraphic]] from a [glTF](https://www.khronos.org/gltf/) asset suitable for use in [view decorations]($docs/learning/frontend/ViewDecorations).
|
|
@@ -1014,16 +1146,17 @@ export class GltfReader {
|
|
|
1014
1146
|
* @public
|
|
1015
1147
|
*/
|
|
1016
1148
|
export async function readGltfGraphics(args) {
|
|
1017
|
-
const
|
|
1018
|
-
const
|
|
1019
|
-
const reader = props ? new Reader(props, args) : undefined;
|
|
1149
|
+
const props = GltfReaderProps.create(args.gltf, true, args.baseUrl); // glTF supports exactly one coordinate system with y axis up.
|
|
1150
|
+
const reader = props ? new GltfGraphicsReader(props, args) : undefined;
|
|
1020
1151
|
if (!reader)
|
|
1021
1152
|
return undefined;
|
|
1022
1153
|
const result = await reader.read();
|
|
1023
1154
|
return result.graphic;
|
|
1024
1155
|
}
|
|
1025
|
-
/** Implements [[readGltfGraphics]].
|
|
1026
|
-
|
|
1156
|
+
/** Implements [[readGltfGraphics]]. Exported strictly for tests.
|
|
1157
|
+
* @internal
|
|
1158
|
+
*/
|
|
1159
|
+
export class GltfGraphicsReader extends GltfReader {
|
|
1027
1160
|
constructor(props, args) {
|
|
1028
1161
|
var _a, _b, _c;
|
|
1029
1162
|
super({
|
|
@@ -1031,6 +1164,7 @@ class Reader extends GltfReader {
|
|
|
1031
1164
|
iModel: args.iModel,
|
|
1032
1165
|
vertexTableRequired: true,
|
|
1033
1166
|
});
|
|
1167
|
+
this.binaryData = props.binaryData;
|
|
1034
1168
|
const pickableId = (_a = args.pickableOptions) === null || _a === void 0 ? void 0 : _a.id;
|
|
1035
1169
|
if (pickableId) {
|
|
1036
1170
|
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);
|
|
@@ -1038,8 +1172,12 @@ class Reader extends GltfReader {
|
|
|
1038
1172
|
}
|
|
1039
1173
|
}
|
|
1040
1174
|
async read() {
|
|
1041
|
-
await this.
|
|
1175
|
+
await this.resolveResources();
|
|
1042
1176
|
return this.readGltfAndCreateGraphics(true, this._featureTable, undefined);
|
|
1043
1177
|
}
|
|
1178
|
+
get nodes() { return this._nodes; }
|
|
1179
|
+
get scenes() { var _a; return (_a = this._glTF.scenes) !== null && _a !== void 0 ? _a : emptyDict; }
|
|
1180
|
+
get sceneNodes() { return this._sceneNodes; }
|
|
1181
|
+
get textures() { return this._textures; }
|
|
1044
1182
|
}
|
|
1045
1183
|
//# sourceMappingURL=GltfReader.js.map
|