@forgeax/engine-gltf 0.1.28 → 0.1.29
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 +1 -1
- package/dist/bridge.d.ts +7 -0
- package/dist/bridge.d.ts.map +1 -1
- package/dist/cli-gltf.mjs +6 -4
- package/dist/cli-gltf.mjs.map +1 -1
- package/dist/gltf-importer.d.ts.map +1 -1
- package/dist/importer-entry.mjs +44 -18
- package/dist/importer-entry.mjs.map +1 -1
- package/dist/index.mjs +44 -18
- package/dist/index.mjs.map +1 -1
- package/dist/node-file-entry.mjs +6 -4
- package/dist/node-file-entry.mjs.map +1 -1
- package/dist/parse-gltf.d.ts.map +1 -1
- package/dist/parse-skin.d.ts +8 -16
- package/dist/parse-skin.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/__tests__/bridge.unit.test.ts +70 -51
- package/src/__tests__/gltf.unit.test.ts +95 -15
- package/src/__tests__/morph-import.integration.test.ts +1 -1
- package/src/bridge.ts +34 -10
- package/src/gltf-importer.ts +29 -11
- package/src/parse-gltf.ts +5 -0
- package/src/parse-skin.ts +14 -41
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gltf-importer.d.ts","sourceRoot":"","sources":["../src/gltf-importer.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAEV,QAAQ,EAIR,QAAQ,EAMT,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"gltf-importer.d.ts","sourceRoot":"","sources":["../src/gltf-importer.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAEV,QAAQ,EAIR,QAAQ,EAMT,MAAM,uBAAuB,CAAC;AAmB/B,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAqB,MAAM,iBAAiB,CAAC;AAwUlF,iFAAiF;AACjF,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,OAAO,EACZ,kBAAkB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/C,kBAAkB,GAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAa,GAC1D,SAAS,QAAQ,EAAE,CA2CrB;AA6oBD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,8BAA8B,GAAG,QAAQ,CAMrF;AAED,8EAA8E;AAC9E,eAAO,MAAM,YAAY,EAAE,QAA+B,CAAC"}
|
package/dist/importer-entry.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { MeshoptDecoder } from 'meshoptimizer';
|
|
|
2
2
|
import { deriveDefaultLodScreenCoverages } from '@forgeax/engine-import';
|
|
3
3
|
import { packMeshBinV4 } from '@forgeax/engine-import/mesh-bin';
|
|
4
4
|
import { AssetGuid } from '@forgeax/engine-pack/guid';
|
|
5
|
-
import { ImportError, toShared, err, ok, reconcileMeshMaterialSlotTopology, IMPORT_ERROR_HINTS, resolveMeshMaterialSlotDefaultGuid, createMaterialError, standardMaterialParameters, STANDARD_MATERIAL_PARAM_SCHEMA, STANDARD_PHYSICAL_PARAMETER_NAMES, STANDARD_TRANSMISSION_PARAMETER_NAMES, STANDARD_LAYER_PARAMETER_GROUPS } from '@forgeax/engine-types';
|
|
5
|
+
import { ImportError, readConservativeAnimatedBounds, toShared, err, ok, reconcileMeshMaterialSlotTopology, IMPORT_ERROR_HINTS, resolveMeshMaterialSlotDefaultGuid, createMaterialError, standardMaterialParameters, STANDARD_MATERIAL_PARAM_SCHEMA, STANDARD_PHYSICAL_PARAMETER_NAMES, STANDARD_TRANSMISSION_PARAMETER_NAMES, STANDARD_LAYER_PARAMETER_GROUPS, parseConservativeAnimatedBounds } from '@forgeax/engine-types';
|
|
6
6
|
import { computeTangentVec4, packInterleavedVertexAttributes } from '@forgeax/engine-geometry';
|
|
7
7
|
import { box3, mat4, vec3, quat } from '@forgeax/engine-math';
|
|
8
8
|
import { deriveAnimationTargetId } from '@forgeax/engine-animation/target-id';
|
|
@@ -443,7 +443,7 @@ function composeMat4(out, tx, ty, tz, qx, qy, qz, qw, sx, sy, sz) {
|
|
|
443
443
|
function gltfDocToSceneAsset(doc, ctx) {
|
|
444
444
|
const sceneIr = doc.scenes[doc.defaultSceneIndex];
|
|
445
445
|
const resultNodes = [];
|
|
446
|
-
if (sceneIr === void 0) return { kind: "scene", entities:
|
|
446
|
+
if (sceneIr === void 0) return { kind: "scene", entities: {} };
|
|
447
447
|
const importedLights = doc.lights ?? doc.extensions?.KHR_lights_punctual?.lights ?? [];
|
|
448
448
|
const animationTargetIds = /* @__PURE__ */ new Map();
|
|
449
449
|
for (const clip of doc.animationClips) {
|
|
@@ -536,7 +536,10 @@ function gltfDocToSceneAsset(doc, ctx) {
|
|
|
536
536
|
components.MeshRenderer = { materials: [] };
|
|
537
537
|
}
|
|
538
538
|
if (ir.instancing !== void 0) {
|
|
539
|
-
|
|
539
|
+
const collectionId = ctx.instanceCollectionIdsByNodeIndex?.get(gltfNodeIdx);
|
|
540
|
+
if (collectionId !== void 0) {
|
|
541
|
+
components.Instances = { collectionId };
|
|
542
|
+
}
|
|
540
543
|
}
|
|
541
544
|
if (isCamera) {
|
|
542
545
|
components.Camera = {
|
|
@@ -564,10 +567,20 @@ function gltfDocToSceneAsset(doc, ctx) {
|
|
|
564
567
|
for (let i = 0; i < 16; i++) parentWorld[i] = savedParent[i] ?? 0;
|
|
565
568
|
};
|
|
566
569
|
for (const rootIdx of sceneIr.nodes) visit(rootIdx, null);
|
|
567
|
-
const
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
570
|
+
const keyByLocalId = /* @__PURE__ */ new Map();
|
|
571
|
+
for (const node of resultNodes) keyByLocalId.set(node.localIdx, `node-${node.localIdx}`);
|
|
572
|
+
const entities = {};
|
|
573
|
+
for (const node of resultNodes) {
|
|
574
|
+
const components = { ...node.components };
|
|
575
|
+
const childOf = components.ChildOf;
|
|
576
|
+
if (childOf !== void 0 && typeof childOf.parent === "number") {
|
|
577
|
+
const parentKey = keyByLocalId.get(childOf.parent);
|
|
578
|
+
if (parentKey === void 0)
|
|
579
|
+
throw new Error(`gltfDocToSceneAsset: missing parent node ${childOf.parent}`);
|
|
580
|
+
components.ChildOf = { ...childOf, parent: parentKey };
|
|
581
|
+
}
|
|
582
|
+
entities[`node-${node.localIdx}`] = { components };
|
|
583
|
+
}
|
|
571
584
|
const lightFacts = importedLights.map((light) => ({
|
|
572
585
|
kind: light.type,
|
|
573
586
|
intensity: light.intensity,
|
|
@@ -576,7 +589,7 @@ function gltfDocToSceneAsset(doc, ctx) {
|
|
|
576
589
|
}));
|
|
577
590
|
return {
|
|
578
591
|
kind: "scene",
|
|
579
|
-
entities
|
|
592
|
+
entities,
|
|
580
593
|
...lightFacts.length === 0 ? {} : { lights: lightFacts }
|
|
581
594
|
};
|
|
582
595
|
}
|
|
@@ -2283,8 +2296,6 @@ function parseAnimation(animationsJson, nodesJson, accessors, bufferViews, buffe
|
|
|
2283
2296
|
}
|
|
2284
2297
|
return ok(clips);
|
|
2285
2298
|
}
|
|
2286
|
-
|
|
2287
|
-
// src/parse-skin.ts
|
|
2288
2299
|
var MAX_JOINTS = 256;
|
|
2289
2300
|
var SKIN_ACCESSOR_TYPES = ["MAT4"];
|
|
2290
2301
|
function identityMat4() {
|
|
@@ -2365,10 +2376,14 @@ function parseSkin(skinsJson, nodesJson, accessors, bufferViews, buffers) {
|
|
|
2365
2376
|
if (!pathResult.ok) return err(pathResult.error);
|
|
2366
2377
|
jointPaths.push(pathResult.value.join("/"));
|
|
2367
2378
|
}
|
|
2379
|
+
const bounds = parseConservativeAnimatedBounds(
|
|
2380
|
+
skin.extras?.forgeax?.conservativeAnimatedBounds
|
|
2381
|
+
);
|
|
2368
2382
|
records.push({
|
|
2369
2383
|
jointCount: joints.length,
|
|
2370
2384
|
inverseBindMatrices: ibm,
|
|
2371
|
-
jointPaths
|
|
2385
|
+
jointPaths,
|
|
2386
|
+
...bounds === void 0 ? {} : { bounds }
|
|
2372
2387
|
});
|
|
2373
2388
|
}
|
|
2374
2389
|
return ok(records);
|
|
@@ -3220,6 +3235,16 @@ function isGlbBytes(source) {
|
|
|
3220
3235
|
function publishesCatalogProduct(input) {
|
|
3221
3236
|
return input.importSettings.geometry !== "procedural";
|
|
3222
3237
|
}
|
|
3238
|
+
function applyImportSettingsBounds(doc, importSettings) {
|
|
3239
|
+
let changed = false;
|
|
3240
|
+
const skeletons = doc.skeletons.map((record, sourceIndex) => {
|
|
3241
|
+
const bounds = readConservativeAnimatedBounds(importSettings, sourceIndex);
|
|
3242
|
+
if (bounds === void 0 || record.bounds !== void 0) return record;
|
|
3243
|
+
changed = true;
|
|
3244
|
+
return { ...record, bounds };
|
|
3245
|
+
});
|
|
3246
|
+
return changed ? { ...doc, skeletons } : doc;
|
|
3247
|
+
}
|
|
3223
3248
|
function previousMaterialSlotTopology(ctx, meshSourceKey) {
|
|
3224
3249
|
if (meshSourceKey === void 0) return void 0;
|
|
3225
3250
|
const value = ctx.sourceOverrides?.[meshSourceKey]?.materialSlots;
|
|
@@ -3539,7 +3564,7 @@ async function importGltf(ctx, meshopt) {
|
|
|
3539
3564
|
}
|
|
3540
3565
|
const parsed = await parseDoc(ctx.source, read.value, ctx, meshopt);
|
|
3541
3566
|
if (!parsed.ok) return parsed;
|
|
3542
|
-
const doc = parsed.value;
|
|
3567
|
+
const doc = applyImportSettingsBounds(parsed.value, ctx.importSettings);
|
|
3543
3568
|
const maps = buildHandleMaps(ctx.subAssets, doc);
|
|
3544
3569
|
const imageColorSpaces = deriveTextureColorSpace({
|
|
3545
3570
|
imageCount: (doc.images ?? []).length,
|
|
@@ -3838,7 +3863,7 @@ async function importGltf(ctx, meshopt) {
|
|
|
3838
3863
|
fieldName: prov.fieldName,
|
|
3839
3864
|
...prov.arrayIndex !== void 0 ? { arrayIndex: prov.arrayIndex } : {}
|
|
3840
3865
|
},
|
|
3841
|
-
|
|
3866
|
+
sceneEntityKey: prov.sceneEntityKey
|
|
3842
3867
|
};
|
|
3843
3868
|
}
|
|
3844
3869
|
return { guid };
|
|
@@ -3849,19 +3874,19 @@ async function importGltf(ctx, meshopt) {
|
|
|
3849
3874
|
});
|
|
3850
3875
|
const handleValueProvenance = /* @__PURE__ */ new Map();
|
|
3851
3876
|
const skeletonGuidProvenance = /* @__PURE__ */ new Map();
|
|
3852
|
-
for (const entity of scene.entities) {
|
|
3877
|
+
for (const [sceneEntityKey, entity] of Object.entries(scene.entities)) {
|
|
3853
3878
|
const comps = entity.components;
|
|
3854
3879
|
const mf = comps.MeshFilter;
|
|
3855
3880
|
if (mf !== void 0 && typeof mf.assetHandle === "number") {
|
|
3856
3881
|
handleValueProvenance.set(mf.assetHandle, {
|
|
3857
|
-
|
|
3882
|
+
sceneEntityKey,
|
|
3858
3883
|
componentName: "MeshFilter",
|
|
3859
3884
|
fieldName: "assetHandle"
|
|
3860
3885
|
});
|
|
3861
3886
|
}
|
|
3862
3887
|
const skin = comps.Skin;
|
|
3863
3888
|
if (skin !== void 0 && typeof skin.skeleton === "string") {
|
|
3864
|
-
skeletonGuidProvenance.set(skin.skeleton, {
|
|
3889
|
+
skeletonGuidProvenance.set(skin.skeleton, { sceneEntityKey });
|
|
3865
3890
|
}
|
|
3866
3891
|
}
|
|
3867
3892
|
const meshGuidList = [...maps.meshGuidByIndex.values()];
|
|
@@ -3879,7 +3904,7 @@ async function importGltf(ctx, meshopt) {
|
|
|
3879
3904
|
skProv !== void 0 ? {
|
|
3880
3905
|
guid,
|
|
3881
3906
|
sourceField: { componentName: "Skin", fieldName: "skeleton" },
|
|
3882
|
-
|
|
3907
|
+
sceneEntityKey: skProv.sceneEntityKey
|
|
3883
3908
|
} : { guid }
|
|
3884
3909
|
);
|
|
3885
3910
|
cursor++;
|
|
@@ -3909,7 +3934,8 @@ async function importGltf(ctx, meshopt) {
|
|
|
3909
3934
|
const payload = {
|
|
3910
3935
|
kind: "skeleton",
|
|
3911
3936
|
inverseBindMatrices: rec.inverseBindMatrices,
|
|
3912
|
-
jointCount: rec.jointCount
|
|
3937
|
+
jointCount: rec.jointCount,
|
|
3938
|
+
...rec.bounds === void 0 ? {} : { bounds: rec.bounds }
|
|
3913
3939
|
};
|
|
3914
3940
|
out.push({ guid: sub.guid, kind: "skeleton", payload, refs: [], artifacts: {} });
|
|
3915
3941
|
} else if (sub.kind === "skin") {
|