@forgeax/engine-gltf 0.1.4 → 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 +5 -1
  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 +31 -10
  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 +2 -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 +1 -2
  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
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=extension-admission.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-admission.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/extension-admission.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=source-key-diagnostics.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-key-diagnostics.integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/source-key-diagnostics.integration.test.ts"],"names":[],"mappings":""}
package/dist/bridge.d.ts CHANGED
@@ -41,17 +41,16 @@ export interface GltfBridgeContext {
41
41
  /**
42
42
  * glTF skin index -> SkeletonAsset GUID (string form). When a GltfNodeIr carries
43
43
  * a skin reference, the bridge emits `Skin: { skeleton: <guid-string> }` on
44
- * that node's entity; the World scene owner resolves the GUID to a shared ref
45
- * at `world.instantiateScene` time (same protocol as MeshFilter and
44
+ * that node's entity; AssetRegistry._resolveSceneGuids resolves the GUID to
45
+ * a runtime Handle at instantiate time (same protocol as MeshFilter and
46
46
  * MeshRenderer.materials[]). Optional — skinless glTFs pass an empty Map
47
47
  * (or omit the field) and the bridge does not emit Skin.
48
48
  *
49
49
  * tweak-20260611 M6 / D-7: emitting Skin from the bridge means the standard
50
- * typed `assets.load(sceneGuid, sceneAssetKind)` + `world.instantiateScene`
51
- * path Just Works for skinned glTF;
50
+ * loadByGuid<SceneAsset> + instantiate path Just Works for skinned glTF;
52
51
  * demos no longer need to runtime-parseGlb + post-load patch the SceneAsset.
53
- * postSpawnResolveJoints walks the matching SkinAsset.jointPaths against the
54
- * spawn subtree to fill Skin.joints[].
52
+ * postSpawnResolveJoints (called from AssetRegistry.instantiate) walks the
53
+ * matching SkinAsset.jointPaths against the spawn subtree to fill Skin.joints[].
55
54
  */
56
55
  readonly skeletonGuidBySkinIndex?: ReadonlyMap<number, string>;
57
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,SAAS,EACT,MAAM,EAEN,aAAa,EACb,aAAa,EAEb,SAAS,EAIT,MAAM,EACN,UAAU,EAIX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAA4B,KAAK,SAAS,EAAe,MAAM,aAAa,CAAC;AACpF,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,UAAU,EACV,UAAU,EAGX,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,SAAS,GAAE;IACT,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpD,GACL,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CA0U9B;AAED,MAAM,WAAW,iBAAiB;IAChC,oEAAoE;IACpE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;IACzE,4DAA4D;IAC5D,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjF;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChE;AA+DD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB,GAAG,UAAU,CA8NpF;AAED,uFAAuF;AACvF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC;AAEtC,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;IAChF,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;IAChF,8EAA8E;IAC9E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,CAAC;IACtC;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAqDD,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,CA0B7B;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,qBAAqB,GAAG,aAAa,CA0E/F"}
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,SAAS,EACT,MAAM,EAEN,aAAa,EACb,aAAa,EAEb,SAAS,EAIT,MAAM,EACN,UAAU,EAIX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAA4B,KAAK,SAAS,EAAe,MAAM,aAAa,CAAC;AACpF,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,UAAU,EACV,UAAU,EAGX,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,SAAS,GAAE;IACT,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpD,GACL,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CA0U9B;AAED,MAAM,WAAW,iBAAiB;IAChC,oEAAoE;IACpE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;IACzE,4DAA4D;IAC5D,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjF;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChE;AA+DD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB,GAAG,UAAU,CA8NpF;AAED,uFAAuF;AACvF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC;AAEtC,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;IAChF,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;IAChF,8EAA8E;IAC9E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,CAAC;IACtC;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAqDD,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,CA0B7B;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,qBAAqB,GAAG,aAAa,CA0E/F"}
@@ -1 +1 @@
1
- {"version":3,"file":"check-extensions.d.ts","sourceRoot":"","sources":["../src/check-extensions.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAO,KAAK,SAAS,EAAe,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAE5E,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAGhD,CAAC;AAGF,MAAM,WAAW,qBAAqB;IACpC,+DAA+D;IAC/D,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,kBAAkB,GACvB,MAAM,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAsB1C"}
1
+ {"version":3,"file":"check-extensions.d.ts","sourceRoot":"","sources":["../src/check-extensions.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAO,KAAK,SAAS,EAAe,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAE5E,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAGhD,CAAC;AAOF,MAAM,WAAW,qBAAqB;IACpC,+DAA+D;IAC/D,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,kBAAkB,GACvB,MAAM,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAsB1C"}
package/dist/cli-gltf.mjs CHANGED
@@ -392,7 +392,11 @@ var EXTENSION_ALLOWLIST = [
392
392
  "EXT_mesh_gpu_instancing",
393
393
  "EXT_meshopt_compression"
394
394
  ];
395
- var SUPPORTED_EXTENSIONS = [...EXTENSION_ALLOWLIST, "KHR_lights_punctual"];
395
+ var SUPPORTED_EXTENSIONS = [
396
+ ...EXTENSION_ALLOWLIST,
397
+ "KHR_lights_punctual",
398
+ "KHR_texture_transform"
399
+ ];
396
400
  function checkExtensions(json) {
397
401
  const required = json.extensionsRequired ?? [];
398
402
  for (const ext of required) {
@@ -992,9 +996,9 @@ function deriveGltfSourceKeys(items) {
992
996
  ok: false,
993
997
  error: {
994
998
  code: "missing-source-key",
995
- sourceIndices: missing,
996
999
  expected: "every glTF output needs a stable semantic kind or name",
997
- hint: "publish a semantic kind/name key; do not use sourceIndex"
1000
+ hint: "publish a semantic kind/name key; do not use sourceIndex",
1001
+ detail: { sourceIndices: missing }
998
1002
  }
999
1003
  };
1000
1004
  }
@@ -1002,19 +1006,34 @@ function deriveGltfSourceKeys(items) {
1002
1006
  for (let index = 0; index < keys.length; index++) {
1003
1007
  const key = keys[index];
1004
1008
  if (key === void 0) continue;
1009
+ const current = items[index];
1010
+ if (current === void 0) continue;
1005
1011
  const prior = seen.get(key);
1006
1012
  if (prior !== void 0) {
1013
+ const entry = (item) => {
1014
+ const name = item.name?.trim();
1015
+ return {
1016
+ kind: item.kind.trim(),
1017
+ name: name === void 0 || name.length === 0 ? null : name,
1018
+ sourceIndex: item.sourceIndex
1019
+ };
1020
+ };
1021
+ const ambiguous = key === current.kind.trim();
1007
1022
  return {
1008
1023
  ok: false,
1009
1024
  error: {
1010
- code: key === items[index]?.kind ? "ambiguous-source-key" : "duplicate-source-key",
1011
- sourceIndices: [prior, items[index]?.sourceIndex ?? 0],
1025
+ code: ambiguous ? "ambiguous-source-key" : "duplicate-source-key",
1012
1026
  expected: "sourceKey values must be unique within one glTF package",
1013
- hint: key === items[index]?.kind ? "name each otherwise anonymous output; do not use sourceIndex" : "rename duplicate outputs before publishing topology facts"
1027
+ hint: ambiguous ? "name each otherwise anonymous output; do not use sourceIndex" : "rename duplicate outputs before publishing topology facts",
1028
+ detail: {
1029
+ key,
1030
+ sourceIndices: [prior.sourceIndex, current.sourceIndex],
1031
+ entries: [entry(prior), entry(current)]
1032
+ }
1014
1033
  }
1015
1034
  };
1016
1035
  }
1017
- seen.set(key, items[index]?.sourceIndex ?? 0);
1036
+ seen.set(key, current);
1018
1037
  }
1019
1038
  return { ok: true, keys, conflicts: [] };
1020
1039
  }
@@ -2083,10 +2102,12 @@ function toAssetPack(doc, existingMeta, source) {
2083
2102
  if (!reconciled.ok) {
2084
2103
  return err({
2085
2104
  code: "mesh-material-slot-topology-change",
2086
- sourceIndices: reconciled.error.nextIndices,
2087
- previousIndices: reconciled.error.previousIndices,
2088
2105
  expected: `unambiguous material slot identity for mesh ${meshOutput.guid}`,
2089
- hint: reconciled.error.hint
2106
+ hint: reconciled.error.hint,
2107
+ detail: {
2108
+ sourceIndices: reconciled.error.nextIndices,
2109
+ previousIndices: reconciled.error.previousIndices
2110
+ }
2090
2111
  });
2091
2112
  }
2092
2113
  sourceOverrides[meshOutput.sourceKey] = {
@@ -2385,12 +2406,7 @@ async function runWrite(target, ctx) {
2385
2406
  sourceRelative
2386
2407
  );
2387
2408
  if (!pack.ok) {
2388
- return emitError(ctx, {
2389
- code: pack.error.code,
2390
- expected: pack.error.expected,
2391
- hint: pack.error.hint,
2392
- detail: { source: sourceRelative, sourceIndices: pack.error.sourceIndices }
2393
- });
2409
+ return emitError(ctx, pack.error);
2394
2410
  }
2395
2411
  await writeFile(metaPath, serializeMetaJson(pack.value.meta), "utf-8");
2396
2412
  return 0;