@itwin/core-frontend 4.0.0-dev.41 → 4.0.0-dev.46
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/core-frontend.d.ts +1 -0
- package/lib/cjs/core-frontend.d.ts.map +1 -1
- package/lib/cjs/core-frontend.js +1 -0
- package/lib/cjs/core-frontend.js.map +1 -1
- package/lib/cjs/gltf/GltfModel.d.ts +91 -0
- package/lib/cjs/gltf/GltfModel.d.ts.map +1 -0
- package/lib/cjs/gltf/GltfModel.js +10 -0
- package/lib/cjs/gltf/GltfModel.js.map +1 -0
- package/lib/cjs/gltf/GltfParser.d.ts +26 -0
- package/lib/cjs/gltf/GltfParser.d.ts.map +1 -0
- package/lib/cjs/gltf/GltfParser.js +352 -0
- package/lib/cjs/gltf/GltfParser.js.map +1 -0
- package/lib/cjs/gltf/GltfSchema.d.ts +557 -0
- package/lib/cjs/gltf/GltfSchema.d.ts.map +1 -0
- package/lib/cjs/gltf/GltfSchema.js +138 -0
- package/lib/cjs/gltf/GltfSchema.js.map +1 -0
- package/lib/cjs/render/GraphicBuilder.d.ts +5 -2
- package/lib/cjs/render/GraphicBuilder.d.ts.map +1 -1
- package/lib/cjs/render/GraphicBuilder.js +12 -3
- package/lib/cjs/render/GraphicBuilder.js.map +1 -1
- package/lib/cjs/tile/B3dmReader.d.ts +2 -1
- package/lib/cjs/tile/B3dmReader.d.ts.map +1 -1
- package/lib/cjs/tile/B3dmReader.js +2 -1
- package/lib/cjs/tile/B3dmReader.js.map +1 -1
- package/lib/cjs/tile/GltfReader.d.ts +13 -420
- package/lib/cjs/tile/GltfReader.d.ts.map +1 -1
- package/lib/cjs/tile/GltfReader.js +118 -192
- package/lib/cjs/tile/GltfReader.js.map +1 -1
- package/lib/cjs/tile/RealityTileLoader.d.ts.map +1 -1
- package/lib/cjs/tile/RealityTileLoader.js +14 -2
- package/lib/cjs/tile/RealityTileLoader.js.map +1 -1
- package/lib/cjs/tile/Tile.d.ts +10 -1
- package/lib/cjs/tile/Tile.d.ts.map +1 -1
- package/lib/cjs/tile/Tile.js +22 -2
- package/lib/cjs/tile/Tile.js.map +1 -1
- package/lib/esm/core-frontend.d.ts +1 -0
- package/lib/esm/core-frontend.d.ts.map +1 -1
- package/lib/esm/core-frontend.js +1 -0
- package/lib/esm/core-frontend.js.map +1 -1
- package/lib/esm/gltf/GltfModel.d.ts +91 -0
- package/lib/esm/gltf/GltfModel.d.ts.map +1 -0
- package/lib/esm/gltf/GltfModel.js +9 -0
- package/lib/esm/gltf/GltfModel.js.map +1 -0
- package/lib/esm/gltf/GltfParser.d.ts +26 -0
- package/lib/esm/gltf/GltfParser.d.ts.map +1 -0
- package/lib/esm/gltf/GltfParser.js +329 -0
- package/lib/esm/gltf/GltfParser.js.map +1 -0
- package/lib/esm/gltf/GltfSchema.d.ts +557 -0
- package/lib/esm/gltf/GltfSchema.d.ts.map +1 -0
- package/lib/esm/gltf/GltfSchema.js +131 -0
- package/lib/esm/gltf/GltfSchema.js.map +1 -0
- package/lib/esm/render/GraphicBuilder.d.ts +5 -2
- package/lib/esm/render/GraphicBuilder.d.ts.map +1 -1
- package/lib/esm/render/GraphicBuilder.js +13 -4
- package/lib/esm/render/GraphicBuilder.js.map +1 -1
- package/lib/esm/tile/B3dmReader.d.ts +2 -1
- package/lib/esm/tile/B3dmReader.d.ts.map +1 -1
- package/lib/esm/tile/B3dmReader.js +2 -1
- package/lib/esm/tile/B3dmReader.js.map +1 -1
- package/lib/esm/tile/GltfReader.d.ts +13 -420
- package/lib/esm/tile/GltfReader.d.ts.map +1 -1
- package/lib/esm/tile/GltfReader.js +75 -149
- package/lib/esm/tile/GltfReader.js.map +1 -1
- package/lib/esm/tile/RealityTileLoader.d.ts.map +1 -1
- package/lib/esm/tile/RealityTileLoader.js +14 -2
- package/lib/esm/tile/RealityTileLoader.js.map +1 -1
- package/lib/esm/tile/Tile.d.ts +10 -1
- package/lib/esm/tile/Tile.d.ts.map +1 -1
- package/lib/esm/tile/Tile.js +22 -2
- package/lib/esm/tile/Tile.js.map +1 -1
- package/package.json +22 -22
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/** @packageDocumentation
|
|
2
|
+
* @module Rendering
|
|
3
|
+
*/
|
|
4
|
+
import { Transform, XAndY, XYAndZ } from "@itwin/core-geometry";
|
|
5
|
+
import { GltfAlphaMode } from "./GltfSchema";
|
|
6
|
+
/** Types describing the in-memory representation of a glTF model as parsed from a [[GltfDocument]].
|
|
7
|
+
* This API is incomplete.
|
|
8
|
+
* @alpha
|
|
9
|
+
*/
|
|
10
|
+
export declare namespace Gltf {
|
|
11
|
+
interface Buffer {
|
|
12
|
+
data: Uint8Array;
|
|
13
|
+
}
|
|
14
|
+
interface PositionQuantization {
|
|
15
|
+
origin: XYAndZ;
|
|
16
|
+
scale: XYAndZ;
|
|
17
|
+
}
|
|
18
|
+
interface Attribute {
|
|
19
|
+
buffer: Buffer;
|
|
20
|
+
byteStride?: number;
|
|
21
|
+
}
|
|
22
|
+
interface PositionAttribute extends Attribute {
|
|
23
|
+
componentType: "f32" | "u8" | "i8" | "u16" | "i16";
|
|
24
|
+
quantization?: PositionQuantization;
|
|
25
|
+
decodedMin: XYAndZ;
|
|
26
|
+
decodedMax: XYAndZ;
|
|
27
|
+
}
|
|
28
|
+
interface ColorAttribute extends Attribute {
|
|
29
|
+
componentType: "f32" | "u8" | "u16";
|
|
30
|
+
}
|
|
31
|
+
interface Indices {
|
|
32
|
+
dataType: "u8" | "u16" | "u32";
|
|
33
|
+
count: number;
|
|
34
|
+
buffer: Buffer;
|
|
35
|
+
}
|
|
36
|
+
type PrimitiveType = "triangles";
|
|
37
|
+
interface Primitive {
|
|
38
|
+
indices: Indices;
|
|
39
|
+
attributeCount: number;
|
|
40
|
+
position: PositionAttribute;
|
|
41
|
+
color?: ColorAttribute;
|
|
42
|
+
}
|
|
43
|
+
interface TextureUVQuantization {
|
|
44
|
+
origin: XAndY;
|
|
45
|
+
scale: XAndY;
|
|
46
|
+
}
|
|
47
|
+
interface NormalAttribute extends Attribute {
|
|
48
|
+
componentType: "f32" | "i8" | "i16";
|
|
49
|
+
}
|
|
50
|
+
interface TextureUVAttribute extends Attribute {
|
|
51
|
+
componentType: "f32" | "u8" | "u16" | "i8" | "i16";
|
|
52
|
+
quantization?: TextureUVQuantization;
|
|
53
|
+
}
|
|
54
|
+
interface Rgba {
|
|
55
|
+
r: number;
|
|
56
|
+
g: number;
|
|
57
|
+
b: number;
|
|
58
|
+
a: number;
|
|
59
|
+
}
|
|
60
|
+
interface MetallicRoughness {
|
|
61
|
+
baseColorFactor: Rgba;
|
|
62
|
+
metallicFactor: number;
|
|
63
|
+
roughnessFactor: number;
|
|
64
|
+
}
|
|
65
|
+
interface Material {
|
|
66
|
+
metallicRoughness: MetallicRoughness;
|
|
67
|
+
alphaMode: GltfAlphaMode;
|
|
68
|
+
alphaCutoff: number;
|
|
69
|
+
doubleSided: boolean;
|
|
70
|
+
unlit: boolean;
|
|
71
|
+
}
|
|
72
|
+
interface TrianglesPrimitive extends Primitive {
|
|
73
|
+
type: "triangles";
|
|
74
|
+
material: Material;
|
|
75
|
+
normal?: NormalAttribute;
|
|
76
|
+
textureUV?: TextureUVAttribute;
|
|
77
|
+
}
|
|
78
|
+
type AnyPrimitive = TrianglesPrimitive;
|
|
79
|
+
interface Node {
|
|
80
|
+
/** Transform from this node's local coordinate system to its parent node's coordinate system (or the model's coordinate system, if no parent node). */
|
|
81
|
+
toParent?: Transform;
|
|
82
|
+
/** The primitives drawn by this node. For glTF 2.0, there is exactly one primitive per node; glTF 1.0 permits any number of primitives per node. */
|
|
83
|
+
primitives: AnyPrimitive[];
|
|
84
|
+
}
|
|
85
|
+
interface Model {
|
|
86
|
+
/** Transform from model coordinates to world coordinates. */
|
|
87
|
+
toWorld?: Transform;
|
|
88
|
+
nodes: Node[];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=GltfModel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GltfModel.d.ts","sourceRoot":"","sources":["../../../src/gltf/GltfModel.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C;;;GAGG;AACH,yBAAiB,IAAI,CAAC;IAIpB,UAAiB,MAAM;QACrB,IAAI,EAAE,UAAU,CAAC;KAClB;IAED,UAAiB,oBAAoB;QACnC,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf;IAED,UAAiB,SAAS;QACxB,MAAM,EAAE,MAAM,CAAC;QAEf,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IAED,UAAiB,iBAAkB,SAAQ,SAAS;QAElD,aAAa,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC;QACnD,YAAY,CAAC,EAAE,oBAAoB,CAAC;QAEpC,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB;IAED,UAAiB,cAAe,SAAQ,SAAS;QAC/C,aAAa,EAAE,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;KACrC;IAED,UAAiB,OAAO;QACtB,QAAQ,EAAE,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC;QAC/B,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB;IAED,KAAY,aAAa,GAAG,WAAW,CAAC;IAExC,UAAiB,SAAS;QACxB,OAAO,EAAE,OAAO,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,iBAAiB,CAAC;QAC5B,KAAK,CAAC,EAAE,cAAc,CAAC;KACxB;IAED,UAAiB,qBAAqB;QACpC,MAAM,EAAE,KAAK,CAAC;QACd,KAAK,EAAE,KAAK,CAAC;KACd;IAED,UAAiB,eAAgB,SAAQ,SAAS;QAEhD,aAAa,EAAE,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;KACrC;IAED,UAAiB,kBAAmB,SAAQ,SAAS;QAEnD,aAAa,EAAE,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;QACnD,YAAY,CAAC,EAAE,qBAAqB,CAAC;KACtC;IAED,UAAiB,IAAI;QACnB,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX;IAED,UAAiB,iBAAiB;QAChC,eAAe,EAAE,IAAI,CAAC;QAEtB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;KAEzB;IAED,UAAiB,QAAQ;QACvB,iBAAiB,EAAE,iBAAiB,CAAC;QACrC,SAAS,EAAE,aAAa,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,OAAO,CAAC;QAErB,KAAK,EAAE,OAAO,CAAC;KAChB;IAED,UAAiB,kBAAmB,SAAQ,SAAS;QACnD,IAAI,EAAE,WAAW,CAAC;QAClB,QAAQ,EAAE,QAAQ,CAAC;QACnB,MAAM,CAAC,EAAE,eAAe,CAAC;QACzB,SAAS,CAAC,EAAE,kBAAkB,CAAC;KAChC;IAED,KAAY,YAAY,GAAG,kBAAkB,CAAC;IAE9C,UAAiB,IAAI;QACnB,uJAAuJ;QACvJ,QAAQ,CAAC,EAAE,SAAS,CAAC;QACrB,oJAAoJ;QACpJ,UAAU,EAAE,YAAY,EAAE,CAAC;KAC5B;IAED,UAAiB,KAAK;QACpB,6DAA6D;QAC7D,OAAO,CAAC,EAAE,SAAS,CAAC;QACpB,KAAK,EAAE,IAAI,EAAE,CAAC;KACf;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
/** @packageDocumentation
|
|
6
|
+
* @module Rendering
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=GltfModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GltfModel.js","sourceRoot":"","sources":["../../../src/gltf/GltfModel.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Rendering\r\n */\r\n\r\nimport { Transform, XAndY, XYAndZ } from \"@itwin/core-geometry\";\r\nimport { GltfAlphaMode } from \"./GltfSchema\";\r\n\r\n/** Types describing the in-memory representation of a glTF model as parsed from a [[GltfDocument]].\r\n * This API is incomplete.\r\n * @alpha\r\n */\r\nexport namespace Gltf {\r\n // A view into (usually a subset of) a GltfBuffer, used for vertex attributes and indices.\r\n // Attributes may be interleaved in which case they share the same Buffer object and the stride is specified on each Attribute.\r\n // The same Buffer object may also be used by more than one set of attributes or indices.\r\n export interface Buffer {\r\n data: Uint8Array;\r\n }\r\n\r\n export interface PositionQuantization {\r\n origin: XYAndZ;\r\n scale: XYAndZ;\r\n }\r\n\r\n export interface Attribute {\r\n buffer: Buffer;\r\n // Default zero.\r\n byteStride?: number;\r\n }\r\n\r\n export interface PositionAttribute extends Attribute {\r\n // If not \"f32\", the positions are quantized or normalized.\r\n componentType: \"f32\" | \"u8\" | \"i8\" | \"u16\" | \"i16\";\r\n quantization?: PositionQuantization;\r\n // Unquantized if quantization is defined.\r\n decodedMin: XYAndZ;\r\n decodedMax: XYAndZ;\r\n }\r\n\r\n export interface ColorAttribute extends Attribute {\r\n componentType: \"f32\" | \"u8\" | \"u16\";\r\n }\r\n\r\n export interface Indices {\r\n dataType: \"u8\" | \"u16\" | \"u32\";\r\n count: number;\r\n buffer: Buffer;\r\n }\r\n\r\n export type PrimitiveType = \"triangles\";\r\n\r\n export interface Primitive {\r\n indices: Indices;\r\n attributeCount: number;\r\n position: PositionAttribute;\r\n color?: ColorAttribute;\r\n }\r\n\r\n export interface TextureUVQuantization {\r\n origin: XAndY;\r\n scale: XAndY;\r\n }\r\n\r\n export interface NormalAttribute extends Attribute {\r\n // Always normalized.\r\n componentType: \"f32\" | \"i8\" | \"i16\";\r\n }\r\n\r\n export interface TextureUVAttribute extends Attribute {\r\n // If not \"f32\", the components are quantized or normalized.\r\n componentType: \"f32\" | \"u8\" | \"u16\" | \"i8\" | \"i16\";\r\n quantization?: TextureUVQuantization;\r\n }\r\n\r\n export interface Rgba {\r\n r: number;\r\n g: number;\r\n b: number;\r\n a: number;\r\n }\r\n\r\n export interface MetallicRoughness {\r\n baseColorFactor: Rgba;\r\n // ###TODO_GLTF baseColorTexture;\r\n metallicFactor: number;\r\n roughnessFactor: number;\r\n // ###TODO_GLTF metallicRoughnessTexture;\r\n }\r\n\r\n export interface Material {\r\n metallicRoughness: MetallicRoughness;\r\n alphaMode: GltfAlphaMode;\r\n alphaCutoff: number;\r\n doubleSided: boolean;\r\n // NB: a mesh have normals defined but still be intended to be rendered without lighting.\r\n unlit: boolean;\r\n }\r\n\r\n export interface TrianglesPrimitive extends Primitive {\r\n type: \"triangles\";\r\n material: Material;\r\n normal?: NormalAttribute;\r\n textureUV?: TextureUVAttribute;\r\n }\r\n\r\n export type AnyPrimitive = TrianglesPrimitive;\r\n\r\n export interface Node {\r\n /** Transform from this node's local coordinate system to its parent node's coordinate system (or the model's coordinate system, if no parent node). */\r\n toParent?: Transform;\r\n /** The primitives drawn by this node. For glTF 2.0, there is exactly one primitive per node; glTF 1.0 permits any number of primitives per node. */\r\n primitives: AnyPrimitive[];\r\n }\r\n\r\n export interface Model {\r\n /** Transform from model coordinates to world coordinates. */\r\n toWorld?: Transform;\r\n nodes: Node[];\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** @packageDocumentation
|
|
2
|
+
* @module Rendering
|
|
3
|
+
*/
|
|
4
|
+
import { GltfDocument } from "./GltfSchema";
|
|
5
|
+
import { Gltf } from "./GltfModel";
|
|
6
|
+
/** @internal */
|
|
7
|
+
export interface ParseGltfLogger {
|
|
8
|
+
log(message: string, type: "error" | "warning" | "info"): void;
|
|
9
|
+
}
|
|
10
|
+
/** Arguments supplied to [[parseGltf]].
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export interface ParseGltfArgs {
|
|
14
|
+
logger?: ParseGltfLogger;
|
|
15
|
+
gltf: Uint8Array | GltfDocument;
|
|
16
|
+
noCreateImageBitmap?: boolean;
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
isCanceled?: boolean;
|
|
19
|
+
upAxis?: "y" | "z";
|
|
20
|
+
}
|
|
21
|
+
/** Parse a [[GltfDocument]] or binary representation thereof to produce a [[Gltf.Model]].
|
|
22
|
+
* This implementation is incomplete and not currently used.
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseGltf(args: ParseGltfArgs): Promise<Gltf.Model | undefined>;
|
|
26
|
+
//# sourceMappingURL=GltfParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GltfParser.d.ts","sourceRoot":"","sources":["../../../src/gltf/GltfParser.ts"],"names":[],"mappings":"AAIA;;GAEG;AAWH,OAAO,EAC4H,YAAY,EAC9I,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,gBAAgB;AAChB,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;CAChE;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,IAAI,EAAE,UAAU,GAAG,YAAY,CAAC;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CA+FpF"}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
/** @packageDocumentation
|
|
6
|
+
* @module Rendering
|
|
7
|
+
*/
|
|
8
|
+
import { ByteStream, JsonUtils, Logger, utf8ToString } from "@itwin/core-bentley";
|
|
9
|
+
import { Matrix3d, Point3d, Point4d, Transform } from "@itwin/core-geometry";
|
|
10
|
+
import { GlbHeader, ImageSource, TileFormat } from "@itwin/core-common";
|
|
11
|
+
import { FrontendLoggerCategory } from "../FrontendLoggerCategory";
|
|
12
|
+
import { getImageSourceFormatForMimeType, imageBitmapFromImageSource, imageElementFromImageSource, tryImageElementFromUrl, } from "../ImageUtil";
|
|
13
|
+
import { getGltfNodeMeshIds, gltfDictionaryIterator, GltfMeshMode, traverseGltfNodes, } from "./GltfSchema";
|
|
14
|
+
/** Parse a [[GltfDocument]] or binary representation thereof to produce a [[Gltf.Model]].
|
|
15
|
+
* This implementation is incomplete and not currently used.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export async function parseGltf(args) {
|
|
19
|
+
const source = args.gltf;
|
|
20
|
+
let version;
|
|
21
|
+
let json;
|
|
22
|
+
let binary;
|
|
23
|
+
if (source instanceof Uint8Array) {
|
|
24
|
+
// It may be JSON - check for magic indicating glb.
|
|
25
|
+
const buffer = ByteStream.fromUint8Array(source);
|
|
26
|
+
if (TileFormat.Gltf !== buffer.readUint32()) {
|
|
27
|
+
try {
|
|
28
|
+
const utf8Json = utf8ToString(source);
|
|
29
|
+
if (!utf8Json)
|
|
30
|
+
return undefined;
|
|
31
|
+
json = JSON.parse(utf8Json);
|
|
32
|
+
version = 2;
|
|
33
|
+
}
|
|
34
|
+
catch (_) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
buffer.reset();
|
|
40
|
+
const header = new GlbHeader(buffer);
|
|
41
|
+
if (!header.isValid)
|
|
42
|
+
return undefined;
|
|
43
|
+
version = header.version;
|
|
44
|
+
if (header.binaryChunk)
|
|
45
|
+
binary = new Uint8Array(source.buffer, source.byteOffset + header.binaryChunk.offset, header.binaryChunk.length);
|
|
46
|
+
try {
|
|
47
|
+
const jsonBytes = new Uint8Array(source.buffer, source.byteOffset + header.jsonChunk.offset, header.jsonChunk.length);
|
|
48
|
+
const jsonStr = utf8ToString(jsonBytes);
|
|
49
|
+
if (undefined === jsonStr)
|
|
50
|
+
return undefined;
|
|
51
|
+
json = JSON.parse(jsonStr);
|
|
52
|
+
}
|
|
53
|
+
catch (_) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
version = 2; // ###TODO verify against source.asset?.version
|
|
60
|
+
json = source;
|
|
61
|
+
}
|
|
62
|
+
// asset is required in glTF 2, optional in glTF 1
|
|
63
|
+
const asset = JsonUtils.asObject(json.asset);
|
|
64
|
+
if (version === 2 && !asset)
|
|
65
|
+
return undefined;
|
|
66
|
+
const document = {
|
|
67
|
+
asset,
|
|
68
|
+
scene: JsonUtils.asString(json.scene),
|
|
69
|
+
extensions: JsonUtils.asObject(json.extensions),
|
|
70
|
+
extensionsUsed: JsonUtils.asArray(json.extensionsUsed),
|
|
71
|
+
extensionsRequired: JsonUtils.asArray(json.extensionsRequired),
|
|
72
|
+
accessors: JsonUtils.asObject(json.accessors),
|
|
73
|
+
buffers: JsonUtils.asObject(json.buffers),
|
|
74
|
+
bufferViews: JsonUtils.asObject(json.bufferViews),
|
|
75
|
+
images: JsonUtils.asObject(json.images),
|
|
76
|
+
materials: JsonUtils.asObject(json.materials),
|
|
77
|
+
meshes: JsonUtils.asObject(json.meshes),
|
|
78
|
+
nodes: JsonUtils.asObject(json.nodes),
|
|
79
|
+
samplers: JsonUtils.asObject(json.samplers),
|
|
80
|
+
scenes: JsonUtils.asObject(json.scenes),
|
|
81
|
+
textures: JsonUtils.asObject(json.textures),
|
|
82
|
+
techniques: JsonUtils.asObject(json.techniques),
|
|
83
|
+
};
|
|
84
|
+
if (!document.meshes)
|
|
85
|
+
return undefined;
|
|
86
|
+
const logger = args.logger ?? {
|
|
87
|
+
log: (message, type) => {
|
|
88
|
+
const category = `${FrontendLoggerCategory.Package}.gltf`;
|
|
89
|
+
const fn = type === "error" ? "logError" : (type === "warning" ? "logWarning" : "logInfo");
|
|
90
|
+
Logger[fn](category, message);
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
const parser = new GltfParser({
|
|
94
|
+
document,
|
|
95
|
+
version,
|
|
96
|
+
upAxis: args.upAxis ?? "y",
|
|
97
|
+
binary,
|
|
98
|
+
baseUrl: args.baseUrl,
|
|
99
|
+
logger,
|
|
100
|
+
isCanceled: () => args.isCanceled ?? false,
|
|
101
|
+
imageFromImageSource: (args.noCreateImageBitmap ?
|
|
102
|
+
async (imgSrc) => imageElementFromImageSource(imgSrc) :
|
|
103
|
+
async (imgSrc) => imageBitmapFromImageSource(imgSrc)),
|
|
104
|
+
});
|
|
105
|
+
return parser.parse();
|
|
106
|
+
}
|
|
107
|
+
class GltfParser {
|
|
108
|
+
constructor(options) {
|
|
109
|
+
this._dracoMeshes = new Map();
|
|
110
|
+
this._version = options.version;
|
|
111
|
+
this._upAxis = options.upAxis;
|
|
112
|
+
this._baseUrl = options.baseUrl;
|
|
113
|
+
this._logger = options.logger;
|
|
114
|
+
this._isCanceled = options.isCanceled;
|
|
115
|
+
this._imageFromImageSource = options.imageFromImageSource;
|
|
116
|
+
const emptyDict = {};
|
|
117
|
+
const doc = options.document;
|
|
118
|
+
this._buffers = doc.buffers ?? emptyDict;
|
|
119
|
+
this._images = doc.images ?? emptyDict;
|
|
120
|
+
this._nodes = doc.nodes ?? emptyDict;
|
|
121
|
+
this._meshes = doc.meshes ?? emptyDict;
|
|
122
|
+
this._bufferViews = doc.bufferViews ?? emptyDict;
|
|
123
|
+
this._accessors = doc.accessors ?? emptyDict;
|
|
124
|
+
if (options.binary) {
|
|
125
|
+
const buffer = this._buffers[this._version === 2 ? 0 : "binary_glTF"];
|
|
126
|
+
if (buffer && undefined === buffer.uri)
|
|
127
|
+
buffer.resolvedBuffer = { data: options.binary };
|
|
128
|
+
}
|
|
129
|
+
let sceneNodes;
|
|
130
|
+
if (doc.scenes && undefined !== doc.scene)
|
|
131
|
+
sceneNodes = doc.scenes[doc.scene]?.nodes;
|
|
132
|
+
this._sceneNodes = sceneNodes ?? Object.keys(this._nodes);
|
|
133
|
+
}
|
|
134
|
+
async parse() {
|
|
135
|
+
// ###TODO_GLTF RTC_CENTER
|
|
136
|
+
// ###TODO_GLTF pseudo-rtc bias (apply translation to each point at read time, for scalable mesh...)
|
|
137
|
+
const toWorld = undefined;
|
|
138
|
+
await this.resolveResources();
|
|
139
|
+
if (this._isCanceled())
|
|
140
|
+
return undefined;
|
|
141
|
+
// ###TODO_GLTF compute content range (maybe do so elsewhere?)
|
|
142
|
+
// I think spec says POSITION must specify min and max?
|
|
143
|
+
const nodes = [];
|
|
144
|
+
for (const nodeKey of this._sceneNodes) {
|
|
145
|
+
const node = this._nodes[nodeKey];
|
|
146
|
+
if (node)
|
|
147
|
+
nodes.push(this.parseNode(node));
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
toWorld,
|
|
151
|
+
nodes,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
parseNode(node) {
|
|
155
|
+
const primitives = [];
|
|
156
|
+
for (const meshId of getGltfNodeMeshIds(node)) {
|
|
157
|
+
const mesh = this._meshes[meshId];
|
|
158
|
+
if (!mesh)
|
|
159
|
+
continue;
|
|
160
|
+
const parsedPrimitives = this.parsePrimitives(mesh);
|
|
161
|
+
for (const primitive of parsedPrimitives)
|
|
162
|
+
primitives.push(primitive);
|
|
163
|
+
}
|
|
164
|
+
let toParent;
|
|
165
|
+
if (node.matrix) {
|
|
166
|
+
const origin = Point3d.create(node.matrix[12], node.matrix[13], node.matrix[14]);
|
|
167
|
+
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]);
|
|
168
|
+
toParent = Transform.createOriginAndMatrix(origin, matrix);
|
|
169
|
+
}
|
|
170
|
+
else if (node.rotation || node.scale || node.translation) {
|
|
171
|
+
// SPEC: To compose the local transformation matrix, TRS properties MUST be converted to matrices and postmultiplied in the T * R * S order;
|
|
172
|
+
// first the scale is applied to the vertices, then the rotation, and then the translation.
|
|
173
|
+
const scale = Transform.createRefs(undefined, node.scale ? Matrix3d.createScale(node.scale[0], node.scale[1], node.scale[2]) : Matrix3d.identity);
|
|
174
|
+
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);
|
|
175
|
+
rot.matrix.transposeInPlace(); // See comment on Matrix3d.createFromQuaternion
|
|
176
|
+
const trans = Transform.createTranslation(node.translation ? new Point3d(node.translation[0], node.translation[1], node.translation[2]) : Point3d.createZero());
|
|
177
|
+
toParent = scale.multiplyTransformTransform(rot);
|
|
178
|
+
trans.multiplyTransformTransform(toParent, toParent);
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
primitives,
|
|
182
|
+
toParent,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
parsePrimitives(mesh) {
|
|
186
|
+
const primitives = [];
|
|
187
|
+
if (!mesh.primitives)
|
|
188
|
+
return primitives;
|
|
189
|
+
for (const primitive of mesh.primitives) {
|
|
190
|
+
const parsedPrimitive = this.parsePrimitive(primitive);
|
|
191
|
+
if (parsedPrimitive)
|
|
192
|
+
primitives.push(parsedPrimitive);
|
|
193
|
+
}
|
|
194
|
+
return primitives;
|
|
195
|
+
}
|
|
196
|
+
parsePrimitive(primitive) {
|
|
197
|
+
const meshMode = JsonUtils.asInt(primitive.mode, GltfMeshMode.Triangles);
|
|
198
|
+
switch (meshMode) {
|
|
199
|
+
case GltfMeshMode.TriangleStrip:
|
|
200
|
+
return this.parseTrianglesPrimitive(primitive);
|
|
201
|
+
default:
|
|
202
|
+
// ###TODO_GLTF Make parser support all primitive types. Consumer can choose to do whatever with them.
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
parseTrianglesPrimitive(primitive) {
|
|
207
|
+
const posId = primitive.attributes.POSITION;
|
|
208
|
+
const pos = undefined !== posId ? this._accessors[posId] : undefined;
|
|
209
|
+
if (!pos)
|
|
210
|
+
return undefined;
|
|
211
|
+
return undefined; // ###TODO_GLTF
|
|
212
|
+
}
|
|
213
|
+
traverseNodes(nodeIds) {
|
|
214
|
+
return traverseGltfNodes(nodeIds, this._nodes, new Set());
|
|
215
|
+
}
|
|
216
|
+
async resolveResources() {
|
|
217
|
+
// Load any external images and buffers.
|
|
218
|
+
await this._resolveResources();
|
|
219
|
+
// If any meshes are draco-compressed, dynamically load the decoder module and then decode the meshes.
|
|
220
|
+
const dracoMeshes = [];
|
|
221
|
+
for (const node of this.traverseNodes(this._sceneNodes)) {
|
|
222
|
+
for (const meshId of getGltfNodeMeshIds(node)) {
|
|
223
|
+
const mesh = this._meshes[meshId];
|
|
224
|
+
if (mesh?.primitives)
|
|
225
|
+
for (const primitive of mesh.primitives)
|
|
226
|
+
if (primitive.extensions?.KHR_draco_mesh_compression)
|
|
227
|
+
dracoMeshes.push(primitive.extensions.KHR_draco_mesh_compression);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (dracoMeshes.length === 0)
|
|
231
|
+
return;
|
|
232
|
+
try {
|
|
233
|
+
const dracoLoader = (await import("@loaders.gl/draco")).DracoLoader;
|
|
234
|
+
await Promise.all(dracoMeshes.map(async (x) => this.decodeDracoMesh(x, dracoLoader)));
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
Logger.logWarning(FrontendLoggerCategory.Render, "Failed to decode draco-encoded glTF mesh");
|
|
238
|
+
Logger.logException(FrontendLoggerCategory.Render, err);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async _resolveResources() {
|
|
242
|
+
// ###TODO traverse the scene nodes to find resources referenced by them, instead of resolving everything - some resources may not
|
|
243
|
+
// be required for the scene.
|
|
244
|
+
const promises = [];
|
|
245
|
+
try {
|
|
246
|
+
for (const buffer of gltfDictionaryIterator(this._buffers))
|
|
247
|
+
if (!buffer.resolvedBuffer)
|
|
248
|
+
promises.push(this.resolveBuffer(buffer));
|
|
249
|
+
await Promise.all(promises);
|
|
250
|
+
if (this._isCanceled())
|
|
251
|
+
return;
|
|
252
|
+
promises.length = 0;
|
|
253
|
+
for (const image of gltfDictionaryIterator(this._images))
|
|
254
|
+
if (!image.resolvedImage)
|
|
255
|
+
promises.push(this.resolveImage(image));
|
|
256
|
+
await Promise.all(promises);
|
|
257
|
+
}
|
|
258
|
+
catch (_) {
|
|
259
|
+
// ###TODO_GLTF log
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
resolveUrl(uri) {
|
|
263
|
+
try {
|
|
264
|
+
return new URL(uri, this._baseUrl).toString();
|
|
265
|
+
}
|
|
266
|
+
catch (_) {
|
|
267
|
+
return undefined;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
async resolveBuffer(buffer) {
|
|
271
|
+
if (buffer.resolvedBuffer || undefined === buffer.uri)
|
|
272
|
+
return;
|
|
273
|
+
try {
|
|
274
|
+
const url = this.resolveUrl(buffer.uri);
|
|
275
|
+
const response = url ? await fetch(url) : undefined;
|
|
276
|
+
if (this._isCanceled())
|
|
277
|
+
return;
|
|
278
|
+
const data = await response?.arrayBuffer();
|
|
279
|
+
if (this._isCanceled())
|
|
280
|
+
return;
|
|
281
|
+
if (data)
|
|
282
|
+
buffer.resolvedBuffer = { data: new Uint8Array(data) };
|
|
283
|
+
}
|
|
284
|
+
catch (_) {
|
|
285
|
+
//
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async resolveImage(image) {
|
|
289
|
+
if (image.resolvedImage)
|
|
290
|
+
return;
|
|
291
|
+
const bvSrc = undefined !== image.bufferView ? image : image.extensions?.KHR_binary_glTF;
|
|
292
|
+
if (undefined !== bvSrc?.bufferView) {
|
|
293
|
+
const format = undefined !== bvSrc.mimeType ? getImageSourceFormatForMimeType(bvSrc.mimeType) : undefined;
|
|
294
|
+
const bufferView = this._bufferViews[bvSrc.bufferView];
|
|
295
|
+
if (undefined === format || !bufferView || !bufferView.byteLength || bufferView.byteLength < 0)
|
|
296
|
+
return;
|
|
297
|
+
const bufferData = this._buffers[bufferView.buffer]?.resolvedBuffer?.data;
|
|
298
|
+
if (!bufferData)
|
|
299
|
+
return;
|
|
300
|
+
const offset = bufferView.byteOffset ?? 0;
|
|
301
|
+
const bytes = bufferData.subarray(offset, offset + bufferView.byteLength);
|
|
302
|
+
try {
|
|
303
|
+
const imageSource = new ImageSource(bytes, format);
|
|
304
|
+
image.resolvedImage = await this._imageFromImageSource(imageSource);
|
|
305
|
+
}
|
|
306
|
+
catch (_) {
|
|
307
|
+
//
|
|
308
|
+
}
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const url = undefined !== image.uri ? this.resolveUrl(image.uri) : undefined;
|
|
312
|
+
if (undefined !== url)
|
|
313
|
+
image.resolvedImage = await tryImageElementFromUrl(url);
|
|
314
|
+
}
|
|
315
|
+
async decodeDracoMesh(ext, loader) {
|
|
316
|
+
const bv = this._bufferViews[ext.bufferView];
|
|
317
|
+
if (!bv || !bv.byteLength)
|
|
318
|
+
return;
|
|
319
|
+
let buf = this._buffers[bv.buffer]?.resolvedBuffer?.data;
|
|
320
|
+
if (!buf)
|
|
321
|
+
return;
|
|
322
|
+
const offset = bv.byteOffset ?? 0;
|
|
323
|
+
buf = buf.subarray(offset, offset + bv.byteLength);
|
|
324
|
+
const mesh = await loader.parse(buf, {}); // NB: `options` argument declared optional but will produce exception if not supplied.
|
|
325
|
+
if (mesh)
|
|
326
|
+
this._dracoMeshes.set(ext, mesh);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=GltfParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GltfParser.js","sourceRoot":"","sources":["../../../src/gltf/GltfParser.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Rendering\r\n */\r\n\r\nimport { ByteStream, JsonUtils, Logger, utf8ToString } from \"@itwin/core-bentley\";\r\nimport { Matrix3d, Point3d, Point4d, Transform } from \"@itwin/core-geometry\";\r\nimport { GlbHeader, ImageSource, TileFormat } from \"@itwin/core-common\";\r\nimport type { DracoLoader, DracoMesh } from \"@loaders.gl/draco\";\r\nimport { FrontendLoggerCategory } from \"../FrontendLoggerCategory\";\r\nimport {\r\n getImageSourceFormatForMimeType, imageBitmapFromImageSource, imageElementFromImageSource, tryImageElementFromUrl,\r\n} from \"../ImageUtil\";\r\nimport { TextureImageSource } from \"../render/RenderTexture\";\r\nimport {\r\n DracoMeshCompression, getGltfNodeMeshIds, GltfAccessor, GltfBuffer, GltfBufferViewProps, GltfDictionary, gltfDictionaryIterator, GltfDocument, GltfId, GltfImage, GltfMesh, GltfMeshMode, GltfMeshPrimitive, GltfNode, traverseGltfNodes,\r\n} from \"./GltfSchema\";\r\nimport { Gltf } from \"./GltfModel\";\r\n\r\n/** @internal */\r\nexport interface ParseGltfLogger {\r\n log(message: string, type: \"error\" | \"warning\" | \"info\"): void;\r\n}\r\n\r\n/** Arguments supplied to [[parseGltf]].\r\n * @internal\r\n */\r\nexport interface ParseGltfArgs {\r\n logger?: ParseGltfLogger;\r\n gltf: Uint8Array | GltfDocument;\r\n noCreateImageBitmap?: boolean;\r\n baseUrl?: string;\r\n isCanceled?: boolean;\r\n upAxis?: \"y\" | \"z\"; // default \"y\"\r\n}\r\n\r\n/** Parse a [[GltfDocument]] or binary representation thereof to produce a [[Gltf.Model]].\r\n * This implementation is incomplete and not currently used.\r\n * @internal\r\n */\r\nexport async function parseGltf(args: ParseGltfArgs): Promise<Gltf.Model | undefined> {\r\n const source = args.gltf;\r\n let version: number;\r\n let json: GltfDocument;\r\n let binary: Uint8Array | undefined;\r\n\r\n if (source instanceof Uint8Array) {\r\n // It may be JSON - check for magic indicating glb.\r\n const buffer = ByteStream.fromUint8Array(source);\r\n if (TileFormat.Gltf !== buffer.readUint32()) {\r\n try {\r\n const utf8Json = utf8ToString(source);\r\n if (!utf8Json)\r\n return undefined;\r\n\r\n json = JSON.parse(utf8Json);\r\n version = 2;\r\n } catch (_) {\r\n return undefined;\r\n }\r\n } else {\r\n buffer.reset();\r\n const header = new GlbHeader(buffer);\r\n if (!header.isValid)\r\n return undefined;\r\n\r\n version = header.version;\r\n if (header.binaryChunk)\r\n binary = new Uint8Array(source.buffer, source.byteOffset + header.binaryChunk.offset, header.binaryChunk.length);\r\n\r\n try {\r\n const jsonBytes = new Uint8Array(source.buffer, source.byteOffset + header.jsonChunk.offset, header.jsonChunk.length);\r\n const jsonStr = utf8ToString(jsonBytes);\r\n if (undefined === jsonStr)\r\n return undefined;\r\n\r\n json = JSON.parse(jsonStr);\r\n } catch (_) {\r\n return undefined;\r\n }\r\n }\r\n } else {\r\n version = 2; // ###TODO verify against source.asset?.version\r\n json = source;\r\n }\r\n\r\n // asset is required in glTF 2, optional in glTF 1\r\n const asset = JsonUtils.asObject(json.asset);\r\n if (version === 2 && !asset)\r\n return undefined;\r\n\r\n const document: GltfDocument = {\r\n asset,\r\n scene: JsonUtils.asString(json.scene),\r\n extensions: JsonUtils.asObject(json.extensions),\r\n extensionsUsed: JsonUtils.asArray(json.extensionsUsed),\r\n extensionsRequired: JsonUtils.asArray(json.extensionsRequired),\r\n accessors: JsonUtils.asObject(json.accessors),\r\n buffers: JsonUtils.asObject(json.buffers),\r\n bufferViews: JsonUtils.asObject(json.bufferViews),\r\n images: JsonUtils.asObject(json.images),\r\n materials: JsonUtils.asObject(json.materials),\r\n meshes: JsonUtils.asObject(json.meshes),\r\n nodes: JsonUtils.asObject(json.nodes),\r\n samplers: JsonUtils.asObject(json.samplers),\r\n scenes: JsonUtils.asObject(json.scenes),\r\n textures: JsonUtils.asObject(json.textures),\r\n techniques: JsonUtils.asObject(json.techniques),\r\n };\r\n\r\n if (!document.meshes)\r\n return undefined;\r\n\r\n const logger = args.logger ?? {\r\n log: (message: string, type: \"error\" | \"warning\" | \"info\") => {\r\n const category = `${FrontendLoggerCategory.Package}.gltf`;\r\n const fn = type === \"error\" ? \"logError\" : (type === \"warning\" ? \"logWarning\" : \"logInfo\");\r\n Logger[fn](category, message);\r\n },\r\n };\r\n\r\n const parser = new GltfParser({\r\n document,\r\n version,\r\n upAxis: args.upAxis ?? \"y\",\r\n binary,\r\n baseUrl: args.baseUrl,\r\n logger,\r\n isCanceled: () => args.isCanceled ?? false,\r\n imageFromImageSource: (args.noCreateImageBitmap ?\r\n async (imgSrc) => imageElementFromImageSource(imgSrc) :\r\n async (imgSrc) => imageBitmapFromImageSource(imgSrc)),\r\n });\r\n\r\n return parser.parse();\r\n}\r\n\r\ninterface GltfParserOptions {\r\n document: GltfDocument;\r\n version: number;\r\n upAxis: \"y\" | \"z\";\r\n binary?: Uint8Array;\r\n baseUrl?: string;\r\n logger: ParseGltfLogger;\r\n imageFromImageSource: (source: ImageSource) => Promise<TextureImageSource>;\r\n isCanceled: () => boolean;\r\n}\r\n\r\ntype ParserBuffer = GltfBuffer & { resolvedBuffer?: Gltf.Buffer };\r\ntype ParserImage = GltfImage & { resolvedImage?: TextureImageSource };\r\n\r\nclass GltfParser {\r\n private readonly _version: number;\r\n private readonly _upAxis: \"y\" | \"z\";\r\n private readonly _baseUrl?: string;\r\n private readonly _logger: ParseGltfLogger;\r\n private readonly _isCanceled: () => boolean;\r\n private readonly _buffers: GltfDictionary<ParserBuffer>;\r\n private readonly _images: GltfDictionary<ParserImage>;\r\n private readonly _nodes: GltfDictionary<GltfNode>;\r\n private readonly _meshes: GltfDictionary<GltfMesh>;\r\n private readonly _accessors: GltfDictionary<GltfAccessor>;\r\n private readonly _sceneNodes: GltfId[];\r\n private readonly _bufferViews: GltfDictionary<GltfBufferViewProps>;\r\n private readonly _imageFromImageSource: (source: ImageSource) => Promise<TextureImageSource>;\r\n private readonly _dracoMeshes = new Map<DracoMeshCompression, DracoMesh>();\r\n\r\n public constructor(options: GltfParserOptions) {\r\n this._version = options.version;\r\n this._upAxis = options.upAxis;\r\n this._baseUrl = options.baseUrl;\r\n this._logger = options.logger;\r\n this._isCanceled = options.isCanceled;\r\n this._imageFromImageSource = options.imageFromImageSource;\r\n\r\n const emptyDict = { };\r\n const doc = options.document;\r\n this._buffers = doc.buffers ?? emptyDict;\r\n this._images = doc.images ?? emptyDict;\r\n this._nodes = doc.nodes ?? emptyDict;\r\n this._meshes = doc.meshes ?? emptyDict;\r\n this._bufferViews = doc.bufferViews ?? emptyDict;\r\n this._accessors = doc.accessors ?? emptyDict;\r\n\r\n if (options.binary) {\r\n const buffer = this._buffers[this._version === 2 ? 0 : \"binary_glTF\"];\r\n if (buffer && undefined === buffer.uri)\r\n buffer.resolvedBuffer = { data: options.binary };\r\n }\r\n\r\n let sceneNodes;\r\n if (doc.scenes && undefined !== doc.scene)\r\n sceneNodes = doc.scenes[doc.scene]?.nodes;\r\n\r\n this._sceneNodes = sceneNodes ?? Object.keys(this._nodes);\r\n }\r\n\r\n public async parse(): Promise<Gltf.Model | undefined> {\r\n // ###TODO_GLTF RTC_CENTER\r\n // ###TODO_GLTF pseudo-rtc bias (apply translation to each point at read time, for scalable mesh...)\r\n const toWorld = undefined;\r\n\r\n await this.resolveResources();\r\n if (this._isCanceled())\r\n return undefined;\r\n\r\n // ###TODO_GLTF compute content range (maybe do so elsewhere?)\r\n // I think spec says POSITION must specify min and max?\r\n\r\n const nodes: Gltf.Node[] = [];\r\n for (const nodeKey of this._sceneNodes) {\r\n const node = this._nodes[nodeKey];\r\n if (node)\r\n nodes.push(this.parseNode(node));\r\n }\r\n\r\n return {\r\n toWorld,\r\n nodes,\r\n };\r\n }\r\n\r\n private parseNode(node: GltfNode): Gltf.Node {\r\n const primitives = [];\r\n for (const meshId of getGltfNodeMeshIds(node)) {\r\n const mesh = this._meshes[meshId];\r\n if (!mesh)\r\n continue;\r\n\r\n const parsedPrimitives = this.parsePrimitives(mesh);\r\n for (const primitive of parsedPrimitives)\r\n primitives.push(primitive);\r\n }\r\n\r\n let toParent;\r\n if (node.matrix) {\r\n const origin = Point3d.create(node.matrix[12], node.matrix[13], node.matrix[14]);\r\n const matrix = Matrix3d.createRowValues(\r\n node.matrix[0], node.matrix[4], node.matrix[8],\r\n node.matrix[1], node.matrix[5], node.matrix[9],\r\n node.matrix[2], node.matrix[6], node.matrix[10],\r\n );\r\n\r\n toParent = Transform.createOriginAndMatrix(origin, matrix);\r\n } else if (node.rotation || node.scale || node.translation) {\r\n // SPEC: To compose the local transformation matrix, TRS properties MUST be converted to matrices and postmultiplied in the T * R * S order;\r\n // first the scale is applied to the vertices, then the rotation, and then the translation.\r\n const scale = Transform.createRefs(undefined, node.scale ? Matrix3d.createScale(node.scale[0], node.scale[1], node.scale[2]) : Matrix3d.identity);\r\n 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);\r\n rot.matrix.transposeInPlace(); // See comment on Matrix3d.createFromQuaternion\r\n const trans = Transform.createTranslation(node.translation ? new Point3d(node.translation[0], node.translation[1], node.translation[2]) : Point3d.createZero());\r\n\r\n toParent = scale.multiplyTransformTransform(rot);\r\n trans.multiplyTransformTransform(toParent, toParent);\r\n }\r\n\r\n return {\r\n primitives,\r\n toParent,\r\n };\r\n }\r\n\r\n private parsePrimitives(mesh: GltfMesh): Gltf.AnyPrimitive[] {\r\n const primitives: Gltf.AnyPrimitive[] = [];\r\n if (!mesh.primitives)\r\n return primitives;\r\n\r\n for (const primitive of mesh.primitives) {\r\n const parsedPrimitive = this.parsePrimitive(primitive);\r\n if (parsedPrimitive)\r\n primitives.push(parsedPrimitive);\r\n }\r\n\r\n return primitives;\r\n }\r\n\r\n private parsePrimitive(primitive: GltfMeshPrimitive): Gltf.AnyPrimitive | undefined {\r\n const meshMode = JsonUtils.asInt(primitive.mode, GltfMeshMode.Triangles);\r\n switch (meshMode) {\r\n case GltfMeshMode.TriangleStrip:\r\n return this.parseTrianglesPrimitive(primitive);\r\n default:\r\n // ###TODO_GLTF Make parser support all primitive types. Consumer can choose to do whatever with them.\r\n return undefined;\r\n }\r\n }\r\n\r\n private parseTrianglesPrimitive(primitive: GltfMeshPrimitive): Gltf.TrianglesPrimitive | undefined {\r\n const posId = primitive.attributes.POSITION;\r\n const pos = undefined !== posId ? this._accessors[posId] : undefined;\r\n if (!pos)\r\n return undefined;\r\n\r\n return undefined; // ###TODO_GLTF\r\n }\r\n\r\n private traverseNodes(nodeIds: Iterable<GltfId>): Iterable<GltfNode> {\r\n return traverseGltfNodes(nodeIds, this._nodes, new Set<GltfId>());\r\n }\r\n\r\n private async resolveResources(): Promise<void> {\r\n // Load any external images and buffers.\r\n await this._resolveResources();\r\n\r\n // If any meshes are draco-compressed, dynamically load the decoder module and then decode the meshes.\r\n const dracoMeshes: DracoMeshCompression[] = [];\r\n\r\n for (const node of this.traverseNodes(this._sceneNodes)) {\r\n for (const meshId of getGltfNodeMeshIds(node)) {\r\n const mesh = this._meshes[meshId];\r\n if (mesh?.primitives)\r\n for (const primitive of mesh.primitives)\r\n if (primitive.extensions?.KHR_draco_mesh_compression)\r\n dracoMeshes.push(primitive.extensions.KHR_draco_mesh_compression);\r\n }\r\n }\r\n\r\n if (dracoMeshes.length === 0)\r\n return;\r\n\r\n try {\r\n const dracoLoader = (await import(\"@loaders.gl/draco\")).DracoLoader;\r\n await Promise.all(dracoMeshes.map(async (x) => this.decodeDracoMesh(x, dracoLoader)));\r\n } catch (err) {\r\n Logger.logWarning(FrontendLoggerCategory.Render, \"Failed to decode draco-encoded glTF mesh\");\r\n Logger.logException(FrontendLoggerCategory.Render, err);\r\n }\r\n }\r\n\r\n private async _resolveResources(): Promise<void> {\r\n // ###TODO traverse the scene nodes to find resources referenced by them, instead of resolving everything - some resources may not\r\n // be required for the scene.\r\n const promises: Array<Promise<void>> = [];\r\n try {\r\n for (const buffer of gltfDictionaryIterator(this._buffers))\r\n if (!buffer.resolvedBuffer)\r\n promises.push(this.resolveBuffer(buffer));\r\n\r\n await Promise.all(promises);\r\n if (this._isCanceled())\r\n return;\r\n\r\n promises.length = 0;\r\n for (const image of gltfDictionaryIterator(this._images))\r\n if (!image.resolvedImage)\r\n promises.push(this.resolveImage(image));\r\n\r\n await Promise.all(promises);\r\n } catch (_) {\r\n // ###TODO_GLTF log\r\n }\r\n }\r\n\r\n private resolveUrl(uri: string): string | undefined {\r\n try {\r\n return new URL(uri, this._baseUrl).toString();\r\n } catch (_) {\r\n return undefined;\r\n }\r\n }\r\n\r\n private async resolveBuffer(buffer: ParserBuffer): Promise<void> {\r\n if (buffer.resolvedBuffer || undefined === buffer.uri)\r\n return;\r\n\r\n try {\r\n const url = this.resolveUrl(buffer.uri);\r\n const response = url ? await fetch(url) : undefined;\r\n if (this._isCanceled())\r\n return;\r\n\r\n const data = await response?.arrayBuffer();\r\n if (this._isCanceled())\r\n return;\r\n\r\n if (data)\r\n buffer.resolvedBuffer = { data: new Uint8Array(data) };\r\n } catch (_) {\r\n //\r\n }\r\n }\r\n\r\n private async resolveImage(image: ParserImage): Promise<void> {\r\n if (image.resolvedImage)\r\n return;\r\n\r\n interface BufferViewSource { bufferView?: GltfId, mimeType?: string }\r\n const bvSrc: BufferViewSource | undefined = undefined !== image.bufferView ? image : image.extensions?.KHR_binary_glTF;\r\n if (undefined !== bvSrc?.bufferView) {\r\n const format = undefined !== bvSrc.mimeType ? getImageSourceFormatForMimeType(bvSrc.mimeType) : undefined;\r\n const bufferView = this._bufferViews[bvSrc.bufferView];\r\n if (undefined === format || !bufferView || !bufferView.byteLength || bufferView.byteLength < 0)\r\n return;\r\n\r\n const bufferData = this._buffers[bufferView.buffer]?.resolvedBuffer?.data;\r\n if (!bufferData)\r\n return;\r\n\r\n const offset = bufferView.byteOffset ?? 0;\r\n const bytes = bufferData.subarray(offset, offset + bufferView.byteLength);\r\n try {\r\n const imageSource = new ImageSource(bytes, format);\r\n image.resolvedImage = await this._imageFromImageSource(imageSource);\r\n } catch (_) {\r\n //\r\n }\r\n\r\n return;\r\n }\r\n\r\n const url = undefined !== image.uri ? this.resolveUrl(image.uri) : undefined;\r\n if (undefined !== url)\r\n image.resolvedImage = await tryImageElementFromUrl(url);\r\n }\r\n\r\n private async decodeDracoMesh(ext: DracoMeshCompression, loader: typeof DracoLoader): Promise<void> {\r\n const bv = this._bufferViews[ext.bufferView];\r\n if (!bv || !bv.byteLength)\r\n return;\r\n\r\n let buf = this._buffers[bv.buffer]?.resolvedBuffer?.data;\r\n if (!buf)\r\n return;\r\n\r\n const offset = bv.byteOffset ?? 0;\r\n buf = buf.subarray(offset, offset + bv.byteLength);\r\n const mesh = await loader.parse(buf, { }); // NB: `options` argument declared optional but will produce exception if not supplied.\r\n if (mesh)\r\n this._dracoMeshes.set(ext, mesh);\r\n }\r\n}\r\n"]}
|