@babylonjs/lite 0.1.1 → 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.
Files changed (262) hide show
  1. package/_mat4-storage-f64-CjDoht2w.js +11 -0
  2. package/_mat4-storage-f64-CjDoht2w.js.map +1 -0
  3. package/{alpha-test-fragment-CUiHCw7W.js → alpha-test-fragment-B7DjSnF7.js} +2 -2
  4. package/{alpha-test-fragment-CUiHCw7W.js.map → alpha-test-fragment-B7DjSnF7.js.map} +1 -1
  5. package/assets/splat-sort-worker-DT3eybMZ.js.map +1 -0
  6. package/{background-dds-skybox-yHTqabU3.js → background-dds-skybox-BEX309u3.js} +14 -14
  7. package/background-dds-skybox-BEX309u3.js.map +1 -0
  8. package/{background-ground-DIw6D3qf.js → background-ground-BU0HOcM4.js} +20 -20
  9. package/background-ground-BU0HOcM4.js.map +1 -0
  10. package/{background-hdr-skybox-c4uuTmkP.js → background-hdr-skybox--RRRic_K.js} +10 -10
  11. package/background-hdr-skybox--RRRic_K.js.map +1 -0
  12. package/{background-solid-skybox-DPGBpPbm.js → background-solid-skybox-BrH2fXSu.js} +12 -13
  13. package/background-solid-skybox-BrH2fXSu.js.map +1 -0
  14. package/{billboard-renderable-D8mlVGCd.js → billboard-renderable-BHWryAeC.js} +46 -10
  15. package/billboard-renderable-BHWryAeC.js.map +1 -0
  16. package/{clamp-block-BdII67hT.js → clamp-block-DqbwnQGW.js} +2 -2
  17. package/{clamp-block-BdII67hT.js.map → clamp-block-DqbwnQGW.js.map} +1 -1
  18. package/{clearcoat-fragment-LCiG98Rf.js → clearcoat-fragment-D6FSCie1.js} +2 -2
  19. package/{clearcoat-fragment-LCiG98Rf.js.map → clearcoat-fragment-D6FSCie1.js.map} +1 -1
  20. package/{create-skeleton-C9JdIJnb.js → create-skeleton-D_uplboC.js} +9 -9
  21. package/create-skeleton-D_uplboC.js.map +1 -0
  22. package/{cubemap-skybox-material-DvXMVc4k.js → cubemap-skybox-material-DQcMMdf-.js} +6 -7
  23. package/cubemap-skybox-material-DQcMMdf-.js.map +1 -0
  24. package/{curve-block-BlJpXVYv.js → curve-block-21rT0JjG.js} +2 -2
  25. package/{curve-block-BlJpXVYv.js.map → curve-block-21rT0JjG.js.map} +1 -1
  26. package/{emissive-fragment-BnNvbBCw.js → emissive-fragment-C5FtBs3y.js} +3 -3
  27. package/emissive-fragment-C5FtBs3y.js.map +1 -0
  28. package/{esm-shadow-view-DN9HIaM4.js → esm-shadow-view-Cl3rPGof.js} +2 -2
  29. package/{esm-shadow-view-DN9HIaM4.js.map → esm-shadow-view-Cl3rPGof.js.map} +1 -1
  30. package/{esm-shadow-view-Dk9NFtLq.js → esm-shadow-view-Gtd1LWRP.js} +2 -2
  31. package/{esm-shadow-view-Dk9NFtLq.js.map → esm-shadow-view-Gtd1LWRP.js.map} +1 -1
  32. package/{esm-shadow-view-DGKdF1NI.js → esm-shadow-view-c5YV4Eg9.js} +2 -2
  33. package/{esm-shadow-view-DGKdF1NI.js.map → esm-shadow-view-c5YV4Eg9.js.map} +1 -1
  34. package/{gaussian-splatting-pipeline-sh-DgJl7l56.js → gaussian-splatting-pipeline-sh-7J31V23x.js} +19 -19
  35. package/gaussian-splatting-pipeline-sh-7J31V23x.js.map +1 -0
  36. package/geometry-texture-output-dXk4E9uu.js +41 -0
  37. package/geometry-texture-output-dXk4E9uu.js.map +1 -0
  38. package/geometry-view-BsFJpBJa.js +404 -0
  39. package/geometry-view-BsFJpBJa.js.map +1 -0
  40. package/{gltf-animation-D7uyTyO3.js → gltf-animation-K_zZxj_d.js} +7 -7
  41. package/gltf-animation-K_zZxj_d.js.map +1 -0
  42. package/gltf-color-normalize-Qxl-9C48.js +29 -0
  43. package/gltf-color-normalize-Qxl-9C48.js.map +1 -0
  44. package/{gltf-ext-basisu-CPg5kPrx.js → gltf-ext-basisu-CDbPclzZ.js} +53 -18
  45. package/gltf-ext-basisu-CDbPclzZ.js.map +1 -0
  46. package/{gltf-ext-node-visibility-MafA9ot2.js → gltf-ext-node-visibility-DXCJEYr6.js} +2 -2
  47. package/{gltf-ext-node-visibility-MafA9ot2.js.map → gltf-ext-node-visibility-DXCJEYr6.js.map} +1 -1
  48. package/{gltf-ext-quantization-CpZyLDIz.js → gltf-ext-quantization-CvHI_0Vg.js} +4 -3
  49. package/gltf-ext-quantization-CvHI_0Vg.js.map +1 -0
  50. package/{gltf-ext-uv-transform-CE_-T1Tr.js → gltf-ext-uv-transform-DgYazJBs.js} +2 -2
  51. package/{gltf-ext-uv-transform-CE_-T1Tr.js.map → gltf-ext-uv-transform-DgYazJBs.js.map} +1 -1
  52. package/{gltf-feature-animation-pointer-BjpwOOqo.js → gltf-feature-animation-pointer-D1RJRFBw.js} +9 -9
  53. package/gltf-feature-animation-pointer-D1RJRFBw.js.map +1 -0
  54. package/{gltf-feature-animations-CCizegp8.js → gltf-feature-animations-Cmc1uoIu.js} +2 -2
  55. package/{gltf-feature-animations-CCizegp8.js.map → gltf-feature-animations-Cmc1uoIu.js.map} +1 -1
  56. package/{gltf-feature-draco-yGSMGTE3.js → gltf-feature-draco-CKKzT5E3.js} +6 -5
  57. package/gltf-feature-draco-CKKzT5E3.js.map +1 -0
  58. package/{gltf-feature-gpu-instancing-2e_CFQnl.js → gltf-feature-gpu-instancing-n87SO6Vh.js} +7 -6
  59. package/gltf-feature-gpu-instancing-n87SO6Vh.js.map +1 -0
  60. package/{gltf-feature-lights-punctual-DDDg4j0U.js → gltf-feature-lights-punctual-Ckm3ciL8.js} +5 -5
  61. package/{gltf-feature-lights-punctual-DDDg4j0U.js.map → gltf-feature-lights-punctual-Ckm3ciL8.js.map} +1 -1
  62. package/{gltf-feature-meshopt-Des96YFI.js → gltf-feature-meshopt-DLC4SF1E.js} +7 -6
  63. package/gltf-feature-meshopt-DLC4SF1E.js.map +1 -0
  64. package/{gltf-feature-morph-CKCw6tkX.js → gltf-feature-morph-Cjtu7hYa.js} +4 -4
  65. package/gltf-feature-morph-Cjtu7hYa.js.map +1 -0
  66. package/gltf-feature-registry-C63Hjp9w.js +59 -0
  67. package/gltf-feature-registry-C63Hjp9w.js.map +1 -0
  68. package/{gltf-feature-skeleton-D8hWLqi2.js → gltf-feature-skeleton-DKbOGidp.js} +3 -3
  69. package/{gltf-feature-skeleton-D8hWLqi2.js.map → gltf-feature-skeleton-DKbOGidp.js.map} +1 -1
  70. package/{gltf-feature-variants-Ds6v9byg.js → gltf-feature-variants-Cmzu0O0e.js} +2 -2
  71. package/{gltf-feature-variants-Ds6v9byg.js.map → gltf-feature-variants-Cmzu0O0e.js.map} +1 -1
  72. package/{gltf-glb-parser-D6UZWFuC.js → gltf-glb-parser-Cj5MHS-v.js} +5 -4
  73. package/gltf-glb-parser-Cj5MHS-v.js.map +1 -0
  74. package/{gltf-interleave-DGnUlz28.js → gltf-interleave-gHf9_t0i.js} +14 -14
  75. package/gltf-interleave-gHf9_t0i.js.map +1 -0
  76. package/gltf-normals-b2h74380.js +37 -0
  77. package/gltf-normals-b2h74380.js.map +1 -0
  78. package/{gltf-pbr-builder-ext-BFOxOCnQ.js → gltf-pbr-builder-ext-edNcjwPf.js} +5 -5
  79. package/gltf-pbr-builder-ext-edNcjwPf.js.map +1 -0
  80. package/{gltf-variants-DFbr8EES.js → gltf-variants-CPxNdtP4.js} +4 -4
  81. package/{gltf-variants-DFbr8EES.js.map → gltf-variants-CPxNdtP4.js.map} +1 -1
  82. package/{gs-picking-pipeline-DzfMASL9.js → gs-picking-pipeline-DYaW_Lg3.js} +14 -14
  83. package/gs-picking-pipeline-DYaW_Lg3.js.map +1 -0
  84. package/havok-floating-origin-Dr-18Nds.js +198 -0
  85. package/havok-floating-origin-Dr-18Nds.js.map +1 -0
  86. package/index-CLElg2Bo.js +39209 -0
  87. package/index-CLElg2Bo.js.map +1 -0
  88. package/index-CYZDclhF.js +918 -0
  89. package/index-CYZDclhF.js.map +1 -0
  90. package/index-SMJ67XwT.js +3330 -0
  91. package/index-SMJ67XwT.js.map +1 -0
  92. package/index.d.ts +2508 -119
  93. package/index.js +444 -302
  94. package/{input-block-DgAJBzN_.js → input-block-DqEedWF2.js} +2 -2
  95. package/{input-block-DgAJBzN_.js.map → input-block-DqEedWF2.js.map} +1 -1
  96. package/{iridescence-fragment-Gymp7or5.js → iridescence-fragment-BHU59-gQ.js} +2 -2
  97. package/{iridescence-fragment-Gymp7or5.js.map → iridescence-fragment-BHU59-gQ.js.map} +1 -1
  98. package/{light-block-B11ew7FA.js → light-block-Bv37V8vl.js} +2 -2
  99. package/{light-block-B11ew7FA.js.map → light-block-Bv37V8vl.js.map} +1 -1
  100. package/{loop-block-Bb23EOMb.js → loop-block-qTg8vb99.js} +2 -2
  101. package/{loop-block-Bb23EOMb.js.map → loop-block-qTg8vb99.js.map} +1 -1
  102. package/{morph-fragment-DOVo70gP.js → morph-fragment-BRCUr2wQ.js} +2 -2
  103. package/{morph-fragment-DOVo70gP.js.map → morph-fragment-BRCUr2wQ.js.map} +1 -1
  104. package/{multilight-wgsl-BGyiIOp3.js → multilight-wgsl-DMeppAdZ.js} +4 -4
  105. package/{multilight-wgsl-BGyiIOp3.js.map → multilight-wgsl-DMeppAdZ.js.map} +1 -1
  106. package/{node-env-BPZXZzBf.js → node-env-Bc559GmY.js} +6 -5
  107. package/node-env-Bc559GmY.js.map +1 -0
  108. package/node-geometry-view-COmWsRXK.js +291 -0
  109. package/node-geometry-view-COmWsRXK.js.map +1 -0
  110. package/{node-registry-extra-compat-Dhrw8fDQ.js → node-registry-extra-compat-dWrv7gpS.js} +2 -2
  111. package/{node-registry-extra-compat-Dhrw8fDQ.js.map → node-registry-extra-compat-dWrv7gpS.js.map} +1 -1
  112. package/{node-registry-extra-math-CsAHvIZo.js → node-registry-extra-math-Bn854sX9.js} +2 -2
  113. package/{node-registry-extra-math-CsAHvIZo.js.map → node-registry-extra-math-Bn854sX9.js.map} +1 -1
  114. package/{node-renderable-DlLIdBmd.js → node-renderable-B5G8WcdH.js} +41 -22
  115. package/node-renderable-B5G8WcdH.js.map +1 -0
  116. package/{node-shadow-DKrcqmNg.js → node-shadow-CVIUlNf0.js} +7 -7
  117. package/node-shadow-CVIUlNf0.js.map +1 -0
  118. package/{normal-map-fragment-DpsIXrJf.js → normal-map-fragment-CQSxhjCy.js} +3 -3
  119. package/{normal-map-fragment-DpsIXrJf.js.map → normal-map-fragment-CQSxhjCy.js.map} +1 -1
  120. package/pack-mat4-with-offset-BqB8Jqo7.js +37 -0
  121. package/pack-mat4-with-offset-BqB8Jqo7.js.map +1 -0
  122. package/package.json +3 -10
  123. package/{parse-camera-DM3oJJeT.js → parse-camera-pBRT_6i5.js} +2 -2
  124. package/{parse-camera-DM3oJJeT.js.map → parse-camera-pBRT_6i5.js.map} +1 -1
  125. package/pbr-fog-wgsl-BqdCid6r.js +8 -0
  126. package/pbr-fog-wgsl-BqdCid6r.js.map +1 -0
  127. package/pbr-geometry-view-NiZY_juX.js +491 -0
  128. package/pbr-geometry-view-NiZY_juX.js.map +1 -0
  129. package/{pbr-metallic-roughness-block-h_KAOZrW.js → pbr-metallic-roughness-block-JBSi-tQN.js} +2 -2
  130. package/{pbr-metallic-roughness-block-h_KAOZrW.js.map → pbr-metallic-roughness-block-JBSi-tQN.js.map} +1 -1
  131. package/{pbr-metallic-roughness-block-full-6vMm1Jk6.js → pbr-metallic-roughness-block-full-Ta9lR2cz.js} +2 -2
  132. package/{pbr-metallic-roughness-block-full-6vMm1Jk6.js.map → pbr-metallic-roughness-block-full-Ta9lR2cz.js.map} +1 -1
  133. package/{pbr-mr-helper-core-CIwm-T1G.js → pbr-mr-helper-core-BVWNR08D.js} +2 -2
  134. package/{pbr-mr-helper-core-CIwm-T1G.js.map → pbr-mr-helper-core-BVWNR08D.js.map} +1 -1
  135. package/{pbr-refraction-DGmMSa2v.js → pbr-refraction-C9FvFmAp.js} +2 -2
  136. package/{pbr-refraction-DGmMSa2v.js.map → pbr-refraction-C9FvFmAp.js.map} +1 -1
  137. package/{pbr-renderable-BJxUtPBb.js → pbr-renderable-DzUF2QIk.js} +118 -58
  138. package/pbr-renderable-DzUF2QIk.js.map +1 -0
  139. package/{pbr-shadow-fragment-LO9SlbJj.js → pbr-shadow-fragment-CnqnbGYS.js} +6 -1
  140. package/pbr-shadow-fragment-CnqnbGYS.js.map +1 -0
  141. package/{pbr-template-ext-8q7BcTDf.js → pbr-template-ext-CGgB2n2y.js} +3 -2
  142. package/{pbr-template-ext-8q7BcTDf.js.map → pbr-template-ext-CGgB2n2y.js.map} +1 -1
  143. package/{pbr-tracking-B3alzn91.js → pbr-tracking-3tU1kqea.js} +2 -2
  144. package/{pbr-tracking-B3alzn91.js.map → pbr-tracking-3tU1kqea.js.map} +1 -1
  145. package/pbr-transmission-ext-BcLjRxfB.js +190 -0
  146. package/pbr-transmission-ext-BcLjRxfB.js.map +1 -0
  147. package/recast-navigation.wasm-DG_0AFuk.js +8706 -0
  148. package/recast-navigation.wasm-DG_0AFuk.js.map +1 -0
  149. package/recast-navigation.wasm-compat-C-Bf2ylB.js +8692 -0
  150. package/recast-navigation.wasm-compat-C-Bf2ylB.js.map +1 -0
  151. package/{reflectance-fragment-BCrgPmrt.js → reflectance-fragment-Dbpgw3Jt.js} +2 -2
  152. package/{reflectance-fragment-BCrgPmrt.js.map → reflectance-fragment-Dbpgw3Jt.js.map} +1 -1
  153. package/{rgbd-decode-DCvzUYeI.js → rgbd-decode-DoyUquy3.js} +7 -6
  154. package/rgbd-decode-DoyUquy3.js.map +1 -0
  155. package/{scene-material-swap-C2ykv55W.js → scene-material-swap-nNUH4nGn.js} +11 -4
  156. package/scene-material-swap-nNUH4nGn.js.map +1 -0
  157. package/screenshot-readback-D0Sj9qq3.js +92 -0
  158. package/screenshot-readback-D0Sj9qq3.js.map +1 -0
  159. package/{mesh-features-BLENkYVt.js → shader-composer-BUD_pSX4.js} +7 -55
  160. package/shader-composer-BUD_pSX4.js.map +1 -0
  161. package/{shader-renderable-D-6796KR.js → shader-renderable-D7-RyVxa.js} +62 -27
  162. package/shader-renderable-D7-RyVxa.js.map +1 -0
  163. package/shader-thin-instance-DuBotxDO.js +150 -0
  164. package/shader-thin-instance-DuBotxDO.js.map +1 -0
  165. package/shadow-fragment-core-DHN2G6FI.js.map +1 -1
  166. package/{sheen-fragment-Dze2f7XJ.js → sheen-fragment-1MkEMcbc.js} +2 -2
  167. package/{sheen-fragment-Dze2f7XJ.js.map → sheen-fragment-1MkEMcbc.js.map} +1 -1
  168. package/{singlelight-directional-wgsl-CmUDZxwz.js → singlelight-directional-wgsl-BsV8G456.js} +2 -2
  169. package/{singlelight-directional-wgsl-CmUDZxwz.js.map → singlelight-directional-wgsl-BsV8G456.js.map} +1 -1
  170. package/{singlelight-hemispheric-wgsl-t-83IP_s.js → singlelight-hemispheric-wgsl-Bo0jKlW5.js} +2 -2
  171. package/{singlelight-hemispheric-wgsl-t-83IP_s.js.map → singlelight-hemispheric-wgsl-Bo0jKlW5.js.map} +1 -1
  172. package/{singlelight-point-wgsl-CLzULIYV.js → singlelight-point-wgsl-DV39UP5Y.js} +2 -2
  173. package/{singlelight-point-wgsl-CLzULIYV.js.map → singlelight-point-wgsl-DV39UP5Y.js.map} +1 -1
  174. package/{singlelight-spot-wgsl-DEEUrfVM.js → singlelight-spot-wgsl-yg3od6vL.js} +2 -2
  175. package/{singlelight-spot-wgsl-DEEUrfVM.js.map → singlelight-spot-wgsl-yg3od6vL.js.map} +1 -1
  176. package/{skeleton-fragment-B_XlFbtx.js → skeleton-fragment-DdxYG6kv.js} +2 -2
  177. package/{skeleton-fragment-B_XlFbtx.js.map → skeleton-fragment-DdxYG6kv.js.map} +1 -1
  178. package/{skybox-renderable-DDwzu-PT.js → skybox-renderable-CJD4XmX5.js} +8 -9
  179. package/skybox-renderable-CJD4XmX5.js.map +1 -0
  180. package/{splat-ply-compressed-BahdBG1r.js → splat-ply-compressed-DHjyiVmI.js} +9 -8
  181. package/splat-ply-compressed-DHjyiVmI.js.map +1 -0
  182. package/{standard-renderable-GjxL9xSf.js → standard-pipeline-XTbHL7MY.js} +12 -257
  183. package/standard-pipeline-XTbHL7MY.js.map +1 -0
  184. package/standard-renderable-CREWLNHI.js +191 -0
  185. package/standard-renderable-CREWLNHI.js.map +1 -0
  186. package/{std-ambient-fragment-BoUsD06w.js → std-ambient-fragment-Bjx3VFrr.js} +2 -2
  187. package/{std-ambient-fragment-BoUsD06w.js.map → std-ambient-fragment-Bjx3VFrr.js.map} +1 -1
  188. package/{std-cube-reflection-fragment-ulqc3bsP.js → std-cube-reflection-fragment-y9WWdXUt.js} +2 -2
  189. package/{std-cube-reflection-fragment-ulqc3bsP.js.map → std-cube-reflection-fragment-y9WWdXUt.js.map} +1 -1
  190. package/{std-emissive-fragment-DNGj1HdQ.js → std-emissive-fragment-C8Lnmojh.js} +2 -2
  191. package/{std-emissive-fragment-DNGj1HdQ.js.map → std-emissive-fragment-C8Lnmojh.js.map} +1 -1
  192. package/{std-lightmap-fragment-Bqj89aIe.js → std-lightmap-fragment-DFxGcoA5.js} +2 -2
  193. package/{std-lightmap-fragment-Bqj89aIe.js.map → std-lightmap-fragment-DFxGcoA5.js.map} +1 -1
  194. package/{std-opacity-fragment-KuPh5N2Z.js → std-opacity-fragment-EXzFWiSp.js} +2 -2
  195. package/{std-opacity-fragment-KuPh5N2Z.js.map → std-opacity-fragment-EXzFWiSp.js.map} +1 -1
  196. package/{std-reflection-fragment-BA5Ghn_M.js → std-reflection-fragment-BoJORqpG.js} +2 -2
  197. package/{std-reflection-fragment-BA5Ghn_M.js.map → std-reflection-fragment-BoJORqpG.js.map} +1 -1
  198. package/std-shadow-fragment-Bq-Wc8UJ.js +13 -0
  199. package/std-shadow-fragment-Bq-Wc8UJ.js.map +1 -0
  200. package/{std-specular-fragment-CE-6scqd.js → std-specular-fragment-CM5R5j2g.js} +2 -2
  201. package/{std-specular-fragment-CE-6scqd.js.map → std-specular-fragment-CM5R5j2g.js.map} +1 -1
  202. package/{std-tracking-CNKZ-hJN.js → std-tracking-Cif_wXeT.js} +2 -2
  203. package/{std-tracking-CNKZ-hJN.js.map → std-tracking-Cif_wXeT.js.map} +1 -1
  204. package/{subsurface-fragment-liM3y2-P.js → subsurface-fragment-BEaAXYXz.js} +2 -2
  205. package/{subsurface-fragment-liM3y2-P.js.map → subsurface-fragment-BEaAXYXz.js.map} +1 -1
  206. package/swapchain-overlay-UCLilhbq.js +37 -0
  207. package/swapchain-overlay-UCLilhbq.js.map +1 -0
  208. package/thin-instance-cull-binding-DWKUt5ZN.js +310 -0
  209. package/thin-instance-cull-binding-DWKUt5ZN.js.map +1 -0
  210. package/{thin-instance-gpu-C9Gv_Z1w.js → thin-instance-gpu-BDdRcNAh.js} +30 -5
  211. package/thin-instance-gpu-BDdRcNAh.js.map +1 -0
  212. package/{tracking-primitives-wgdBY85t.js → tracking-primitives-CglRNTlX.js} +2 -2
  213. package/{tracking-primitives-wgdBY85t.js.map → tracking-primitives-CglRNTlX.js.map} +1 -1
  214. package/{unlit-fragment-BIlhJpz6.js → unlit-fragment-kxfZWlnp.js} +2 -2
  215. package/{unlit-fragment-BIlhJpz6.js.map → unlit-fragment-kxfZWlnp.js.map} +1 -1
  216. package/{wgsl-helpers-DyzNzCeE.js → wgsl-helpers-D8sl1VVA.js} +4 -4
  217. package/{wgsl-helpers-DyzNzCeE.js.map → wgsl-helpers-D8sl1VVA.js.map} +1 -1
  218. package/assets/splat-sort-worker-Crg3CaCc.js.map +0 -1
  219. package/background-dds-skybox-yHTqabU3.js.map +0 -1
  220. package/background-ground-DIw6D3qf.js.map +0 -1
  221. package/background-hdr-skybox-c4uuTmkP.js.map +0 -1
  222. package/background-solid-skybox-DPGBpPbm.js.map +0 -1
  223. package/billboard-renderable-D8mlVGCd.js.map +0 -1
  224. package/create-skeleton-C9JdIJnb.js.map +0 -1
  225. package/cubemap-skybox-material-DvXMVc4k.js.map +0 -1
  226. package/emissive-fragment-BnNvbBCw.js.map +0 -1
  227. package/gaussian-splatting-pipeline-sh-DgJl7l56.js.map +0 -1
  228. package/gltf-animation-D7uyTyO3.js.map +0 -1
  229. package/gltf-ext-basisu-CPg5kPrx.js.map +0 -1
  230. package/gltf-ext-quantization-CpZyLDIz.js.map +0 -1
  231. package/gltf-feature-animation-pointer-BjpwOOqo.js.map +0 -1
  232. package/gltf-feature-draco-yGSMGTE3.js.map +0 -1
  233. package/gltf-feature-gpu-instancing-2e_CFQnl.js.map +0 -1
  234. package/gltf-feature-meshopt-Des96YFI.js.map +0 -1
  235. package/gltf-feature-morph-CKCw6tkX.js.map +0 -1
  236. package/gltf-glb-parser-D6UZWFuC.js.map +0 -1
  237. package/gltf-interleave-DGnUlz28.js.map +0 -1
  238. package/gltf-pbr-builder-ext-BFOxOCnQ.js.map +0 -1
  239. package/gs-picking-pipeline-DzfMASL9.js.map +0 -1
  240. package/index-C8HOR2sB.js +0 -19222
  241. package/index-C8HOR2sB.js.map +0 -1
  242. package/mesh-features-BLENkYVt.js.map +0 -1
  243. package/node-env-BPZXZzBf.js.map +0 -1
  244. package/node-registry-DwgC4yth.js +0 -190
  245. package/node-registry-DwgC4yth.js.map +0 -1
  246. package/node-renderable-DlLIdBmd.js.map +0 -1
  247. package/node-shadow-DKrcqmNg.js.map +0 -1
  248. package/pbr-renderable-BJxUtPBb.js.map +0 -1
  249. package/pbr-shadow-fragment-LO9SlbJj.js.map +0 -1
  250. package/pbr-transmission-ext-BxW4CEGu.js +0 -581
  251. package/pbr-transmission-ext-BxW4CEGu.js.map +0 -1
  252. package/rgbd-decode-DCvzUYeI.js.map +0 -1
  253. package/scene-material-swap-C2ykv55W.js.map +0 -1
  254. package/shader-renderable-D-6796KR.js.map +0 -1
  255. package/skybox-renderable-DDwzu-PT.js.map +0 -1
  256. package/splat-ply-compressed-BahdBG1r.js.map +0 -1
  257. package/standard-renderable-GjxL9xSf.js.map +0 -1
  258. package/std-shadow-fragment-FNQfrJuC.js +0 -8
  259. package/std-shadow-fragment-FNQfrJuC.js.map +0 -1
  260. package/swapchain-overlay-DcCSFDp7.js +0 -35
  261. package/swapchain-overlay-DcCSFDp7.js.map +0 -1
  262. package/thin-instance-gpu-C9Gv_Z1w.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 { j as mat4Invert, k as mat4Identity, l as mat4MultiplyInto, g as computeNodeWorldMatrix, r as resolveAccessor, I as INTERP_CUBICSPLINE, n as INTERP_STEP, o as INTERP_LINEAR, P as PATH_WEIGHTS, p as PATH_SCALE, q as PATH_ROTATION, t as PATH_TRANSLATION, u as findParent } from "./index-C8HOR2sB.js";
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 Float32Array(src.buffer, src.byteOffset, length);
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 Float32Array(ibmData._data.buffer, ibmData._data.byteOffset, jointCount * 16);
18
+ return new F32(ibmData._data.buffer, ibmData._data.byteOffset, jointCount * 16);
19
19
  }
20
- const out = new Float32Array(jointCount * 16);
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,9 +33,9 @@ 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 Float32Array(numBones * 16);
36
+ const data = new F32(numBones * 16);
37
37
  const invMeshWorld = mat4Invert(skin.meshWorldMatrix) ?? mat4Identity();
38
- const tmp = new Float32Array(16);
38
+ const tmp = getLoaderTmpAnim();
39
39
  for (let i = 0; i < numBones; i++) {
40
40
  mat4MultiplyInto(tmp, 0, invMeshWorld, 0, skin.jointWorldMatrices[i], 0);
41
41
  mat4MultiplyInto(data, i * 16, tmp, 0, skin.inverseBindMatrices, i * 16);
@@ -242,4 +242,4 @@ export {
242
242
  extractSkin,
243
243
  parseAnimationData
244
244
  };
245
- //# sourceMappingURL=gltf-animation-D7uyTyO3.js.map
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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"}
@@ -0,0 +1,29 @@
1
+ function normalizeColorToVec3(data, count, comps) {
2
+ const out = new Float32Array(count * 3);
3
+ if (data instanceof Float32Array) {
4
+ for (let v = 0; v < count; v++) {
5
+ out[v * 3] = data[v * comps];
6
+ out[v * 3 + 1] = data[v * comps + 1];
7
+ out[v * 3 + 2] = data[v * comps + 2];
8
+ }
9
+ } else if (data instanceof Uint16Array) {
10
+ const inv = 1 / 65535;
11
+ for (let v = 0; v < count; v++) {
12
+ out[v * 3] = data[v * comps] * inv;
13
+ out[v * 3 + 1] = data[v * comps + 1] * inv;
14
+ out[v * 3 + 2] = data[v * comps + 2] * inv;
15
+ }
16
+ } else if (data instanceof Uint8Array) {
17
+ const inv = 1 / 255;
18
+ for (let v = 0; v < count; v++) {
19
+ out[v * 3] = data[v * comps] * inv;
20
+ out[v * 3 + 1] = data[v * comps + 1] * inv;
21
+ out[v * 3 + 2] = data[v * comps + 2] * inv;
22
+ }
23
+ }
24
+ return out;
25
+ }
26
+ export {
27
+ normalizeColorToVec3
28
+ };
29
+ //# sourceMappingURL=gltf-color-normalize-Qxl-9C48.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gltf-color-normalize-Qxl-9C48.js","sources":["../src/loader-gltf/gltf-color-normalize.ts"],"sourcesContent":["/** glTF COLOR_0 vertex-color normalization — dynamically imported.\n *\n * Isolated from the core loader so scenes whose assets have no COLOR_0 attribute\n * (the common case) never bundle or fetch this code. Loaded lazily by\n * `load-gltf.ts` only when a primitive actually provides COLOR_0.\n *\n * Zero module-level side effects — safe for tree-shaking.\n */\n\n/** Normalize a glTF COLOR_0 attribute to a tight float32 VEC3 (RGB) buffer.\n *\n * The PBR/standard vertex pipelines bind vertex color as a single format: `float32x3`\n * (stride 12). glTF COLOR_0 is far more permissive — it may be VEC3 or VEC4, and its\n * component type may be float OR normalized unsigned byte/short. Binding any other layout\n * to the stride-12 float pipeline misaligns every vertex (garbage / black colors). So we\n * always convert here: integer types are normalized to [0,1] (per the glTF spec, integer\n * COLOR_0 is always normalized), VEC4 alpha is dropped (Lite shading multiplies only the\n * rgb of vertex color into the base color), and the result is a tight Float32Array RGB.\n *\n * `data` is the resolved accessor view (Float32Array | Uint8Array | Uint16Array), `count`\n * the vertex count, and `comps` the component count (3 or 4). */\nexport function normalizeColorToVec3(data: ArrayBufferView, count: number, comps: number): Float32Array {\n const out = new Float32Array(count * 3);\n if (data instanceof Float32Array) {\n for (let v = 0; v < count; v++) {\n out[v * 3] = data[v * comps]!;\n out[v * 3 + 1] = data[v * comps + 1]!;\n out[v * 3 + 2] = data[v * comps + 2]!;\n }\n } else if (data instanceof Uint16Array) {\n const inv = 1 / 65535;\n for (let v = 0; v < count; v++) {\n out[v * 3] = data[v * comps]! * inv;\n out[v * 3 + 1] = data[v * comps + 1]! * inv;\n out[v * 3 + 2] = data[v * comps + 2]! * inv;\n }\n } else if (data instanceof Uint8Array) {\n const inv = 1 / 255;\n for (let v = 0; v < count; v++) {\n out[v * 3] = data[v * comps]! * inv;\n out[v * 3 + 1] = data[v * comps + 1]! * inv;\n out[v * 3 + 2] = data[v * comps + 2]! * inv;\n }\n }\n return out;\n}\n"],"names":[],"mappings":"AAqBO,SAAS,qBAAqB,MAAuB,OAAe,OAA6B;AACpG,QAAM,MAAM,IAAI,aAAa,QAAQ,CAAC;AACtC,MAAI,gBAAgB,cAAc;AAC9B,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,UAAI,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK;AAC3B,UAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC;AACnC,UAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC;AAAA,IACvC;AAAA,EACJ,WAAW,gBAAgB,aAAa;AACpC,UAAM,MAAM,IAAI;AAChB,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,UAAI,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK,IAAK;AAChC,UAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAK;AACxC,UAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAK;AAAA,IAC5C;AAAA,EACJ,WAAW,gBAAgB,YAAY;AACnC,UAAM,MAAM,IAAI;AAChB,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,UAAI,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK,IAAK;AAChC,UAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAK;AACxC,UAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAK;AAAA,IAC5C;AAAA,EACJ;AACA,SAAO;AACX;"}
@@ -1,4 +1,4 @@
1
- import { aT as getCompressedFormat, aU as acquireTexture, aO as getOrCreateSampler, r as resolveAccessor } from "./index-C8HOR2sB.js";
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,12 +134,15 @@ 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: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST
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];
141
- const rowBytes = Math.ceil(mip.width / format.blockW) * format.blockBytes;
142
- engine._device.queue.writeTexture({ texture, mipLevel: level }, mip.data, { bytesPerRow: rowBytes }, { width: mip.width, height: mip.height });
141
+ const blocksPerRow = Math.ceil(mip.width / format.blockW);
142
+ const rowBytes = blocksPerRow * format.blockBytes;
143
+ const copyW = blocksPerRow * format.blockW;
144
+ const copyH = Math.ceil(mip.height / format.blockH) * format.blockH;
145
+ engine._device.queue.writeTexture({ texture, mipLevel: level }, mip.data, { bytesPerRow: rowBytes }, { width: copyW, height: copyH });
143
146
  }
144
147
  const tex2d = { texture, view: texture.createView(), sampler: makeSampler(engine, mips.length), width, height, invertY: true };
145
148
  acquireTexture(tex2d);
@@ -152,7 +155,7 @@ function uploadUncompressed(engine, mips, info, sRGB) {
152
155
  size: { width, height },
153
156
  format: sRGB ? srgbFormat(info.format) : info.format,
154
157
  mipLevelCount: mips.length,
155
- usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST
158
+ usage: TU.TEXTURE_BINDING | TU.COPY_DST
156
159
  });
157
160
  for (let level = 0; level < mips.length; level++) {
158
161
  const mip = mips[level];
@@ -173,7 +176,7 @@ function uploadUncompressed(engine, mips, info, sRGB) {
173
176
  }
174
177
  async function uploadKtx2Texture2D(engine, buffer, sRGB) {
175
178
  const decoder = await loadKtx2Decoder();
176
- const decoded = await decoder.decode(new Uint8Array(buffer), RGBA_CAPS, { forceRGBA: true });
179
+ const decoded = await decoder.decode(new U8(buffer), RGBA_CAPS, { forceRGBA: true });
177
180
  const mips = validateDecoded(decoded);
178
181
  const compressed = getCompressedFormat(decoded.transcodedFormat);
179
182
  if (compressed) {
@@ -187,17 +190,18 @@ async function uploadKtx2Texture2D(engine, buffer, sRGB) {
187
190
  }
188
191
  async function decodeKtx2ImageBitmapFromBuffer(buffer) {
189
192
  const decoder = await loadKtx2Decoder();
190
- const decoded = await decoder.decode(new Uint8Array(buffer), RGBA_CAPS, { forceRGBA: true });
193
+ const decoded = await decoder.decode(new U8(buffer), RGBA_CAPS, { forceRGBA: true });
191
194
  const mip0 = validateDecoded(decoded)[0];
192
195
  if (mip0.data.length !== mip0.width * mip0.height * 4) {
193
196
  throw new Error("KTX2: RGBA decode size does not match image dimensions");
194
197
  }
195
- const pixels = new Uint8ClampedArray(mip0.data.length);
198
+ const pixels = new U8C(mip0.data.length);
196
199
  pixels.set(mip0.data);
197
200
  return createImageBitmap(new ImageData(pixels, mip0.width, mip0.height));
198
201
  }
199
202
  const NAME = "KHR_texture_basisu";
200
203
  const FLOAT = 5126;
204
+ const COMPONENT_BYTES = { 5120: 1, 5121: 1, 5122: 2, 5123: 2, 5125: 4, 5126: 4 };
201
205
  const TYPE_SIZES = {
202
206
  SCALAR: 1,
203
207
  VEC2: 2,
@@ -262,8 +266,8 @@ async function resolveImageBuffer(ctx, imageIdx) {
262
266
  throw new Error(`${NAME}: bufferView ${image.bufferView} not found`);
263
267
  }
264
268
  const offset = ctx.binChunk.byteOffset + (bv.byteOffset ?? 0);
265
- const copy = new Uint8Array(bv.byteLength);
266
- copy.set(new Uint8Array(ctx.binChunk.buffer, offset, bv.byteLength));
269
+ const copy = new U8(bv.byteLength);
270
+ copy.set(new U8(ctx.binChunk.buffer, offset, bv.byteLength));
267
271
  return copy.buffer;
268
272
  }
269
273
  if (image.uri) {
@@ -354,25 +358,56 @@ async function uploadOrmTexture(data, ctx) {
354
358
  }
355
359
  return tex;
356
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
+ }
357
389
  function readStridedFloat(json, binChunk, accessorIdx) {
358
390
  const accessor = json.accessors[accessorIdx];
359
391
  const bufferView = json.bufferViews[accessor.bufferView];
360
- if (accessor.componentType !== FLOAT) {
361
- throw new Error(`${NAME}: strided accessor ${accessorIdx} uses unsupported component type: ${accessor.componentType}`);
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}`);
362
396
  }
363
397
  const componentCount = TYPE_SIZES[accessor.type] ?? 1;
364
- const elementBytes = componentCount * 4;
398
+ const elementBytes = componentCount * compBytes;
365
399
  const byteStride = bufferView.byteStride ?? elementBytes;
366
400
  if (byteStride < elementBytes) {
367
401
  throw new Error(`${NAME}: invalid accessor stride ${byteStride} for accessor ${accessorIdx}`);
368
402
  }
403
+ const normalized = accessor.normalized === true;
369
404
  const baseOffset = binChunk.byteOffset + (bufferView.byteOffset ?? 0) + (accessor.byteOffset ?? 0);
370
- const view = new DataView(binChunk.buffer);
371
- const out = new Float32Array(accessor.count * componentCount);
405
+ const view = new DV(binChunk.buffer);
406
+ const out = new F32(accessor.count * componentCount);
372
407
  for (let i = 0, o = 0; i < accessor.count; i++) {
373
408
  const src = baseOffset + i * byteStride;
374
409
  for (let c = 0; c < componentCount; c++, o++) {
375
- out[o] = view.getFloat32(src + c * 4, true);
410
+ out[o] = readComponent(view, src + c * compBytes, componentType, normalized);
376
411
  }
377
412
  }
378
413
  return out;
@@ -403,7 +438,7 @@ const ext = {
403
438
  }
404
439
  }
405
440
  const posAcc = gltf.accessors[attrs.POSITION];
406
- const idx = primitive.indices === void 0 ? new Uint32Array(0) : new Uint32Array(resolveAccessor(gltf, binChunk, primitive.indices)._data);
441
+ const idx = primitive.indices === void 0 ? new U32(0) : new U32(resolveAccessor(gltf, binChunk, primitive.indices)._data);
407
442
  decoded.set(primitive, {
408
443
  _attributes: attributes,
409
444
  _indices: idx,
@@ -449,4 +484,4 @@ const ext = {
449
484
  export {
450
485
  ext as default
451
486
  };
452
- //# sourceMappingURL=gltf-ext-basisu-CPg5kPrx.js.map
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 { h as setSubtreeVisible } from "./index-C8HOR2sB.js";
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-MafA9ot2.js.map
25
+ //# sourceMappingURL=gltf-ext-node-visibility-DXCJEYr6.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gltf-ext-node-visibility-MafA9ot2.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
+ {"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 Uint8Array(out).set(new Uint8Array(binChunk.buffer, binChunk.byteOffset, binChunk.byteLength));
63
- const outView = new DataView(out);
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-CpZyLDIz.js.map
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":"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"}
@@ -1,4 +1,4 @@
1
- import { f as cloneTexture2D } from "./index-C8HOR2sB.js";
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-CE_-T1Tr.js.map
38
+ //# sourceMappingURL=gltf-ext-uv-transform-DgYazJBs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gltf-ext-uv-transform-CE_-T1Tr.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;"}
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;"}