@forgeax/engine-gltf 0.1.4 → 0.1.7
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 +18 -11
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/extension-admission.unit.test.d.ts +2 -0
- package/dist/__tests__/extension-admission.unit.test.d.ts.map +1 -0
- package/dist/__tests__/source-key-diagnostics.integration.test.d.ts +2 -0
- package/dist/__tests__/source-key-diagnostics.integration.test.d.ts.map +1 -0
- package/dist/bridge.d.ts +5 -6
- package/dist/bridge.d.ts.map +1 -1
- package/dist/check-extensions.d.ts.map +1 -1
- package/dist/cli-gltf.mjs +32 -16
- package/dist/cli-gltf.mjs.map +1 -1
- package/dist/gltf-importer.d.ts.map +1 -1
- package/dist/importer-entry.mjs +5 -1
- 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 +31 -10
- package/dist/index.mjs.map +1 -1
- package/dist/node-file-entry.mjs +5 -1
- package/dist/node-file-entry.mjs.map +1 -1
- package/dist/parse-gltf.d.ts.map +1 -1
- package/dist/source-key.d.ts +26 -4
- package/dist/source-key.d.ts.map +1 -1
- package/package.json +13 -15
- package/src/__tests__/extension-admission.unit.test.ts +19 -0
- package/src/__tests__/gltf.unit.test.ts +1 -1
- package/src/__tests__/material-texture-transform.unit.test.ts +30 -0
- package/src/__tests__/meshopt-real-matrix.integration.test.ts +108 -24
- package/src/__tests__/morph-import.integration.test.ts +31 -44
- package/src/__tests__/source-key-diagnostics.integration.test.ts +140 -0
- package/src/__tests__/source-key-producer.integration.test.ts +2 -2
- package/src/bridge.ts +9 -10
- package/src/check-extensions.ts +8 -4
- package/src/cli-gltf.ts +1 -6
- package/src/gltf-importer.ts +1 -2
- package/src/index.ts +1 -0
- package/src/parse-gltf.ts +7 -5
- package/src/source-key.ts +51 -17
- package/dist/__tests__/asset-runtime-fixture.d.ts +0 -14
- package/dist/__tests__/asset-runtime-fixture.d.ts.map +0 -1
- package/src/__tests__/asset-runtime-fixture.ts +0 -278
package/dist/parse-gltf.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-gltf.d.ts","sourceRoot":"","sources":["../src/parse-gltf.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"parse-gltf.d.ts","sourceRoot":"","sources":["../src/parse-gltf.ts"],"names":[],"mappings":"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"}
|
package/dist/source-key.d.ts
CHANGED
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
import type { GltfDocItemLike } from './sub-asset-key.js';
|
|
2
|
-
|
|
3
|
-
readonly code: 'missing-source-key' | 'duplicate-source-key' | 'ambiguous-source-key' | 'mesh-material-slot-topology-change';
|
|
4
|
-
readonly sourceIndices: readonly number[];
|
|
2
|
+
interface GltfSourceKeyErrorBase {
|
|
5
3
|
readonly expected: string;
|
|
6
4
|
readonly hint: string;
|
|
7
|
-
readonly previousIndices?: readonly number[];
|
|
8
5
|
}
|
|
6
|
+
export interface GltfSourceKeyConflictEntry {
|
|
7
|
+
readonly kind: string;
|
|
8
|
+
readonly name: string | null;
|
|
9
|
+
readonly sourceIndex: number;
|
|
10
|
+
}
|
|
11
|
+
export type GltfSourceKeyError = (GltfSourceKeyErrorBase & {
|
|
12
|
+
readonly code: 'missing-source-key';
|
|
13
|
+
readonly detail: {
|
|
14
|
+
readonly sourceIndices: readonly number[];
|
|
15
|
+
};
|
|
16
|
+
}) | (GltfSourceKeyErrorBase & {
|
|
17
|
+
readonly code: 'duplicate-source-key' | 'ambiguous-source-key';
|
|
18
|
+
readonly detail: {
|
|
19
|
+
readonly key: string;
|
|
20
|
+
readonly sourceIndices: readonly number[];
|
|
21
|
+
readonly entries: readonly GltfSourceKeyConflictEntry[];
|
|
22
|
+
};
|
|
23
|
+
}) | (GltfSourceKeyErrorBase & {
|
|
24
|
+
readonly code: 'mesh-material-slot-topology-change';
|
|
25
|
+
readonly detail: {
|
|
26
|
+
readonly sourceIndices: readonly number[];
|
|
27
|
+
readonly previousIndices: readonly number[];
|
|
28
|
+
};
|
|
29
|
+
});
|
|
9
30
|
export type GltfSourceKeyErrorCode = GltfSourceKeyError['code'];
|
|
10
31
|
export type GltfSourceKeyResult = {
|
|
11
32
|
readonly ok: true;
|
|
@@ -19,4 +40,5 @@ export type GltfSourceKeyResult = {
|
|
|
19
40
|
export declare function sourceKeyForGltfOutput(item: Pick<GltfDocItemLike, 'kind' | 'name'>): string | undefined;
|
|
20
41
|
/** Require every output in a multi-output declaration to carry a unique key. */
|
|
21
42
|
export declare function deriveGltfSourceKeys(items: readonly GltfDocItemLike[]): GltfSourceKeyResult;
|
|
43
|
+
export {};
|
|
22
44
|
//# sourceMappingURL=source-key.d.ts.map
|
package/dist/source-key.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-key.d.ts","sourceRoot":"","sources":["../src/source-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,WAAW,kBAAkB;
|
|
1
|
+
{"version":3,"file":"source-key.d.ts","sourceRoot":"","sources":["../src/source-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,kBAAkB,GAC1B,CAAC,sBAAsB,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;CAChE,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,sBAAsB,GAAG,sBAAsB,CAAC;IAC/D,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;QAC1C,QAAQ,CAAC,OAAO,EAAE,SAAS,0BAA0B,EAAE,CAAC;KACzD,CAAC;CACH,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,oCAAoC,CAAC;IACpD,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;QAC1C,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;KAC7C,CAAC;CACH,CAAC,CAAC;AAEP,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAEhE,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,CAAA;CAAE,GACxF;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAE/D,gFAAgF;AAChF,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,MAAM,GAAG,SAAS,CAKpB;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,eAAe,EAAE,GAAG,mBAAmB,CAsD3F"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgeax/engine-gltf",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"sideEffects": false,
|
|
8
|
-
"description": "Runtime glTF 2.0 importer (Tier-B subset: scenes + nodes + meshes (POSITION + INDICES) + UnlitMaterial.baseColor + Camera.perspective). Pure-function pipeline parseGlb / parseGltf / toAssetPack consumed by build-time CLI (forgeax-engine-remote-gltf import) writing <source>.meta.json (external-asset-package; assetType=gltf) for
|
|
8
|
+
"description": "Runtime glTF 2.0 importer (Tier-B subset: scenes + nodes + meshes (POSITION + INDICES) + UnlitMaterial.baseColor + Camera.perspective). Pure-function pipeline parseGlb / parseGltf / toAssetPack consumed by build-time CLI (forgeax-engine-remote-gltf import) writing <source>.meta.json (external-asset-package; assetType=gltf) for runtime loadByGuid<SceneAsset>.",
|
|
9
9
|
"bin": {
|
|
10
10
|
"forgeax-engine-remote-gltf": "./dist/cli-gltf.mjs"
|
|
11
11
|
},
|
|
@@ -38,23 +38,21 @@
|
|
|
38
38
|
"LICENSE"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@forgeax/engine-animation": "0.1.
|
|
42
|
-
"@forgeax/engine-geometry": "0.1.
|
|
43
|
-
"@forgeax/engine-import": "0.1.
|
|
44
|
-
"@forgeax/engine-math": "0.1.
|
|
45
|
-
"@forgeax/engine-pack": "0.1.
|
|
46
|
-
"@forgeax/engine-scene": "0.1.
|
|
47
|
-
"@forgeax/engine-types": "0.1.
|
|
41
|
+
"@forgeax/engine-animation": "0.1.7",
|
|
42
|
+
"@forgeax/engine-geometry": "0.1.7",
|
|
43
|
+
"@forgeax/engine-import": "0.1.7",
|
|
44
|
+
"@forgeax/engine-math": "0.1.7",
|
|
45
|
+
"@forgeax/engine-pack": "0.1.7",
|
|
46
|
+
"@forgeax/engine-scene": "0.1.7",
|
|
47
|
+
"@forgeax/engine-types": "0.1.7",
|
|
48
48
|
"@webgpu/types": "^0.1.71",
|
|
49
49
|
"meshoptimizer": "^0.20.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@forgeax/engine-assets-runtime": "0.1.
|
|
53
|
-
"@forgeax/engine-
|
|
54
|
-
"@forgeax/engine-
|
|
55
|
-
"@forgeax/engine-
|
|
56
|
-
"@forgeax/engine-render": "0.1.4",
|
|
57
|
-
"@forgeax/engine-runtime": "0.1.4",
|
|
52
|
+
"@forgeax/engine-assets-runtime": "0.1.7",
|
|
53
|
+
"@forgeax/engine-picking": "0.1.7",
|
|
54
|
+
"@forgeax/engine-render": "0.1.7",
|
|
55
|
+
"@forgeax/engine-runtime": "0.1.7",
|
|
58
56
|
"@types/node": "^20.14.0"
|
|
59
57
|
},
|
|
60
58
|
"forgeax": {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { checkExtensions } from '../check-extensions.js';
|
|
3
|
+
|
|
4
|
+
describe('glTF required extension admission', () => {
|
|
5
|
+
it('keeps unknown required extensions fail-closed', () => {
|
|
6
|
+
const result = checkExtensions({
|
|
7
|
+
extensionsRequired: ['KHR_forgeax_unknown'],
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
expect(result.ok).toBe(false);
|
|
11
|
+
if (result.ok) return;
|
|
12
|
+
expect(result.error.code).toBe('gltf-extension-unsupported');
|
|
13
|
+
if (result.error.code !== 'gltf-extension-unsupported') return;
|
|
14
|
+
expect(result.error.detail).toEqual({
|
|
15
|
+
extension: 'KHR_forgeax_unknown',
|
|
16
|
+
source: 'extensionsRequired',
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -2469,7 +2469,7 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
2469
2469
|
expect(result.ok).toBe(false);
|
|
2470
2470
|
if (result.ok) return;
|
|
2471
2471
|
expect(result.error.code).toBe('duplicate-source-key');
|
|
2472
|
-
expect(result.error.sourceIndices).toEqual([0, 1]);
|
|
2472
|
+
expect(result.error.detail.sourceIndices).toEqual([0, 1]);
|
|
2473
2473
|
expect(stderrSpy).not.toHaveBeenCalled();
|
|
2474
2474
|
});
|
|
2475
2475
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { Handle } from '@forgeax/engine-types';
|
|
1
2
|
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { toMaterialAsset } from '../bridge.js';
|
|
2
4
|
import { parseGltf } from '../parse-gltf.js';
|
|
3
5
|
|
|
4
6
|
const noopLoader = async (_uri: string) => new ArrayBuffer(0);
|
|
@@ -8,6 +10,8 @@ describe('glTF KHR_texture_transform per-slot parsing', () => {
|
|
|
8
10
|
const result = await parseGltf(
|
|
9
11
|
{
|
|
10
12
|
asset: { version: '2.0' },
|
|
13
|
+
extensionsRequired: ['KHR_texture_transform'],
|
|
14
|
+
extensionsUsed: ['KHR_texture_transform'],
|
|
11
15
|
textures: [
|
|
12
16
|
{ source: 0, sampler: 0 },
|
|
13
17
|
{ source: 1, sampler: 1 },
|
|
@@ -71,5 +75,31 @@ describe('glTF KHR_texture_transform per-slot parsing', () => {
|
|
|
71
75
|
rotation: -0.75,
|
|
72
76
|
scale: [4, 5],
|
|
73
77
|
});
|
|
78
|
+
|
|
79
|
+
const materialIr = result.value.materials[0];
|
|
80
|
+
expect(materialIr).toBeDefined();
|
|
81
|
+
if (materialIr === undefined) return;
|
|
82
|
+
const projected = toMaterialAsset(materialIr, {
|
|
83
|
+
textureHandles: new Map([
|
|
84
|
+
[0, 100],
|
|
85
|
+
[1, 101],
|
|
86
|
+
]) as unknown as ReadonlyMap<number, Handle<'TextureAsset', 'shared'>>,
|
|
87
|
+
});
|
|
88
|
+
expect(projected.values).toMatchObject({
|
|
89
|
+
baseColorTexture: {
|
|
90
|
+
texture: 100,
|
|
91
|
+
coordinates: {
|
|
92
|
+
set: 6,
|
|
93
|
+
transform: { offset: [0.25, 0.5], rotation: 0.75, scale: [2, 3] },
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
metallicRoughnessTexture: {
|
|
97
|
+
texture: 101,
|
|
98
|
+
coordinates: {
|
|
99
|
+
set: 7,
|
|
100
|
+
transform: { offset: [-0.25, -0.5], rotation: -0.75, scale: [4, 5] },
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
});
|
|
74
104
|
});
|
|
75
105
|
});
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { ImportContext, ImportedAsset } from '@forgeax/engine-types';
|
|
1
|
+
import { AssetRegistry } from '@forgeax/engine-assets-runtime';
|
|
2
|
+
import type { Asset, ImportContext, ImportedAsset } from '@forgeax/engine-types';
|
|
3
3
|
import { MeshoptDecoder, MeshoptEncoder } from 'meshoptimizer';
|
|
4
4
|
import { describe, expect, it } from 'vitest';
|
|
5
|
-
import { meshIrToMeshAsset } from '../bridge.js';
|
|
6
5
|
import { createGltfImporter } from '../gltf-importer.js';
|
|
7
6
|
import { parseGlb } from '../parse-gltf.js';
|
|
8
|
-
import {
|
|
7
|
+
import { unwrapMeshAsset as meshIrToMeshAsset } from './bridge-test-helpers.js';
|
|
9
8
|
|
|
10
9
|
function bytesOf(view: ArrayBufferView): Uint8Array {
|
|
11
10
|
return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
|
|
@@ -142,10 +141,7 @@ describe('real EXT_meshopt_compression glTF matrix', () => {
|
|
|
142
141
|
]);
|
|
143
142
|
expect(Array.from(result.value.meshes[0]?.indices ?? [])).toEqual([0, 1, 2]);
|
|
144
143
|
|
|
145
|
-
const
|
|
146
|
-
expect(meshResult.ok).toBe(true);
|
|
147
|
-
if (!meshResult.ok) return;
|
|
148
|
-
const mesh = meshResult.value;
|
|
144
|
+
const mesh = meshIrToMeshAsset(result.value.meshes);
|
|
149
145
|
expect([
|
|
150
146
|
mesh.vertices[0],
|
|
151
147
|
mesh.vertices[1],
|
|
@@ -191,7 +187,7 @@ describe('real EXT_meshopt_compression glTF matrix', () => {
|
|
|
191
187
|
expect(mesh?.payload.indices).toEqual(new Uint16Array([0, 1, 2]));
|
|
192
188
|
});
|
|
193
189
|
|
|
194
|
-
it('loads the imported compressed artifact through Pack, Catalog, and
|
|
190
|
+
it('loads the imported compressed artifact through Pack, Catalog, and loadByGuid', async () => {
|
|
195
191
|
await MeshoptEncoder.ready;
|
|
196
192
|
await MeshoptDecoder.ready;
|
|
197
193
|
const guid = '019f0000-0000-7000-8000-000000000202';
|
|
@@ -214,19 +210,65 @@ describe('real EXT_meshopt_compression glTF matrix', () => {
|
|
|
214
210
|
const mesh = imported.value.assets.find((asset: ImportedAsset) => asset.guid === guid);
|
|
215
211
|
expect(mesh?.kind).toBe('mesh');
|
|
216
212
|
if (mesh?.kind !== 'mesh') return;
|
|
213
|
+
const meshPayload = mesh.payload as Extract<Asset, { kind: 'mesh' }>;
|
|
217
214
|
const body = mesh.artifacts.body;
|
|
218
215
|
expect(body?.bytes.byteLength).toBeGreaterThan(0);
|
|
219
216
|
if (body === undefined) return;
|
|
220
217
|
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
218
|
+
const packIndexUrl = '/meshopt-pack-index.json';
|
|
219
|
+
const packageUrl = '/ddc/meshopt-pack.pack.json';
|
|
220
|
+
const originalFetch = globalThis.fetch;
|
|
221
|
+
const registry = new AssetRegistry({} as never);
|
|
222
|
+
registry.configurePackIndex(packIndexUrl);
|
|
223
|
+
globalThis.fetch = ((input: string) => {
|
|
224
|
+
const url = typeof input === 'string' ? input : String(input);
|
|
225
|
+
if (url === packIndexUrl) {
|
|
226
|
+
return Promise.resolve({
|
|
227
|
+
ok: true,
|
|
228
|
+
json: async () => [{ guid, packageUrl, kind: 'mesh' }],
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
if (url === packageUrl) {
|
|
232
|
+
const pack = {
|
|
233
|
+
schemaVersion: '2.0.0',
|
|
234
|
+
kind: 'internal-text-package',
|
|
235
|
+
assets: [
|
|
236
|
+
{
|
|
237
|
+
guid,
|
|
238
|
+
kind: 'mesh',
|
|
239
|
+
payload: meshPayload,
|
|
240
|
+
refs: [],
|
|
241
|
+
artifacts: {
|
|
242
|
+
body: {
|
|
243
|
+
path: 'mesh.bin',
|
|
244
|
+
mediaType: body.mediaType,
|
|
245
|
+
byteLength: body.bytes.byteLength,
|
|
246
|
+
assetCodec: body.assetCodec,
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
};
|
|
252
|
+
return Promise.resolve({
|
|
253
|
+
ok: true,
|
|
254
|
+
json: async () => JSON.parse(JSON.stringify(pack)),
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return Promise.resolve({
|
|
258
|
+
ok: true,
|
|
259
|
+
arrayBuffer: async () =>
|
|
260
|
+
body.bytes.buffer.slice(
|
|
261
|
+
body.bytes.byteOffset,
|
|
262
|
+
body.bytes.byteOffset + body.bytes.byteLength,
|
|
263
|
+
),
|
|
264
|
+
});
|
|
265
|
+
}) as unknown as typeof globalThis.fetch;
|
|
266
|
+
|
|
225
267
|
try {
|
|
226
|
-
const loaded = await
|
|
268
|
+
const loaded = await registry.loadByGuid(registry.parseGuid(guid));
|
|
227
269
|
expect(loaded.ok).toBe(true);
|
|
228
270
|
if (!loaded.ok) return;
|
|
229
|
-
const payload = loaded.value;
|
|
271
|
+
const payload = loaded.value as { vertices: Float32Array; indices?: Uint16Array };
|
|
230
272
|
expect([
|
|
231
273
|
payload.vertices[0],
|
|
232
274
|
payload.vertices[1],
|
|
@@ -240,7 +282,7 @@ describe('real EXT_meshopt_compression glTF matrix', () => {
|
|
|
240
282
|
]).toEqual([0, 0, 0, 1, 0, 0, 0, 1, 0]);
|
|
241
283
|
expect(Array.from(payload.indices ?? [])).toEqual([0, 1, 2]);
|
|
242
284
|
} finally {
|
|
243
|
-
|
|
285
|
+
globalThis.fetch = originalFetch;
|
|
244
286
|
}
|
|
245
287
|
});
|
|
246
288
|
|
|
@@ -266,21 +308,63 @@ describe('real EXT_meshopt_compression glTF matrix', () => {
|
|
|
266
308
|
if (!imported.ok) return;
|
|
267
309
|
const mesh = imported.value.assets.find((asset: ImportedAsset) => asset.guid === guid);
|
|
268
310
|
if (mesh?.kind !== 'mesh' || mesh.artifacts.body === undefined) return;
|
|
311
|
+
const meshPayload = mesh.payload as Extract<Asset, { kind: 'mesh' }>;
|
|
269
312
|
const damaged = new Uint8Array(mesh.artifacts.body.bytes);
|
|
270
313
|
const lastByte = damaged.length - 1;
|
|
271
314
|
damaged[lastByte] = (damaged[lastByte] ?? 0) ^ 0xff;
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
315
|
+
const registry = new AssetRegistry({} as never);
|
|
316
|
+
const packIndexUrl = '/meshopt-damaged-index.json';
|
|
317
|
+
const packageUrl = '/ddc/meshopt-damaged.pack.json';
|
|
318
|
+
registry.configurePackIndex(packIndexUrl);
|
|
319
|
+
const originalFetch = globalThis.fetch;
|
|
320
|
+
globalThis.fetch = ((input: string) => {
|
|
321
|
+
const url = typeof input === 'string' ? input : String(input);
|
|
322
|
+
if (url === packIndexUrl)
|
|
323
|
+
return Promise.resolve({
|
|
324
|
+
ok: true,
|
|
325
|
+
json: async () => [{ guid, packageUrl, kind: 'mesh' }],
|
|
326
|
+
});
|
|
327
|
+
if (url === packageUrl)
|
|
328
|
+
return Promise.resolve({
|
|
329
|
+
ok: true,
|
|
330
|
+
json: async () => ({
|
|
331
|
+
schemaVersion: '2.0.0',
|
|
332
|
+
kind: 'internal-text-package',
|
|
333
|
+
assets: [
|
|
334
|
+
{
|
|
335
|
+
guid,
|
|
336
|
+
kind: 'mesh',
|
|
337
|
+
payload: meshPayload,
|
|
338
|
+
refs: [],
|
|
339
|
+
artifacts: {
|
|
340
|
+
body: {
|
|
341
|
+
path: 'mesh.bin',
|
|
342
|
+
mediaType: mesh.artifacts.body?.mediaType,
|
|
343
|
+
byteLength: damaged.byteLength,
|
|
344
|
+
assetCodec: mesh.artifacts.body?.assetCodec,
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
],
|
|
349
|
+
}),
|
|
350
|
+
});
|
|
351
|
+
return Promise.resolve({
|
|
352
|
+
ok: true,
|
|
353
|
+
arrayBuffer: async () =>
|
|
354
|
+
damaged.buffer.slice(damaged.byteOffset, damaged.byteOffset + damaged.byteLength),
|
|
355
|
+
});
|
|
356
|
+
}) as unknown as typeof globalThis.fetch;
|
|
277
357
|
try {
|
|
278
|
-
const loaded = await
|
|
358
|
+
const loaded = await registry.loadByGuid(registry.parseGuid(guid));
|
|
279
359
|
expect(loaded.ok).toBe(false);
|
|
280
360
|
if (loaded.ok) return;
|
|
281
|
-
expect(
|
|
361
|
+
expect([
|
|
362
|
+
'asset-parse-failed',
|
|
363
|
+
'asset-artifact-integrity-mismatch',
|
|
364
|
+
'mesh-bin-contract-violation',
|
|
365
|
+
]).toContain(loaded.error.code);
|
|
282
366
|
} finally {
|
|
283
|
-
|
|
367
|
+
globalThis.fetch = originalFetch;
|
|
284
368
|
}
|
|
285
369
|
});
|
|
286
370
|
});
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import {
|
|
3
|
-
import { World } from '@forgeax/engine-ecs';
|
|
4
|
-
import { meshAssetKind } from '@forgeax/engine-geometry';
|
|
2
|
+
import { AssetRegistry } from '@forgeax/engine-assets-runtime';
|
|
5
3
|
import { ImporterRegistry, type RunImportMeta, runImport } from '@forgeax/engine-import';
|
|
6
|
-
import {
|
|
4
|
+
import type { AnimationClip, MeshAsset, SceneAsset } from '@forgeax/engine-types';
|
|
7
5
|
import { describe, expect, it } from 'vitest';
|
|
8
6
|
import { gltfImporter } from '../gltf-importer.js';
|
|
9
|
-
import {
|
|
10
|
-
createAssetRuntimeFixture,
|
|
11
|
-
installMeshDecoder,
|
|
12
|
-
installPassthroughDecoder,
|
|
13
|
-
} from './asset-runtime-fixture';
|
|
14
7
|
|
|
15
8
|
const MESH_GUID = '11111111-1111-4111-8111-111111111111';
|
|
16
9
|
const MATERIAL_GUID = '22222222-2222-4222-8222-222222222222';
|
|
@@ -56,8 +49,8 @@ async function importFixture() {
|
|
|
56
49
|
return result.value.pack;
|
|
57
50
|
}
|
|
58
51
|
|
|
59
|
-
describe('real glTF morph import through Pack and
|
|
60
|
-
it('preserves two targets and two animation keyframes through
|
|
52
|
+
describe('real glTF morph import through Pack and AssetRegistry', () => {
|
|
53
|
+
it('preserves two targets and two animation keyframes through loadByGuid', async () => {
|
|
61
54
|
const pack = await importFixture();
|
|
62
55
|
const meshEntry = pack.assets.find((asset) => asset.guid === MESH_GUID);
|
|
63
56
|
const sceneEntry = pack.assets.find((asset) => asset.guid === SCENE_GUID);
|
|
@@ -90,39 +83,33 @@ describe('real glTF morph import through Pack and typed asset owners', () => {
|
|
|
90
83
|
expect(animationPayload.channels[0]?.sampler.input).toEqual([0, 1]);
|
|
91
84
|
expect(animationPayload.channels[0]?.sampler.output).toEqual([0, 0.75, 0.25, 0]);
|
|
92
85
|
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const loadedMesh = await assets.load(MESH_GUID, meshAssetKind);
|
|
105
|
-
const loadedScene = await assets.load(SCENE_GUID, sceneAssetKind);
|
|
106
|
-
const loadedAnimation = await assets.load(ANIMATION_GUID, animationClipContribution.kind);
|
|
107
|
-
expect(loadedMesh.ok).toBe(true);
|
|
108
|
-
expect(loadedScene.ok).toBe(true);
|
|
109
|
-
expect(loadedAnimation.ok).toBe(true);
|
|
110
|
-
if (!loadedMesh.ok || !loadedScene.ok || !loadedAnimation.ok) return;
|
|
111
|
-
|
|
112
|
-
const world = new World();
|
|
113
|
-
world.internSharedRef('MeshAsset', loadedMesh.value);
|
|
114
|
-
world.internSharedRef('SceneAsset', loadedScene.value);
|
|
115
|
-
world.internSharedRef('AnimationClip', loadedAnimation.value);
|
|
86
|
+
const runtime = new AssetRegistry({} as never);
|
|
87
|
+
const parsedMesh = runtime.parseAssetPayload('mesh', meshEntry?.payload ?? {});
|
|
88
|
+
const parsedAnimation = runtime.parseAssetPayload(
|
|
89
|
+
'animation-clip',
|
|
90
|
+
animationEntry?.payload ?? {},
|
|
91
|
+
);
|
|
92
|
+
expect(parsedMesh).toMatchObject({ kind: 'mesh', morphWeights: new Float32Array([0, 0]) });
|
|
93
|
+
expect(parsedAnimation).toMatchObject({ kind: 'animation-clip' });
|
|
94
|
+
expect(runtime.catalog(MESH_GUID, parsedMesh as never).ok).toBe(true);
|
|
95
|
+
expect(runtime.catalog(SCENE_GUID, sceneEntry?.payload as never).ok).toBe(true);
|
|
96
|
+
expect(runtime.catalog(ANIMATION_GUID, parsedAnimation as never).ok).toBe(true);
|
|
116
97
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
98
|
+
const loadedMesh = await runtime.loadByGuid<MeshAsset>(runtime.parseGuid(MESH_GUID));
|
|
99
|
+
const loadedScene = await runtime.loadByGuid<SceneAsset>(runtime.parseGuid(SCENE_GUID));
|
|
100
|
+
const loadedAnimation = await runtime.loadByGuid<AnimationClip>(
|
|
101
|
+
runtime.parseGuid(ANIMATION_GUID),
|
|
102
|
+
);
|
|
103
|
+
expect(loadedMesh.ok).toBe(true);
|
|
104
|
+
expect(loadedScene.ok).toBe(true);
|
|
105
|
+
expect(loadedAnimation.ok).toBe(true);
|
|
106
|
+
if (!loadedMesh.ok || !loadedScene.ok || !loadedAnimation.ok) return;
|
|
107
|
+
expect(Array.from(loadedMesh.value.morphWeights ?? [])).toEqual([0, 0]);
|
|
108
|
+
const sceneEntity = loadedScene.value.entities[0];
|
|
109
|
+
expect(sceneEntity?.components.MorphWeights?.weights).toEqual([0, 0]);
|
|
110
|
+
expect(loadedAnimation.value.channels[0]?.property).toBe('weights');
|
|
111
|
+
expect(Array.from(loadedAnimation.value.channels[0]?.sampler.output ?? [])).toEqual([
|
|
112
|
+
0, 0.75, 0.25, 0,
|
|
113
|
+
]);
|
|
127
114
|
});
|
|
128
115
|
});
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { access, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { describe, expect, it } from 'vitest';
|
|
6
|
+
import { runCliGltf } from '../cli-gltf.js';
|
|
7
|
+
import { parseGlb, toAssetPack } from '../parse-gltf.js';
|
|
8
|
+
|
|
9
|
+
const GLB_MAGIC = 0x46546c67;
|
|
10
|
+
const GLB_JSON_CHUNK = 0x4e4f534a;
|
|
11
|
+
|
|
12
|
+
function meshGlb(names: readonly (string | null)[]): Uint8Array {
|
|
13
|
+
const positions = new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]);
|
|
14
|
+
const json = {
|
|
15
|
+
asset: { version: '2.0' },
|
|
16
|
+
scene: 0,
|
|
17
|
+
scenes: [{ name: 'Scene', nodes: names.map((_, index) => index) }],
|
|
18
|
+
nodes: names.map((_, index) => ({ name: `Node${index}`, mesh: index })),
|
|
19
|
+
meshes: names.map((name) => ({
|
|
20
|
+
...(name === null ? {} : { name }),
|
|
21
|
+
primitives: [{ attributes: { POSITION: 0 } }],
|
|
22
|
+
})),
|
|
23
|
+
accessors: [{ bufferView: 0, componentType: 5126, count: 3, type: 'VEC3' }],
|
|
24
|
+
bufferViews: [{ buffer: 0, byteOffset: 0, byteLength: positions.byteLength }],
|
|
25
|
+
buffers: [{ byteLength: positions.byteLength }],
|
|
26
|
+
};
|
|
27
|
+
const encodedJson = new TextEncoder().encode(JSON.stringify(json));
|
|
28
|
+
const jsonLength = Math.ceil(encodedJson.byteLength / 4) * 4;
|
|
29
|
+
const binLength = Math.ceil(positions.byteLength / 4) * 4;
|
|
30
|
+
const bytes = new Uint8Array(12 + 8 + jsonLength + 8 + binLength);
|
|
31
|
+
const view = new DataView(bytes.buffer);
|
|
32
|
+
view.setUint32(0, GLB_MAGIC, true);
|
|
33
|
+
view.setUint32(4, 2, true);
|
|
34
|
+
view.setUint32(8, bytes.byteLength, true);
|
|
35
|
+
view.setUint32(12, jsonLength, true);
|
|
36
|
+
view.setUint32(16, GLB_JSON_CHUNK, true);
|
|
37
|
+
bytes.fill(0x20, 20, 20 + jsonLength);
|
|
38
|
+
bytes.set(encodedJson, 20);
|
|
39
|
+
const binHeader = 20 + jsonLength;
|
|
40
|
+
view.setUint32(binHeader, binLength, true);
|
|
41
|
+
view.setUint32(binHeader + 4, 0x004e4942, true);
|
|
42
|
+
bytes.set(new Uint8Array(positions.buffer), binHeader + 8);
|
|
43
|
+
return bytes;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function digest(bytes: Uint8Array): string {
|
|
47
|
+
return createHash('sha256').update(bytes).digest('hex');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function directError(bytes: Uint8Array, source: string): Promise<unknown> {
|
|
51
|
+
const parsed = await parseGlb(bytes.buffer as ArrayBuffer, source);
|
|
52
|
+
expect(parsed.ok).toBe(true);
|
|
53
|
+
if (!parsed.ok) return undefined;
|
|
54
|
+
const packed = toAssetPack(parsed.value, undefined, source);
|
|
55
|
+
expect(packed.ok).toBe(false);
|
|
56
|
+
return packed.ok ? undefined : packed.error;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
describe('glTF source-key diagnostics', () => {
|
|
60
|
+
it.each([
|
|
61
|
+
{
|
|
62
|
+
label: 'named duplicate',
|
|
63
|
+
names: ['Hero', 'Hero'],
|
|
64
|
+
expected: {
|
|
65
|
+
code: 'duplicate-source-key',
|
|
66
|
+
detail: {
|
|
67
|
+
key: 'mesh:Hero',
|
|
68
|
+
sourceIndices: [0, 1],
|
|
69
|
+
entries: [
|
|
70
|
+
{ kind: 'mesh', name: 'Hero', sourceIndex: 0 },
|
|
71
|
+
{ kind: 'mesh', name: 'Hero', sourceIndex: 1 },
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
label: 'anonymous ambiguity',
|
|
78
|
+
names: [null, null],
|
|
79
|
+
expected: {
|
|
80
|
+
code: 'ambiguous-source-key',
|
|
81
|
+
detail: {
|
|
82
|
+
key: 'mesh',
|
|
83
|
+
sourceIndices: [0, 1],
|
|
84
|
+
entries: [
|
|
85
|
+
{ kind: 'mesh', name: null, sourceIndex: 0 },
|
|
86
|
+
{ kind: 'mesh', name: null, sourceIndex: 1 },
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
])('keeps direct and CLI $label errors identical without mutating the GLB', async (fixture) => {
|
|
92
|
+
const tempDir = await mkdtemp(join(tmpdir(), 'gltf-source-key-detail-'));
|
|
93
|
+
try {
|
|
94
|
+
const sourcePath = join(tempDir, `${fixture.label.replaceAll(' ', '-')}.glb`);
|
|
95
|
+
const bytes = meshGlb(fixture.names);
|
|
96
|
+
const before = digest(bytes);
|
|
97
|
+
await writeFile(sourcePath, bytes);
|
|
98
|
+
|
|
99
|
+
const direct = await directError(bytes, sourcePath);
|
|
100
|
+
expect(direct).toMatchObject(fixture.expected);
|
|
101
|
+
|
|
102
|
+
const stderr: string[] = [];
|
|
103
|
+
const exitCode = await runCliGltf(['import', sourcePath], {
|
|
104
|
+
stdoutWrite: () => {},
|
|
105
|
+
stderrWrite: (line) => stderr.push(line),
|
|
106
|
+
});
|
|
107
|
+
expect(exitCode).toBe(1);
|
|
108
|
+
const cli = JSON.parse(stderr[0] as string) as unknown;
|
|
109
|
+
expect(cli).toEqual(direct);
|
|
110
|
+
await expect(access(`${sourcePath}.meta.json`)).rejects.toThrow();
|
|
111
|
+
expect(digest(await readFile(sourcePath))).toBe(before);
|
|
112
|
+
} finally {
|
|
113
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('continues to write a sibling meta for a valid GLB without mutating its source', async () => {
|
|
118
|
+
const tempDir = await mkdtemp(join(tmpdir(), 'gltf-source-key-success-'));
|
|
119
|
+
try {
|
|
120
|
+
const sourcePath = join(tempDir, 'unique.glb');
|
|
121
|
+
const bytes = meshGlb(['HeroA', 'HeroB']);
|
|
122
|
+
const before = digest(bytes);
|
|
123
|
+
await writeFile(sourcePath, bytes);
|
|
124
|
+
|
|
125
|
+
const exitCode = await runCliGltf(['import', sourcePath], {
|
|
126
|
+
stdoutWrite: () => {},
|
|
127
|
+
stderrWrite: () => {},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
expect(exitCode).toBe(0);
|
|
131
|
+
expect(JSON.parse(await readFile(`${sourcePath}.meta.json`, 'utf-8'))).toMatchObject({
|
|
132
|
+
importer: 'gltf',
|
|
133
|
+
source: 'unique.glb',
|
|
134
|
+
});
|
|
135
|
+
expect(digest(await readFile(sourcePath))).toBe(before);
|
|
136
|
+
} finally {
|
|
137
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
});
|