@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.
- package/lib/cjs/render/GraphicBuilder.d.ts +1 -1
- package/lib/cjs/render/GraphicBuilder.js.map +1 -1
- package/lib/cjs/tile/B3dmReader.d.ts +1 -0
- package/lib/cjs/tile/B3dmReader.d.ts.map +1 -1
- package/lib/cjs/tile/B3dmReader.js +3 -2
- package/lib/cjs/tile/B3dmReader.js.map +1 -1
- package/lib/cjs/tile/GltfReader.d.ts +438 -32
- package/lib/cjs/tile/GltfReader.d.ts.map +1 -1
- package/lib/cjs/tile/GltfReader.js +409 -166
- package/lib/cjs/tile/GltfReader.js.map +1 -1
- package/lib/cjs/tile/I3dmReader.d.ts +1 -0
- package/lib/cjs/tile/I3dmReader.d.ts.map +1 -1
- package/lib/cjs/tile/I3dmReader.js +2 -1
- package/lib/cjs/tile/I3dmReader.js.map +1 -1
- package/lib/cjs/tile/ImdlReader.d.ts +334 -10
- package/lib/cjs/tile/ImdlReader.d.ts.map +1 -1
- package/lib/cjs/tile/ImdlReader.js +84 -44
- package/lib/cjs/tile/ImdlReader.js.map +1 -1
- package/lib/esm/render/GraphicBuilder.d.ts +1 -1
- package/lib/esm/render/GraphicBuilder.js.map +1 -1
- package/lib/esm/tile/B3dmReader.d.ts +1 -0
- package/lib/esm/tile/B3dmReader.d.ts.map +1 -1
- package/lib/esm/tile/B3dmReader.js +4 -3
- package/lib/esm/tile/B3dmReader.js.map +1 -1
- package/lib/esm/tile/GltfReader.d.ts +438 -32
- package/lib/esm/tile/GltfReader.d.ts.map +1 -1
- package/lib/esm/tile/GltfReader.js +384 -143
- package/lib/esm/tile/GltfReader.js.map +1 -1
- package/lib/esm/tile/I3dmReader.d.ts +1 -0
- package/lib/esm/tile/I3dmReader.d.ts.map +1 -1
- package/lib/esm/tile/I3dmReader.js +2 -1
- package/lib/esm/tile/I3dmReader.js.map +1 -1
- package/lib/esm/tile/ImdlReader.d.ts +334 -10
- package/lib/esm/tile/ImdlReader.d.ts.map +1 -1
- package/lib/esm/tile/ImdlReader.js +86 -46
- package/lib/esm/tile/ImdlReader.js.map +1 -1
- 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,
|
|
178
|
+
constructor(buffer, binaryData, glTF, yAxisUp) {
|
|
27
179
|
this.buffer = buffer;
|
|
28
180
|
this.binaryData = binaryData;
|
|
29
|
-
this.
|
|
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
|
|
48
|
-
const
|
|
49
|
-
if (undefined ===
|
|
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
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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,
|
|
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.
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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 (
|
|
154
|
-
if (
|
|
155
|
-
transform = core_geometry_1.Transform.
|
|
156
|
-
else if (
|
|
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 (
|
|
383
|
+
if (transformToRoot)
|
|
163
384
|
transform = transformToRoot.multiplyTransformTransform(transform);
|
|
164
385
|
range = transform.inverse().multiplyRange(contentRange);
|
|
165
386
|
}
|
|
166
|
-
|
|
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,
|
|
425
|
+
readNodeAndCreateGraphics(renderGraphicList, node, featureTable, transformStack, instances, pseudoRtcBias) {
|
|
206
426
|
if (undefined === node)
|
|
207
427
|
return core_common_1.TileReadStatus.InvalidTileData;
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
|
265
|
-
|
|
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
|
|
506
|
+
case GltfDataType.UnsignedByte:
|
|
281
507
|
dataSize = 1;
|
|
282
508
|
break;
|
|
283
|
-
case
|
|
509
|
+
case GltfDataType.UnsignedShort:
|
|
284
510
|
dataSize = 2;
|
|
285
511
|
break;
|
|
286
|
-
case
|
|
287
|
-
case
|
|
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
|
|
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,
|
|
315
|
-
readBufferData16(json, accessorName) { return this.readBufferData(json, accessorName,
|
|
316
|
-
readBufferData8(json, accessorName) { return this.readBufferData(json, accessorName,
|
|
317
|
-
readBufferDataFloat(json, accessorName) { return this.readBufferData(json, accessorName,
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
351
|
-
|
|
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 = (
|
|
355
|
-
const ext = Array.isArray(techniques) ? (
|
|
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 ===
|
|
362
|
-
return extractId((
|
|
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((
|
|
367
|
-
|
|
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 =
|
|
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
|
|
391
|
-
const displayParams = this.createDisplayParams(
|
|
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,
|
|
597
|
+
const meshMode = core_bentley_1.JsonUtils.asInt(primitive.mode, GltfMeshMode.Triangles);
|
|
396
598
|
switch (meshMode) {
|
|
397
|
-
case
|
|
599
|
+
case GltfMeshMode.Lines:
|
|
398
600
|
primitiveType = MeshPrimitives_1.Mesh.PrimitiveType.Polyline;
|
|
399
601
|
break;
|
|
400
|
-
case
|
|
602
|
+
case GltfMeshMode.Points:
|
|
401
603
|
primitiveType = MeshPrimitives_1.Mesh.PrimitiveType.Point;
|
|
402
604
|
break;
|
|
403
|
-
case
|
|
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 (
|
|
431
|
-
texStep =
|
|
432
|
-
else
|
|
433
|
-
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 ((
|
|
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 ((
|
|
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 (
|
|
534
|
-
const buffer = view.toBufferData(
|
|
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 (
|
|
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(
|
|
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
|
|
612
|
-
const data = view.toBufferData(
|
|
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
|
|
625
|
-
const data = view.toBufferData(
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
|
|
927
|
+
var _a, _b;
|
|
928
|
+
if (undefined === this._glTF.textures)
|
|
726
929
|
return;
|
|
727
930
|
const transparentTextures = new Set();
|
|
728
|
-
|
|
729
|
-
const
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|