@forgeax/engine-gltf 0.1.7 → 0.1.20

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 (39) hide show
  1. package/README.md +9 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/__tests__/transmission-pack-carrier.integration.test.d.ts +2 -0
  4. package/dist/__tests__/transmission-pack-carrier.integration.test.d.ts.map +1 -0
  5. package/dist/bridge.d.ts.map +1 -1
  6. package/dist/check-extensions.d.ts +3 -3
  7. package/dist/check-extensions.d.ts.map +1 -1
  8. package/dist/cli-gltf.mjs +161 -69
  9. package/dist/cli-gltf.mjs.map +1 -1
  10. package/dist/errors.d.ts +7 -0
  11. package/dist/errors.d.ts.map +1 -1
  12. package/dist/gltf-importer.d.ts.map +1 -1
  13. package/dist/importer-entry.mjs +177 -72
  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 +177 -72
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/material/parse-material.d.ts +118 -0
  20. package/dist/material/parse-material.d.ts.map +1 -0
  21. package/dist/node-file-entry.mjs +161 -69
  22. package/dist/node-file-entry.mjs.map +1 -1
  23. package/dist/parse-gltf.d.ts +17 -103
  24. package/dist/parse-gltf.d.ts.map +1 -1
  25. package/package.json +12 -12
  26. package/src/__tests__/bridge-material-values.unit.test.ts +46 -0
  27. package/src/__tests__/gltf-error-derived-views.test-d.ts +4 -0
  28. package/src/__tests__/gltf-error-policy-owner.unit.test.ts +26 -178
  29. package/src/__tests__/gltf.unit.test.ts +34 -13
  30. package/src/__tests__/material-pack-refs.integration.test.ts +12 -0
  31. package/src/__tests__/parse-gltf.unit.test.ts +121 -0
  32. package/src/__tests__/transmission-pack-carrier.integration.test.ts +82 -0
  33. package/src/bridge.ts +12 -1
  34. package/src/check-extensions.ts +14 -9
  35. package/src/errors.ts +12 -0
  36. package/src/gltf-importer.ts +6 -0
  37. package/src/index.ts +1 -0
  38. package/src/material/parse-material.ts +342 -0
  39. package/src/parse-gltf.ts +50 -277
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ export type { GltfBridgeContext, MaterialBridgeContext } from './bridge.js';
7
7
  export { gltfDocToSceneAsset, meshIrToMeshAsset, toMaterialAsset } from './bridge.js';
8
8
  export type { ExtensionsCheckResult, GltfExtensionsJson } from './check-extensions.js';
9
9
  export { checkExtensions, EXTENSION_ALLOWLIST } from './check-extensions.js';
10
- export type { GltfAccessorTypeMismatchDetail, GltfAnimationCubicsplineUnsupportedDetail, GltfBufferOutOfBoundsDetail, GltfColorAccessorMalformedDetail, GltfColorAccessorUnsupportedDetail, GltfError, GltfErrorCode, GltfErrorDetail, GltfExtensionUnsupportedDetail, GltfImageExtractFailedDetail, GltfImageMimeUnsupportedDetail, GltfInstancingCountMismatchDetail, GltfMalformedHeaderDetail, GltfMetaMissingDetail, GltfMorphInvalidDetail, GltfMorphUnsupportedDetail, GltfSkinAttrAsymmetricDetail, GltfSkinJointCountExceededDetail, GltfSkinJointNameMissingDetail, GltfTextureLoadFailedDetail, GltfVersionUnsupportedDetail, Result, } from './errors.js';
10
+ export type { GltfAccessorTypeMismatchDetail, GltfAnimationCubicsplineUnsupportedDetail, GltfBufferOutOfBoundsDetail, GltfColorAccessorMalformedDetail, GltfColorAccessorUnsupportedDetail, GltfError, GltfErrorCode, GltfErrorDetail, GltfExtensionUnsupportedDetail, GltfImageExtractFailedDetail, GltfImageMimeUnsupportedDetail, GltfInstancingCountMismatchDetail, GltfMalformedHeaderDetail, GltfMaterialTransmissionInvalidDetail, GltfMetaMissingDetail, GltfMorphInvalidDetail, GltfMorphUnsupportedDetail, GltfSkinAttrAsymmetricDetail, GltfSkinJointCountExceededDetail, GltfSkinJointNameMissingDetail, GltfTextureLoadFailedDetail, GltfVersionUnsupportedDetail, Result, } from './errors.js';
11
11
  export { err, GLTF_ERROR_HINTS, gltfErr, ok } from './errors.js';
12
12
  export { gltfImporter } from './gltf-importer.js';
13
13
  export type { GlbChunks } from './parse-glb-chunks.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAkBA,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,OAAO,EACP,cAAc,EACd,cAAc,EACd,QAAQ,EACR,WAAW,EACX,OAAO,EACP,sBAAsB,EACtB,UAAU,GACX,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,eAAe,GAChB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/E,YAAY,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAK5E,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACtF,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEvF,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC7E,YAAY,EACV,8BAA8B,EAC9B,yCAAyC,EACzC,2BAA2B,EAC3B,gCAAgC,EAChC,kCAAkC,EAClC,SAAS,EACT,aAAa,EACb,eAAe,EACf,8BAA8B,EAC9B,4BAA4B,EAC5B,8BAA8B,EAC9B,iCAAiC,EACjC,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,4BAA4B,EAC5B,gCAAgC,EAChC,8BAA8B,EAC9B,2BAA2B,EAC3B,4BAA4B,EAC5B,MAAM,GACP,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxE,YAAY,EACV,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,OAAO,EACP,WAAW,EACX,cAAc,EACd,UAAU,EACV,UAAU,EACV,uBAAuB,EACvB,0BAA0B,EAC1B,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,sBAAsB,EACtB,QAAQ,EACR,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AASnE,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,YAAY,EACV,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,iBAAiB,EACjB,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,SAAS,EACT,SAAS,GACV,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -26,6 +26,10 @@ var gltfErrorPolicy = {
26
26
  expected: "extension listed in v1 allowlist (see EXTENSION_ALLOWLIST in @forgeax/engine-gltf)",
27
27
  hint: "see feat-future-gltf-extensions-allowlist; remove this extension or wait for the allowlist to expand"
28
28
  },
29
+ "gltf-material-transmission-invalid": {
30
+ expected: "KHR transmission, IOR, and volume values are finite and within their glTF ranges",
31
+ hint: "repair the named glTF material extension value and re-import the source"
32
+ },
29
33
  "gltf-accessor-type-mismatch": {
30
34
  expected: "dense fixed-stride accessor with supported componentType",
31
35
  hint: "sparse: see feat-future-gltf-sparse-accessor; morph: see feat-future-gltf-morph; interleaved: see feat-future-gltf-mesh-multi-section"
@@ -868,7 +872,9 @@ function validateMaterialUvSets(mat, primitive, availableSets) {
868
872
  ["metallicRoughnessTexture", mat.metallicRoughnessTexture],
869
873
  ["normalTexture", mat.normalTexture],
870
874
  ["occlusionTexture", mat.occlusionTexture],
871
- ["emissiveTexture", mat.emissiveTexture]
875
+ ["emissiveTexture", mat.emissiveTexture],
876
+ ["transmissionTexture", mat.transmissionTexture],
877
+ ["thicknessTexture", mat.thicknessTexture]
872
878
  ];
873
879
  for (const [slot, rawBinding] of slots) {
874
880
  const binding = textureInfo(rawBinding);
@@ -903,7 +909,9 @@ function toMaterialAsset(mat, ctx) {
903
909
  ["metallicRoughnessTexture", mat.metallicRoughnessTexture],
904
910
  ["normalTexture", mat.normalTexture],
905
911
  ["occlusionTexture", mat.occlusionTexture],
906
- ["emissiveTexture", mat.emissiveTexture]
912
+ ["emissiveTexture", mat.emissiveTexture],
913
+ ["transmissionTexture", mat.transmissionTexture],
914
+ ["thicknessTexture", mat.thicknessTexture]
907
915
  ];
908
916
  for (const [slot, info] of textureSlots) {
909
917
  const value = textureValue(info, slot, ctx);
@@ -912,6 +920,11 @@ function toMaterialAsset(mat, ctx) {
912
920
  if (mat.occlusionTexture !== void 0 && values.occlusionStrength === void 0) {
913
921
  values.occlusionStrength = 1;
914
922
  }
923
+ if (mat.transmissionFactor !== void 0) values.transmission = mat.transmissionFactor;
924
+ if (mat.ior !== void 0) values.ior = mat.ior;
925
+ if (mat.thicknessFactor !== void 0) values.thickness = mat.thicknessFactor;
926
+ if (mat.attenuationColor !== void 0) values.attenuationColor = mat.attenuationColor;
927
+ if (mat.attenuationDistance !== void 0) values.attenuationDistance = mat.attenuationDistance;
915
928
  const module = ctx?.skinned === true ? "forgeax::pbr-skin" : "forgeax::default-standard-pbr";
916
929
  const isMask = mat.alphaMode === "MASK";
917
930
  const alphaCutoff = isMask ? mat.alphaCutoff ?? 0.5 : void 0;
@@ -958,7 +971,10 @@ var EXTENSION_ALLOWLIST = [
958
971
  var SUPPORTED_EXTENSIONS = [
959
972
  ...EXTENSION_ALLOWLIST,
960
973
  "KHR_lights_punctual",
961
- "KHR_texture_transform"
974
+ "KHR_texture_transform",
975
+ "KHR_materials_transmission",
976
+ "KHR_materials_ior",
977
+ "KHR_materials_volume"
962
978
  ];
963
979
  function checkExtensions(json) {
964
980
  const required = json.extensionsRequired ?? [];
@@ -1408,6 +1424,152 @@ function deriveTextureColorSpace(input) {
1408
1424
  return result;
1409
1425
  }
1410
1426
 
1427
+ // src/material/parse-material.ts
1428
+ function tuple2(values) {
1429
+ if (values === void 0 || values.length < 2) return void 0;
1430
+ return [values[0] ?? 0, values[1] ?? 0];
1431
+ }
1432
+ function tuple3(values) {
1433
+ if (values === void 0 || values.length < 3) return void 0;
1434
+ return [values[0] ?? 0, values[1] ?? 0, values[2] ?? 0];
1435
+ }
1436
+ function parseTextureInfo(info, textures) {
1437
+ const transformJson = info.extensions?.KHR_texture_transform;
1438
+ const offset = tuple2(transformJson?.offset);
1439
+ const scale = tuple2(transformJson?.scale);
1440
+ const transform = offset === void 0 && transformJson?.rotation === void 0 && scale === void 0 ? void 0 : {
1441
+ ...offset === void 0 ? {} : { offset },
1442
+ ...transformJson?.rotation === void 0 ? {} : { rotation: transformJson.rotation },
1443
+ ...scale === void 0 ? {} : { scale }
1444
+ };
1445
+ const sampler = textures[info.index]?.sampler;
1446
+ return {
1447
+ texture: info.index,
1448
+ ...sampler === void 0 ? {} : { sampler },
1449
+ ...info.texCoord === void 0 && transformJson?.texCoord === void 0 ? {} : { texCoord: transformJson?.texCoord ?? info.texCoord },
1450
+ ...transform === void 0 ? {} : { transform }
1451
+ };
1452
+ }
1453
+ function finiteOrUndefined(value) {
1454
+ return value !== void 0 && Number.isFinite(value) ? value : void 0;
1455
+ }
1456
+ function parseMaterial(matJson, textures) {
1457
+ const pbr = matJson.pbrMetallicRoughness;
1458
+ const baseColor = pbr?.baseColorFactor ?? [1, 1, 1, 1];
1459
+ const baseColor4 = [
1460
+ baseColor[0] ?? 1,
1461
+ baseColor[1] ?? 1,
1462
+ baseColor[2] ?? 1,
1463
+ baseColor[3] ?? 1
1464
+ ];
1465
+ const alphaMode = matJson.alphaMode === "MASK" || matJson.alphaMode === "BLEND" ? matJson.alphaMode : void 0;
1466
+ const alphaCutoff = alphaMode === "MASK" ? matJson.alphaCutoff ?? 0.5 : void 0;
1467
+ const emissiveFactor = tuple3(matJson.emissiveFactor);
1468
+ const transmission = matJson.extensions?.KHR_materials_transmission;
1469
+ const ior = matJson.extensions?.KHR_materials_ior;
1470
+ const volume = matJson.extensions?.KHR_materials_volume;
1471
+ const attenuationColor = tuple3(volume?.attenuationColor);
1472
+ const invalid = (extension, field, reason, actual) => err(
1473
+ gltfErr("gltf-material-transmission-invalid", {
1474
+ extension,
1475
+ field,
1476
+ reason,
1477
+ ...actual === void 0 ? {} : { actual }
1478
+ })
1479
+ );
1480
+ if (transmission?.transmissionFactor !== void 0 && (typeof transmission.transmissionFactor !== "number" || !Number.isFinite(transmission.transmissionFactor))) {
1481
+ return invalid(
1482
+ "KHR_materials_transmission",
1483
+ "transmissionFactor",
1484
+ "non-finite",
1485
+ transmission.transmissionFactor
1486
+ );
1487
+ }
1488
+ if (transmission?.transmissionFactor !== void 0 && (transmission.transmissionFactor < 0 || transmission.transmissionFactor > 1)) {
1489
+ return invalid(
1490
+ "KHR_materials_transmission",
1491
+ "transmissionFactor",
1492
+ "range",
1493
+ transmission.transmissionFactor
1494
+ );
1495
+ }
1496
+ if (ior?.ior !== void 0 && (typeof ior.ior !== "number" || !Number.isFinite(ior.ior))) {
1497
+ return invalid("KHR_materials_ior", "ior", "non-finite", ior.ior);
1498
+ }
1499
+ if (ior?.ior !== void 0 && ior.ior < 1) {
1500
+ return invalid("KHR_materials_ior", "ior", "range", ior.ior);
1501
+ }
1502
+ if (volume?.thicknessFactor !== void 0 && !Number.isFinite(volume.thicknessFactor)) {
1503
+ return invalid("KHR_materials_volume", "thicknessFactor", "non-finite", volume.thicknessFactor);
1504
+ }
1505
+ if (volume?.thicknessFactor !== void 0 && volume.thicknessFactor < 0) {
1506
+ return invalid("KHR_materials_volume", "thicknessFactor", "range", volume.thicknessFactor);
1507
+ }
1508
+ if (volume?.attenuationColor !== void 0 && (attenuationColor === void 0 || attenuationColor.some((value) => !Number.isFinite(value) || value < 0 || value > 1))) {
1509
+ return invalid("KHR_materials_volume", "attenuationColor", "range", volume.attenuationColor);
1510
+ }
1511
+ if (volume?.attenuationDistance !== void 0 && !Number.isFinite(volume.attenuationDistance) && volume.attenuationDistance !== Number.POSITIVE_INFINITY) {
1512
+ return invalid(
1513
+ "KHR_materials_volume",
1514
+ "attenuationDistance",
1515
+ "non-finite",
1516
+ volume.attenuationDistance
1517
+ );
1518
+ }
1519
+ if (volume?.attenuationDistance !== void 0 && Number.isFinite(volume.attenuationDistance) && volume.attenuationDistance <= 0) {
1520
+ return invalid(
1521
+ "KHR_materials_volume",
1522
+ "attenuationDistance",
1523
+ "range",
1524
+ volume.attenuationDistance
1525
+ );
1526
+ }
1527
+ if (alphaMode === "BLEND" && (transmission?.transmissionFactor ?? 0) > 0) {
1528
+ return invalid("KHR_materials_transmission", "alphaMode", "blend", alphaMode);
1529
+ }
1530
+ return ok({
1531
+ ...matJson.name === void 0 ? {} : { name: matJson.name },
1532
+ baseColorFactor: baseColor4,
1533
+ ...emissiveFactor === void 0 ? {} : { emissiveFactor },
1534
+ metallicFactor: pbr?.metallicFactor ?? 1,
1535
+ roughnessFactor: pbr?.roughnessFactor ?? 1,
1536
+ ...pbr?.baseColorTexture === void 0 ? {} : { baseColorTexture: parseTextureInfo(pbr.baseColorTexture, textures) },
1537
+ ...pbr?.metallicRoughnessTexture === void 0 ? {} : { metallicRoughnessTexture: parseTextureInfo(pbr.metallicRoughnessTexture, textures) },
1538
+ ...matJson.normalTexture === void 0 ? {} : {
1539
+ normalTexture: {
1540
+ ...parseTextureInfo(matJson.normalTexture, textures),
1541
+ ...matJson.normalTexture.scale === void 0 ? {} : { scale: matJson.normalTexture.scale }
1542
+ }
1543
+ },
1544
+ ...matJson.occlusionTexture === void 0 ? {} : {
1545
+ occlusionTexture: {
1546
+ ...parseTextureInfo(matJson.occlusionTexture, textures),
1547
+ ...matJson.occlusionTexture.strength === void 0 ? {} : { strength: matJson.occlusionTexture.strength }
1548
+ }
1549
+ },
1550
+ ...matJson.emissiveTexture === void 0 ? {} : { emissiveTexture: parseTextureInfo(matJson.emissiveTexture, textures) },
1551
+ ...transmission === void 0 ? {} : {
1552
+ transmissionFactor: transmission.transmissionFactor ?? 0,
1553
+ transmissionChannel: 0,
1554
+ ...transmission.transmissionTexture === void 0 ? {} : {
1555
+ transmissionTexture: parseTextureInfo(transmission.transmissionTexture, textures)
1556
+ }
1557
+ },
1558
+ ...ior === void 0 ? {} : { ior: ior.ior ?? 1.5 },
1559
+ ...volume === void 0 ? {} : {
1560
+ thicknessFactor: volume.thicknessFactor ?? 0,
1561
+ thicknessChannel: 1,
1562
+ ...volume.thicknessTexture === void 0 ? {} : { thicknessTexture: parseTextureInfo(volume.thicknessTexture, textures) },
1563
+ ...attenuationColor === void 0 ? {} : { attenuationColor },
1564
+ ...finiteOrUndefined(volume.attenuationDistance) === void 0 ? {} : { attenuationDistance: volume.attenuationDistance }
1565
+ },
1566
+ ...alphaMode === void 0 ? {} : { alphaMode },
1567
+ ...alphaCutoff === void 0 ? {} : { alphaCutoff },
1568
+ ...matJson.doubleSided === true ? { doubleSided: true } : {},
1569
+ ...pbr?.baseColorTexture?.texCoord === void 0 || pbr.baseColorTexture.texCoord === 0 ? {} : { baseColorTexCoord: pbr.baseColorTexture.texCoord }
1570
+ });
1571
+ }
1572
+
1411
1573
  // src/meshopt-decode.ts
1412
1574
  function viewBytes(view, buffers) {
1413
1575
  const buffer = buffers[view.buffer];
@@ -1933,7 +2095,7 @@ var IDENTITY = {
1933
2095
  rotation: [0, 0, 0, 1],
1934
2096
  scale: [1, 1, 1]
1935
2097
  };
1936
- function tuple3(arr, fallback) {
2098
+ function tuple32(arr, fallback) {
1937
2099
  if (arr === void 0 || arr.length < 3) return fallback;
1938
2100
  return [arr[0] ?? fallback[0], arr[1] ?? fallback[1], arr[2] ?? fallback[2]];
1939
2101
  }
@@ -1969,9 +2131,9 @@ function decomposeNodeTransform(node, nodeIndex, diagnostics) {
1969
2131
  return IDENTITY;
1970
2132
  }
1971
2133
  return {
1972
- translation: tuple3(node.translation, IDENTITY.translation),
2134
+ translation: tuple32(node.translation, IDENTITY.translation),
1973
2135
  rotation: tuple4(node.rotation, IDENTITY.rotation),
1974
- scale: tuple3(node.scale, IDENTITY.scale)
2136
+ scale: tuple32(node.scale, IDENTITY.scale)
1975
2137
  };
1976
2138
  }
1977
2139
 
@@ -2092,27 +2254,6 @@ function decodeAttributeAccessor(accessorIndex, accessor, bufferViews, buffers)
2092
2254
  if (decoded.value.kind !== "f32") return err(unknownAccessor(accessorIndex));
2093
2255
  return ok(decoded.value.data);
2094
2256
  }
2095
- function tuple2(values) {
2096
- if (values === void 0 || values.length < 2) return void 0;
2097
- return [values[0] ?? 0, values[1] ?? 0];
2098
- }
2099
- function parseTextureInfo(info, textures) {
2100
- const transformJson = info.extensions?.KHR_texture_transform;
2101
- const offset = tuple2(transformJson?.offset);
2102
- const scale = tuple2(transformJson?.scale);
2103
- const transform = offset === void 0 && transformJson?.rotation === void 0 && scale === void 0 ? void 0 : {
2104
- ...offset === void 0 ? {} : { offset },
2105
- ...transformJson?.rotation === void 0 ? {} : { rotation: transformJson.rotation },
2106
- ...scale === void 0 ? {} : { scale }
2107
- };
2108
- const sampler = textures[info.index]?.sampler;
2109
- return {
2110
- texture: info.index,
2111
- ...sampler === void 0 ? {} : { sampler },
2112
- ...info.texCoord === void 0 && transformJson?.texCoord === void 0 ? {} : { texCoord: transformJson?.texCoord ?? info.texCoord },
2113
- ...transform === void 0 ? {} : { transform }
2114
- };
2115
- }
2116
2257
  async function resolveBuffer(buf, externalLoader, binChunk) {
2117
2258
  if (buf.uri === void 0) {
2118
2259
  if (binChunk === void 0) {
@@ -2660,51 +2801,11 @@ async function parseGltfWithBin(json, ctx) {
2660
2801
  ...sampJson.name === void 0 ? {} : { name: sampJson.name }
2661
2802
  });
2662
2803
  }
2663
- const materialsJson = json.materials ?? [];
2664
2804
  const materials = [];
2665
- for (const matJson of materialsJson) {
2666
- const pbr = matJson.pbrMetallicRoughness;
2667
- const baseColor = pbr?.baseColorFactor ?? [1, 1, 1, 1];
2668
- const baseColor4 = [
2669
- baseColor[0] ?? 1,
2670
- baseColor[1] ?? 1,
2671
- baseColor[2] ?? 1,
2672
- baseColor[3] ?? 1
2673
- ];
2674
- const alphaMode = matJson.alphaMode === "MASK" || matJson.alphaMode === "BLEND" ? matJson.alphaMode : void 0;
2675
- const alphaCutoff = alphaMode === "MASK" ? matJson.alphaCutoff ?? 0.5 : void 0;
2676
- const emissiveFactor = matJson.emissiveFactor;
2677
- const emissiveFactor3 = [
2678
- emissiveFactor?.[0] ?? 0,
2679
- emissiveFactor?.[1] ?? 0,
2680
- emissiveFactor?.[2] ?? 0
2681
- ];
2682
- materials.push({
2683
- ...matJson.name === void 0 ? {} : { name: matJson.name },
2684
- baseColorFactor: baseColor4,
2685
- ...emissiveFactor === void 0 ? {} : { emissiveFactor: emissiveFactor3 },
2686
- metallicFactor: pbr?.metallicFactor ?? 1,
2687
- roughnessFactor: pbr?.roughnessFactor ?? 1,
2688
- ...pbr?.baseColorTexture === void 0 ? {} : { baseColorTexture: parseTextureInfo(pbr.baseColorTexture, textures) },
2689
- ...pbr?.metallicRoughnessTexture === void 0 ? {} : { metallicRoughnessTexture: parseTextureInfo(pbr.metallicRoughnessTexture, textures) },
2690
- ...matJson.normalTexture === void 0 ? {} : {
2691
- normalTexture: {
2692
- ...parseTextureInfo(matJson.normalTexture, textures),
2693
- ...matJson.normalTexture.scale === void 0 ? {} : { scale: matJson.normalTexture.scale }
2694
- }
2695
- },
2696
- ...matJson.occlusionTexture === void 0 ? {} : {
2697
- occlusionTexture: {
2698
- ...parseTextureInfo(matJson.occlusionTexture, textures),
2699
- ...matJson.occlusionTexture.strength === void 0 ? {} : { strength: matJson.occlusionTexture.strength }
2700
- }
2701
- },
2702
- ...matJson.emissiveTexture === void 0 ? {} : { emissiveTexture: parseTextureInfo(matJson.emissiveTexture, textures) },
2703
- ...alphaMode === void 0 ? {} : { alphaMode },
2704
- ...alphaCutoff === void 0 ? {} : { alphaCutoff },
2705
- ...matJson.doubleSided === true ? { doubleSided: true } : {},
2706
- ...pbr?.baseColorTexture?.texCoord === void 0 || pbr.baseColorTexture.texCoord === 0 ? {} : { baseColorTexCoord: pbr.baseColorTexture.texCoord }
2707
- });
2805
+ for (const material of json.materials ?? []) {
2806
+ const parsedMaterial = parseMaterial(material, textures);
2807
+ if (!parsedMaterial.ok) return err(parsedMaterial.error);
2808
+ materials.push(parsedMaterial.value);
2708
2809
  }
2709
2810
  const diagnostics = {
2710
2811
  nodeNames: [],
@@ -3238,6 +3339,8 @@ function materialRefsForPack(mat, doc, textureGuidByIndex, samplerGuidByIndex =
3238
3339
  pushRefsForSlot(mat.normalTexture, "normalTexture");
3239
3340
  pushRefsForSlot(mat.occlusionTexture, "occlusionTexture");
3240
3341
  pushRefsForSlot(mat.emissiveTexture, "emissiveTexture");
3342
+ pushRefsForSlot(mat.transmissionTexture, "transmissionTexture");
3343
+ pushRefsForSlot(mat.thicknessTexture, "thicknessTexture");
3241
3344
  return refs;
3242
3345
  }
3243
3346
  function availableUvSets(mesh) {
@@ -3256,7 +3359,9 @@ function rewriteMaterialAssetRefs(matAsset, mat, doc, maps) {
3256
3359
  ["metallicRoughnessTexture", mat.metallicRoughnessTexture],
3257
3360
  ["normalTexture", mat.normalTexture],
3258
3361
  ["occlusionTexture", mat.occlusionTexture],
3259
- ["emissiveTexture", mat.emissiveTexture]
3362
+ ["emissiveTexture", mat.emissiveTexture],
3363
+ ["transmissionTexture", mat.transmissionTexture],
3364
+ ["thicknessTexture", mat.thicknessTexture]
3260
3365
  ];
3261
3366
  let cursor = 0;
3262
3367
  for (const [slot, rawBinding] of slots) {