@babylonjs/viewer
Version:
The Babylon Viewer aims to simplify a specific but common Babylon.js use case: loading, viewing, and interacting with a 3D model.
95 lines (92 loc) • 5.93 kB
JavaScript
import { as as needsOrmComposite, at as anyPrimitive, au as mat4Determinant3 } from './index-DMbDahsc.esm.js';
const M = "KHR_materials_";
const GS = "KHR_gaussian_splatting";
const _features = [
// Pre-parse features (buffer-level): order matters — meshopt decompresses
// bufferViews first, then sparse accessors are materialized (so their base can
// read decompressed data), then quantization dequantizes the resulting accessors.
["EXT_meshopt_compression", () => import('./gltf-feature-meshopt-CcEJ2YCh.esm.js')],
[(j) => !!j.accessors?.some((a) => a.sparse), () => import('./gltf-feature-sparse-Ct9hIe7L.esm.js')],
["KHR_mesh_quantization", () => import('./gltf-ext-quantization-DUBVnyIn.esm.js')],
// Pre-mesh features (geometry decompression)
["KHR_draco_mesh_compression", () => import('./gltf-feature-draco-o91cCLh1.esm.js')],
// Material extensions
[M + "clearcoat", () => import('./gltf-ext-clearcoat-DAF7TtW1.esm.js')],
[M + "iridescence", () => import('./gltf-ext-iridescence-B-vyDCHW.esm.js')],
[M + "emissive_strength", () => import('./gltf-ext-emissive-strength-ChAboOT-.esm.js')],
[M + "sheen", () => import('./gltf-ext-sheen-BLsmC9yw.esm.js')],
[M + "anisotropy", () => import('./gltf-ext-anisotropy-CLofc_lU.esm.js')],
[M + "diffuse_transmission", () => import('./gltf-ext-diffuse-transmission-DOv2bfTP.esm.js')],
[M + "unlit", () => import('./gltf-ext-unlit-DqjbpQHw.esm.js')],
[M + "pbrSpecularGlossiness", () => import('./gltf-ext-spec-gloss-HSzoR1ZR.esm.js')],
// Dielectric cluster (ior/specular/transmission/volume/dispersion) — any of the five triggers the
// loader; transmission refraction is wired dynamically by the PBR material path when needed.
[(j) => ["transmission", "volume", "ior", "specular", "dispersion"].some((e) => j.extensionsUsed?.includes(M + e)), () => import('./gltf-ext-dielectric-CyPonQhq.esm.js')],
["KHR_texture_transform", () => import('./gltf-ext-uv-transform-BuxByHwO.esm.js')],
["KHR_texture_basisu", () => import('./gltf-ext-basisu-Cb3mrE7b.esm.js')],
[needsOrmComposite, () => import('./gltf-ext-orm-CSBI7gEy.esm.js')],
// Per-mesh features (predicates inlined to avoid eager imports)
[(j) => !!j.skins?.length && anyPrimitive(j, (p) => p.attributes?.JOINTS_0 !== void 0), () => import('./gltf-feature-skeleton-BbwGu1l8.esm.js')],
[(j) => anyPrimitive(j, (p) => !!p.targets?.length), () => import('./gltf-feature-morph-aY8xWoXm.esm.js')],
// Non-triangle primitive topology (POINTS/LINES/LINE_STRIP/TRIANGLE_STRIP) or a
// negative-determinant node (negative scale / mirrored matrix): both need the lazy primitive
// feature (topology threading + winding reversal). Triangle-list positive-winding never triggers.
//
// Gaussian-splatting primitives are POINTS-mode by definition, but the GS feature consumes them
// into a GaussianSplattingMesh with its own pipeline, so they never reach the PBR pipeline that
// reads the primitive state — loading the feature for them fetches a chunk nothing then reads.
// A GS asset that ALSO carries a genuinely exotic primitive, or a mirrored node, still triggers.
[(j) => hasNegDetNode(j) || anyPrimitive(j, (p) => p.mode !== void 0 && p.mode !== 4 && !p.extensions?.[GS]), () => import('./gltf-feature-primitive-_T6tuILC.esm.js')],
// Per-asset features
[hasGltfExtras, () => import('./gltf-feature-extras-DWMyMqbH.esm.js')],
["KHR_lights_punctual", () => import('./gltf-feature-lights-punctual-D8EOvMia.esm.js')],
[GS, () => import('./gltf-feature-gaussian-splatting-BiH_nkp6.esm.js').then(function (n) { return n.g; })],
["EXT_lights_image_based", () => import('./gltf-ext-lights-image-based-Dg4YnF8h.esm.js')],
[(j) => !!j.animations?.length, () => import('./gltf-feature-animations-B4X0cvR1.esm.js')],
// Non-Float32 / normalized animation sampler accessors (e.g. Animation_SamplerType normalized
// BYTE/SHORT rotation) need the lazy denorm converter; plain float samplers never load it.
[hasNonFloatAnimSampler, () => import('./gltf-sampler-denorm-BEGb_DMT.esm.js')],
[M + "variants", () => import('./gltf-feature-variants-Dtx2N51L.esm.js')],
["KHR_node_visibility", () => import('./gltf-ext-node-visibility-BlozAYLu.esm.js')],
["KHR_animation_pointer", () => import('./gltf-feature-animation-pointer-C-4at_Z4.esm.js').then(function (n) { return n.g; })],
["EXT_mesh_gpu_instancing", () => import('./gltf-feature-gpu-instancing-DulaRY6V.esm.js')],
["KHR_xmp_json_ld", () => import('./gltf-feature-xmp-DA66RV4C.esm.js')]
];
async function loadGltfFeatures(json) {
const used = json.extensionsUsed ?? [];
const mods = await Promise.all(_features.flatMap(([t, load]) => (typeof t === "string" ? used.includes(t) : t(json)) ? [load()] : []));
return mods.map((m) => m.default);
}
async function runGltfMaterialFeatures(mat, features, ctx) {
const fragments = await Promise.all(features.map((feature) => feature.applyMaterial(mat, ctx)));
let layers;
for (const fragment of fragments) {
if (fragment) {
Object.assign(layers ??= {}, fragment);
}
}
return layers;
}
function hasGltfExtras(json) {
const hasExtras = (item) => item?.extras !== void 0;
return [json.asset, json.nodes, json.materials, json.animations, json.meshes].flat().some(hasExtras) || anyPrimitive(json, hasExtras);
}
function hasNonFloatAnimSampler(json) {
const accessors = json.accessors;
return !!json.animations?.some(
(a) => a.samplers?.some((s) => accessors[s.input]?.componentType !== 5126 || accessors[s.output]?.componentType !== 5126)
);
}
function hasNegDetNode(json) {
return !!json.nodes?.some((n) => {
if (n.scale) {
return n.scale[0] * n.scale[1] * n.scale[2] < 0;
}
if (n.matrix) {
return mat4Determinant3(n.matrix) < 0;
}
return false;
});
}
export { loadGltfFeatures, runGltfMaterialFeatures };
//# sourceMappingURL=gltf-feature-registry-Bi0l6k0Y.esm.js.map