@forgeax/engine-gltf 0.1.7 → 0.1.19
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/README.md +9 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/transmission-pack-carrier.integration.test.d.ts +2 -0
- package/dist/__tests__/transmission-pack-carrier.integration.test.d.ts.map +1 -0
- package/dist/bridge.d.ts.map +1 -1
- package/dist/check-extensions.d.ts +3 -3
- package/dist/check-extensions.d.ts.map +1 -1
- package/dist/cli-gltf.mjs +161 -69
- package/dist/cli-gltf.mjs.map +1 -1
- package/dist/errors.d.ts +7 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/gltf-importer.d.ts.map +1 -1
- package/dist/importer-entry.mjs +177 -72
- package/dist/importer-entry.mjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +177 -72
- package/dist/index.mjs.map +1 -1
- package/dist/material/parse-material.d.ts +118 -0
- package/dist/material/parse-material.d.ts.map +1 -0
- package/dist/node-file-entry.mjs +161 -69
- package/dist/node-file-entry.mjs.map +1 -1
- package/dist/parse-gltf.d.ts +17 -103
- package/dist/parse-gltf.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/__tests__/bridge-material-values.unit.test.ts +46 -0
- package/src/__tests__/gltf-error-derived-views.test-d.ts +4 -0
- package/src/__tests__/gltf-error-policy-owner.unit.test.ts +26 -178
- package/src/__tests__/gltf.unit.test.ts +28 -4
- package/src/__tests__/material-pack-refs.integration.test.ts +12 -0
- package/src/__tests__/parse-gltf.unit.test.ts +121 -0
- package/src/__tests__/transmission-pack-carrier.integration.test.ts +82 -0
- package/src/bridge.ts +12 -1
- package/src/check-extensions.ts +14 -9
- package/src/errors.ts +12 -0
- package/src/gltf-importer.ts +6 -0
- package/src/index.ts +1 -0
- package/src/material/parse-material.ts +342 -0
- package/src/parse-gltf.ts +50 -277
package/src/parse-gltf.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
// parse-gltf.ts - JSON-side glTF importer entry
|
|
2
|
-
//
|
|
3
|
-
// w17 lands the full parseGltf main function plus parseGlb / toAssetPack
|
|
4
|
-
// siblings. The helpers exported here include both the surface API
|
|
5
|
-
// (parseGltf / parseGlb / toAssetPack) and a few mesh / scene utilities
|
|
6
|
-
// the main path uses internally.
|
|
1
|
+
// parse-gltf.ts - JSON-side glTF importer entry.
|
|
2
|
+
// The public parse, GLB, asset-pack, mesh, and scene helpers live here.
|
|
7
3
|
|
|
8
4
|
import { mat4, quat, vec3 } from '@forgeax/engine-math';
|
|
9
5
|
import {
|
|
@@ -23,6 +19,14 @@ import { decodeColorAccessor } from './accessor/decode-color.js';
|
|
|
23
19
|
import { checkExtensions, type GltfExtensionsJson } from './check-extensions.js';
|
|
24
20
|
import { Base64DecodeError, dataUriBase64Payload, decodeBase64 } from './data-uri.js';
|
|
25
21
|
import { err, type GltfError, gltfErr, ok, type Result } from './errors.js';
|
|
22
|
+
import {
|
|
23
|
+
type GltfImageIr,
|
|
24
|
+
type GltfMaterialIr,
|
|
25
|
+
type GltfMaterialJson,
|
|
26
|
+
type GltfSamplerIr,
|
|
27
|
+
type GltfTextureIr,
|
|
28
|
+
parseMaterial,
|
|
29
|
+
} from './material/parse-material.js';
|
|
26
30
|
import {
|
|
27
31
|
type GltfBufferViewDecodeCapability,
|
|
28
32
|
type MeshoptBufferViewJson,
|
|
@@ -41,6 +45,21 @@ import {
|
|
|
41
45
|
import type { GltfSourceKeyError } from './source-key.js';
|
|
42
46
|
import { type DecomposedTransform, decomposeNodeTransform } from './transform.js';
|
|
43
47
|
|
|
48
|
+
export type {
|
|
49
|
+
GltfImageIr,
|
|
50
|
+
GltfMaterialIr,
|
|
51
|
+
GltfMaterialJson,
|
|
52
|
+
GltfNormalTextureInfoIr,
|
|
53
|
+
GltfOcclusionTextureInfoIr,
|
|
54
|
+
GltfSamplerIr,
|
|
55
|
+
GltfTextureInfoIr,
|
|
56
|
+
GltfTextureIr,
|
|
57
|
+
GltfTextureTransformIr,
|
|
58
|
+
NormalTextureInfoJson,
|
|
59
|
+
OcclusionTextureInfoJson,
|
|
60
|
+
TextureInfoJson,
|
|
61
|
+
} from './material/parse-material.js';
|
|
62
|
+
|
|
44
63
|
export interface MeshPrimitiveJson {
|
|
45
64
|
readonly attributes?: Record<string, number>;
|
|
46
65
|
readonly indices?: number;
|
|
@@ -55,12 +74,7 @@ export interface MeshJson {
|
|
|
55
74
|
readonly primitives: readonly MeshPrimitiveJson[];
|
|
56
75
|
}
|
|
57
76
|
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
// Shape: a denormalised view of the parsed glTF JSON, post-validation,
|
|
61
|
-
// suitable for downstream `toAssetPack` and runtime AssetRegistry
|
|
62
|
-
// hand-off. Math types are POD (number tuples), no Vec3/Quat brand at
|
|
63
|
-
// the boundary (charter proposition 5).
|
|
77
|
+
// Tier-B IR: validated glTF JSON projected into downstream POD records.
|
|
64
78
|
|
|
65
79
|
interface InstancingAttributes {
|
|
66
80
|
readonly TRANSLATION?: number;
|
|
@@ -217,26 +231,26 @@ export interface GltfMeshIr {
|
|
|
217
231
|
readonly positions: Float32Array;
|
|
218
232
|
readonly normals?: Float32Array;
|
|
219
233
|
readonly texcoord0?: Float32Array;
|
|
220
|
-
/** TEXCOORD_1 per-vertex UV set 1
|
|
234
|
+
/** TEXCOORD_1 per-vertex UV set 1. */
|
|
221
235
|
readonly texcoord1?: Float32Array;
|
|
222
|
-
/** TEXCOORD_2 per-vertex UV set 2
|
|
236
|
+
/** TEXCOORD_2 per-vertex UV set 2. */
|
|
223
237
|
readonly texcoord2?: Float32Array;
|
|
224
|
-
/** TEXCOORD_3 per-vertex UV set 3
|
|
238
|
+
/** TEXCOORD_3 per-vertex UV set 3. */
|
|
225
239
|
readonly texcoord3?: Float32Array;
|
|
226
|
-
/** TEXCOORD_4 per-vertex UV set 4
|
|
240
|
+
/** TEXCOORD_4 per-vertex UV set 4. */
|
|
227
241
|
readonly texcoord4?: Float32Array;
|
|
228
|
-
/** TEXCOORD_5 per-vertex UV set 5
|
|
242
|
+
/** TEXCOORD_5 per-vertex UV set 5. */
|
|
229
243
|
readonly texcoord5?: Float32Array;
|
|
230
|
-
/** TEXCOORD_6 per-vertex UV set 6
|
|
244
|
+
/** TEXCOORD_6 per-vertex UV set 6. */
|
|
231
245
|
readonly texcoord6?: Float32Array;
|
|
232
|
-
/** TEXCOORD_7 per-vertex UV set 7
|
|
246
|
+
/** TEXCOORD_7 per-vertex UV set 7. */
|
|
233
247
|
readonly texcoord7?: Float32Array;
|
|
234
248
|
readonly tangents?: Float32Array;
|
|
235
|
-
/** COLOR_0 importer carrier
|
|
249
|
+
/** COLOR_0 importer carrier. */
|
|
236
250
|
readonly colors0?: Float32Array;
|
|
237
|
-
/** JOINTS_0 per-vertex joint indices
|
|
251
|
+
/** JOINTS_0 per-vertex joint indices. */
|
|
238
252
|
readonly joints0?: Uint16Array;
|
|
239
|
-
/** WEIGHTS_0 per-vertex skin weights
|
|
253
|
+
/** WEIGHTS_0 per-vertex skin weights. */
|
|
240
254
|
readonly weights0?: Float32Array;
|
|
241
255
|
readonly morphTargets?: readonly {
|
|
242
256
|
readonly position?: Float32Array;
|
|
@@ -244,109 +258,17 @@ export interface GltfMeshIr {
|
|
|
244
258
|
readonly tangent?: Float32Array;
|
|
245
259
|
}[];
|
|
246
260
|
readonly morphWeights?: Float32Array;
|
|
247
|
-
/**
|
|
248
|
-
* Optional per-glTF-spec: when omitted, primitive declares non-indexed
|
|
249
|
-
* geometry (vertex buffer is consumed in vertex order, every 3 verts =
|
|
250
|
-
* 1 triangle for triangle-list). bridge.ts handles undefined by routing
|
|
251
|
-
* MeshAsset.indices to undefined and submesh.indexCount=0 (vertexCount
|
|
252
|
-
* carries the draw count for `pass.draw(vertexCount)`).
|
|
253
|
-
* bug-20260612 hello-skin visual layered gate: prior shape coerced
|
|
254
|
-
* undefined into Uint16Array(0) and tripped MeshAsset.indices !==
|
|
255
|
-
* undefined branches downstream into drawIndexed(0).
|
|
256
|
-
* U16 (incl. widened U8) or U32 — width preserved from the source accessor;
|
|
257
|
-
* bridge.ts narrows U32 to U16 when the merged maxIndex fits.
|
|
258
|
-
*/
|
|
261
|
+
/** Undefined means non-indexed; otherwise source width is preserved. */
|
|
259
262
|
readonly indices?: Uint16Array | Uint32Array;
|
|
260
263
|
readonly materialIndex: number | null;
|
|
261
|
-
/**
|
|
262
|
-
* Owning glTF mesh index in the original document (`gltf.meshes[meshIndex]`).
|
|
263
|
-
* After OOS-7 flattening, multiple GltfMeshIr entries may share the same
|
|
264
|
-
* meshIndex (one per primitive). Bridge layer uses this to filter material
|
|
265
|
-
* collection per node, fixing the verify-r1 charter-defect where multi
|
|
266
|
-
* glTF-mesh documents would silently misalign materials across nodes.
|
|
267
|
-
*/
|
|
264
|
+
/** Owning glTF mesh index; multiple IR rows may share it after flattening. */
|
|
268
265
|
readonly meshIndex: number;
|
|
269
266
|
}
|
|
270
267
|
|
|
271
|
-
export interface GltfTextureIr {
|
|
272
|
-
readonly sampler?: number;
|
|
273
|
-
readonly source: number;
|
|
274
|
-
readonly name?: string;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
export interface GltfTextureTransformIr {
|
|
278
|
-
readonly offset?: readonly [number, number];
|
|
279
|
-
readonly rotation?: number;
|
|
280
|
-
readonly scale?: readonly [number, number];
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
export interface GltfTextureInfoIr {
|
|
284
|
-
readonly texture: number;
|
|
285
|
-
readonly sampler?: number;
|
|
286
|
-
readonly texCoord?: number;
|
|
287
|
-
readonly transform?: GltfTextureTransformIr;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
export interface GltfNormalTextureInfoIr extends GltfTextureInfoIr {
|
|
291
|
-
readonly scale?: number;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
export interface GltfOcclusionTextureInfoIr extends GltfTextureInfoIr {
|
|
295
|
-
readonly strength?: number;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
export interface GltfImageIr {
|
|
299
|
-
readonly uri?: string;
|
|
300
|
-
readonly mimeType?: string;
|
|
301
|
-
readonly bufferView?: number;
|
|
302
|
-
readonly name?: string;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
export interface GltfSamplerIr {
|
|
306
|
-
readonly magFilter?: number;
|
|
307
|
-
readonly minFilter?: number;
|
|
308
|
-
readonly wrapS: number;
|
|
309
|
-
readonly wrapT: number;
|
|
310
|
-
readonly name?: string;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
export interface GltfMaterialIr {
|
|
314
|
-
readonly name?: string;
|
|
315
|
-
readonly baseColorFactor: readonly [number, number, number, number];
|
|
316
|
-
/** glTF emissiveFactor; omitted means the glTF default [0, 0, 0]. */
|
|
317
|
-
readonly emissiveFactor?: readonly [number, number, number];
|
|
318
|
-
readonly baseColorTexture?: GltfTextureInfoIr | number;
|
|
319
|
-
/** Texture binding for the emissive map. */
|
|
320
|
-
readonly emissiveTexture?: GltfTextureInfoIr | number;
|
|
321
|
-
readonly metallicFactor: number;
|
|
322
|
-
readonly roughnessFactor: number;
|
|
323
|
-
readonly metallicRoughnessTexture?: GltfTextureInfoIr | number;
|
|
324
|
-
readonly normalTexture?: GltfNormalTextureInfoIr | number;
|
|
325
|
-
readonly occlusionTexture?: GltfOcclusionTextureInfoIr | number;
|
|
326
|
-
/**
|
|
327
|
-
* glTF `alphaMode` (`'OPAQUE'` | `'MASK'` | `'BLEND'`). Absent -> `'OPAQUE'`
|
|
328
|
-
* (glTF spec default). Drives the bridge's transparent / alpha-test routing.
|
|
329
|
-
*/
|
|
330
|
-
readonly alphaMode?: 'OPAQUE' | 'MASK' | 'BLEND';
|
|
331
|
-
/** glTF `alphaCutoff` (MASK-mode threshold; glTF spec default 0.5). */
|
|
332
|
-
readonly alphaCutoff?: number;
|
|
333
|
-
/**
|
|
334
|
-
* glTF `doubleSided`. Absent -> false (the glTF spec default). The bridge
|
|
335
|
-
* maps this to a no-cull material pass so reverse-facing glass and cards
|
|
336
|
-
* remain visible without changing their authored winding.
|
|
337
|
-
*/
|
|
338
|
-
readonly doubleSided?: boolean;
|
|
339
|
-
/**
|
|
340
|
-
* baseColorTexture UV-set index (glTF `baseColorTexture.texCoord`). Absent
|
|
341
|
-
* -> 0. Selects which interleaved UV set the base-color sampler reads.
|
|
342
|
-
*/
|
|
343
|
-
readonly baseColorTexCoord?: number;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
268
|
export interface NodeInstancingIr {
|
|
347
|
-
/** Number of instances.
|
|
269
|
+
/** Number of instances. */
|
|
348
270
|
readonly count: number;
|
|
349
|
-
/**
|
|
271
|
+
/** Column-major transforms packed into one Float32Array. */
|
|
350
272
|
readonly transforms: Float32Array;
|
|
351
273
|
}
|
|
352
274
|
|
|
@@ -367,16 +289,12 @@ export interface GltfNodeIr {
|
|
|
367
289
|
readonly name?: string;
|
|
368
290
|
readonly transform: DecomposedTransform;
|
|
369
291
|
readonly meshIndex: number | null;
|
|
370
|
-
/** Node-authored morph weights override mesh defaults
|
|
292
|
+
/** Node-authored morph weights override mesh defaults. */
|
|
371
293
|
readonly morphWeights?: Float32Array;
|
|
372
|
-
/** Valid when node carries `skin` reference. Null when no skin. */
|
|
373
294
|
readonly skinIndex: number | null;
|
|
374
295
|
readonly children: readonly number[];
|
|
375
|
-
/** Present when node carries EXT_mesh_gpu_instancing (feat-20260518). */
|
|
376
296
|
readonly instancing?: NodeInstancingIr;
|
|
377
|
-
/** glTF camera index. Null when the node does not reference a camera. */
|
|
378
297
|
readonly camera: number | null;
|
|
379
|
-
/** KHR_lights_punctual light index. Null when the node has no light. */
|
|
380
298
|
readonly lightIndex?: number | null;
|
|
381
299
|
}
|
|
382
300
|
|
|
@@ -430,29 +348,6 @@ interface BuffersJson {
|
|
|
430
348
|
readonly uri?: string;
|
|
431
349
|
}
|
|
432
350
|
|
|
433
|
-
interface TextureTransformJson {
|
|
434
|
-
readonly offset?: readonly number[];
|
|
435
|
-
readonly rotation?: number;
|
|
436
|
-
readonly scale?: readonly number[];
|
|
437
|
-
readonly texCoord?: number;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
interface TextureInfoJson {
|
|
441
|
-
readonly index: number;
|
|
442
|
-
readonly texCoord?: number;
|
|
443
|
-
readonly extensions?: {
|
|
444
|
-
readonly KHR_texture_transform?: TextureTransformJson;
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
interface NormalTextureInfoJson extends TextureInfoJson {
|
|
449
|
-
readonly scale?: number;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
interface OcclusionTextureInfoJson extends TextureInfoJson {
|
|
453
|
-
readonly strength?: number;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
351
|
interface RootGltfJson extends GltfExtensionsJson {
|
|
457
352
|
readonly asset?: { readonly version?: string };
|
|
458
353
|
readonly scene?: number;
|
|
@@ -501,23 +396,7 @@ interface RootGltfJson extends GltfExtensionsJson {
|
|
|
501
396
|
readonly inverseBindMatrices?: number;
|
|
502
397
|
}>;
|
|
503
398
|
readonly meshes?: readonly MeshJson[];
|
|
504
|
-
readonly materials?: ReadonlyArray<
|
|
505
|
-
readonly name?: string;
|
|
506
|
-
readonly pbrMetallicRoughness?: {
|
|
507
|
-
readonly baseColorFactor?: readonly number[];
|
|
508
|
-
readonly baseColorTexture?: TextureInfoJson;
|
|
509
|
-
readonly metallicFactor?: number;
|
|
510
|
-
readonly roughnessFactor?: number;
|
|
511
|
-
readonly metallicRoughnessTexture?: TextureInfoJson;
|
|
512
|
-
};
|
|
513
|
-
readonly normalTexture?: NormalTextureInfoJson;
|
|
514
|
-
readonly emissiveFactor?: readonly number[];
|
|
515
|
-
readonly emissiveTexture?: TextureInfoJson;
|
|
516
|
-
readonly occlusionTexture?: OcclusionTextureInfoJson;
|
|
517
|
-
readonly alphaMode?: string;
|
|
518
|
-
readonly alphaCutoff?: number;
|
|
519
|
-
readonly doubleSided?: boolean;
|
|
520
|
-
}>;
|
|
399
|
+
readonly materials?: ReadonlyArray<GltfMaterialJson>;
|
|
521
400
|
readonly textures?: ReadonlyArray<{
|
|
522
401
|
readonly sampler?: number;
|
|
523
402
|
readonly source?: number;
|
|
@@ -556,37 +435,6 @@ interface RootGltfJson extends GltfExtensionsJson {
|
|
|
556
435
|
}>;
|
|
557
436
|
}
|
|
558
437
|
|
|
559
|
-
function tuple2(values: readonly number[] | undefined): readonly [number, number] | undefined {
|
|
560
|
-
if (values === undefined || values.length < 2) return undefined;
|
|
561
|
-
return [values[0] ?? 0, values[1] ?? 0];
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
function parseTextureInfo(
|
|
565
|
-
info: TextureInfoJson,
|
|
566
|
-
textures: readonly GltfTextureIr[],
|
|
567
|
-
): GltfTextureInfoIr {
|
|
568
|
-
const transformJson = info.extensions?.KHR_texture_transform;
|
|
569
|
-
const offset = tuple2(transformJson?.offset);
|
|
570
|
-
const scale = tuple2(transformJson?.scale);
|
|
571
|
-
const transform =
|
|
572
|
-
offset === undefined && transformJson?.rotation === undefined && scale === undefined
|
|
573
|
-
? undefined
|
|
574
|
-
: {
|
|
575
|
-
...(offset === undefined ? {} : { offset }),
|
|
576
|
-
...(transformJson?.rotation === undefined ? {} : { rotation: transformJson.rotation }),
|
|
577
|
-
...(scale === undefined ? {} : { scale }),
|
|
578
|
-
};
|
|
579
|
-
const sampler = textures[info.index]?.sampler;
|
|
580
|
-
return {
|
|
581
|
-
texture: info.index,
|
|
582
|
-
...(sampler === undefined ? {} : { sampler }),
|
|
583
|
-
...(info.texCoord === undefined && transformJson?.texCoord === undefined
|
|
584
|
-
? {}
|
|
585
|
-
: { texCoord: transformJson?.texCoord ?? info.texCoord }),
|
|
586
|
-
...(transform === undefined ? {} : { transform }),
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
|
|
590
438
|
export type ExternalLoader = (uri: string) => Promise<ArrayBuffer>;
|
|
591
439
|
|
|
592
440
|
async function resolveBuffer(
|
|
@@ -757,14 +605,7 @@ async function parseGltfWithBin(
|
|
|
757
605
|
buffers.splice(0, buffers.length, ...projected.value.buffers);
|
|
758
606
|
|
|
759
607
|
const meshes: GltfMeshIr[] = [];
|
|
760
|
-
//
|
|
761
|
-
// build-time consumers (gltfImporter scene arm) can hand them to
|
|
762
|
-
// gltfDocToSceneAsset's `meshPrimitiveCount` parameter without re-parsing
|
|
763
|
-
// the JSON. Without this, importGltf at gltf-importer.ts ~272 walks the
|
|
764
|
-
// already-flattened doc.meshes (one entry per primitive) and cannot
|
|
765
|
-
// reconstruct the gltfMesh -> primitiveCount map; the bridge then uses
|
|
766
|
-
// identity (gltfMeshIdx == flatIdx) and any multi-primitive .gltf imports
|
|
767
|
-
// misindex meshes after the first primitive.
|
|
608
|
+
// Preserve original mesh -> primitive counts for the flattened IR.
|
|
768
609
|
const meshPrimitiveCount = new Map<number, number>();
|
|
769
610
|
for (let meshIndex = 0; meshIndex < meshesJson.length; meshIndex++) {
|
|
770
611
|
const meshJson = meshesJson[meshIndex];
|
|
@@ -826,9 +667,7 @@ async function parseGltfWithBin(
|
|
|
826
667
|
const positions = new Float32Array(positionsDecoded.length);
|
|
827
668
|
positions.set(positionsDecoded);
|
|
828
669
|
|
|
829
|
-
// Decode optional
|
|
830
|
-
// TANGENT (VEC4). Each uses the existing decodeAttributeAccessor helper.
|
|
831
|
-
// Missing attributes leave the GltfMeshIr field undefined.
|
|
670
|
+
// Decode optional NORMAL, TEXCOORD_0, and TANGENT attributes.
|
|
832
671
|
const attrs = prim.attributes ?? {};
|
|
833
672
|
|
|
834
673
|
let colors0: Float32Array | undefined;
|
|
@@ -1165,12 +1004,6 @@ async function parseGltfWithBin(
|
|
|
1165
1004
|
owned.set(src);
|
|
1166
1005
|
indices = owned;
|
|
1167
1006
|
} else if (indexDecoded.value.kind === 'u32') {
|
|
1168
|
-
// U32 indices ride through end-to-end: MeshAsset.indices is
|
|
1169
|
-
// `Uint16Array | Uint32Array`, mesh-bin serializes iwidth=4, and
|
|
1170
|
-
// the GPU runtime auto-selects 'uint32' via `instanceof Uint32Array`
|
|
1171
|
-
// (createRenderer.ts). bridge.ts merges by value, so small meshes
|
|
1172
|
-
// whose maxIndex < 65536 are losslessly narrowed to Uint16 there.
|
|
1173
|
-
// Re-allocate over a fresh ArrayBuffer for the same reason as u16.
|
|
1174
1007
|
const src = indexDecoded.value.data;
|
|
1175
1008
|
const owned = new Uint32Array(src.length);
|
|
1176
1009
|
owned.set(src);
|
|
@@ -1263,70 +1096,12 @@ async function parseGltfWithBin(
|
|
|
1263
1096
|
});
|
|
1264
1097
|
}
|
|
1265
1098
|
|
|
1266
|
-
// Materials
|
|
1267
|
-
const materialsJson = json.materials ?? [];
|
|
1099
|
+
// Materials are normalized by the material parser owner before entering the IR.
|
|
1268
1100
|
const materials: GltfMaterialIr[] = [];
|
|
1269
|
-
for (const
|
|
1270
|
-
const
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
baseColor[0] ?? 1,
|
|
1274
|
-
baseColor[1] ?? 1,
|
|
1275
|
-
baseColor[2] ?? 1,
|
|
1276
|
-
baseColor[3] ?? 1,
|
|
1277
|
-
];
|
|
1278
|
-
|
|
1279
|
-
const alphaMode =
|
|
1280
|
-
matJson.alphaMode === 'MASK' || matJson.alphaMode === 'BLEND' ? matJson.alphaMode : undefined;
|
|
1281
|
-
const alphaCutoff = alphaMode === 'MASK' ? (matJson.alphaCutoff ?? 0.5) : undefined;
|
|
1282
|
-
const emissiveFactor = matJson.emissiveFactor;
|
|
1283
|
-
const emissiveFactor3: readonly [number, number, number] = [
|
|
1284
|
-
emissiveFactor?.[0] ?? 0,
|
|
1285
|
-
emissiveFactor?.[1] ?? 0,
|
|
1286
|
-
emissiveFactor?.[2] ?? 0,
|
|
1287
|
-
];
|
|
1288
|
-
materials.push({
|
|
1289
|
-
...(matJson.name === undefined ? {} : { name: matJson.name }),
|
|
1290
|
-
baseColorFactor: baseColor4,
|
|
1291
|
-
...(emissiveFactor === undefined ? {} : { emissiveFactor: emissiveFactor3 }),
|
|
1292
|
-
metallicFactor: pbr?.metallicFactor ?? 1.0,
|
|
1293
|
-
roughnessFactor: pbr?.roughnessFactor ?? 1.0,
|
|
1294
|
-
...(pbr?.baseColorTexture === undefined
|
|
1295
|
-
? {}
|
|
1296
|
-
: { baseColorTexture: parseTextureInfo(pbr.baseColorTexture, textures) }),
|
|
1297
|
-
...(pbr?.metallicRoughnessTexture === undefined
|
|
1298
|
-
? {}
|
|
1299
|
-
: { metallicRoughnessTexture: parseTextureInfo(pbr.metallicRoughnessTexture, textures) }),
|
|
1300
|
-
...(matJson.normalTexture === undefined
|
|
1301
|
-
? {}
|
|
1302
|
-
: {
|
|
1303
|
-
normalTexture: {
|
|
1304
|
-
...parseTextureInfo(matJson.normalTexture, textures),
|
|
1305
|
-
...(matJson.normalTexture.scale === undefined
|
|
1306
|
-
? {}
|
|
1307
|
-
: { scale: matJson.normalTexture.scale }),
|
|
1308
|
-
},
|
|
1309
|
-
}),
|
|
1310
|
-
...(matJson.occlusionTexture === undefined
|
|
1311
|
-
? {}
|
|
1312
|
-
: {
|
|
1313
|
-
occlusionTexture: {
|
|
1314
|
-
...parseTextureInfo(matJson.occlusionTexture, textures),
|
|
1315
|
-
...(matJson.occlusionTexture.strength === undefined
|
|
1316
|
-
? {}
|
|
1317
|
-
: { strength: matJson.occlusionTexture.strength }),
|
|
1318
|
-
},
|
|
1319
|
-
}),
|
|
1320
|
-
...(matJson.emissiveTexture === undefined
|
|
1321
|
-
? {}
|
|
1322
|
-
: { emissiveTexture: parseTextureInfo(matJson.emissiveTexture, textures) }),
|
|
1323
|
-
...(alphaMode === undefined ? {} : { alphaMode }),
|
|
1324
|
-
...(alphaCutoff === undefined ? {} : { alphaCutoff }),
|
|
1325
|
-
...(matJson.doubleSided === true ? { doubleSided: true } : {}),
|
|
1326
|
-
...(pbr?.baseColorTexture?.texCoord === undefined || pbr.baseColorTexture.texCoord === 0
|
|
1327
|
-
? {}
|
|
1328
|
-
: { baseColorTexCoord: pbr.baseColorTexture.texCoord }),
|
|
1329
|
-
});
|
|
1101
|
+
for (const material of json.materials ?? []) {
|
|
1102
|
+
const parsedMaterial = parseMaterial(material, textures);
|
|
1103
|
+
if (!parsedMaterial.ok) return err(parsedMaterial.error);
|
|
1104
|
+
materials.push(parsedMaterial.value);
|
|
1330
1105
|
}
|
|
1331
1106
|
|
|
1332
1107
|
// Nodes + diagnostics.
|
|
@@ -1725,7 +1500,5 @@ export function toAssetPack(
|
|
|
1725
1500
|
return ok({ meta, subAssets: reuse.value.subAssets });
|
|
1726
1501
|
}
|
|
1727
1502
|
|
|
1728
|
-
//
|
|
1729
|
-
// downstream consumers can grep the constants table from a single
|
|
1730
|
-
// import. (TS strict mode would otherwise drop the binding.)
|
|
1503
|
+
// Keep the component-type table available from this importer module.
|
|
1731
1504
|
export { COMPONENT_TYPE };
|