@forgeax/engine-gltf 0.1.3 → 0.1.6

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.
Files changed (41) hide show
  1. package/README.md +18 -11
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/__tests__/extension-admission.unit.test.d.ts +2 -0
  4. package/dist/__tests__/extension-admission.unit.test.d.ts.map +1 -0
  5. package/dist/__tests__/source-key-diagnostics.integration.test.d.ts +2 -0
  6. package/dist/__tests__/source-key-diagnostics.integration.test.d.ts.map +1 -0
  7. package/dist/bridge.d.ts +5 -6
  8. package/dist/bridge.d.ts.map +1 -1
  9. package/dist/check-extensions.d.ts.map +1 -1
  10. package/dist/cli-gltf.mjs +32 -16
  11. package/dist/cli-gltf.mjs.map +1 -1
  12. package/dist/gltf-importer.d.ts.map +1 -1
  13. package/dist/importer-entry.mjs +14 -3
  14. package/dist/importer-entry.mjs.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.mjs +40 -12
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/node-file-entry.mjs +5 -1
  20. package/dist/node-file-entry.mjs.map +1 -1
  21. package/dist/parse-gltf.d.ts.map +1 -1
  22. package/dist/source-key.d.ts +26 -4
  23. package/dist/source-key.d.ts.map +1 -1
  24. package/package.json +13 -15
  25. package/src/__tests__/extension-admission.unit.test.ts +19 -0
  26. package/src/__tests__/gltf.unit.test.ts +1 -1
  27. package/src/__tests__/material-texture-transform.unit.test.ts +30 -0
  28. package/src/__tests__/meshopt-real-matrix.integration.test.ts +108 -24
  29. package/src/__tests__/morph-import.integration.test.ts +31 -44
  30. package/src/__tests__/source-key-diagnostics.integration.test.ts +140 -0
  31. package/src/__tests__/source-key-producer.integration.test.ts +10 -2
  32. package/src/bridge.ts +9 -10
  33. package/src/check-extensions.ts +8 -4
  34. package/src/cli-gltf.ts +1 -6
  35. package/src/gltf-importer.ts +13 -4
  36. package/src/index.ts +1 -0
  37. package/src/parse-gltf.ts +7 -5
  38. package/src/source-key.ts +51 -17
  39. package/dist/__tests__/asset-runtime-fixture.d.ts +0 -14
  40. package/dist/__tests__/asset-runtime-fixture.d.ts.map +0 -1
  41. package/src/__tests__/asset-runtime-fixture.ts +0 -278
@@ -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":"AAQA,OAAO,EAEL,WAAW,EAIZ,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,cAAc,EAEf,MAAM,+BAA+B,CAAC;AAIvC,OAAO,EAAO,KAAK,SAAS,EAAe,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EACL,KAAK,8BAA8B,EAGpC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,uBAAuB,EAAkB,MAAM,sBAAsB,CAAC;AAGpF,OAAO,EAAE,KAAK,kBAAkB,EAAa,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,KAAK,mBAAmB,EAA0B,MAAM,gBAAgB,CAAC;AAElF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACnD;AA+JD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC;IAClC,6GAA6G;IAC7G,QAAQ,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC;IAClC,mEAAmE;IACnE,QAAQ,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC;IAClC,mEAAmE;IACnE,QAAQ,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC;IAClC,mEAAmE;IACnE,QAAQ,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC;IAClC,mEAAmE;IACnE,QAAQ,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC;IAClC,mEAAmE;IACnE,QAAQ,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC;IAClC,mEAAmE;IACnE,QAAQ,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACjC,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,iIAAiI;IACjI,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAC/B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS;QAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;QACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;QAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;KACjC,EAAE,CAAC;IACJ,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,sBAAsB,CAAC;CAC7C;AAED,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,0BAA2B,SAAQ,iBAAiB;IACnE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpE,qEAAqE;IACrE,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC;IACvD,4CAA4C;IAC5C,QAAQ,CAAC,eAAe,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC;IACtD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC;IAC/D,QAAQ,CAAC,aAAa,CAAC,EAAE,uBAAuB,GAAG,MAAM,CAAC;IAC1D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,0BAA0B,GAAG,MAAM,CAAC;IAChE;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IACjD,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC;CACnC;AAED,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;AAErE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE;QACd,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;KACjC,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC,mEAAmE;IACnE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,yEAAyE;IACzE,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IACvC,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;IAClD,QAAQ,CAAC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAClD,QAAQ,CAAC,cAAc,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC5D,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,CAAC,EAAE;QACpB,QAAQ,CAAC,mBAAmB,CAAC,EAAE;YAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;SAClD,CAAC;KACH,CAAC;IACF;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3D;AAoKD,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AA6BnE,KAAK,cAAc,GAAG,SAAS,GAAG,WAAW,CAAC;AA4B9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,8BAA8B,CAAC;CACnD;AA6vBD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,OAAO,EACb,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAc1C;AAcD,wBAAsB,SAAS,CAC7B,IAAI,EAAE,OAAO,EACb,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAGrC;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CA+B1C;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAGrC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAClD;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;AAE5E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,MAAM,EAAE,MAAM,GACb,mBAAmB,CAwLrB;AAKD,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -1,11 +1,32 @@
1
1
  import type { GltfDocItemLike } from './sub-asset-key.js';
2
- export interface GltfSourceKeyError {
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
@@ -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;IACjC,QAAQ,CAAC,IAAI,EACT,oBAAoB,GACpB,sBAAsB,GACtB,sBAAsB,GACtB,oCAAoC,CAAC;IACzC,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AAED,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,CAwC3F"}
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",
3
+ "version": "0.1.6",
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 typed assets.load(guid, sceneAssetKind) and World scene ownership.",
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.3",
42
- "@forgeax/engine-geometry": "0.1.3",
43
- "@forgeax/engine-import": "0.1.3",
44
- "@forgeax/engine-math": "0.1.3",
45
- "@forgeax/engine-pack": "0.1.3",
46
- "@forgeax/engine-scene": "0.1.3",
47
- "@forgeax/engine-types": "0.1.3",
41
+ "@forgeax/engine-animation": "0.1.6",
42
+ "@forgeax/engine-geometry": "0.1.6",
43
+ "@forgeax/engine-import": "0.1.6",
44
+ "@forgeax/engine-math": "0.1.6",
45
+ "@forgeax/engine-pack": "0.1.6",
46
+ "@forgeax/engine-scene": "0.1.6",
47
+ "@forgeax/engine-types": "0.1.6",
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.3",
53
- "@forgeax/engine-ecs": "0.1.3",
54
- "@forgeax/engine-geometry": "0.1.3",
55
- "@forgeax/engine-picking": "0.1.3",
56
- "@forgeax/engine-render": "0.1.3",
57
- "@forgeax/engine-runtime": "0.1.3",
52
+ "@forgeax/engine-assets-runtime": "0.1.6",
53
+ "@forgeax/engine-picking": "0.1.6",
54
+ "@forgeax/engine-render": "0.1.6",
55
+ "@forgeax/engine-runtime": "0.1.6",
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 { meshAssetKind } from '@forgeax/engine-geometry';
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 { createAssetRuntimeFixture, installMeshDecoder } from './asset-runtime-fixture';
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 meshResult = meshIrToMeshAsset(result.value.meshes);
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 typed assets.load', async () => {
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 assets = createAssetRuntimeFixture([mesh], {
222
- packageUrl: 'https://assets.test/meshopt-pack.pack.json',
223
- });
224
- installMeshDecoder(assets);
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 assets.load(guid, meshAssetKind);
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
- assets.dispose();
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 assets = createAssetRuntimeFixture([mesh], {
273
- packageUrl: 'https://assets.test/meshopt-damaged.pack.json',
274
- artifactOverrides: new Map([[`${guid}:body`, damaged]]),
275
- });
276
- installMeshDecoder(assets);
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 assets.load(guid, meshAssetKind);
358
+ const loaded = await registry.loadByGuid(registry.parseGuid(guid));
279
359
  expect(loaded.ok).toBe(false);
280
360
  if (loaded.ok) return;
281
- expect(loaded.error.code).toBe('asset-integrity-failed');
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
- assets.dispose();
367
+ globalThis.fetch = originalFetch;
284
368
  }
285
369
  });
286
370
  });
@@ -1,16 +1,9 @@
1
1
  import { readFile } from 'node:fs/promises';
2
- import { animationClipContribution } from '@forgeax/engine-animation';
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 { sceneAssetDecoder, sceneAssetKind } from '@forgeax/engine-scene';
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 typed asset owners', () => {
60
- it('preserves two targets and two animation keyframes through typed loads', async () => {
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 assets = createAssetRuntimeFixture(pack.assets);
94
- installMeshDecoder(assets);
95
- assets.installDecoder(sceneAssetKind, sceneAssetDecoder);
96
- assets.installDecoder(animationClipContribution.kind, animationClipContribution.decoder);
97
- for (const asset of pack.assets) {
98
- if (asset.kind !== 'mesh' && asset.kind !== 'scene' && asset.kind !== 'animation-clip') {
99
- installPassthroughDecoder(assets, asset.kind);
100
- }
101
- }
102
-
103
- try {
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
- expect(Array.from(loadedMesh.value.morphWeights ?? [])).toEqual([0, 0]);
118
- const sceneEntity = loadedScene.value.entities[0];
119
- expect(sceneEntity?.components.MorphWeights?.weights).toEqual([0, 0]);
120
- expect(loadedAnimation.value.channels[0]?.property).toBe('weights');
121
- expect(Array.from(loadedAnimation.value.channels[0]?.sampler.output ?? [])).toEqual([
122
- 0, 0.75, 0.25, 0,
123
- ]);
124
- } finally {
125
- assets.dispose();
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
+ });