@babylonjs/lite 0.2.0 → 1.0.0
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/{_mat4-storage-f64-Bvh5TymE.js → _mat4-storage-f64-CjDoht2w.js} +3 -2
- package/_mat4-storage-f64-CjDoht2w.js.map +1 -0
- package/{alpha-test-fragment-BCChpzaV.js → alpha-test-fragment-B7DjSnF7.js} +2 -2
- package/{alpha-test-fragment-BCChpzaV.js.map → alpha-test-fragment-B7DjSnF7.js.map} +1 -1
- package/assets/splat-sort-worker-DT3eybMZ.js.map +1 -0
- package/{background-dds-skybox-ZjrSIxrT.js → background-dds-skybox-BEX309u3.js} +13 -13
- package/background-dds-skybox-BEX309u3.js.map +1 -0
- package/{background-ground-B2Mie-MI.js → background-ground-BU0HOcM4.js} +19 -19
- package/background-ground-BU0HOcM4.js.map +1 -0
- package/{background-hdr-skybox-DDRJYuT2.js → background-hdr-skybox--RRRic_K.js} +10 -10
- package/background-hdr-skybox--RRRic_K.js.map +1 -0
- package/{background-solid-skybox-fjXlnWaD.js → background-solid-skybox-BrH2fXSu.js} +11 -12
- package/background-solid-skybox-BrH2fXSu.js.map +1 -0
- package/{billboard-renderable-DKmlOgbM.js → billboard-renderable-BHWryAeC.js} +46 -10
- package/billboard-renderable-BHWryAeC.js.map +1 -0
- package/{clamp-block-CxRBPlUq.js → clamp-block-DqbwnQGW.js} +2 -2
- package/{clamp-block-CxRBPlUq.js.map → clamp-block-DqbwnQGW.js.map} +1 -1
- package/{clearcoat-fragment-KbZAa0TA.js → clearcoat-fragment-D6FSCie1.js} +2 -2
- package/{clearcoat-fragment-KbZAa0TA.js.map → clearcoat-fragment-D6FSCie1.js.map} +1 -1
- package/{create-skeleton-BBI5urcj.js → create-skeleton-D_uplboC.js} +9 -9
- package/create-skeleton-D_uplboC.js.map +1 -0
- package/{cubemap-skybox-material-DvW81drX.js → cubemap-skybox-material-DQcMMdf-.js} +6 -7
- package/cubemap-skybox-material-DQcMMdf-.js.map +1 -0
- package/{curve-block-Dh_xdUj-.js → curve-block-21rT0JjG.js} +2 -2
- package/{curve-block-Dh_xdUj-.js.map → curve-block-21rT0JjG.js.map} +1 -1
- package/{emissive-fragment-DD8cvHyx.js → emissive-fragment-C5FtBs3y.js} +3 -3
- package/emissive-fragment-C5FtBs3y.js.map +1 -0
- package/{esm-shadow-view-DYAc62Kl.js → esm-shadow-view-Cl3rPGof.js} +2 -2
- package/{esm-shadow-view-DYAc62Kl.js.map → esm-shadow-view-Cl3rPGof.js.map} +1 -1
- package/{esm-shadow-view-DHVS9r7H.js → esm-shadow-view-Gtd1LWRP.js} +2 -2
- package/{esm-shadow-view-DHVS9r7H.js.map → esm-shadow-view-Gtd1LWRP.js.map} +1 -1
- package/{esm-shadow-view-15S4JK6p.js → esm-shadow-view-c5YV4Eg9.js} +2 -2
- package/{esm-shadow-view-15S4JK6p.js.map → esm-shadow-view-c5YV4Eg9.js.map} +1 -1
- package/{gaussian-splatting-pipeline-sh-BvkUhA9V.js → gaussian-splatting-pipeline-sh-7J31V23x.js} +19 -19
- package/gaussian-splatting-pipeline-sh-7J31V23x.js.map +1 -0
- package/geometry-texture-output-dXk4E9uu.js +41 -0
- package/geometry-texture-output-dXk4E9uu.js.map +1 -0
- package/geometry-view-BsFJpBJa.js +404 -0
- package/geometry-view-BsFJpBJa.js.map +1 -0
- package/{gltf-animation-KnPzeOIY.js → gltf-animation-K_zZxj_d.js} +6 -6
- package/gltf-animation-K_zZxj_d.js.map +1 -0
- package/{gltf-ext-basisu-kmth3UWX.js → gltf-ext-basisu-CDbPclzZ.js} +48 -16
- package/gltf-ext-basisu-CDbPclzZ.js.map +1 -0
- package/{gltf-ext-node-visibility-BjRRd6si.js → gltf-ext-node-visibility-DXCJEYr6.js} +2 -2
- package/{gltf-ext-node-visibility-BjRRd6si.js.map → gltf-ext-node-visibility-DXCJEYr6.js.map} +1 -1
- package/{gltf-ext-quantization-CpZyLDIz.js → gltf-ext-quantization-CvHI_0Vg.js} +4 -3
- package/gltf-ext-quantization-CvHI_0Vg.js.map +1 -0
- package/{gltf-ext-uv-transform-MHmR-YyM.js → gltf-ext-uv-transform-DgYazJBs.js} +2 -2
- package/{gltf-ext-uv-transform-MHmR-YyM.js.map → gltf-ext-uv-transform-DgYazJBs.js.map} +1 -1
- package/{gltf-feature-animation-pointer-rFqLfbO_.js → gltf-feature-animation-pointer-D1RJRFBw.js} +9 -9
- package/gltf-feature-animation-pointer-D1RJRFBw.js.map +1 -0
- package/{gltf-feature-animations-DikONdzi.js → gltf-feature-animations-Cmc1uoIu.js} +2 -2
- package/{gltf-feature-animations-DikONdzi.js.map → gltf-feature-animations-Cmc1uoIu.js.map} +1 -1
- package/{gltf-feature-draco-yGSMGTE3.js → gltf-feature-draco-CKKzT5E3.js} +6 -5
- package/gltf-feature-draco-CKKzT5E3.js.map +1 -0
- package/{gltf-feature-gpu-instancing-Cj1XjmM6.js → gltf-feature-gpu-instancing-n87SO6Vh.js} +4 -4
- package/gltf-feature-gpu-instancing-n87SO6Vh.js.map +1 -0
- package/{gltf-feature-lights-punctual-C-0SlGmD.js → gltf-feature-lights-punctual-Ckm3ciL8.js} +5 -5
- package/{gltf-feature-lights-punctual-C-0SlGmD.js.map → gltf-feature-lights-punctual-Ckm3ciL8.js.map} +1 -1
- package/{gltf-feature-meshopt-Des96YFI.js → gltf-feature-meshopt-DLC4SF1E.js} +7 -6
- package/gltf-feature-meshopt-DLC4SF1E.js.map +1 -0
- package/{gltf-feature-morph-BAcY14XU.js → gltf-feature-morph-Cjtu7hYa.js} +4 -4
- package/gltf-feature-morph-Cjtu7hYa.js.map +1 -0
- package/{gltf-feature-registry-97sY_x5O.js → gltf-feature-registry-C63Hjp9w.js} +15 -15
- package/{gltf-feature-registry-97sY_x5O.js.map → gltf-feature-registry-C63Hjp9w.js.map} +1 -1
- package/{gltf-feature-skeleton-lVjkDfIU.js → gltf-feature-skeleton-DKbOGidp.js} +3 -3
- package/{gltf-feature-skeleton-lVjkDfIU.js.map → gltf-feature-skeleton-DKbOGidp.js.map} +1 -1
- package/{gltf-feature-variants-BphF4JmV.js → gltf-feature-variants-Cmzu0O0e.js} +2 -2
- package/{gltf-feature-variants-BphF4JmV.js.map → gltf-feature-variants-Cmzu0O0e.js.map} +1 -1
- package/{gltf-glb-parser-D6UZWFuC.js → gltf-glb-parser-Cj5MHS-v.js} +5 -4
- package/gltf-glb-parser-Cj5MHS-v.js.map +1 -0
- package/{gltf-interleave-C9eBqH_F.js → gltf-interleave-gHf9_t0i.js} +14 -14
- package/gltf-interleave-gHf9_t0i.js.map +1 -0
- package/{gltf-pbr-builder-ext-DPC0zg_u.js → gltf-pbr-builder-ext-edNcjwPf.js} +5 -5
- package/gltf-pbr-builder-ext-edNcjwPf.js.map +1 -0
- package/{gltf-variants-CnBEZr0o.js → gltf-variants-CPxNdtP4.js} +4 -4
- package/{gltf-variants-CnBEZr0o.js.map → gltf-variants-CPxNdtP4.js.map} +1 -1
- package/{gs-picking-pipeline-Bx8LTav6.js → gs-picking-pipeline-DYaW_Lg3.js} +14 -14
- package/gs-picking-pipeline-DYaW_Lg3.js.map +1 -0
- package/havok-floating-origin-Dr-18Nds.js +198 -0
- package/havok-floating-origin-Dr-18Nds.js.map +1 -0
- package/index-CLElg2Bo.js +39209 -0
- package/index-CLElg2Bo.js.map +1 -0
- package/index-CYZDclhF.js +918 -0
- package/index-CYZDclhF.js.map +1 -0
- package/index-SMJ67XwT.js +3330 -0
- package/index-SMJ67XwT.js.map +1 -0
- package/index.d.ts +2007 -105
- package/index.js +446 -322
- package/{input-block-Coi_aZwl.js → input-block-DqEedWF2.js} +2 -2
- package/{input-block-Coi_aZwl.js.map → input-block-DqEedWF2.js.map} +1 -1
- package/{iridescence-fragment-DwZcCTdD.js → iridescence-fragment-BHU59-gQ.js} +2 -2
- package/{iridescence-fragment-DwZcCTdD.js.map → iridescence-fragment-BHU59-gQ.js.map} +1 -1
- package/{light-block-Np_h5gPI.js → light-block-Bv37V8vl.js} +2 -2
- package/{light-block-Np_h5gPI.js.map → light-block-Bv37V8vl.js.map} +1 -1
- package/{loop-block-BFkLFYGm.js → loop-block-qTg8vb99.js} +2 -2
- package/{loop-block-BFkLFYGm.js.map → loop-block-qTg8vb99.js.map} +1 -1
- package/{morph-fragment-DqH-w61u.js → morph-fragment-BRCUr2wQ.js} +2 -2
- package/{morph-fragment-DqH-w61u.js.map → morph-fragment-BRCUr2wQ.js.map} +1 -1
- package/{multilight-wgsl-B9Mf9d-q.js → multilight-wgsl-DMeppAdZ.js} +2 -2
- package/{multilight-wgsl-B9Mf9d-q.js.map → multilight-wgsl-DMeppAdZ.js.map} +1 -1
- package/{node-env-BPZXZzBf.js → node-env-Bc559GmY.js} +6 -5
- package/node-env-Bc559GmY.js.map +1 -0
- package/node-geometry-view-COmWsRXK.js +291 -0
- package/node-geometry-view-COmWsRXK.js.map +1 -0
- package/{node-registry-extra-compat-Ch7ApZHF.js → node-registry-extra-compat-dWrv7gpS.js} +2 -2
- package/{node-registry-extra-compat-Ch7ApZHF.js.map → node-registry-extra-compat-dWrv7gpS.js.map} +1 -1
- package/{node-registry-extra-math-6ezzTkPj.js → node-registry-extra-math-Bn854sX9.js} +2 -2
- package/{node-registry-extra-math-6ezzTkPj.js.map → node-registry-extra-math-Bn854sX9.js.map} +1 -1
- package/{node-renderable-CS0CmsSp.js → node-renderable-B5G8WcdH.js} +15 -13
- package/node-renderable-B5G8WcdH.js.map +1 -0
- package/{node-shadow-CpnrdvtJ.js → node-shadow-CVIUlNf0.js} +7 -7
- package/node-shadow-CVIUlNf0.js.map +1 -0
- package/{normal-map-fragment-DradEMl-.js → normal-map-fragment-CQSxhjCy.js} +2 -2
- package/{normal-map-fragment-DradEMl-.js.map → normal-map-fragment-CQSxhjCy.js.map} +1 -1
- package/package.json +3 -10
- package/{parse-camera-CgV4bWc0.js → parse-camera-pBRT_6i5.js} +2 -2
- package/{parse-camera-CgV4bWc0.js.map → parse-camera-pBRT_6i5.js.map} +1 -1
- package/pbr-geometry-view-NiZY_juX.js +491 -0
- package/pbr-geometry-view-NiZY_juX.js.map +1 -0
- package/{pbr-metallic-roughness-block-BFwZj2Nw.js → pbr-metallic-roughness-block-JBSi-tQN.js} +2 -2
- package/{pbr-metallic-roughness-block-BFwZj2Nw.js.map → pbr-metallic-roughness-block-JBSi-tQN.js.map} +1 -1
- package/{pbr-metallic-roughness-block-full-5t0HT3xl.js → pbr-metallic-roughness-block-full-Ta9lR2cz.js} +2 -2
- package/{pbr-metallic-roughness-block-full-5t0HT3xl.js.map → pbr-metallic-roughness-block-full-Ta9lR2cz.js.map} +1 -1
- package/{pbr-mr-helper-core-R5tOZ8Ap.js → pbr-mr-helper-core-BVWNR08D.js} +2 -2
- package/{pbr-mr-helper-core-R5tOZ8Ap.js.map → pbr-mr-helper-core-BVWNR08D.js.map} +1 -1
- package/{pbr-refraction-Dd11HnaI.js → pbr-refraction-C9FvFmAp.js} +2 -2
- package/{pbr-refraction-Dd11HnaI.js.map → pbr-refraction-C9FvFmAp.js.map} +1 -1
- package/{pbr-renderable-BHAdF5Vw.js → pbr-renderable-DzUF2QIk.js} +60 -42
- package/pbr-renderable-DzUF2QIk.js.map +1 -0
- package/{pbr-shadow-fragment-BxUrFJYZ.js → pbr-shadow-fragment-CnqnbGYS.js} +2 -2
- package/{pbr-shadow-fragment-BxUrFJYZ.js.map → pbr-shadow-fragment-CnqnbGYS.js.map} +1 -1
- package/{pbr-tracking-D6i3yPb7.js → pbr-tracking-3tU1kqea.js} +2 -2
- package/{pbr-tracking-D6i3yPb7.js.map → pbr-tracking-3tU1kqea.js.map} +1 -1
- package/{pbr-transmission-ext-Dll8EYwE.js → pbr-transmission-ext-BcLjRxfB.js} +2 -2
- package/{pbr-transmission-ext-Dll8EYwE.js.map → pbr-transmission-ext-BcLjRxfB.js.map} +1 -1
- package/recast-navigation.wasm-DG_0AFuk.js +8706 -0
- package/recast-navigation.wasm-DG_0AFuk.js.map +1 -0
- package/recast-navigation.wasm-compat-C-Bf2ylB.js +8692 -0
- package/recast-navigation.wasm-compat-C-Bf2ylB.js.map +1 -0
- package/{reflectance-fragment-ejMJ4O1o.js → reflectance-fragment-Dbpgw3Jt.js} +2 -2
- package/{reflectance-fragment-ejMJ4O1o.js.map → reflectance-fragment-Dbpgw3Jt.js.map} +1 -1
- package/{rgbd-decode-DCvzUYeI.js → rgbd-decode-DoyUquy3.js} +7 -6
- package/rgbd-decode-DoyUquy3.js.map +1 -0
- package/{scene-material-swap-C2ykv55W.js → scene-material-swap-nNUH4nGn.js} +11 -4
- package/scene-material-swap-nNUH4nGn.js.map +1 -0
- package/screenshot-readback-D0Sj9qq3.js +92 -0
- package/screenshot-readback-D0Sj9qq3.js.map +1 -0
- package/{mesh-features-BAJpbMog.js → shader-composer-BUD_pSX4.js} +3 -54
- package/shader-composer-BUD_pSX4.js.map +1 -0
- package/{shader-renderable-BMf_vvO0.js → shader-renderable-D7-RyVxa.js} +25 -19
- package/shader-renderable-D7-RyVxa.js.map +1 -0
- package/{shader-thin-instance-5_WUfi3m.js → shader-thin-instance-DuBotxDO.js} +4 -4
- package/shader-thin-instance-DuBotxDO.js.map +1 -0
- package/{sheen-fragment-CS6z29Fs.js → sheen-fragment-1MkEMcbc.js} +2 -2
- package/{sheen-fragment-CS6z29Fs.js.map → sheen-fragment-1MkEMcbc.js.map} +1 -1
- package/{singlelight-directional-wgsl-4MIgZMeC.js → singlelight-directional-wgsl-BsV8G456.js} +2 -2
- package/{singlelight-directional-wgsl-4MIgZMeC.js.map → singlelight-directional-wgsl-BsV8G456.js.map} +1 -1
- package/{singlelight-hemispheric-wgsl-CK-GUYWe.js → singlelight-hemispheric-wgsl-Bo0jKlW5.js} +2 -2
- package/{singlelight-hemispheric-wgsl-CK-GUYWe.js.map → singlelight-hemispheric-wgsl-Bo0jKlW5.js.map} +1 -1
- package/{singlelight-point-wgsl-CYtzqCbP.js → singlelight-point-wgsl-DV39UP5Y.js} +2 -2
- package/{singlelight-point-wgsl-CYtzqCbP.js.map → singlelight-point-wgsl-DV39UP5Y.js.map} +1 -1
- package/{singlelight-spot-wgsl-DVbaVufF.js → singlelight-spot-wgsl-yg3od6vL.js} +2 -2
- package/{singlelight-spot-wgsl-DVbaVufF.js.map → singlelight-spot-wgsl-yg3od6vL.js.map} +1 -1
- package/{skeleton-fragment-BOVmc8YS.js → skeleton-fragment-DdxYG6kv.js} +2 -2
- package/{skeleton-fragment-BOVmc8YS.js.map → skeleton-fragment-DdxYG6kv.js.map} +1 -1
- package/{skybox-renderable-DDcCPSly.js → skybox-renderable-CJD4XmX5.js} +7 -8
- package/skybox-renderable-CJD4XmX5.js.map +1 -0
- package/{splat-ply-compressed-BahdBG1r.js → splat-ply-compressed-DHjyiVmI.js} +9 -8
- package/splat-ply-compressed-DHjyiVmI.js.map +1 -0
- package/{standard-renderable-D1bhoF0K.js → standard-pipeline-XTbHL7MY.js} +11 -202
- package/standard-pipeline-XTbHL7MY.js.map +1 -0
- package/standard-renderable-CREWLNHI.js +191 -0
- package/standard-renderable-CREWLNHI.js.map +1 -0
- package/{std-ambient-fragment-C6WNm8dQ.js → std-ambient-fragment-Bjx3VFrr.js} +2 -2
- package/{std-ambient-fragment-C6WNm8dQ.js.map → std-ambient-fragment-Bjx3VFrr.js.map} +1 -1
- package/{std-cube-reflection-fragment-Bqutpy2q.js → std-cube-reflection-fragment-y9WWdXUt.js} +2 -2
- package/{std-cube-reflection-fragment-Bqutpy2q.js.map → std-cube-reflection-fragment-y9WWdXUt.js.map} +1 -1
- package/{std-emissive-fragment-B-A83rqX.js → std-emissive-fragment-C8Lnmojh.js} +2 -2
- package/{std-emissive-fragment-B-A83rqX.js.map → std-emissive-fragment-C8Lnmojh.js.map} +1 -1
- package/{std-lightmap-fragment-Df7KJezh.js → std-lightmap-fragment-DFxGcoA5.js} +2 -2
- package/{std-lightmap-fragment-Df7KJezh.js.map → std-lightmap-fragment-DFxGcoA5.js.map} +1 -1
- package/{std-opacity-fragment-D9et2jip.js → std-opacity-fragment-EXzFWiSp.js} +2 -2
- package/{std-opacity-fragment-D9et2jip.js.map → std-opacity-fragment-EXzFWiSp.js.map} +1 -1
- package/{std-reflection-fragment-DBJeT-yg.js → std-reflection-fragment-BoJORqpG.js} +2 -2
- package/{std-reflection-fragment-DBJeT-yg.js.map → std-reflection-fragment-BoJORqpG.js.map} +1 -1
- package/{std-shadow-fragment-C6fD8rW-.js → std-shadow-fragment-Bq-Wc8UJ.js} +2 -2
- package/{std-shadow-fragment-C6fD8rW-.js.map → std-shadow-fragment-Bq-Wc8UJ.js.map} +1 -1
- package/{std-specular-fragment-C2ZOss-t.js → std-specular-fragment-CM5R5j2g.js} +2 -2
- package/{std-specular-fragment-C2ZOss-t.js.map → std-specular-fragment-CM5R5j2g.js.map} +1 -1
- package/{std-tracking-C4L4nQGc.js → std-tracking-Cif_wXeT.js} +2 -2
- package/{std-tracking-C4L4nQGc.js.map → std-tracking-Cif_wXeT.js.map} +1 -1
- package/{subsurface-fragment-C1H4ytqK.js → subsurface-fragment-BEaAXYXz.js} +2 -2
- package/{subsurface-fragment-C1H4ytqK.js.map → subsurface-fragment-BEaAXYXz.js.map} +1 -1
- package/swapchain-overlay-UCLilhbq.js +37 -0
- package/swapchain-overlay-UCLilhbq.js.map +1 -0
- package/{thin-instance-cull-binding-CCxrPNO6.js → thin-instance-cull-binding-DWKUt5ZN.js} +12 -12
- package/thin-instance-cull-binding-DWKUt5ZN.js.map +1 -0
- package/{thin-instance-gpu-E8DBd8XL.js → thin-instance-gpu-BDdRcNAh.js} +15 -7
- package/thin-instance-gpu-BDdRcNAh.js.map +1 -0
- package/{tracking-primitives-w4BVV9p9.js → tracking-primitives-CglRNTlX.js} +2 -2
- package/{tracking-primitives-w4BVV9p9.js.map → tracking-primitives-CglRNTlX.js.map} +1 -1
- package/{unlit-fragment-DU9_mhzZ.js → unlit-fragment-kxfZWlnp.js} +2 -2
- package/{unlit-fragment-DU9_mhzZ.js.map → unlit-fragment-kxfZWlnp.js.map} +1 -1
- package/_mat4-storage-f64-Bvh5TymE.js.map +0 -1
- package/assets/splat-sort-worker-Crg3CaCc.js.map +0 -1
- package/background-dds-skybox-ZjrSIxrT.js.map +0 -1
- package/background-ground-B2Mie-MI.js.map +0 -1
- package/background-hdr-skybox-DDRJYuT2.js.map +0 -1
- package/background-solid-skybox-fjXlnWaD.js.map +0 -1
- package/billboard-renderable-DKmlOgbM.js.map +0 -1
- package/create-skeleton-BBI5urcj.js.map +0 -1
- package/cubemap-skybox-material-DvW81drX.js.map +0 -1
- package/emissive-fragment-DD8cvHyx.js.map +0 -1
- package/gaussian-splatting-pipeline-sh-BvkUhA9V.js.map +0 -1
- package/gltf-animation-KnPzeOIY.js.map +0 -1
- package/gltf-ext-basisu-kmth3UWX.js.map +0 -1
- package/gltf-ext-quantization-CpZyLDIz.js.map +0 -1
- package/gltf-feature-animation-pointer-rFqLfbO_.js.map +0 -1
- package/gltf-feature-draco-yGSMGTE3.js.map +0 -1
- package/gltf-feature-gpu-instancing-Cj1XjmM6.js.map +0 -1
- package/gltf-feature-meshopt-Des96YFI.js.map +0 -1
- package/gltf-feature-morph-BAcY14XU.js.map +0 -1
- package/gltf-glb-parser-D6UZWFuC.js.map +0 -1
- package/gltf-interleave-C9eBqH_F.js.map +0 -1
- package/gltf-pbr-builder-ext-DPC0zg_u.js.map +0 -1
- package/gs-picking-pipeline-Bx8LTav6.js.map +0 -1
- package/index-B7Qhw0xL.js +0 -21232
- package/index-B7Qhw0xL.js.map +0 -1
- package/mesh-features-BAJpbMog.js.map +0 -1
- package/no-color-view-DsyLSL-W.js +0 -8
- package/no-color-view-DsyLSL-W.js.map +0 -1
- package/node-env-BPZXZzBf.js.map +0 -1
- package/node-registry-Bd-AlrgC.js +0 -190
- package/node-registry-Bd-AlrgC.js.map +0 -1
- package/node-renderable-CS0CmsSp.js.map +0 -1
- package/node-shadow-CpnrdvtJ.js.map +0 -1
- package/pbr-renderable-BHAdF5Vw.js.map +0 -1
- package/rgbd-decode-DCvzUYeI.js.map +0 -1
- package/scene-material-swap-C2ykv55W.js.map +0 -1
- package/shader-renderable-BMf_vvO0.js.map +0 -1
- package/shader-thin-instance-5_WUfi3m.js.map +0 -1
- package/skybox-renderable-DDcCPSly.js.map +0 -1
- package/splat-ply-compressed-BahdBG1r.js.map +0 -1
- package/standard-renderable-D1bhoF0K.js.map +0 -1
- package/swapchain-overlay-DcCSFDp7.js +0 -35
- package/swapchain-overlay-DcCSFDp7.js.map +0 -1
- package/thin-instance-cull-binding-CCxrPNO6.js.map +0 -1
- package/thin-instance-gpu-E8DBd8XL.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometry-view-BsFJpBJa.js","sources":["../src/material/standard/standard-geometry-output-shader.ts","../src/material/standard/standard-geometry-renderable.ts","../src/material/standard/geometry-view.ts"],"sourcesContent":["/** Standard geometry-output shader composer.\n *\n * Builds the WGSL for a {@link createStandardGeometryMaterialView}-wrapped\n * Standard material that targets the geometry-renderer MRT pass.\n *\n * Design — *zero bundle impact* on scenes that never load the\n * geometry-renderer task:\n *\n * 1. Reuse `composeStandardShader` verbatim. The standard composer already\n * emits the bump perturbation (`normalW = perturbNormal(...)` via the AC\n * slot), opacity-texture alpha modulation, alpha-cutout discard,\n * instancing, thin-instance colour, etc. None of that needs to be\n * re-implemented.\n * 2. Post-process the resulting fragment WGSL: change the entry signature\n * to return a `FragmentOutput` MRT struct, prepend the struct\n * declaration, and replace `return color;` with code that writes each\n * requested geometry attachment from the already-in-scope intermediate\n * variables (`normalW`, `baseColor`, `specularColor`, `alpha`,\n * `input.vp`, …).\n * 3. Add a small `geometryParams` ShaderFragment that contributes a `gp`\n * UBO binding (camera near/far + previous viewProjection) only when the\n * requested attachment list needs it (NORMALIZED_VIEW_DEPTH /\n * LINEAR_VELOCITY).\n *\n * The lighting / fog block still runs and produces a dead `color` value\n * the WGSL compiler folds away. Acceptable cost for the architectural\n * reuse — matches the user's directive: \"inject some shader code at the\n * end of the fragment to output the data for the geometry textures\".\n */\n\nimport { GeometryTextureType } from \"../../frame-graph/geometry-types.js\";\nimport type { ComposedShader, ShaderFragment, Varying } from \"../../shader/fragment-types.js\";\nimport { composeStandardShader } from \"./standard-pipeline.js\";\nimport { HAS_SPECULAR_TEXTURE, MATERIAL_ALPHA_BLEND, SPECULAR_USES_UV2 } from \"./standard-flags.js\";\n\nconst STAGE_FRAGMENT = 0x2;\nconst STAGE_VERTEX = 0x1;\n\n/** Tags whether the geometry pass needs the per-task `gp` UBO. */\nfunction needsGpUbo(attachments: readonly GeometryTextureType[]): boolean {\n for (const t of attachments) {\n if (t === GeometryTextureType.NORMALIZED_VIEW_DEPTH || t === GeometryTextureType.LINEAR_VELOCITY) {\n return true;\n }\n }\n return false;\n}\n\n/** Tags whether the geometry pass needs the previous-clip varying (velocity). */\nfunction needsVelocity(attachments: readonly GeometryTextureType[]): boolean {\n return attachments.includes(GeometryTextureType.LINEAR_VELOCITY);\n}\n\n/** Tags whether the geometry pass needs the local-position varying. */\nfunction needsLocalPos(attachments: readonly GeometryTextureType[]): boolean {\n return attachments.includes(GeometryTextureType.LOCAL_POSITION);\n}\n\n/** Per-attachment WGSL output expression. `alpha` is the in-scope standard\n * fragment alpha (mat.dc.a × opacityTex × …). `wg` is `writeGeomInfo` — a\n * binary 0/1 gate matching BJS `default.fragment.fx` PREPASS\n * (`color.a > 0.4 ? 1.0 : 0.0`). Combined with the per-attachment\n * ALPHA_COMBINE blend state, low-opacity samples preserve the destination\n * (background) while high-opacity samples overwrite it.\n *\n * All variable references resolve to symbols already declared by\n * `standard-template.ts` / the standard fragment registry:\n * - `normalW` — normalized world normal (post-bump if HAS_BUMP_TEXTURE).\n * - `input.vp` — world position.\n * - `baseColor`/`mat.tl` — diffuse texture sample (rgb) × diffuseLevel.\n * - `specularColor`/`mat.sc` — specular colour, replaced by the std-specular\n * fragment's `textureSample(sT, sS, uv).rgb` when HAS_SPECULAR_TEXTURE.\n * - `scene.view` — view matrix from the canonical SceneUniforms.\n * - `gp.cameraNearFar` / `gp.previousViewProjection` — from the geometry\n * params UBO (added only when `needsGpUbo`).\n * - `input.vCurrentClip` / `input.vPreviousClip` — added by the velocity\n * fragment when LINEAR_VELOCITY is requested. */\nfunction attachmentExpr(type: GeometryTextureType, wg: string, hasSpecular: boolean, specularUv: string): string {\n switch (type) {\n case GeometryTextureType.IRRADIANCE:\n // BJS Standard material can't split irradiance — outputs (0, 0, 0).\n return `vec4<f32>(0.0, 0.0, 0.0, ${wg})`;\n case GeometryTextureType.WORLD_POSITION:\n return `vec4<f32>(input.vp, ${wg})`;\n case GeometryTextureType.LOCAL_POSITION:\n // `vLocalPos` is contributed by the geometry-params fragment (added\n // only when LOCAL_POSITION is requested).\n return `vec4<f32>(input.vLocalPos, ${wg})`;\n case GeometryTextureType.REFLECTIVITY:\n // BJS: vec4(toLinearSpace(specularMapColor)) * writeGeometryInfo\n // (.a is glossiness when a specular texture is present). The std\n // pipeline drops the texture .a inside `specularColor`, so the\n // geometry path re-samples the specular texture here to recover it.\n return hasSpecular\n ? `(vec4<f32>(pow(textureSample(sT, sS, ${specularUv}).rgb, vec3<f32>(2.2)), textureSample(sT, sS, ${specularUv}).a) * ${wg})`\n : `vec4<f32>(pow(mat.sc.rgb, vec3<f32>(2.2)), 1.0) * ${wg}`;\n case GeometryTextureType.VIEW_DEPTH:\n return `vec4<f32>((scene.view * vec4<f32>(input.vp, 1.0)).z, 0.0, 0.0, ${wg})`;\n case GeometryTextureType.NORMALIZED_VIEW_DEPTH:\n return `vec4<f32>(((scene.view * vec4<f32>(input.vp, 1.0)).z - gp.cameraNearFar.x) / (gp.cameraNearFar.y - gp.cameraNearFar.x), 0.0, 0.0, ${wg})`;\n case GeometryTextureType.SCREENSPACE_DEPTH:\n // `clipPos` is the @builtin(position) fragment input declared by\n // shader-composer (fragment input struct).\n return `vec4<f32>(input.clipPos.z, 0.0, 0.0, ${wg})`;\n case GeometryTextureType.VIEW_NORMAL:\n return `vec4<f32>(normalize((scene.view * vec4<f32>(normalW, 0.0)).xyz), ${wg})`;\n case GeometryTextureType.WORLD_NORMAL:\n return `vec4<f32>(normalW * 0.5 + vec3<f32>(0.5), ${wg})`;\n case GeometryTextureType.ALBEDO:\n // BJS: vec4(baseColor.rgb, writeGeometryInfo). The standard\n // fragment already multiplied the diffuse sample by `mat.tl`\n // (texture level) when building `baseColor`.\n return `vec4<f32>(baseColor, ${wg})`;\n case GeometryTextureType.LINEAR_VELOCITY: {\n const cur = `(input.vCurrentClip.xy / input.vCurrentClip.w)`;\n const prev = `(input.vPreviousClip.xy / input.vPreviousClip.w)`;\n return `vec4<f32>(0.5 * (${prev} - ${cur}), 0.0, ${wg})`;\n }\n }\n}\n\n/** ShaderFragment contributing the `gp` UBO + (optionally) velocity / local-position varyings.\n *\n * Only included in the fragment list when an attachment actually needs it,\n * so opaque-only / WORLD_POSITION-only configs add zero bytes vs the bare\n * standard shader. */\nfunction createGeometryParamsFragment(needsParamsUbo: boolean, needsVelocityVaryings: boolean, needsLocalPosVarying: boolean): ShaderFragment {\n const bindings = needsParamsUbo ? [{ _name: \"gp\", _type: { _kind: \"uniform-buffer\" as const }, _visibility: STAGE_FRAGMENT | STAGE_VERTEX }] : [];\n const helpers = needsParamsUbo ? `struct gpUniforms { previousViewProjection: mat4x4<f32>, cameraNearFar: vec4<f32>, };` : \"\";\n const varyings: Varying[] = [];\n if (needsVelocityVaryings) {\n varyings.push({ _name: \"vCurrentClip\", _type: \"vec4<f32>\" }, { _name: \"vPreviousClip\", _type: \"vec4<f32>\" });\n }\n if (needsLocalPosVarying) {\n varyings.push({ _name: \"vLocalPos\", _type: \"vec3<f32>\" });\n }\n // Velocity needs the previous-world matrix on the mesh UBO too — but that\n // is out of scope of this fragment (the standard mesh UBO does not have\n // it). LINEAR_VELOCITY is therefore deferred behind a TODO; HillValley /\n // scene 145 does not request it.\n const vbParts: string[] = [];\n if (needsVelocityVaryings) {\n vbParts.push(`out.vCurrentClip = scene.viewProjection * vec4<f32>(out.vp, 1.0);`);\n vbParts.push(`out.vPreviousClip = gp.previousViewProjection * vec4<f32>(out.vp, 1.0);`);\n }\n if (needsLocalPosVarying) {\n vbParts.push(`out.vLocalPos = position;`);\n }\n const slots: ShaderFragment[\"_vertexSlots\"] = vbParts.length > 0 ? { VB: vbParts.join(\"\\n\") } : {};\n return {\n _id: \"~geometry-params\",\n _bindings: bindings,\n _helperFunctions: helpers,\n // gp UBO is also visible to the vertex stage when present, so the\n // struct declaration must be available there too.\n _vertexHelperFunctions: helpers,\n _varyings: varyings,\n _vertexSlots: slots,\n };\n}\n\n/** Compose a Standard geometry-output shader.\n *\n * Reuses {@link composeStandardShader} verbatim — every standard-material\n * feature (bump perturbation, alpha discard, instancing, …) flows through\n * the same code path. The fragment WGSL is then string-patched to switch\n * the entry-point return type to a multi-attachment `FragmentOutput`.\n *\n * @param emitColor - When true, an extra `@location(N) color: vec4<f32>`\n * attachment is appended to `FragmentOutput` (N = `attachments.length`)\n * and populated with the standard lit `color` value. Used when the\n * task's `targetTexture` is set — that target receives the real (lit)\n * material color alongside the geometry-data attachments. */\nexport function composeStandardGeometryShader(\n features: number,\n meshFeatures: number,\n extFragments: ShaderFragment[],\n attachments: readonly GeometryTextureType[],\n esmShadowDepthCode = \"\",\n emitColor = false\n): ComposedShader {\n const wantsGp = needsGpUbo(attachments);\n const wantsVelocity = needsVelocity(attachments);\n const wantsLocalPos = needsLocalPos(attachments);\n const fragments = wantsGp || wantsVelocity || wantsLocalPos ? [...extFragments, createGeometryParamsFragment(wantsGp, wantsVelocity, wantsLocalPos)] : extFragments;\n\n // Strip MATERIAL_ALPHA_BLEND so the standard fragment does NOT emit\n // ALPHA_COMBINE blend in its color output — we drive blending per\n // attachment in the geometry pipeline state instead.\n const stdFeatures = features & ~MATERIAL_ALPHA_BLEND;\n const base = composeStandardShader(stdFeatures, meshFeatures, fragments, esmShadowDepthCode);\n\n const hasSpecular = (features & HAS_SPECULAR_TEXTURE) !== 0;\n const specularUv = (features & SPECULAR_USES_UV2) !== 0 ? \"input.vv\" : \"input.vu\";\n\n // ── Post-process the fragment WGSL ────────────────────────────────────\n\n // 1) Replace the return type. `composeStandardShader` always emits\n // `-> @location(0) vec4<f32>` for the color path (no _noColorOutput\n // in our flow).\n const fragmentSignatureFrom = \"-> @location(0) vec4<f32>\";\n const fragmentSignatureTo = \"-> FragmentOutput\";\n if (!base._fragmentWGSL.includes(fragmentSignatureFrom)) {\n throw new Error(\"composeStandardGeometryShader: standard fragment signature mismatch — bypass active?\");\n }\n let frag = base._fragmentWGSL.replace(fragmentSignatureFrom, fragmentSignatureTo);\n\n // 2) Inject FragmentOutput struct right before `@fragment fn main`. When\n // `emitColor` is set, append an extra slot at @location(N) for the\n // standard `color` output (the \"real\" lit material color), with\n // N = attachments.length.\n const colorSlot = attachments.length;\n const extraColorLine = emitColor ? `\\n@location(${colorSlot}) color: vec4<f32>,` : \"\";\n const outputStruct = `struct FragmentOutput {\n${attachments.map((_, i) => `@location(${i}) f${i}: vec4<f32>,`).join(\"\\n\")}${extraColorLine}\n};\n`;\n frag = frag.replace(\"@fragment fn main\", `${outputStruct}@fragment fn main`);\n\n // 3) Replace `return color;` with MRT writes + `return out;`. We use\n // `alpha` (the standard fragment's running alpha) for the\n // writeGeometryInfo gate so opacity-texture and material-alpha\n // materials get a correct binary mask under the per-attachment\n // ALPHA_COMBINE blend pipeline state.\n const wg = `select(0.0, 1.0, alpha > 0.4)`;\n const writes = attachments.map((type, i) => `out.f${i} = ${attachmentExpr(type, wg, hasSpecular, specularUv)};`).join(\"\\n\");\n const extraColorWrite = emitColor ? `\\nout.color = color;` : \"\";\n const replacement = `var out: FragmentOutput;\n${writes}${extraColorWrite}\nreturn out;`;\n if (!frag.includes(\"return color;\")) {\n throw new Error(\"composeStandardGeometryShader: 'return color;' not found in composed fragment — template changed?\");\n }\n frag = frag.replace(\"return color;\", replacement);\n\n return { ...base, _fragmentWGSL: frag };\n}\n","/** Standard geometry-MRT renderable factory.\n *\n * Builds a {@link Renderable} that draws a single mesh through a\n * {@link createStandardGeometryMaterialView} into the geometry renderer\n * task's multi-attachment render target. Mirrors the regular\n * {@link buildStandardMeshRenderables} structure (rebuildSingle closure\n * → Renderable.bind() → DrawBinding.update/draw) so that per-mesh\n * bind groups, mesh UBO refreshes (including writeMeshLightSelection),\n * and material UBO version tracking flow through the exact same\n * contract scenes already use for ordinary Standard renderables.\n *\n * Feature parity with {@link buildStandardMeshRenderables}: thin\n * instances (matrix + optional per-instance colour), bound-texture\n * acquire/release lifecycle, sort-centre tracking for transparency\n * ordering. Shadows are intentionally excluded — the geometry pass\n * writes raw G-buffer attachments, not shaded colour.\n *\n * Per-(view, mesh-feature-variant) shared state — composed shader,\n * mesh BGL, pipeline cache — is cached on `view._geometry` keyed by\n * the mesh-feature bits that affect shader composition (thin-instance\n * matrix / colour). Per-mesh state (UBOs, bind group, sort centre)\n * lives in the closure returned by {@link buildStandardGeometryRenderable}.\n *\n * This module is imported only by {@link createStandardGeometryMaterialView}\n * — scenes that do not use the geometry renderer task pay zero bytes for it.\n */\n\nimport { F32 } from \"../../engine/typed-arrays.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\nimport type { Mesh } from \"../../mesh/mesh.js\";\nimport type { MeshGroupBuilder, Renderable } from \"../../render/renderable.js\";\nimport { writeMeshLightSelection } from \"../../render/lights-ubo.js\";\nimport type { SceneContext } from \"../../scene/scene-core.js\";\nimport { createUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { acquireTexture, releaseTexture } from \"../../resource/gpu-pool.js\";\nimport type { ComposedShader, ShaderFragment } from \"../../shader/fragment-types.js\";\nimport { targetSignatureKey } from \"../../engine/render-target.js\";\nimport { createThinInstanceFragment } from \"../../shader/fragments/thin-instance-fragment.js\";\nimport { syncThinInstanceBuffers } from \"../../mesh/thin-instance-gpu.js\";\n\nimport type { Material } from \"../material.js\";\nimport type { StandardMaterialProps } from \"./standard-material.js\";\nimport { _getStdExtsSorted, DOUBLE_SIDED, HAS_DIFFUSE_TEXTURE, HAS_OPACITY_TEXTURE, NEEDS_UV, NEEDS_UV2 } from \"./standard-flags.js\";\nimport { writeStdMaterialData } from \"./standard-pipeline.js\";\nimport { composeStandardGeometryShader } from \"./standard-geometry-output-shader.js\";\nimport { getSceneBindGroupLayout } from \"../../render/scene-helpers.js\";\nimport { collectStdBoundTextures } from \"./collect-std-bound-textures.js\";\nimport { _computeMeshFeatures, MSH_HAS_INSTANCE_COLOR, MSH_HAS_THIN_INSTANCES } from \"../mesh-features.js\";\nimport type { StandardGeometryMaterialView } from \"./geometry-view.js\";\n\n/** Singleton {@link MeshGroupBuilder} that geometry views point at via their\n * overridden `_buildGroup`. The async builder body is unreachable — geometry\n * views are dispatched per-mesh via {@link RenderTask.addMesh} which calls\n * `_rebuildSingle` directly. Centralizing the per-mesh factory here means\n * `resolvePendingMeshes` doesn't need any view-aware branching. */\nexport const standardGeometryGroupBuilder: MeshGroupBuilder = (async () => {\n throw new Error(\"standard-geometry view does not support scene group building\");\n}) as MeshGroupBuilder;\nstandardGeometryGroupBuilder._rebuildSingle = (scene: SceneContext, mesh: Mesh, materialOverride?: Material): Renderable => {\n const view = (materialOverride ?? mesh.material) as StandardGeometryMaterialView;\n return buildStandardGeometryRenderable(scene, mesh, view);\n};\nstandardGeometryGroupBuilder._materialFamily = \"standard\";\n\n/** Per-(task, source-material, mesh-variant) shared resources lazily attached\n * to the view. Cached on `view._geometry` (Map keyed by mesh-variant bits) to\n * keep the same WGSL + BGL + pipeline objects across all meshes that share\n * the view and the same shader-relevant mesh features. */\ninterface StandardGeometryViewResources {\n _composed: ComposedShader;\n _features: number;\n _meshBGL: GPUBindGroupLayout;\n _pipelineLayout: GPUPipelineLayout;\n _vertModule: GPUShaderModule;\n _fragModule: GPUShaderModule;\n _pipelines: Map<string, GPURenderPipeline>;\n /** Ext fragments that contributed bindings — used by per-mesh bind groups. */\n _extFragments: readonly { _ext: ReturnType<typeof _getStdExtsSorted>[number] }[];\n _alphaBlend: boolean;\n /** Shared material UBO and dirty-version state (one per source material in this view). */\n _matUBO: GPUBuffer;\n _matData: Float32Array;\n _lastUboVersion: number;\n /** Optional UV-transform UBO. Allocated when the view's features include NEEDS_UV. */\n _upUBO: GPUBuffer | null;\n}\n\n/** Pack the mesh-feature bits that change shader composition / pipeline\n * into a 2-bit variant key. At most 4 variants per view in the worst case. */\nfunction _variantKey(meshFeatures: number): number {\n let k = 0;\n if (meshFeatures & MSH_HAS_THIN_INSTANCES) {\n k |= 1;\n }\n if (meshFeatures & MSH_HAS_INSTANCE_COLOR) {\n k |= 2;\n }\n return k;\n}\n\n/** Build a {@link Renderable} for one mesh drawn through a Standard geometry view.\n * Reuses or creates per-(view, mesh-variant) shared resources on `view._geometry`. */\nexport function buildStandardGeometryRenderable(scene: SceneContext, mesh: Mesh, view: StandardGeometryMaterialView): Renderable {\n const engine = scene.surface.engine;\n const device = engine._device;\n const source = view.source as StandardMaterialProps;\n // Geometry pass has no receiver path — pass receiveShadows=false.\n const meshFeatures = _computeMeshFeatures(mesh, false);\n const variantKey = _variantKey(meshFeatures);\n const res = _ensureViewResources(view, engine, meshFeatures, variantKey);\n const features = res._features;\n\n // Per-mesh UBOs + bind group.\n const meshUboData = new F32(res._composed._meshUboSpec._totalBytes / 4);\n meshUboData.set(mesh.worldMatrix, 0);\n writeMeshLightSelection(mesh, scene.lights, meshUboData);\n const meshUBO = createUniformBuffer(engine, meshUboData);\n\n const bg = _createGeometryMeshBindGroup(engine, view, res, mesh, meshUBO);\n\n // Acquire all textures the standard shader references so the GPU-pool\n // doesn't release them while the geometry pass holds bind groups on\n // them. Mirrors standard-renderable's lifecycle exactly.\n const boundTextures = collectStdBoundTextures(source);\n for (const t of boundTextures) {\n acquireTexture(t);\n }\n const prevDisposables = (scene as SceneContext)._meshDisposables.get(mesh) ?? [];\n (scene as SceneContext)._meshDisposables.set(mesh, [\n ...prevDisposables,\n () => {\n for (const t of boundTextures) {\n releaseTexture(t);\n }\n },\n ]);\n\n let _lastWorldVersion = mesh.worldMatrixVersion;\n let _lastLightsCount = scene.lights.length;\n\n const needsUV = (features & NEEDS_UV) !== 0;\n const needsUV2 = (features & NEEDS_UV2) !== 0;\n const isAlphaBlend = res._alphaBlend;\n const hasThinInstances = (meshFeatures & MSH_HAS_THIN_INSTANCES) !== 0;\n const hasInstanceColor = (meshFeatures & MSH_HAS_INSTANCE_COLOR) !== 0;\n const sortCenter = [mesh.worldMatrix[12]!, mesh.worldMatrix[13]!, mesh.worldMatrix[14]!] as [number, number, number];\n\n const update = (): void => {\n if (mesh.worldMatrixVersion !== _lastWorldVersion || scene.lights.length !== _lastLightsCount) {\n sortCenter[0] = mesh.worldMatrix[12]!;\n sortCenter[1] = mesh.worldMatrix[13]!;\n sortCenter[2] = mesh.worldMatrix[14]!;\n meshUboData.set(mesh.worldMatrix, 0);\n writeMeshLightSelection(mesh, scene.lights, meshUboData);\n device.queue.writeBuffer(meshUBO, 0, meshUboData as Float32Array<ArrayBuffer>);\n _lastWorldVersion = mesh.worldMatrixVersion;\n _lastLightsCount = scene.lights.length;\n }\n if (source._uboVersion !== res._lastUboVersion) {\n res._lastUboVersion = source._uboVersion;\n const textureLevel = (features & HAS_DIFFUSE_TEXTURE) !== 0 ? 1.0 : 0.0;\n res._matData.fill(0);\n writeStdMaterialData(res._matData, source, textureLevel);\n device.queue.writeBuffer(res._matUBO, 0, res._matData.buffer, 0, 96);\n }\n };\n\n const draw = (pass: GPURenderPassEncoder | GPURenderBundleEncoder): number => {\n if (mesh.visible === false) {\n return 0;\n }\n pass.setBindGroup(1, bg);\n const g = (mesh as Mesh)._gpu;\n let slot = 0;\n pass.setVertexBuffer(slot++, g.positionBuffer);\n pass.setVertexBuffer(slot++, g.normalBuffer);\n if (needsUV && g.uvBuffer) {\n pass.setVertexBuffer(slot++, g.uvBuffer);\n }\n if (needsUV2 && g.uv2Buffer) {\n pass.setVertexBuffer(slot++, g.uv2Buffer);\n }\n const ti = hasThinInstances ? mesh.thinInstances : null;\n if (ti) {\n slot = syncThinInstanceBuffers(engine, ti, pass, slot, hasInstanceColor);\n }\n pass.setIndexBuffer(g.indexBuffer, g.indexFormat);\n if (ti && ti.count > 0) {\n pass.drawIndexed(g.indexCount, ti.count);\n } else {\n pass.drawIndexed(g.indexCount);\n }\n return 1;\n };\n\n const r: Renderable = {\n order: mesh.renderOrder ?? (isAlphaBlend ? 200 : 100),\n isTransparent: isAlphaBlend,\n mesh,\n bind(eng: EngineContext, sig: RenderTargetSignature) {\n return {\n renderable: r,\n pipeline: _getOrCreateGeometryPipeline(eng as EngineContext, sig, view, res),\n update,\n draw,\n };\n },\n };\n r._worldCenter = sortCenter;\n return r;\n}\n\n// ─── Shared per-view resources ─────────────────────────────────────────────\n\nfunction _ensureViewResources(view: StandardGeometryMaterialView, engine: EngineContext, meshFeatures: number, variantKey: number): StandardGeometryViewResources {\n let cache = view._geometry as Map<number, StandardGeometryViewResources> | undefined;\n if (!cache) {\n cache = new Map();\n Object.defineProperty(view, \"_geometry\", { value: cache, enumerable: false, configurable: true });\n }\n const cached = cache.get(variantKey);\n if (cached) {\n return cached;\n }\n const source = view.source as StandardMaterialProps;\n const features = view._renderFeatures.features;\n\n // Collect the same ext fragments the regular Standard renderable would —\n // bump, opacity, specular, … — so the shared shader code is identical.\n const sortedExts = _getStdExtsSorted();\n const frags: ShaderFragment[] = [];\n const usedExts: { _ext: (typeof sortedExts)[number] }[] = [];\n for (const ext of sortedExts) {\n if (features & ext._feature) {\n const f = ext._frag(features);\n if (f) {\n frags.push(f);\n usedExts.push({ _ext: ext });\n }\n }\n }\n\n // Thin instances. Mirror standard-renderable: when per-instance colour is\n // present we override the fragment's AT slot with a BC slot that\n // multiplies the final lit `color` (only consumed when `emitColor` is on\n // — otherwise WGSL folds the dead code).\n if (meshFeatures & MSH_HAS_THIN_INSTANCES) {\n const hasColor = (meshFeatures & MSH_HAS_INSTANCE_COLOR) !== 0;\n const tiFrag = createThinInstanceFragment(hasColor);\n if (hasColor) {\n const { _fragmentSlots: _drop, ...rest } = tiFrag;\n frags.push({\n ...rest,\n _fragmentSlots: {\n BC: `color = vec4<f32>(color.rgb * input.vInstanceColor.rgb, color.a * input.vInstanceColor.a);`,\n },\n });\n } else {\n frags.push(tiFrag);\n }\n }\n\n const composed = composeStandardGeometryShader(features, meshFeatures, frags, view._geometryAttachments, \"\", view._emitColor);\n const device = engine._device;\n const meshBGL = device.createBindGroupLayout(composed._meshBGLDescriptor);\n // Pipeline layout: scene BG (group 0) + mesh BG (group 1). Geometry pass\n // has no shadow receiver group.\n const sceneBGL = getSceneBindGroupLayout(engine);\n const pipelineLayout = device.createPipelineLayout({\n bindGroupLayouts: [sceneBGL, meshBGL],\n });\n const vertModule = device.createShaderModule({ code: composed._vertexWGSL });\n const fragModule = device.createShaderModule({ code: composed._fragmentWGSL });\n\n // Re-detect alpha-blend from the *source* material — the view masked it\n // out so the composer doesn't emit standard's source-over color blend.\n const alphaBlend = source.alpha < 1 || (features & HAS_OPACITY_TEXTURE) !== 0;\n\n // Shared material UBO (one per source material per view). All meshes of\n // this material reuse the same UBO; updates are version-guarded.\n const matData = new F32(24);\n const textureLevel = (features & HAS_DIFFUSE_TEXTURE) !== 0 ? 1.0 : 0.0;\n writeStdMaterialData(matData, source, textureLevel);\n const matUBO = createUniformBuffer(engine, matData);\n\n // UV transform UBO when the vertex stage emits UV math.\n let upUBO: GPUBuffer | null = null;\n if ((features & NEEDS_UV) !== 0) {\n const uvData = new F32(4);\n let scaleX = 1;\n let scaleY = 1;\n let offsetY = 0;\n if ((features & HAS_DIFFUSE_TEXTURE) !== 0 && source.diffuseTexture) {\n scaleX = source.uvScale[0];\n scaleY = source.uvScale[1];\n if (source.diffuseTexture.invertY) {\n offsetY = scaleY;\n scaleY = -scaleY;\n }\n } else if ((features & HAS_OPACITY_TEXTURE) !== 0 && source.opacityTexture?.invertY) {\n offsetY = 1;\n scaleY = -1;\n } else if (source.bumpTexture?.invertY) {\n offsetY = 1;\n scaleY = -1;\n }\n uvData[0] = scaleX;\n uvData[1] = scaleY;\n uvData[2] = 0;\n uvData[3] = offsetY;\n upUBO = createUniformBuffer(engine, uvData);\n }\n\n const res: StandardGeometryViewResources = {\n _composed: composed,\n _features: features,\n _meshBGL: meshBGL,\n _pipelineLayout: pipelineLayout,\n _vertModule: vertModule,\n _fragModule: fragModule,\n _pipelines: new Map(),\n _extFragments: usedExts,\n _alphaBlend: alphaBlend,\n _matUBO: matUBO,\n _matData: matData,\n _lastUboVersion: source._uboVersion,\n _upUBO: upUBO,\n };\n cache.set(variantKey, res);\n return res;\n}\n\nfunction _createGeometryMeshBindGroup(\n engine: EngineContext,\n view: StandardGeometryMaterialView,\n res: StandardGeometryViewResources,\n _mesh: Mesh,\n meshUBO: GPUBuffer\n): GPUBindGroup {\n const source = view.source as StandardMaterialProps;\n const features = res._features;\n let nextBinding = 0;\n const entries: GPUBindGroupEntry[] = [\n { binding: nextBinding++, resource: { buffer: meshUBO } },\n { binding: nextBinding++, resource: { buffer: res._matUBO } },\n ];\n if ((features & HAS_DIFFUSE_TEXTURE) !== 0 && source.diffuseTexture) {\n const tex = source.diffuseTexture;\n entries.push({ binding: nextBinding++, resource: tex.texture.createView() }, { binding: nextBinding++, resource: tex.sampler });\n }\n if ((features & NEEDS_UV) !== 0 && res._upUBO) {\n entries.push({ binding: nextBinding++, resource: { buffer: res._upUBO } });\n }\n for (const used of res._extFragments) {\n if (used._ext._bind) {\n nextBinding = used._ext._bind(source, entries, nextBinding);\n }\n }\n // Geometry-params `gp` UBO is contributed by the geometry composer as the\n // last fragment, so its binding is appended last. Present iff the\n // requested attachments need it (LINEAR_VELOCITY or NORMALIZED_VIEW_DEPTH).\n if (view._gpUBO) {\n entries.push({ binding: nextBinding++, resource: { buffer: view._gpUBO } });\n }\n return engine._device.createBindGroup({ layout: res._meshBGL, entries });\n}\n\nfunction _getOrCreateGeometryPipeline(\n engine: EngineContext,\n sig: RenderTargetSignature,\n view: StandardGeometryMaterialView,\n res: StandardGeometryViewResources\n): GPURenderPipeline {\n const key = targetSignatureKey(sig);\n const cached = res._pipelines.get(key);\n if (cached) {\n return cached;\n }\n const device = engine._device;\n const formats = (sig as RenderTargetSignature & { _colorFormats?: readonly GPUTextureFormat[] })._colorFormats ?? (sig._colorFormat ? [sig._colorFormat] : []);\n if (formats.length === 0) {\n throw new Error(\"standard-geometry: render target has no color attachments\");\n }\n const alphaBlend = res._alphaBlend;\n const blendState: GPUBlendState | undefined = alphaBlend\n ? {\n color: { srcFactor: \"src-alpha\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n alpha: { srcFactor: \"src-alpha\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n }\n : undefined;\n const colorTargets: GPUColorTargetState[] = formats.map((fmt) => (blendState ? { format: fmt, blend: blendState } : { format: fmt }));\n const cullMode = (res._features & DOUBLE_SIDED) !== 0 ? \"none\" : view._reverseCulling ? \"front\" : \"back\";\n const pipeline = device.createRenderPipeline({\n layout: res._pipelineLayout,\n vertex: { module: res._vertModule, entryPoint: \"main\", buffers: res._composed._vertexBufferLayouts },\n fragment: { module: res._fragModule, entryPoint: \"main\", targets: colorTargets },\n depthStencil: sig._depthStencilFormat\n ? {\n format: sig._depthStencilFormat,\n depthCompare: sig._depthCompare ?? \"greater-equal\",\n // BJS disables depth-write for transparent/opacity meshes in the\n // geometry pass so background depth survives partially-transparent pixels.\n depthWriteEnabled: !alphaBlend,\n }\n : undefined,\n multisample: { count: sig._sampleCount },\n // Geometry MRT renders to offscreen targets, so it needs the same\n // Render upright — front face is always \"ccw\".\n primitive: { topology: \"triangle-list\", cullMode, frontFace: \"ccw\" },\n });\n res._pipelines.set(key, pipeline);\n return pipeline;\n}\n","/** Standard material view helper that targets geometry-rendering MRT output.\n *\n * The geometry renderer task wraps each Standard caster material in a\n * `StandardGeometryMaterialView`. The view carries the per-task attachment\n * list, target-texture intent, optional `gp` UBO (shared across the task's\n * materials), and reverse-culling flag. The view also shadows\n * {@link Material._buildGroup} with {@link standardGeometryGroupBuilder} so\n * that `RenderTask.addMesh` (and the geometry renderer task) materialize a\n * {@link Renderable} through the shared standard geometry renderable\n * infrastructure — no view-aware branching required in core render-task.\n *\n * The geometry-output WGSL itself is produced by post-processing the regular\n * composed standard shader in `./standard-geometry-output-shader.ts`. */\n\nimport { createMaterialView } from \"../material-view.js\";\nimport type { MaterialView } from \"../material.js\";\nimport type { GeometryTextureType } from \"../../frame-graph/geometry-types.js\";\nimport { GEOMETRY_OUTPUT, MATERIAL_ALPHA_BLEND } from \"./standard-flags.js\";\nimport type { StandardMaterialProps } from \"./standard-material.js\";\nimport { standardGeometryGroupBuilder } from \"./standard-geometry-renderable.js\";\n\n/** Per-task ordered attachment list driving the geometry template. The array\n * index is the MRT color-attachment slot used in `@location(i)`. */\nexport type StandardGeometryAttachments = readonly GeometryTextureType[];\n\n/** Per-(task, material) geometry view configuration. All fields are owned by\n * the geometry renderer task; the view captures them so per-mesh renderables\n * pick up the same pipeline state and bindings. */\nexport interface StandardGeometryViewConfig {\n /** Ordered MRT attachment list — index = `@location(i)`. */\n readonly attachments: StandardGeometryAttachments;\n /** When true, the composed fragment emits the real (lit) material color\n * at `@location(N)` (N = attachments.length). The target texture is\n * added to the pipeline color-target list at the same slot. */\n readonly emitColor: boolean;\n /** Per-task previous-VP + camera-near-far UBO. Required when\n * {@link attachments} contains `NORMALIZED_VIEW_DEPTH` or\n * `LINEAR_VELOCITY`; ignored otherwise. */\n readonly gpUBO?: GPUBuffer | null;\n /** Flip culling direction. */\n readonly reverseCulling?: boolean;\n}\n\n/** Standard material view that emits geometry textures instead of shaded colour. */\nexport interface StandardGeometryMaterialView extends MaterialView {\n /** @internal Ordered MRT attachment list — index = `@location(i)`. */\n readonly _geometryAttachments: StandardGeometryAttachments;\n /** @internal Geometry pipeline carries an extra `@location(N)` color attachment. */\n readonly _emitColor: boolean;\n /** @internal Optional per-task geometry-params UBO shared with the composer's\n * `geometryParams` fragment. */\n readonly _gpUBO: GPUBuffer | null;\n /** @internal */\n readonly _reverseCulling: boolean;\n /** @internal Shared per-view resources cache populated lazily by the renderable\n * factory. Opaque to callers. */\n _geometry?: unknown;\n}\n\n/** Wrap a Standard material as a geometry-output view.\n * - Sets the `GEOMETRY_OUTPUT` feature bit.\n * - Clears `MATERIAL_ALPHA_BLEND`: the geometry pipeline drives blending per\n * attachment via the pipeline color-target state, not via the standard\n * fragment's source-over color output.\n * - Shadows `_buildGroup` with {@link standardGeometryGroupBuilder} so the\n * natural `material._buildGroup._rebuildSingle` dispatch in\n * `resolvePendingMeshes` builds a geometry-MRT renderable for this view. */\nexport function createStandardGeometryMaterialView(source: StandardMaterialProps, config: StandardGeometryViewConfig): StandardGeometryMaterialView {\n const baseFeatures = source._renderFeatures?.features ?? 0;\n const view = createMaterialView(source, { features: (baseFeatures & ~MATERIAL_ALPHA_BLEND) | GEOMETRY_OUTPUT }) as StandardGeometryMaterialView;\n Object.defineProperty(view, \"_geometryAttachments\", { value: config.attachments, enumerable: false });\n Object.defineProperty(view, \"_emitColor\", { value: config.emitColor, enumerable: false });\n Object.defineProperty(view, \"_gpUBO\", { value: config.gpUBO ?? null, enumerable: false });\n Object.defineProperty(view, \"_reverseCulling\", { value: config.reverseCulling ?? false, enumerable: false });\n Object.defineProperty(view, \"_buildGroup\", { value: standardGeometryGroupBuilder, enumerable: false });\n return view;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ba as mat4Invert, bb as mat4Identity, bc as getLoaderTmpAnim, bd as mat4MultiplyInto, a as F32, b8 as computeNodeWorldMatrix, r as resolveAccessor, be as INTERP_CUBICSPLINE, bf as INTERP_STEP, bg as INTERP_LINEAR, bh as PATH_WEIGHTS, bi as PATH_SCALE, bj as PATH_ROTATION, bk as PATH_TRANSLATION, bl as findParent } from "./index-CLElg2Bo.js";
|
|
2
2
|
let _parsePointerChannel = null;
|
|
3
3
|
let _convertSampler = null;
|
|
4
4
|
function _installPointerHandlers(parser, converter) {
|
|
@@ -9,15 +9,15 @@ function toSamplerFloat32(src, length, normalized) {
|
|
|
9
9
|
if (_convertSampler) {
|
|
10
10
|
return _convertSampler(src, length, normalized);
|
|
11
11
|
}
|
|
12
|
-
return new
|
|
12
|
+
return new F32(src.buffer, src.byteOffset, length);
|
|
13
13
|
}
|
|
14
14
|
function resolveIBMs(json, binChunk, skin) {
|
|
15
15
|
const jointCount = skin.joints.length;
|
|
16
16
|
if (skin.inverseBindMatrices !== void 0) {
|
|
17
17
|
const ibmData = resolveAccessor(json, binChunk, skin.inverseBindMatrices);
|
|
18
|
-
return new
|
|
18
|
+
return new F32(ibmData._data.buffer, ibmData._data.byteOffset, jointCount * 16);
|
|
19
19
|
}
|
|
20
|
-
const out = new
|
|
20
|
+
const out = new F32(jointCount * 16);
|
|
21
21
|
for (let i = 0; i < jointCount; i++) {
|
|
22
22
|
const o = i * 16;
|
|
23
23
|
out[o] = out[o + 5] = out[o + 10] = out[o + 15] = 1;
|
|
@@ -33,7 +33,7 @@ function extractSkin(json, binChunk, skinIdx, meshWorldMatrix, parentMap, worldM
|
|
|
33
33
|
}
|
|
34
34
|
function computeBoneTextureData(skin) {
|
|
35
35
|
const numBones = skin.jointNodes.length;
|
|
36
|
-
const data = new
|
|
36
|
+
const data = new F32(numBones * 16);
|
|
37
37
|
const invMeshWorld = mat4Invert(skin.meshWorldMatrix) ?? mat4Identity();
|
|
38
38
|
const tmp = getLoaderTmpAnim();
|
|
39
39
|
for (let i = 0; i < numBones; i++) {
|
|
@@ -242,4 +242,4 @@ export {
|
|
|
242
242
|
extractSkin,
|
|
243
243
|
parseAnimationData
|
|
244
244
|
};
|
|
245
|
-
//# sourceMappingURL=gltf-animation-
|
|
245
|
+
//# sourceMappingURL=gltf-animation-K_zZxj_d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gltf-animation-K_zZxj_d.js","sources":["../src/loader-gltf/gltf-animation.ts"],"sourcesContent":["/**\n * Lazy-loaded animation/skin parsing for glTF.\n * Dynamically imported by load-gltf.ts only when a glTF contains animations or skins.\n *\n * This module is pointer-feature agnostic: KHR_animation_pointer (and the\n * non-Float32 sampler conversion that CubeVisibility-style assets need) are\n * installed via the registration seam below, so scenes that don't declare\n * the extension pay zero bytes for it.\n */\nimport { F32 } from \"../engine/typed-arrays.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport type { Mesh } from \"../mesh/mesh.js\";\nimport type { GltfAnimationData, AnimationClip, AnimationSampler, AnimationChannel, NodeRest, SkeletonBinding, MorphBinding, AnimatedNodeTarget } from \"../animation/types.js\";\nimport { INTERP_LINEAR, INTERP_STEP, INTERP_CUBICSPLINE, PATH_TRANSLATION, PATH_ROTATION, PATH_SCALE, PATH_WEIGHTS } from \"../animation/types.js\";\nimport { mat4Identity } from \"../math/mat4-identity.js\";\nimport { mat4Invert } from \"../math/mat4-invert.js\";\nimport { mat4MultiplyInto } from \"../math/mat4-multiply-into.js\";\nimport type { Mat4Storage } from \"../math/types.js\";\nimport { resolveAccessor, computeNodeWorldMatrix, findParent } from \"./gltf-parser.js\";\nimport { getLoaderTmpAnim } from \"./_loader-scratch.js\";\nimport type { SceneNode } from \"../scene/scene-node.js\";\n\n/** Registration seam for KHR_animation_pointer. The pointer feature module\n * calls `_installPointerHandlers` on side-effect import; if never called,\n * pointer channels are skipped and non-Float32 samplers fall back to the\n * aliasing fast path (which throws on misaligned/short accessors). */\nexport type PointerChannelParser = (ptr: string, channel: any, nodeMap: readonly (SceneNode | undefined)[] | undefined) => AnimationChannel | null;\nexport type SamplerConverter = (src: ArrayBufferView, length: number, normalized: boolean) => Float32Array;\nlet _parsePointerChannel: PointerChannelParser | null = null;\nlet _convertSampler: SamplerConverter | null = null;\nexport function _installPointerHandlers(parser: PointerChannelParser, converter: SamplerConverter): void {\n _parsePointerChannel = parser;\n _convertSampler = converter;\n}\n\n/** Convert sampler input/output to Float32Array. Default: reinterpret existing\n * Float32 accessor as Float32Array (legacy behaviour; fast but requires\n * aligned Float32 data). KHR_animation_pointer installs a converter that\n * additionally handles non-Float32 / normalized accessors. */\nfunction toSamplerFloat32(src: ArrayBufferView, length: number, normalized: boolean): Float32Array {\n if (_convertSampler) {\n return _convertSampler(src, length, normalized);\n }\n return new F32(src.buffer, src.byteOffset, length);\n}\n\n/** Parsed skin/skeleton data. */\nexport interface GltfSkinData {\n /** Node indices of joints in this skin. */\n jointNodes: number[];\n /** Inverse bind matrices — one 4×4 per joint (column-major Float32Array). */\n inverseBindMatrices: Float32Array;\n /** World matrices of each joint at rest pose. */\n jointWorldMatrices: Mat4[];\n /** World matrix of the mesh node that owns this skin. */\n meshWorldMatrix: Mat4;\n}\n\n// ─── Skin / Skeleton Extraction ─────────────────────────────────────\n\n/** Resolve a skin's inverse-bind matrices, filling with identities when absent. */\nfunction resolveIBMs(json: any, binChunk: DataView, skin: any): Float32Array {\n const jointCount = skin.joints.length;\n if (skin.inverseBindMatrices !== undefined) {\n const ibmData = resolveAccessor(json, binChunk, skin.inverseBindMatrices);\n return new F32(ibmData._data.buffer, ibmData._data.byteOffset, jointCount * 16);\n }\n const out = new F32(jointCount * 16);\n for (let i = 0; i < jointCount; i++) {\n const o = i * 16;\n out[o] = out[o + 5] = out[o + 10] = out[o + 15] = 1;\n }\n return out;\n}\n\nexport function extractSkin(\n json: any,\n binChunk: DataView,\n skinIdx: number,\n meshWorldMatrix: Mat4,\n parentMap: Map<number, number>,\n worldMatrixCache: Map<number, Mat4>\n): GltfSkinData {\n const skin = json.skins[skinIdx];\n const jointNodes: number[] = skin.joints;\n const inverseBindMatrices = resolveIBMs(json, binChunk, skin);\n const jointWorldMatrices: Mat4[] = jointNodes.map((nodeIdx) => computeNodeWorldMatrix(json, nodeIdx, parentMap, worldMatrixCache));\n return { jointNodes, inverseBindMatrices, jointWorldMatrices, meshWorldMatrix };\n}\n\n/** Compute rest-pose bone texture data. Each bone gets 4 vec4 (one 4×4 matrix).\n * Formula: boneMatrix[i] = inverse(meshWorld) * jointWorld[i] * IBM[i]\n * At rest pose this simplifies to identity for each bone. */\nexport function computeBoneTextureData(skin: GltfSkinData): Float32Array {\n const numBones = skin.jointNodes.length;\n const data = new F32(numBones * 16);\n const invMeshWorld = mat4Invert(skin.meshWorldMatrix) ?? mat4Identity();\n const tmp = getLoaderTmpAnim() as unknown as Mat4Storage;\n for (let i = 0; i < numBones; i++) {\n mat4MultiplyInto(tmp, 0, invMeshWorld as unknown as Mat4Storage, 0, skin.jointWorldMatrices[i]! as unknown as Mat4Storage, 0);\n mat4MultiplyInto(data, i * 16, tmp, 0, skin.inverseBindMatrices, i * 16);\n }\n return data;\n}\n\n// ─── Animation Parsing ──────────────────────────────────────────────\n\nconst INTERP_MAP: Record<string, 0 | 1 | 2> = {\n LINEAR: INTERP_LINEAR,\n STEP: INTERP_STEP,\n CUBICSPLINE: INTERP_CUBICSPLINE,\n};\n\nconst PATH_MAP: Record<string, 0 | 1 | 2 | 3> = {\n translation: PATH_TRANSLATION,\n rotation: PATH_ROTATION,\n scale: PATH_SCALE,\n weights: PATH_WEIGHTS,\n};\n\n/**\n * Parse glTF animation data: clips, node hierarchy, and skeleton bindings.\n * Returns null if no animations, or no drivable state at all (no skeletons,\n * no morphs, no pointer channels).\n *\n * `nodeMap` (optional) maps glTF node index → SceneNode. It's required to\n * resolve KHR_animation_pointer targets that write to node properties.\n */\nexport function parseAnimationData(\n json: any,\n binChunk: DataView,\n meshes: Mesh[],\n parentMap: Map<number, number>,\n worldMatrixCache: Map<number, Mat4>,\n nodeMap?: readonly (SceneNode | undefined)[]\n): GltfAnimationData | null {\n if (!json.animations || json.animations.length === 0) {\n return null;\n }\n\n let pointerChannelCount = 0;\n\n // Parse animation clips\n const clips: AnimationClip[] = [];\n for (const anim of json.animations) {\n const samplers: AnimationSampler[] = [];\n for (const s of anim.samplers) {\n const inputAcc = resolveAccessor(json, binChunk, s.input);\n const outputAcc = resolveAccessor(json, binChunk, s.output);\n const inNorm = json.accessors[s.input]?.normalized === true;\n const outNorm = json.accessors[s.output]?.normalized === true;\n samplers.push({\n input: toSamplerFloat32(inputAcc._data, inputAcc._count, inNorm),\n output: toSamplerFloat32(outputAcc._data, outputAcc._count * outputAcc._componentCount, outNorm),\n interpolation: INTERP_MAP[s.interpolation ?? \"LINEAR\"] ?? INTERP_LINEAR,\n });\n }\n\n const channels: AnimationChannel[] = [];\n for (const c of anim.channels) {\n // KHR_animation_pointer: delegated to the registered pointer parser\n // (installed by gltf-feature-animation-pointer on side-effect import).\n const ptr = c.target?.extensions?.KHR_animation_pointer?.pointer;\n if (ptr) {\n if (!_parsePointerChannel) {\n continue;\n }\n const ch = _parsePointerChannel(ptr, c, nodeMap);\n if (ch) {\n channels.push(ch);\n pointerChannelCount++;\n }\n continue;\n }\n if (c.target.node === undefined) {\n continue;\n }\n const path = PATH_MAP[c.target.path];\n if (path === undefined) {\n continue;\n }\n channels.push({ samplerIdx: c.sampler, nodeIdx: c.target.node, path });\n }\n\n let duration = 0;\n for (const s of samplers) {\n if (s.input.length > 0) {\n const last = s.input[s.input.length - 1]!;\n if (last > duration) {\n duration = last;\n }\n }\n }\n\n clips.push({ name: anim.name ?? \"\", channels, samplers, duration });\n }\n\n // Build node hierarchy (rest-pose TRS + parent indices)\n const nodeCount = json.nodes?.length ?? 0;\n const nodes: NodeRest[] = [];\n for (let i = 0; i < nodeCount; i++) {\n const n = json.nodes[i];\n const t = n.translation ?? [0, 0, 0];\n const r = n.rotation ?? [0, 0, 0, 1];\n const s = n.scale ?? [1, 1, 1];\n nodes.push({\n parentIdx: findParent(parentMap, i),\n _matrix: n.matrix as Mat4 | undefined,\n tx: t[0],\n ty: t[1],\n tz: t[2],\n rx: r[0],\n ry: r[1],\n rz: r[2],\n rw: r[3],\n sx: s[0],\n sy: s[1],\n sz: s[2],\n });\n }\n\n // Build skeleton bindings (connect skin data to GPU bone textures)\n // First, build node→gpuMesh mapping by replaying extraction order\n const nodeToMeshIndices = new Map<number, number[]>();\n let gpuIdx = 0;\n for (let ni = 0; ni < nodeCount; ni++) {\n const node = json.nodes[ni];\n if (node.mesh === undefined) {\n continue;\n }\n const mesh = json.meshes[node.mesh];\n const indices: number[] = [];\n for (let p = 0; p < mesh.primitives.length; p++) {\n indices.push(gpuIdx++);\n }\n nodeToMeshIndices.set(ni, indices);\n }\n\n const skeletons: SkeletonBinding[] = [];\n for (let nodeIdx = 0; nodeIdx < nodeCount; nodeIdx++) {\n const node = json.nodes[nodeIdx];\n if (node.skin === undefined || !json.skins) {\n continue;\n }\n\n const meshIndices = nodeToMeshIndices.get(nodeIdx);\n if (!meshIndices) {\n continue;\n }\n\n const skin = json.skins[node.skin];\n const jointNodes: number[] = skin.joints;\n const inverseBindMatrices = resolveIBMs(json, binChunk, skin);\n\n const meshWorldMatrix = computeNodeWorldMatrix(json, nodeIdx, parentMap, worldMatrixCache);\n const invMeshWorld = mat4Invert(meshWorldMatrix) ?? mat4Identity();\n\n // Create a binding for EACH mesh primitive of this skinned node\n for (const mi of meshIndices) {\n const mesh = meshes[mi];\n const skeleton = mesh?.skeleton;\n if (!skeleton) {\n continue;\n }\n skeletons.push({\n jointNodes,\n inverseBindMatrices,\n invMeshWorld,\n boneTexture: skeleton.boneTexture,\n boneCount: jointNodes.length,\n boneMatrices: skeleton.boneMatrices,\n runtimeSkeleton: skeleton,\n });\n }\n }\n\n // Build morph bindings (connect morph-target meshes to GPU weight buffers)\n const morphBindings: MorphBinding[] = [];\n for (let nodeIdx = 0; nodeIdx < nodeCount; nodeIdx++) {\n const node = json.nodes[nodeIdx];\n if (node.mesh === undefined) {\n continue;\n }\n const gltfMesh = json.meshes[node.mesh];\n if (!gltfMesh.primitives?.[0]?.targets?.length) {\n continue;\n }\n\n const meshIndices = nodeToMeshIndices.get(nodeIdx);\n if (!meshIndices) {\n continue;\n }\n\n for (const mi of meshIndices) {\n const mesh = meshes[mi];\n const morphTargets = mesh?.morphTargets;\n if (!morphTargets) {\n continue;\n }\n morphBindings.push({\n nodeIdx,\n weightsBuffer: morphTargets.weightsBuffer,\n weights: morphTargets.weights,\n targetCount: morphTargets.count,\n runtimeMorphTargets: morphTargets,\n });\n }\n }\n\n // Build the node-TRS writeback inputs. `nodeTargets` exposes each glTF node's\n // live scene node (via the structural AnimatedNodeTarget view) so the controller\n // can push evaluated local TRS back onto the scene graph, moving non-skinned\n // node-animated meshes and their descendants. `excludedNodeIndices` lists nodes\n // that MUST NOT be written: skin joints (driven by the skeleton path) plus\n // skinned-mesh nodes and all their ancestors — their bone matrices bake an\n // `invMeshWorld` captured at load, so moving them at runtime would\n // double-transform the skinned vertices.\n const nodeTargets: readonly (AnimatedNodeTarget | undefined)[] = (nodeMap as readonly (AnimatedNodeTarget | undefined)[] | undefined) ?? [];\n const excludedNodeIndices = new Set<number>();\n for (const skin of json.skins ?? []) {\n for (const ji of skin.joints ?? []) {\n excludedNodeIndices.add(ji);\n }\n }\n for (let ni = 0; ni < nodeCount; ni++) {\n if (json.nodes[ni]?.skin === undefined) {\n continue;\n }\n let p = ni;\n while (p >= 0 && !excludedNodeIndices.has(p)) {\n excludedNodeIndices.add(p);\n p = findParent(parentMap, p);\n }\n }\n\n if (\n clips.length === 0 ||\n (skeletons.length === 0 && morphBindings.length === 0 && pointerChannelCount === 0 && !hasWritableNodeChannel(clips, nodeTargets, excludedNodeIndices))\n ) {\n return null;\n }\n return { clips, nodes, skeletons, morphBindings, nodeTargets, excludedNodeIndices };\n}\n\n/** True if any clip animates a non-excluded node that has a live scene target —\n * i.e. there is at least one plain node-TRS channel the controller can write\n * back. Lets purely-skinned/morph/pointer assets short-circuit unchanged. */\nfunction hasWritableNodeChannel(clips: readonly AnimationClip[], nodeTargets: readonly (AnimatedNodeTarget | undefined)[], excludedNodeIndices: ReadonlySet<number>): boolean {\n for (const clip of clips) {\n for (const ch of clip.channels) {\n if (\n (ch.path === PATH_TRANSLATION || ch.path === PATH_ROTATION || ch.path === PATH_SCALE) &&\n ch.nodeIdx >= 0 &&\n !excludedNodeIndices.has(ch.nodeIdx) &&\n nodeTargets[ch.nodeIdx]\n ) {\n return true;\n }\n }\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { e as U8, bR as getCompressedFormat, T as TU, ax as acquireTexture, L as U8C, br as getOrCreateSampler, U as U32, r as resolveAccessor, D as DV, a as F32 } from "./index-CLElg2Bo.js";
|
|
2
2
|
const KTX2_DECODER_URL = "https://cdn.babylonjs.com/babylon.ktx2Decoder.js";
|
|
3
3
|
let _ktx2DecoderPromise = null;
|
|
4
4
|
const GL_RGBA8 = 32856;
|
|
@@ -134,7 +134,7 @@ function uploadCompressed(engine, mips, format, sRGB) {
|
|
|
134
134
|
size: { width, height },
|
|
135
135
|
format: sRGB ? srgbFormat(format.gpuFormat) : format.gpuFormat,
|
|
136
136
|
mipLevelCount: mips.length,
|
|
137
|
-
usage:
|
|
137
|
+
usage: TU.TEXTURE_BINDING | TU.COPY_DST
|
|
138
138
|
});
|
|
139
139
|
for (let level = 0; level < mips.length; level++) {
|
|
140
140
|
const mip = mips[level];
|
|
@@ -155,7 +155,7 @@ function uploadUncompressed(engine, mips, info, sRGB) {
|
|
|
155
155
|
size: { width, height },
|
|
156
156
|
format: sRGB ? srgbFormat(info.format) : info.format,
|
|
157
157
|
mipLevelCount: mips.length,
|
|
158
|
-
usage:
|
|
158
|
+
usage: TU.TEXTURE_BINDING | TU.COPY_DST
|
|
159
159
|
});
|
|
160
160
|
for (let level = 0; level < mips.length; level++) {
|
|
161
161
|
const mip = mips[level];
|
|
@@ -176,7 +176,7 @@ function uploadUncompressed(engine, mips, info, sRGB) {
|
|
|
176
176
|
}
|
|
177
177
|
async function uploadKtx2Texture2D(engine, buffer, sRGB) {
|
|
178
178
|
const decoder = await loadKtx2Decoder();
|
|
179
|
-
const decoded = await decoder.decode(new
|
|
179
|
+
const decoded = await decoder.decode(new U8(buffer), RGBA_CAPS, { forceRGBA: true });
|
|
180
180
|
const mips = validateDecoded(decoded);
|
|
181
181
|
const compressed = getCompressedFormat(decoded.transcodedFormat);
|
|
182
182
|
if (compressed) {
|
|
@@ -190,17 +190,18 @@ async function uploadKtx2Texture2D(engine, buffer, sRGB) {
|
|
|
190
190
|
}
|
|
191
191
|
async function decodeKtx2ImageBitmapFromBuffer(buffer) {
|
|
192
192
|
const decoder = await loadKtx2Decoder();
|
|
193
|
-
const decoded = await decoder.decode(new
|
|
193
|
+
const decoded = await decoder.decode(new U8(buffer), RGBA_CAPS, { forceRGBA: true });
|
|
194
194
|
const mip0 = validateDecoded(decoded)[0];
|
|
195
195
|
if (mip0.data.length !== mip0.width * mip0.height * 4) {
|
|
196
196
|
throw new Error("KTX2: RGBA decode size does not match image dimensions");
|
|
197
197
|
}
|
|
198
|
-
const pixels = new
|
|
198
|
+
const pixels = new U8C(mip0.data.length);
|
|
199
199
|
pixels.set(mip0.data);
|
|
200
200
|
return createImageBitmap(new ImageData(pixels, mip0.width, mip0.height));
|
|
201
201
|
}
|
|
202
202
|
const NAME = "KHR_texture_basisu";
|
|
203
203
|
const FLOAT = 5126;
|
|
204
|
+
const COMPONENT_BYTES = { 5120: 1, 5121: 1, 5122: 2, 5123: 2, 5125: 4, 5126: 4 };
|
|
204
205
|
const TYPE_SIZES = {
|
|
205
206
|
SCALAR: 1,
|
|
206
207
|
VEC2: 2,
|
|
@@ -265,8 +266,8 @@ async function resolveImageBuffer(ctx, imageIdx) {
|
|
|
265
266
|
throw new Error(`${NAME}: bufferView ${image.bufferView} not found`);
|
|
266
267
|
}
|
|
267
268
|
const offset = ctx.binChunk.byteOffset + (bv.byteOffset ?? 0);
|
|
268
|
-
const copy = new
|
|
269
|
-
copy.set(new
|
|
269
|
+
const copy = new U8(bv.byteLength);
|
|
270
|
+
copy.set(new U8(ctx.binChunk.buffer, offset, bv.byteLength));
|
|
270
271
|
return copy.buffer;
|
|
271
272
|
}
|
|
272
273
|
if (image.uri) {
|
|
@@ -357,25 +358,56 @@ async function uploadOrmTexture(data, ctx) {
|
|
|
357
358
|
}
|
|
358
359
|
return tex;
|
|
359
360
|
}
|
|
361
|
+
function readComponent(view, offset, componentType, normalized) {
|
|
362
|
+
switch (componentType) {
|
|
363
|
+
case FLOAT:
|
|
364
|
+
return view.getFloat32(offset, true);
|
|
365
|
+
case 5125: {
|
|
366
|
+
const v = view.getUint32(offset, true);
|
|
367
|
+
return normalized ? v / 4294967295 : v;
|
|
368
|
+
}
|
|
369
|
+
case 5123: {
|
|
370
|
+
const v = view.getUint16(offset, true);
|
|
371
|
+
return normalized ? v / 65535 : v;
|
|
372
|
+
}
|
|
373
|
+
case 5122: {
|
|
374
|
+
const v = view.getInt16(offset, true);
|
|
375
|
+
return normalized ? Math.max(v / 32767, -1) : v;
|
|
376
|
+
}
|
|
377
|
+
case 5121: {
|
|
378
|
+
const v = view.getUint8(offset);
|
|
379
|
+
return normalized ? v / 255 : v;
|
|
380
|
+
}
|
|
381
|
+
case 5120: {
|
|
382
|
+
const v = view.getInt8(offset);
|
|
383
|
+
return normalized ? Math.max(v / 127, -1) : v;
|
|
384
|
+
}
|
|
385
|
+
default:
|
|
386
|
+
throw new Error(`${NAME}: strided accessor uses unsupported component type: ${componentType}`);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
360
389
|
function readStridedFloat(json, binChunk, accessorIdx) {
|
|
361
390
|
const accessor = json.accessors[accessorIdx];
|
|
362
391
|
const bufferView = json.bufferViews[accessor.bufferView];
|
|
363
|
-
|
|
364
|
-
|
|
392
|
+
const componentType = accessor.componentType;
|
|
393
|
+
const compBytes = COMPONENT_BYTES[componentType];
|
|
394
|
+
if (!compBytes) {
|
|
395
|
+
throw new Error(`${NAME}: strided accessor ${accessorIdx} uses unsupported component type: ${componentType}`);
|
|
365
396
|
}
|
|
366
397
|
const componentCount = TYPE_SIZES[accessor.type] ?? 1;
|
|
367
|
-
const elementBytes = componentCount *
|
|
398
|
+
const elementBytes = componentCount * compBytes;
|
|
368
399
|
const byteStride = bufferView.byteStride ?? elementBytes;
|
|
369
400
|
if (byteStride < elementBytes) {
|
|
370
401
|
throw new Error(`${NAME}: invalid accessor stride ${byteStride} for accessor ${accessorIdx}`);
|
|
371
402
|
}
|
|
403
|
+
const normalized = accessor.normalized === true;
|
|
372
404
|
const baseOffset = binChunk.byteOffset + (bufferView.byteOffset ?? 0) + (accessor.byteOffset ?? 0);
|
|
373
|
-
const view = new
|
|
374
|
-
const out = new
|
|
405
|
+
const view = new DV(binChunk.buffer);
|
|
406
|
+
const out = new F32(accessor.count * componentCount);
|
|
375
407
|
for (let i = 0, o = 0; i < accessor.count; i++) {
|
|
376
408
|
const src = baseOffset + i * byteStride;
|
|
377
409
|
for (let c = 0; c < componentCount; c++, o++) {
|
|
378
|
-
out[o] = view
|
|
410
|
+
out[o] = readComponent(view, src + c * compBytes, componentType, normalized);
|
|
379
411
|
}
|
|
380
412
|
}
|
|
381
413
|
return out;
|
|
@@ -406,7 +438,7 @@ const ext = {
|
|
|
406
438
|
}
|
|
407
439
|
}
|
|
408
440
|
const posAcc = gltf.accessors[attrs.POSITION];
|
|
409
|
-
const idx = primitive.indices === void 0 ? new
|
|
441
|
+
const idx = primitive.indices === void 0 ? new U32(0) : new U32(resolveAccessor(gltf, binChunk, primitive.indices)._data);
|
|
410
442
|
decoded.set(primitive, {
|
|
411
443
|
_attributes: attributes,
|
|
412
444
|
_indices: idx,
|
|
@@ -452,4 +484,4 @@ const ext = {
|
|
|
452
484
|
export {
|
|
453
485
|
ext as default
|
|
454
486
|
};
|
|
455
|
-
//# sourceMappingURL=gltf-ext-basisu-
|
|
487
|
+
//# sourceMappingURL=gltf-ext-basisu-CDbPclzZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gltf-ext-basisu-CDbPclzZ.js","sources":["../src/texture/ktx2-loader.ts","../src/loader-gltf/gltf-ext-basisu.ts"],"sourcesContent":["/** KTX2/Basis Universal decoder for glTF KHR_texture_basisu.\n *\n * Kept separate from `basis-loader.ts` so existing `.basis` texture scenes do\n * not pay for KTX2 decoder glue. The CDN decoder is still fetched lazily only\n * after an asset declares KHR_texture_basisu.\n */\n\nimport { U8C, U8 } from \"../engine/typed-arrays.js\";\nimport { TU } from \"../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport { acquireTexture, getOrCreateSampler } from \"../resource/gpu-pool.js\";\nimport type { Texture2D } from \"./texture-2d.js\";\nimport { getCompressedFormat } from \"./compressed-formats.js\";\nimport type { CompressedFormatInfo } from \"./compressed-formats.js\";\n\ninterface Ktx2DecoderCaps {\n astc: boolean;\n bptc: boolean;\n s3tc: boolean;\n pvrtc: boolean;\n etc2: boolean;\n etc1: boolean;\n}\n\ninterface Ktx2DecodedMip {\n width: number;\n height: number;\n data: Uint8Array;\n}\n\ninterface Ktx2DecodedData {\n width: number;\n height: number;\n transcodedFormat: number;\n isInGammaSpace: boolean;\n hasAlpha: boolean;\n transcoderName: string;\n errors?: string;\n mipmaps: Ktx2DecodedMip[];\n}\n\ninterface Ktx2Decoder {\n decode(data: Uint8Array, caps: Ktx2DecoderCaps, options?: { forceRGBA?: boolean }): Promise<Ktx2DecodedData>;\n}\n\ninterface Ktx2DecoderModule {\n KTX2Decoder: new () => Ktx2Decoder;\n MSCTranscoder: { UseFromWorkerThread: boolean };\n WASMMemoryManager: { LoadBinariesFromCurrentThread: boolean };\n}\n\nconst KTX2_DECODER_URL = \"https://cdn.babylonjs.com/babylon.ktx2Decoder.js\";\nlet _ktx2DecoderPromise: Promise<Ktx2Decoder> | null = null;\n\nconst GL_RGBA8 = 0x8058;\nconst GL_R8 = 0x8229;\nconst GL_RG8 = 0x822b;\nconst RGBA_CAPS: Ktx2DecoderCaps = { astc: false, bptc: false, s3tc: false, pvrtc: false, etc2: false, etc1: false };\n\nfunction loadKtx2Decoder(): Promise<Ktx2Decoder> {\n if (_ktx2DecoderPromise) {\n return _ktx2DecoderPromise;\n }\n _ktx2DecoderPromise = new Promise<Ktx2Decoder>((resolve, reject) => {\n const w = globalThis as unknown as { KTX2DECODER?: Ktx2DecoderModule };\n const init = (): void => {\n const mod = w.KTX2DECODER;\n if (!mod) {\n reject(new Error(\"KTX2: decoder global KTX2DECODER not found after script load\"));\n return;\n }\n mod.MSCTranscoder.UseFromWorkerThread = false;\n mod.WASMMemoryManager.LoadBinariesFromCurrentThread = true;\n resolve(new mod.KTX2Decoder());\n };\n if (w.KTX2DECODER) {\n init();\n return;\n }\n const script = document.createElement(\"script\");\n script.src = KTX2_DECODER_URL;\n script.async = true;\n script.onload = init;\n script.onerror = (): void => reject(new Error(`KTX2: failed to load ${script.src}`));\n document.head.appendChild(script);\n });\n _ktx2DecoderPromise.catch(() => {\n _ktx2DecoderPromise = null;\n });\n return _ktx2DecoderPromise;\n}\n\nfunction srgbFormat(format: GPUTextureFormat): GPUTextureFormat {\n switch (format) {\n case \"rgba8unorm\":\n return \"rgba8unorm-srgb\";\n case \"bc1-rgba-unorm\":\n return \"bc1-rgba-unorm-srgb\";\n case \"bc2-rgba-unorm\":\n return \"bc2-rgba-unorm-srgb\";\n case \"bc3-rgba-unorm\":\n return \"bc3-rgba-unorm-srgb\";\n case \"bc7-rgba-unorm\":\n return \"bc7-rgba-unorm-srgb\";\n case \"etc2-rgb8unorm\":\n return \"etc2-rgb8unorm-srgb\";\n case \"etc2-rgb8a1unorm\":\n return \"etc2-rgb8a1unorm-srgb\";\n case \"etc2-rgba8unorm\":\n return \"etc2-rgba8unorm-srgb\";\n case \"astc-4x4-unorm\":\n return \"astc-4x4-unorm-srgb\";\n case \"astc-5x4-unorm\":\n return \"astc-5x4-unorm-srgb\";\n case \"astc-5x5-unorm\":\n return \"astc-5x5-unorm-srgb\";\n case \"astc-6x5-unorm\":\n return \"astc-6x5-unorm-srgb\";\n case \"astc-6x6-unorm\":\n return \"astc-6x6-unorm-srgb\";\n case \"astc-8x5-unorm\":\n return \"astc-8x5-unorm-srgb\";\n case \"astc-8x6-unorm\":\n return \"astc-8x6-unorm-srgb\";\n case \"astc-8x8-unorm\":\n return \"astc-8x8-unorm-srgb\";\n case \"astc-10x5-unorm\":\n return \"astc-10x5-unorm-srgb\";\n case \"astc-10x6-unorm\":\n return \"astc-10x6-unorm-srgb\";\n case \"astc-10x8-unorm\":\n return \"astc-10x8-unorm-srgb\";\n case \"astc-10x10-unorm\":\n return \"astc-10x10-unorm-srgb\";\n case \"astc-12x10-unorm\":\n return \"astc-12x10-unorm-srgb\";\n case \"astc-12x12-unorm\":\n return \"astc-12x12-unorm-srgb\";\n default:\n return format;\n }\n}\n\nfunction uncompressedInfo(glFormat: number): { format: GPUTextureFormat; bytesPerPixel: number } | null {\n switch (glFormat) {\n case GL_RGBA8:\n return { format: \"rgba8unorm\", bytesPerPixel: 4 };\n case GL_R8:\n return { format: \"r8unorm\", bytesPerPixel: 1 };\n case GL_RG8:\n return { format: \"rg8unorm\", bytesPerPixel: 2 };\n default:\n return null;\n }\n}\n\nfunction validateDecoded(decoded: Ktx2DecodedData): Ktx2DecodedMip[] {\n if (decoded.errors) {\n throw new Error(`KTX2: ${decoded.errors}`);\n }\n if (!decoded.mipmaps.length) {\n throw new Error(\"KTX2: decoder produced no mipmaps\");\n }\n for (let i = 0; i < decoded.mipmaps.length; i++) {\n if (!decoded.mipmaps[i]?.data) {\n throw new Error(`KTX2: decoder produced an empty mip ${i}`);\n }\n }\n return decoded.mipmaps;\n}\n\nfunction makeSampler(engine: EngineContext, mipCount: number): GPUSampler {\n return getOrCreateSampler(engine, {\n addressModeU: \"repeat\",\n addressModeV: \"repeat\",\n minFilter: \"linear\",\n magFilter: \"linear\",\n mipmapFilter: mipCount > 1 ? \"linear\" : \"nearest\",\n maxAnisotropy: mipCount > 1 ? 4 : 1,\n });\n}\n\nfunction uploadCompressed(engine: EngineContext, mips: Ktx2DecodedMip[], format: CompressedFormatInfo, sRGB: boolean): Texture2D {\n if (!engine._device.features.has(format.feature as GPUFeatureName)) {\n throw new Error(`KTX2: device does not support ${format.feature}`);\n }\n const width = mips[0]!.width;\n const height = mips[0]!.height;\n const texture = engine._device.createTexture({\n size: { width, height },\n format: sRGB ? srgbFormat(format.gpuFormat) : format.gpuFormat,\n mipLevelCount: mips.length,\n usage: TU.TEXTURE_BINDING | TU.COPY_DST,\n });\n for (let level = 0; level < mips.length; level++) {\n const mip = mips[level]!;\n const blocksPerRow = Math.ceil(mip.width / format.blockW);\n const rowBytes = blocksPerRow * format.blockBytes;\n // Copy extent must be block-padded (physical) size; tail mips smaller\n // than the block are copied as one full block (see ktx-loader.ts).\n const copyW = blocksPerRow * format.blockW;\n const copyH = Math.ceil(mip.height / format.blockH) * format.blockH;\n engine._device.queue.writeTexture({ texture, mipLevel: level }, mip.data as Uint8Array<ArrayBuffer>, { bytesPerRow: rowBytes }, { width: copyW, height: copyH });\n }\n const tex2d: Texture2D = { texture, view: texture.createView(), sampler: makeSampler(engine, mips.length), width, height, invertY: true };\n acquireTexture(tex2d);\n return tex2d;\n}\n\nfunction uploadUncompressed(engine: EngineContext, mips: Ktx2DecodedMip[], info: { format: GPUTextureFormat; bytesPerPixel: number }, sRGB: boolean): Texture2D {\n const width = mips[0]!.width;\n const height = mips[0]!.height;\n const texture = engine._device.createTexture({\n size: { width, height },\n format: sRGB ? srgbFormat(info.format) : info.format,\n mipLevelCount: mips.length,\n usage: TU.TEXTURE_BINDING | TU.COPY_DST,\n });\n for (let level = 0; level < mips.length; level++) {\n const mip = mips[level]!;\n const expected = mip.width * mip.height * info.bytesPerPixel;\n if (mip.data.length !== expected) {\n throw new Error(`KTX2: uncompressed mip ${level} has ${mip.data.length} bytes, expected ${expected}`);\n }\n engine._device.queue.writeTexture(\n { texture, mipLevel: level },\n mip.data as Uint8Array<ArrayBuffer>,\n { bytesPerRow: mip.width * info.bytesPerPixel },\n { width: mip.width, height: mip.height }\n );\n }\n const tex2d: Texture2D = { texture, view: texture.createView(), sampler: makeSampler(engine, mips.length), width, height, invertY: true };\n acquireTexture(tex2d);\n return tex2d;\n}\n\n/** Decode a KTX2 texture with the current WebGPU compression caps and upload the\n * decoder-provided full mip chain directly to a Texture2D. */\nexport async function uploadKtx2Texture2D(engine: EngineContext, buffer: ArrayBuffer, sRGB: boolean): Promise<Texture2D> {\n const decoder = await loadKtx2Decoder();\n const decoded = await decoder.decode(new U8(buffer), RGBA_CAPS, { forceRGBA: true });\n const mips = validateDecoded(decoded);\n\n const compressed = getCompressedFormat(decoded.transcodedFormat);\n if (compressed) {\n return uploadCompressed(engine, mips, compressed, sRGB);\n }\n\n const uncompressed = uncompressedInfo(decoded.transcodedFormat);\n if (uncompressed) {\n return uploadUncompressed(engine, mips, uncompressed, sRGB);\n }\n\n throw new Error(`KTX2: unsupported transcoded format 0x${decoded.transcodedFormat.toString(16)}`);\n}\n\n/** Decode the first mip level of a KTX2 texture into an ImageBitmap so glTF\n * material extensions can reuse the core image upload path. */\nexport async function decodeKtx2ImageBitmapFromBuffer(buffer: ArrayBuffer): Promise<ImageBitmap> {\n const decoder = await loadKtx2Decoder();\n const decoded = await decoder.decode(new U8(buffer), RGBA_CAPS, { forceRGBA: true });\n const mip0 = validateDecoded(decoded)[0]!;\n if (mip0.data.length !== mip0.width * mip0.height * 4) {\n throw new Error(\"KTX2: RGBA decode size does not match image dimensions\");\n }\n const pixels = new U8C(mip0.data.length);\n pixels.set(mip0.data);\n return createImageBitmap(new ImageData(pixels, mip0.width, mip0.height));\n}\n","/** KHR_texture_basisu glTF texture-source extension.\n *\n * The extension redirects textureInfos whose glTF texture declares\n * `extensions.KHR_texture_basisu.source` to the referenced KTX2 image and\n * uploads it through the lazily fetched KTX2 decoder. Core glTF\n * material parsing remains extension-agnostic: this module only loads when the\n * asset lists KHR_texture_basisu in `extensionsUsed`.\n */\n\nimport { F32, U32, U8, DV } from \"../engine/typed-arrays.js\";\nimport type { GltfMatExtCtx } from \"./gltf-material.js\";\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport type { DecodedPrimitive } from \"./gltf-feature.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport { resolveAccessor } from \"./gltf-parser.js\";\nimport { decodeKtx2ImageBitmapFromBuffer, uploadKtx2Texture2D } from \"../texture/ktx2-loader.js\";\n\nconst NAME = \"KHR_texture_basisu\";\nconst FLOAT = 5126;\n// glTF accessor component types → byte size. Interleaved (strided) vertex attributes can be any of these,\n// not just FLOAT (e.g. a normalized `COLOR_0: UNSIGNED_BYTE`), so the strided reader must handle them all.\nconst COMPONENT_BYTES: Record<number, number> = { 5120: 1, 5121: 1, 5122: 2, 5123: 2, 5125: 4, 5126: 4 };\nconst TYPE_SIZES: Record<string, number> = {\n SCALAR: 1,\n VEC2: 2,\n VEC3: 3,\n VEC4: 4,\n MAT2: 4,\n MAT3: 9,\n MAT4: 16,\n};\nconst BASISU_MATERIAL_DATA = \"__basisuMaterialData\";\n\ninterface BasisuMaterialData {\n json: any;\n binChunk: DataView;\n baseUrl: string;\n baseColorTexture?: any;\n metallicRoughnessTexture?: any;\n normalTexture?: any;\n occlusionTexture?: any;\n emissiveTexture?: any;\n specularTexture?: any;\n specularColorTexture?: any;\n bitmaps?: Map<number, Promise<ImageBitmap>>;\n textures?: Map<string, Texture2D>;\n}\n\nfunction basisSourceIndex(tex: unknown): number | null {\n const source = (tex as { extensions?: { KHR_texture_basisu?: { source?: unknown } } } | undefined)?.extensions?.KHR_texture_basisu?.source;\n return typeof source === \"number\" ? source : null;\n}\n\nfunction textureIndex(texInfo: unknown): number | null {\n const index = (texInfo as { index?: unknown } | undefined)?.index;\n return typeof index === \"number\" ? index : null;\n}\n\nfunction textureUsesBasisu(json: any, texInfo: unknown): boolean {\n const index = textureIndex(texInfo);\n return index !== null && basisSourceIndex(json.textures?.[index]) !== null;\n}\n\nfunction stripBasisuTexture(json: any, owner: any, slot: keyof BasisuMaterialData, data: BasisuMaterialData): boolean {\n if (!textureUsesBasisu(json, owner?.[slot])) {\n return false;\n }\n data[slot] = owner[slot];\n delete owner[slot];\n return true;\n}\n\nfunction prepareBasisuMaterials(json: any, binChunk: DataView, baseUrl: string): void {\n for (const mat of json.materials ?? []) {\n const data: BasisuMaterialData = { json, binChunk, baseUrl };\n const pbr = mat.pbrMetallicRoughness ?? {};\n let hasBasisu = stripBasisuTexture(json, pbr, \"baseColorTexture\", data);\n hasBasisu = stripBasisuTexture(json, pbr, \"metallicRoughnessTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"normalTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"occlusionTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"emissiveTexture\", data) || hasBasisu;\n const spec = mat.extensions?.KHR_materials_specular;\n if (spec) {\n hasBasisu = stripBasisuTexture(json, spec, \"specularTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, spec, \"specularColorTexture\", data) || hasBasisu;\n }\n if (hasBasisu) {\n Object.defineProperty(mat, BASISU_MATERIAL_DATA, { value: data });\n }\n }\n}\n\nasync function resolveImageBuffer(ctx: BasisuMaterialData, imageIdx: number): Promise<ArrayBuffer> {\n const image = ctx.json.images?.[imageIdx];\n if (!image) {\n throw new Error(`${NAME}: image ${imageIdx} not found`);\n }\n if (image.bufferView !== undefined) {\n const bv = ctx.json.bufferViews?.[image.bufferView];\n if (!bv) {\n throw new Error(`${NAME}: bufferView ${image.bufferView} not found`);\n }\n const offset = ctx.binChunk.byteOffset + (bv.byteOffset ?? 0);\n const copy = new U8(bv.byteLength);\n copy.set(new U8(ctx.binChunk.buffer, offset, bv.byteLength));\n return copy.buffer;\n }\n if (image.uri) {\n const url = new URL(image.uri, ctx.baseUrl + \"x\").href;\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${NAME}: failed to load image ${response.status} ${response.statusText}`);\n }\n return response.arrayBuffer();\n }\n throw new Error(`${NAME}: image has neither bufferView nor uri`);\n}\n\nasync function loadBasisuBitmap(data: BasisuMaterialData, texInfo: unknown): Promise<ImageBitmap | null> {\n const index = textureIndex(texInfo);\n if (index === null) {\n return null;\n }\n const source = basisSourceIndex(data.json.textures?.[index]);\n if (source === null) {\n return null;\n }\n data.bitmaps ??= new Map();\n let bitmap = data.bitmaps.get(index);\n if (!bitmap) {\n bitmap = resolveImageBuffer(data, source).then(decodeKtx2ImageBitmapFromBuffer);\n data.bitmaps.set(index, bitmap);\n }\n return bitmap;\n}\n\nasync function uploadBasisuTexture(data: BasisuMaterialData, ctx: GltfMatExtCtx, texInfo: unknown, sRGB: boolean): Promise<Texture2D | undefined> {\n const index = textureIndex(texInfo);\n if (index === null) {\n return undefined;\n }\n data.textures ??= new Map();\n const key = `${index}:${sRGB ? 1 : 0}`;\n let tex = data.textures.get(key);\n if (!tex) {\n const source = basisSourceIndex(data.json.textures?.[index]);\n if (source === null) {\n return undefined;\n }\n tex = await uploadKtx2Texture2D(ctx._engine, await resolveImageBuffer(data, source), sRGB);\n data.textures.set(key, tex);\n }\n return tex;\n}\n\nasync function compositeOrm(mr: ImageBitmap, occ: ImageBitmap): Promise<ImageBitmap> {\n const w = mr.width;\n const h = mr.height;\n const c1 = new OffscreenCanvas(w, h);\n const x1 = c1.getContext(\"2d\")!;\n x1.drawImage(mr, 0, 0, w, h);\n const d1 = x1.getImageData(0, 0, w, h);\n const c2 = new OffscreenCanvas(w, h);\n const x2 = c2.getContext(\"2d\")!;\n x2.drawImage(occ, 0, 0, w, h);\n const d2 = x2.getImageData(0, 0, w, h);\n for (let j = 0; j < d1.data.length; j += 4) {\n d1.data[j] = d2.data[j]!;\n }\n x1.putImageData(d1, 0, 0);\n return createImageBitmap(c1);\n}\n\nasync function uploadOrmTexture(data: BasisuMaterialData, ctx: GltfMatExtCtx): Promise<Texture2D | undefined> {\n const mrInfo = data.metallicRoughnessTexture;\n const occInfo = data.occlusionTexture;\n const mrIndex = textureIndex(mrInfo);\n const occIndex = textureIndex(occInfo);\n if (mrIndex === null && occIndex === null) {\n return undefined;\n }\n if (mrIndex === null || occIndex === null || mrIndex === occIndex) {\n return uploadBasisuTexture(data, ctx, mrInfo ?? occInfo, false);\n }\n data.textures ??= new Map();\n const key = `orm:${mrIndex}:${occIndex}`;\n let tex = data.textures.get(key);\n if (!tex) {\n const [mr, occ] = await Promise.all([loadBasisuBitmap(data, mrInfo), loadBasisuBitmap(data, occInfo)]);\n if (!mr || !occ) {\n return undefined;\n }\n tex = ctx._uploadImage(await compositeOrm(mr, occ), false);\n data.textures.set(key, tex);\n }\n return tex;\n}\n\n// Read one interleaved attribute component, decoding its glTF component type to a float. NORMALIZED integer\n// attributes (the `normalized` accessor flag) map to [0,1] (unsigned) or [-1,1] (signed); non-normalized ones\n// pass through as their integer value. DataView handles unaligned little-endian reads, so any stride is fine.\nfunction readComponent(view: DataView, offset: number, componentType: number, normalized: boolean): number {\n switch (componentType) {\n case FLOAT:\n return view.getFloat32(offset, true);\n case 5125: {\n const v = view.getUint32(offset, true);\n return normalized ? v / 4294967295 : v;\n }\n case 5123: {\n const v = view.getUint16(offset, true);\n return normalized ? v / 65535 : v;\n }\n case 5122: {\n const v = view.getInt16(offset, true);\n return normalized ? Math.max(v / 32767, -1) : v;\n }\n case 5121: {\n const v = view.getUint8(offset);\n return normalized ? v / 255 : v;\n }\n case 5120: {\n const v = view.getInt8(offset);\n return normalized ? Math.max(v / 127, -1) : v;\n }\n default:\n throw new Error(`${NAME}: strided accessor uses unsupported component type: ${componentType}`);\n }\n}\n\nfunction readStridedFloat(json: any, binChunk: DataView, accessorIdx: number): Float32Array {\n const accessor = json.accessors[accessorIdx];\n const bufferView = json.bufferViews[accessor.bufferView];\n const componentType = accessor.componentType;\n const compBytes = COMPONENT_BYTES[componentType];\n if (!compBytes) {\n throw new Error(`${NAME}: strided accessor ${accessorIdx} uses unsupported component type: ${componentType}`);\n }\n const componentCount = TYPE_SIZES[accessor.type] ?? 1;\n const elementBytes = componentCount * compBytes;\n const byteStride = bufferView.byteStride ?? elementBytes;\n if (byteStride < elementBytes) {\n throw new Error(`${NAME}: invalid accessor stride ${byteStride} for accessor ${accessorIdx}`);\n }\n const normalized = accessor.normalized === true;\n const baseOffset = binChunk.byteOffset + (bufferView.byteOffset ?? 0) + (accessor.byteOffset ?? 0);\n const view = new DV(binChunk.buffer);\n const out = new F32(accessor.count * componentCount);\n for (let i = 0, o = 0; i < accessor.count; i++) {\n const src = baseOffset + i * byteStride;\n for (let c = 0; c < componentCount; c++, o++) {\n out[o] = readComponent(view, src + c * compBytes, componentType, normalized);\n }\n }\n return out;\n}\n\nconst ext: GltfFeature = {\n id: NAME,\n async preMesh(json, binChunk, baseUrl) {\n const gltf = json as any;\n prepareBasisuMaterials(gltf, binChunk, baseUrl);\n const decoded = new Map<unknown, DecodedPrimitive>();\n for (const mesh of gltf.meshes ?? []) {\n for (const primitive of mesh.primitives ?? []) {\n const attrs = primitive.attributes ?? {};\n const strided = Object.keys(attrs).some((name) => gltf.bufferViews?.[gltf.accessors?.[attrs[name]]?.bufferView]?.byteStride !== undefined);\n if (!strided) {\n continue;\n }\n const attributes = new Map<string, Float32Array>();\n for (const name of Object.keys(attrs)) {\n const accessorIdx = attrs[name];\n const accessor = gltf.accessors[accessorIdx];\n if (gltf.bufferViews?.[accessor.bufferView]?.byteStride !== undefined) {\n attributes.set(name, readStridedFloat(gltf, binChunk, accessorIdx));\n }\n }\n const posAcc = gltf.accessors[attrs.POSITION];\n const idx =\n primitive.indices === undefined ? new U32(0) : new U32(resolveAccessor(gltf, binChunk, primitive.indices)._data as Uint16Array | Uint32Array | Uint8Array);\n decoded.set(primitive, {\n _attributes: attributes,\n _indices: idx,\n _vertexCount: posAcc.count,\n _indexCount: idx.length,\n });\n }\n }\n return decoded;\n },\n async applyMaterial(mat, ctx) {\n const data = mat._rawMatDef?.[BASISU_MATERIAL_DATA] as BasisuMaterialData | undefined;\n if (!data) {\n return null;\n }\n const [baseColorTexture, ormTexture, normalTexture, emissiveTexture, specularTexture, specularColorTexture] = await Promise.all([\n uploadBasisuTexture(data, ctx, data.baseColorTexture, true),\n uploadOrmTexture(data, ctx),\n uploadBasisuTexture(data, ctx, data.normalTexture, false),\n uploadBasisuTexture(data, ctx, data.emissiveTexture, true),\n uploadBasisuTexture(data, ctx, data.specularTexture, false),\n uploadBasisuTexture(data, ctx, data.specularColorTexture, true),\n ]);\n const out: Partial<PbrMaterialProps> = {\n ...(baseColorTexture ? { baseColorTexture } : undefined),\n ...(ormTexture\n ? {\n ormTexture,\n ...(data.metallicRoughnessTexture ? { metallicFactor: mat._metallicFactor, roughnessFactor: mat._roughnessFactor } : undefined),\n ...(data.occlusionTexture ? { occlusionStrength: 1.0, occlusionTexCoord: data.occlusionTexture.texCoord ?? 0 } : undefined),\n }\n : undefined),\n ...(normalTexture ? { normalTexture, normalTextureScale: data.normalTexture?.scale ?? 1 } : undefined),\n ...(emissiveTexture ? { emissiveTexture } : undefined),\n ...(specularTexture ? { metallicReflectanceTexture: specularTexture, useOnlyMetallicFromMetallicReflectanceTexture: true } : undefined),\n ...(specularColorTexture ? { reflectanceTexture: specularColorTexture } : undefined),\n };\n if (!out.baseColorTexture && !out.ormTexture && !out.normalTexture && !out.emissiveTexture && !out.metallicReflectanceTexture && !out.reflectanceTexture) {\n return null;\n }\n return out;\n },\n};\n\nexport default ext;\n"],"names":["_b","_a"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b9 as setSubtreeVisible } from "./index-CLElg2Bo.js";
|
|
2
2
|
function applyVisibility(json, nodeMap) {
|
|
3
3
|
var _a, _b, _c;
|
|
4
4
|
const nodes = json.nodes ?? [];
|
|
@@ -22,4 +22,4 @@ const ext = {
|
|
|
22
22
|
export {
|
|
23
23
|
ext as default
|
|
24
24
|
};
|
|
25
|
-
//# sourceMappingURL=gltf-ext-node-visibility-
|
|
25
|
+
//# sourceMappingURL=gltf-ext-node-visibility-DXCJEYr6.js.map
|
package/{gltf-ext-node-visibility-BjRRd6si.js.map → gltf-ext-node-visibility-DXCJEYr6.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gltf-ext-node-visibility-
|
|
1
|
+
{"version":3,"file":"gltf-ext-node-visibility-DXCJEYr6.js","sources":["../src/loader-gltf/gltf-ext-node-visibility.ts"],"sourcesContent":["/** glTF KHR_node_visibility extension.\n *\n * Sets `node.visible = false` on SceneNodes whose glTF node has\n * `extensions.KHR_node_visibility.visible === false`, and cascades\n * through the subtree via `setSubtreeVisible` so that descendants\n * inherit the invisibility per the extension spec. The render path\n * and camera-AABB filter then skip them. Combined with\n * KHR_animation_pointer, the visible flag can also be toggled at runtime.\n *\n * Dynamically imported by load-gltf only when the asset declares the\n * extension in `extensionsUsed`, so bundles pay zero bytes otherwise. */\n\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport type { SceneNode } from \"../scene/scene-node.js\";\nimport { setSubtreeVisible } from \"../scene/visibility.js\";\n\nfunction applyVisibility(json: any, nodeMap: readonly (SceneNode | undefined)[]): void {\n const nodes = json.nodes ?? [];\n for (let i = 0; i < nodes.length; i++) {\n const vis = nodes[i]?.extensions?.KHR_node_visibility?.visible;\n const sn = nodeMap[i];\n if (vis === false && sn) {\n setSubtreeVisible(sn, false);\n }\n }\n}\n\nconst ext: GltfFeature = {\n id: \"KHR_node_visibility\",\n async applyAsset(_meshes, _root, ctx) {\n if (ctx._nodeMap) {\n applyVisibility(ctx._json, ctx._nodeMap);\n }\n return {};\n },\n};\nexport default ext;\n"],"names":[],"mappings":";AAgBA,SAAS,gBAAgB,MAAW,SAAmD;;AACnF,QAAM,QAAQ,KAAK,SAAS,CAAA;AAC5B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,UAAM,OAAM,uBAAM,CAAC,MAAP,mBAAU,eAAV,mBAAsB,wBAAtB,mBAA2C;AACvD,UAAM,KAAK,QAAQ,CAAC;AACpB,QAAI,QAAQ,SAAS,IAAI;AACrB,wBAAkB,IAAI,KAAK;AAAA,IAC/B;AAAA,EACJ;AACJ;AAEA,MAAM,MAAmB;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM,WAAW,SAAS,OAAO,KAAK;AAClC,QAAI,IAAI,UAAU;AACd,sBAAgB,IAAI,OAAO,IAAI,QAAQ;AAAA,IAC3C;AACA,WAAO,CAAA;AAAA,EACX;AACJ;"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { e as U8, D as DV } from "./index-CLElg2Bo.js";
|
|
1
2
|
const BYTE = 5120;
|
|
2
3
|
const UNSIGNED_BYTE = 5121;
|
|
3
4
|
const SHORT = 5122;
|
|
@@ -59,8 +60,8 @@ const feature = {
|
|
|
59
60
|
}
|
|
60
61
|
const baseLen = align4(binChunk.byteLength);
|
|
61
62
|
const out = new ArrayBuffer(baseLen + appended);
|
|
62
|
-
new
|
|
63
|
-
const outView = new
|
|
63
|
+
new U8(out).set(new U8(binChunk.buffer, binChunk.byteOffset, binChunk.byteLength));
|
|
64
|
+
const outView = new DV(out);
|
|
64
65
|
let cursor = baseLen;
|
|
65
66
|
for (const i of convert) {
|
|
66
67
|
const a = accessors[i];
|
|
@@ -91,4 +92,4 @@ const feature = {
|
|
|
91
92
|
export {
|
|
92
93
|
feature as default
|
|
93
94
|
};
|
|
94
|
-
//# sourceMappingURL=gltf-ext-quantization-
|
|
95
|
+
//# sourceMappingURL=gltf-ext-quantization-CvHI_0Vg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gltf-ext-quantization-CvHI_0Vg.js","sources":["../src/loader-gltf/gltf-ext-quantization.ts"],"sourcesContent":["/**\n * KHR_mesh_quantization (+ post-meshopt) dequantization feature.\n *\n * Runs as a `preParse` hook, after EXT_meshopt_compression. The core accessor\n * reader (`resolveAccessor`) only understands tightly-packed FLOAT / UBYTE /\n * USHORT / UINT data and ignores `byteStride`; quantized assets store vertex\n * attributes (and meshopt-filtered animation outputs) as normalized or signed\n * integers, sometimes padded by a `byteStride`. This feature rewrites every such\n * accessor into a freshly-appended, tightly-packed FLOAT bufferView so the rest\n * of the loader stays completely unaware of quantization. It is dynamic-imported\n * only when `extensionsUsed` lists KHR_mesh_quantization, so non-quantized scenes\n * pay nothing.\n *\n * Conversion rule (role-agnostic, derived from the accessor alone):\n * - signed component types (BYTE/SHORT) → FLOAT (core would otherwise throw)\n * - `normalized` accessors → FLOAT (core would otherwise read raw ints)\n * - strided FLOAT accessors → tightly-packed FLOAT (core ignores byteStride)\n * Unsigned non-normalized integer accessors (JOINTS_0, indices) are left intact:\n * they are already tight and the skeleton / index paths expect integers.\n */\n\nimport { U8, DV } from \"../engine/typed-arrays.js\";\nimport type { GltfFeature } from \"./gltf-feature.js\";\n\nconst BYTE = 5120;\nconst UNSIGNED_BYTE = 5121;\nconst SHORT = 5122;\nconst UNSIGNED_SHORT = 5123;\nconst FLOAT = 5126;\n\nconst TYPE_COMPONENTS: Record<string, number> = { SCALAR: 1, VEC2: 2, VEC3: 3, VEC4: 4, MAT2: 4, MAT3: 9, MAT4: 16 };\nconst COMPONENT_BYTES: Record<number, number> = { 5120: 1, 5121: 1, 5122: 2, 5123: 2, 5125: 4, 5126: 4 };\n\ninterface Accessor {\n bufferView?: number;\n byteOffset?: number;\n componentType: number;\n normalized?: boolean;\n count: number;\n type: string;\n}\n\ninterface BufferView {\n buffer?: number;\n byteOffset?: number;\n byteLength: number;\n byteStride?: number;\n}\n\nfunction align4(n: number): number {\n return (n + 3) & ~3;\n}\n\n/** Read one component as a float, applying glTF normalization when requested. */\nfunction readComponent(view: DataView, offset: number, componentType: number, normalized: boolean): number {\n switch (componentType) {\n case BYTE: {\n const c = view.getInt8(offset);\n return normalized ? Math.max(c / 127, -1) : c;\n }\n case UNSIGNED_BYTE: {\n const c = view.getUint8(offset);\n return normalized ? c / 255 : c;\n }\n case SHORT: {\n const c = view.getInt16(offset, true);\n return normalized ? Math.max(c / 32767, -1) : c;\n }\n case UNSIGNED_SHORT: {\n const c = view.getUint16(offset, true);\n return normalized ? c / 65535 : c;\n }\n case FLOAT:\n return view.getFloat32(offset, true);\n default:\n throw new Error(`KHR_mesh_quantization: unsupported componentType ${componentType}`);\n }\n}\n\nconst feature: GltfFeature = {\n id: \"KHR_mesh_quantization\",\n async preParse(json, binChunk) {\n const accessors: Accessor[] = json.accessors ?? [];\n const bufferViews: BufferView[] = json.bufferViews ?? [];\n\n // Decide which accessors need rewriting and how many float bytes to append.\n const convert: number[] = [];\n let appended = 0;\n for (let i = 0; i < accessors.length; i++) {\n const a = accessors[i]!;\n if (a.bufferView === undefined) {\n continue;\n }\n const componentCount = TYPE_COMPONENTS[a.type] ?? 1;\n const stride = bufferViews[a.bufferView]?.byteStride;\n const signed = a.componentType === BYTE || a.componentType === SHORT;\n const stridedFloat = a.componentType === FLOAT && stride !== undefined && stride !== componentCount * 4;\n if (signed || a.normalized === true || stridedFloat) {\n convert.push(i);\n appended = align4(appended + a.count * componentCount * 4);\n }\n }\n\n if (convert.length === 0) {\n return;\n }\n\n // Build a new buffer: existing data (normalized to offset 0) + appended floats.\n const baseLen = align4(binChunk.byteLength);\n const out = new ArrayBuffer(baseLen + appended);\n new U8(out).set(new U8(binChunk.buffer, binChunk.byteOffset, binChunk.byteLength));\n const outView = new DV(out);\n\n let cursor = baseLen;\n for (const i of convert) {\n const a = accessors[i]!;\n const bv = bufferViews[a.bufferView!]!;\n const componentCount = TYPE_COMPONENTS[a.type] ?? 1;\n const compBytes = COMPONENT_BYTES[a.componentType]!;\n const stride = bv.byteStride ?? componentCount * compBytes;\n // bufferView/accessor byteOffsets are relative to the DataView's own\n // byteOffset (DataView getters add it back), matching resolveAccessor.\n const srcBase = (bv.byteOffset ?? 0) + (a.byteOffset ?? 0);\n\n const dstOffset = cursor;\n for (let v = 0; v < a.count; v++) {\n for (let c = 0; c < componentCount; c++) {\n const value = readComponent(binChunk, srcBase + v * stride + c * compBytes, a.componentType, !!a.normalized);\n outView.setFloat32(dstOffset + (v * componentCount + c) * 4, value, true);\n }\n }\n\n const byteLength = a.count * componentCount * 4;\n const newBvIndex = bufferViews.length;\n bufferViews.push({ buffer: 0, byteOffset: dstOffset, byteLength });\n a.bufferView = newBvIndex;\n a.byteOffset = 0;\n a.componentType = FLOAT;\n a.normalized = false;\n cursor = align4(cursor + byteLength);\n }\n\n return outView;\n },\n};\n\nexport default feature;\n"],"names":[],"mappings":";AAwBA,MAAM,OAAO;AACb,MAAM,gBAAgB;AACtB,MAAM,QAAQ;AACd,MAAM,iBAAiB;AACvB,MAAM,QAAQ;AAEd,MAAM,kBAA0C,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAA;AAChH,MAAM,kBAA0C,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAAA;AAkBrG,SAAS,OAAO,GAAmB;AAC/B,SAAQ,IAAI,IAAK;AACrB;AAGA,SAAS,cAAc,MAAgB,QAAgB,eAAuB,YAA6B;AACvG,UAAQ,eAAA;AAAA,IACJ,KAAK,MAAM;AACP,YAAM,IAAI,KAAK,QAAQ,MAAM;AAC7B,aAAO,aAAa,KAAK,IAAI,IAAI,KAAK,EAAE,IAAI;AAAA,IAChD;AAAA,IACA,KAAK,eAAe;AAChB,YAAM,IAAI,KAAK,SAAS,MAAM;AAC9B,aAAO,aAAa,IAAI,MAAM;AAAA,IAClC;AAAA,IACA,KAAK,OAAO;AACR,YAAM,IAAI,KAAK,SAAS,QAAQ,IAAI;AACpC,aAAO,aAAa,KAAK,IAAI,IAAI,OAAO,EAAE,IAAI;AAAA,IAClD;AAAA,IACA,KAAK,gBAAgB;AACjB,YAAM,IAAI,KAAK,UAAU,QAAQ,IAAI;AACrC,aAAO,aAAa,IAAI,QAAQ;AAAA,IACpC;AAAA,IACA,KAAK;AACD,aAAO,KAAK,WAAW,QAAQ,IAAI;AAAA,IACvC;AACI,YAAM,IAAI,MAAM,oDAAoD,aAAa,EAAE;AAAA,EAAA;AAE/F;AAEA,MAAM,UAAuB;AAAA,EACzB,IAAI;AAAA,EACJ,MAAM,SAAS,MAAM,UAAU;;AAC3B,UAAM,YAAwB,KAAK,aAAa,CAAA;AAChD,UAAM,cAA4B,KAAK,eAAe,CAAA;AAGtD,UAAM,UAAoB,CAAA;AAC1B,QAAI,WAAW;AACf,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACvC,YAAM,IAAI,UAAU,CAAC;AACrB,UAAI,EAAE,eAAe,QAAW;AAC5B;AAAA,MACJ;AACA,YAAM,iBAAiB,gBAAgB,EAAE,IAAI,KAAK;AAClD,YAAM,UAAS,iBAAY,EAAE,UAAU,MAAxB,mBAA2B;AAC1C,YAAM,SAAS,EAAE,kBAAkB,QAAQ,EAAE,kBAAkB;AAC/D,YAAM,eAAe,EAAE,kBAAkB,SAAS,WAAW,UAAa,WAAW,iBAAiB;AACtG,UAAI,UAAU,EAAE,eAAe,QAAQ,cAAc;AACjD,gBAAQ,KAAK,CAAC;AACd,mBAAW,OAAO,WAAW,EAAE,QAAQ,iBAAiB,CAAC;AAAA,MAC7D;AAAA,IACJ;AAEA,QAAI,QAAQ,WAAW,GAAG;AACtB;AAAA,IACJ;AAGA,UAAM,UAAU,OAAO,SAAS,UAAU;AAC1C,UAAM,MAAM,IAAI,YAAY,UAAU,QAAQ;AAC9C,QAAI,GAAG,GAAG,EAAE,IAAI,IAAI,GAAG,SAAS,QAAQ,SAAS,YAAY,SAAS,UAAU,CAAC;AACjF,UAAM,UAAU,IAAI,GAAG,GAAG;AAE1B,QAAI,SAAS;AACb,eAAW,KAAK,SAAS;AACrB,YAAM,IAAI,UAAU,CAAC;AACrB,YAAM,KAAK,YAAY,EAAE,UAAW;AACpC,YAAM,iBAAiB,gBAAgB,EAAE,IAAI,KAAK;AAClD,YAAM,YAAY,gBAAgB,EAAE,aAAa;AACjD,YAAM,SAAS,GAAG,cAAc,iBAAiB;AAGjD,YAAM,WAAW,GAAG,cAAc,MAAM,EAAE,cAAc;AAExD,YAAM,YAAY;AAClB,eAAS,IAAI,GAAG,IAAI,EAAE,OAAO,KAAK;AAC9B,iBAAS,IAAI,GAAG,IAAI,gBAAgB,KAAK;AACrC,gBAAM,QAAQ,cAAc,UAAU,UAAU,IAAI,SAAS,IAAI,WAAW,EAAE,eAAe,CAAC,CAAC,EAAE,UAAU;AAC3G,kBAAQ,WAAW,aAAa,IAAI,iBAAiB,KAAK,GAAG,OAAO,IAAI;AAAA,QAC5E;AAAA,MACJ;AAEA,YAAM,aAAa,EAAE,QAAQ,iBAAiB;AAC9C,YAAM,aAAa,YAAY;AAC/B,kBAAY,KAAK,EAAE,QAAQ,GAAG,YAAY,WAAW,YAAY;AACjE,QAAE,aAAa;AACf,QAAE,aAAa;AACf,QAAE,gBAAgB;AAClB,QAAE,aAAa;AACf,eAAS,OAAO,SAAS,UAAU;AAAA,IACvC;AAEA,WAAO;AAAA,EACX;AACJ;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { v as cloneTexture2D } from "./index-CLElg2Bo.js";
|
|
2
2
|
const ext = {
|
|
3
3
|
id: "KHR_texture_transform",
|
|
4
4
|
wrapTexture(tex, texInfo) {
|
|
@@ -35,4 +35,4 @@ const ext = {
|
|
|
35
35
|
export {
|
|
36
36
|
ext as default
|
|
37
37
|
};
|
|
38
|
-
//# sourceMappingURL=gltf-ext-uv-transform-
|
|
38
|
+
//# sourceMappingURL=gltf-ext-uv-transform-DgYazJBs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gltf-ext-uv-transform-
|
|
1
|
+
{"version":3,"file":"gltf-ext-uv-transform-DgYazJBs.js","sources":["../src/loader-gltf/gltf-ext-uv-transform.ts"],"sourcesContent":["/** Per-textureInfo UV customization: KHR_texture_transform and/or texCoord=1.\n *\n * - Attaches `uScale/vScale/uOffset/vOffset/uAng` + `_hasTx=true` when the\n * textureInfo carries a KHR_texture_transform.\n * - Attaches `_texCoord=1` when the textureInfo (or its transform extension)\n * selects UV set 1. Spec: KHR_texture_transform.texCoord overrides\n * textureInfo.texCoord.\n *\n * Downstream the PBR material detects these fields and compiles a shader\n * with per-texture `txfUV` wrapping and per-texture UV selection. Identity\n * (no transform, texCoord=0) returns the base texture unchanged so the\n * cache reuses the same wrapper.\n *\n * Lazy-loaded: pulled into bundles whose glTF declares KHR_texture_transform\n * in `extensionsUsed` OR uses `texCoord:1` on any textureInfo. */\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport { cloneTexture2D } from \"../texture/texture-2d.js\";\nimport type { GltfFeature } from \"./gltf-feature.js\";\n\ninterface KtInfo {\n texCoord?: number;\n extensions?: {\n KHR_texture_transform?: {\n scale?: [number, number];\n offset?: [number, number];\n rotation?: number;\n texCoord?: number;\n };\n };\n}\n\nconst ext: GltfFeature = {\n id: \"KHR_texture_transform\",\n wrapTexture(tex: Texture2D, texInfo: unknown): Texture2D {\n const info = texInfo as KtInfo | null | undefined;\n if (!info) {\n return tex;\n }\n const kt = info.extensions?.KHR_texture_transform;\n const patch: { uScale?: number; vScale?: number; uOffset?: number; vOffset?: number; uAng?: number; _hasTx?: true; _texCoord?: 0 | 1 } = {};\n if (kt) {\n if (kt.scale) {\n patch.uScale = kt.scale[0];\n patch.vScale = kt.scale[1];\n }\n if (kt.offset) {\n patch.uOffset = kt.offset[0];\n patch.vOffset = kt.offset[1];\n }\n if (kt.rotation) {\n patch.uAng = kt.rotation;\n }\n if (Object.keys(patch).length) {\n patch._hasTx = true;\n }\n }\n // Spec: KHR_texture_transform.texCoord overrides textureInfo.texCoord.\n const tc = kt?.texCoord ?? info.texCoord;\n if (tc === 1) {\n patch._texCoord = 1;\n }\n return Object.keys(patch).length ? cloneTexture2D(tex, patch) : tex;\n },\n};\nexport default ext;\n"],"names":[],"mappings":";AA+BA,MAAM,MAAmB;AAAA,EACrB,IAAI;AAAA,EACJ,YAAY,KAAgB,SAA6B;;AACrD,UAAM,OAAO;AACb,QAAI,CAAC,MAAM;AACP,aAAO;AAAA,IACX;AACA,UAAM,MAAK,UAAK,eAAL,mBAAiB;AAC5B,UAAM,QAAmI,CAAA;AACzI,QAAI,IAAI;AACJ,UAAI,GAAG,OAAO;AACV,cAAM,SAAS,GAAG,MAAM,CAAC;AACzB,cAAM,SAAS,GAAG,MAAM,CAAC;AAAA,MAC7B;AACA,UAAI,GAAG,QAAQ;AACX,cAAM,UAAU,GAAG,OAAO,CAAC;AAC3B,cAAM,UAAU,GAAG,OAAO,CAAC;AAAA,MAC/B;AACA,UAAI,GAAG,UAAU;AACb,cAAM,OAAO,GAAG;AAAA,MACpB;AACA,UAAI,OAAO,KAAK,KAAK,EAAE,QAAQ;AAC3B,cAAM,SAAS;AAAA,MACnB;AAAA,IACJ;AAEA,UAAM,MAAK,yBAAI,aAAY,KAAK;AAChC,QAAI,OAAO,GAAG;AACV,YAAM,YAAY;AAAA,IACtB;AACA,WAAO,OAAO,KAAK,KAAK,EAAE,SAAS,eAAe,KAAK,KAAK,IAAI;AAAA,EACpE;AACJ;"}
|
package/{gltf-feature-animation-pointer-rFqLfbO_.js → gltf-feature-animation-pointer-D1RJRFBw.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { _installPointerHandlers } from "./gltf-animation-
|
|
1
|
+
import { b9 as setSubtreeVisible, a as F32, e as U8, h as U16, bS as I8, bT as I16, bU as PATH_POINTER } from "./index-CLElg2Bo.js";
|
|
2
|
+
import { _installPointerHandlers } from "./gltf-animation-K_zZxj_d.js";
|
|
3
3
|
const _registry = [
|
|
4
4
|
// /nodes/{n}/extensions/KHR_node_visibility/visible — scalar (0 = hidden).
|
|
5
5
|
// The setter cascade handles descendants per the KHR_node_visibility spec
|
|
@@ -54,26 +54,26 @@ _installPointerHandlers(
|
|
|
54
54
|
return ch;
|
|
55
55
|
},
|
|
56
56
|
(src, length, normalized) => {
|
|
57
|
-
const out = new
|
|
58
|
-
if (src instanceof
|
|
57
|
+
const out = new F32(length);
|
|
58
|
+
if (src instanceof F32) {
|
|
59
59
|
for (let i = 0; i < length; i++) {
|
|
60
60
|
out[i] = src[i];
|
|
61
61
|
}
|
|
62
|
-
} else if (src instanceof
|
|
62
|
+
} else if (src instanceof U8) {
|
|
63
63
|
const k = normalized ? 1 / 255 : 1;
|
|
64
64
|
for (let i = 0; i < length; i++) {
|
|
65
65
|
out[i] = src[i] * k;
|
|
66
66
|
}
|
|
67
|
-
} else if (src instanceof
|
|
67
|
+
} else if (src instanceof U16) {
|
|
68
68
|
const k = normalized ? 1 / 65535 : 1;
|
|
69
69
|
for (let i = 0; i < length; i++) {
|
|
70
70
|
out[i] = src[i] * k;
|
|
71
71
|
}
|
|
72
|
-
} else if (src instanceof
|
|
72
|
+
} else if (src instanceof I8) {
|
|
73
73
|
for (let i = 0; i < length; i++) {
|
|
74
74
|
out[i] = normalized ? Math.max(src[i] / 127, -1) : src[i];
|
|
75
75
|
}
|
|
76
|
-
} else if (src instanceof
|
|
76
|
+
} else if (src instanceof I16) {
|
|
77
77
|
for (let i = 0; i < length; i++) {
|
|
78
78
|
out[i] = normalized ? Math.max(src[i] / 32767, -1) : src[i];
|
|
79
79
|
}
|
|
@@ -85,4 +85,4 @@ const feature = { id: "KHR_animation_pointer" };
|
|
|
85
85
|
export {
|
|
86
86
|
feature as default
|
|
87
87
|
};
|
|
88
|
-
//# sourceMappingURL=gltf-feature-animation-pointer-
|
|
88
|
+
//# sourceMappingURL=gltf-feature-animation-pointer-D1RJRFBw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gltf-feature-animation-pointer-D1RJRFBw.js","sources":["../src/loader-gltf/animation-pointer.ts","../src/loader-gltf/gltf-feature-animation-pointer.ts"],"sourcesContent":["/** KHR_animation_pointer — JSON-pointer resolver registry.\n * Handlers are registered incrementally (one per parity scene). Unknown\n * pointers return null and warn once. */\nimport type { SceneNode } from \"../scene/scene-node.js\";\nimport { setSubtreeVisible } from \"../scene/visibility.js\";\n\nexport interface ResolvedPointer {\n writer: (output: Float32Array, offset: number) => void;\n arity: number;\n}\n\nexport interface PointerContext {\n nodes: readonly (SceneNode | undefined)[];\n}\n\ntype PointerFactory = (match: RegExpExecArray, ctx: PointerContext) => ResolvedPointer | null;\n\nconst _registry: [RegExp, PointerFactory][] = [\n // /nodes/{n}/extensions/KHR_node_visibility/visible — scalar (0 = hidden).\n // The setter cascade handles descendants per the KHR_node_visibility spec\n // and bumps the module-scoped visibility epoch so the engine invalidates\n // its cached render bundle.\n [\n /^\\/nodes\\/(\\d+)\\/extensions\\/KHR_node_visibility\\/visible$/,\n (m, ctx) => {\n const n = ctx.nodes[+m[1]!];\n if (!n) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n setSubtreeVisible(n, out[off]! !== 0);\n },\n };\n },\n ],\n];\n\nconst _warned = new Set<string>();\n\nexport function resolveAnimationPointer(pointer: string, ctx: PointerContext): ResolvedPointer | null {\n for (const [rx, make] of _registry) {\n const m = rx.exec(pointer);\n if (m) {\n return make(m, ctx);\n }\n }\n if (!_warned.has(pointer)) {\n _warned.add(pointer);\n\n console.warn(`[babylon-lite] KHR_animation_pointer: no handler for \"${pointer}\"`);\n }\n return null;\n}\n","/** KHR_animation_pointer glTF feature.\n *\n * Registered in load-gltf.ts's feature table gated on\n * `extensionsUsed.includes(\"KHR_animation_pointer\")`, so any scene that\n * doesn't declare the extension pays zero bytes for pointer resolution, the\n * non-Float32 sampler converter, or the visibility cascade helper.\n *\n * On side-effect import this module installs two callbacks into gltf-animation:\n * 1. A pointer-channel parser (resolves the JSON pointer to a writer fn).\n * 2. A sampler converter that handles the non-Float32/misaligned accessor\n * cases the fast path in gltf-animation can't express (e.g. the 11-byte\n * UNSIGNED_BYTE visibility accessor in CubeVisibility.glb). */\n\nimport { F32, U16, I16, U8, I8 } from \"../engine/typed-arrays.js\";\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport type { AnimationChannel } from \"../animation/types.js\";\nimport { PATH_POINTER } from \"../animation/types.js\";\nimport { resolveAnimationPointer } from \"./animation-pointer.js\";\nimport { _installPointerHandlers } from \"./gltf-animation.js\";\n\n_installPointerHandlers(\n (ptr, c, nodeMap) => {\n if (!nodeMap) {\n return null;\n }\n const resolved = resolveAnimationPointer(ptr, { nodes: nodeMap });\n if (!resolved) {\n return null;\n }\n const ch: AnimationChannel = {\n samplerIdx: c.sampler,\n nodeIdx: -1,\n path: PATH_POINTER,\n pointerWriter: resolved.writer,\n pointerArity: resolved.arity,\n };\n return ch;\n },\n (src, length, normalized) => {\n // Convert any animation-sampler payload to a standalone Float32Array.\n // Handles the cases the aligned-Float32 fast path can't express.\n const out = new F32(length);\n if (src instanceof F32) {\n for (let i = 0; i < length; i++) {\n out[i] = src[i]!;\n }\n } else if (src instanceof U8) {\n const k = normalized ? 1 / 255 : 1;\n for (let i = 0; i < length; i++) {\n out[i] = src[i]! * k;\n }\n } else if (src instanceof U16) {\n const k = normalized ? 1 / 65535 : 1;\n for (let i = 0; i < length; i++) {\n out[i] = src[i]! * k;\n }\n } else if (src instanceof I8) {\n for (let i = 0; i < length; i++) {\n out[i] = normalized ? Math.max(src[i]! / 127, -1) : src[i]!;\n }\n } else if (src instanceof I16) {\n for (let i = 0; i < length; i++) {\n out[i] = normalized ? Math.max(src[i]! / 32767, -1) : src[i]!;\n }\n }\n return out;\n }\n);\n\n// No per-asset hook — this feature only installs the seam at import time.\nconst feature: GltfFeature = { id: \"KHR_animation_pointer\" };\nexport default feature;\n"],"names":[],"mappings":";;AAiBA,MAAM,YAAwC;AAAA;AAAA;AAAA;AAAA;AAAA,EAK1C;AAAA,IACI;AAAA,IACA,CAAC,GAAG,QAAQ;AACR,YAAM,IAAI,IAAI,MAAM,CAAC,EAAE,CAAC,CAAE;AAC1B,UAAI,CAAC,GAAG;AACJ,eAAO;AAAA,MACX;AACA,aAAO;AAAA,QACH,OAAO;AAAA,QACP,QAAQ,CAAC,KAAK,QAAQ;AAClB,4BAAkB,GAAG,IAAI,GAAG,MAAO,CAAC;AAAA,QACxC;AAAA,MAAA;AAAA,IAER;AAAA,EAAA;AAER;AAEA,MAAM,8BAAc,IAAA;AAEb,SAAS,wBAAwB,SAAiB,KAA6C;AAClG,aAAW,CAAC,IAAI,IAAI,KAAK,WAAW;AAChC,UAAM,IAAI,GAAG,KAAK,OAAO;AACzB,QAAI,GAAG;AACH,aAAO,KAAK,GAAG,GAAG;AAAA,IACtB;AAAA,EACJ;AACA,MAAI,CAAC,QAAQ,IAAI,OAAO,GAAG;AACvB,YAAQ,IAAI,OAAO;AAEnB,YAAQ,KAAK,yDAAyD,OAAO,GAAG;AAAA,EACpF;AACA,SAAO;AACX;AClCA;AAAA,EACI,CAAC,KAAK,GAAG,YAAY;AACjB,QAAI,CAAC,SAAS;AACV,aAAO;AAAA,IACX;AACA,UAAM,WAAW,wBAAwB,KAAK,EAAE,OAAO,SAAS;AAChE,QAAI,CAAC,UAAU;AACX,aAAO;AAAA,IACX;AACA,UAAM,KAAuB;AAAA,MACzB,YAAY,EAAE;AAAA,MACd,SAAS;AAAA,MACT,MAAM;AAAA,MACN,eAAe,SAAS;AAAA,MACxB,cAAc,SAAS;AAAA,IAAA;AAE3B,WAAO;AAAA,EACX;AAAA,EACA,CAAC,KAAK,QAAQ,eAAe;AAGzB,UAAM,MAAM,IAAI,IAAI,MAAM;AAC1B,QAAI,eAAe,KAAK;AACpB,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC7B,YAAI,CAAC,IAAI,IAAI,CAAC;AAAA,MAClB;AAAA,IACJ,WAAW,eAAe,IAAI;AAC1B,YAAM,IAAI,aAAa,IAAI,MAAM;AACjC,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC7B,YAAI,CAAC,IAAI,IAAI,CAAC,IAAK;AAAA,MACvB;AAAA,IACJ,WAAW,eAAe,KAAK;AAC3B,YAAM,IAAI,aAAa,IAAI,QAAQ;AACnC,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC7B,YAAI,CAAC,IAAI,IAAI,CAAC,IAAK;AAAA,MACvB;AAAA,IACJ,WAAW,eAAe,IAAI;AAC1B,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC7B,YAAI,CAAC,IAAI,aAAa,KAAK,IAAI,IAAI,CAAC,IAAK,KAAK,EAAE,IAAI,IAAI,CAAC;AAAA,MAC7D;AAAA,IACJ,WAAW,eAAe,KAAK;AAC3B,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC7B,YAAI,CAAC,IAAI,aAAa,KAAK,IAAI,IAAI,CAAC,IAAK,OAAO,EAAE,IAAI,IAAI,CAAC;AAAA,MAC/D;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AACJ;AAGA,MAAM,UAAuB,EAAE,IAAI,wBAAA;"}
|