@babylonjs/lite 0.2.0 → 1.0.1

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 (253) hide show
  1. package/{_mat4-storage-f64-Bvh5TymE.js → _mat4-storage-f64-BW9sTaVh.js} +3 -2
  2. package/_mat4-storage-f64-BW9sTaVh.js.map +1 -0
  3. package/{alpha-test-fragment-BCChpzaV.js → alpha-test-fragment-eUG971h3.js} +2 -2
  4. package/{alpha-test-fragment-BCChpzaV.js.map → alpha-test-fragment-eUG971h3.js.map} +1 -1
  5. package/assets/splat-sort-worker-DT3eybMZ.js.map +1 -0
  6. package/{background-dds-skybox-ZjrSIxrT.js → background-dds-skybox-BwG0kYQP.js} +13 -13
  7. package/background-dds-skybox-BwG0kYQP.js.map +1 -0
  8. package/{background-ground-B2Mie-MI.js → background-ground-DiFpKJzF.js} +19 -19
  9. package/background-ground-DiFpKJzF.js.map +1 -0
  10. package/{background-hdr-skybox-DDRJYuT2.js → background-hdr-skybox-DIgJhvfj.js} +10 -10
  11. package/background-hdr-skybox-DIgJhvfj.js.map +1 -0
  12. package/{background-solid-skybox-fjXlnWaD.js → background-solid-skybox--fqHdan_.js} +11 -12
  13. package/background-solid-skybox--fqHdan_.js.map +1 -0
  14. package/{billboard-renderable-DKmlOgbM.js → billboard-renderable-HY2XCd52.js} +46 -10
  15. package/billboard-renderable-HY2XCd52.js.map +1 -0
  16. package/{clamp-block-CxRBPlUq.js → clamp-block-XHdUk2Va.js} +2 -2
  17. package/{clamp-block-CxRBPlUq.js.map → clamp-block-XHdUk2Va.js.map} +1 -1
  18. package/{clearcoat-fragment-KbZAa0TA.js → clearcoat-fragment-CHYw8MPB.js} +2 -2
  19. package/{clearcoat-fragment-KbZAa0TA.js.map → clearcoat-fragment-CHYw8MPB.js.map} +1 -1
  20. package/{create-skeleton-BBI5urcj.js → create-skeleton-9tdiUjRP.js} +9 -9
  21. package/create-skeleton-9tdiUjRP.js.map +1 -0
  22. package/{cubemap-skybox-material-DvW81drX.js → cubemap-skybox-material-DqQ0dyz8.js} +6 -7
  23. package/cubemap-skybox-material-DqQ0dyz8.js.map +1 -0
  24. package/{curve-block-Dh_xdUj-.js → curve-block-S27sXrJQ.js} +2 -2
  25. package/{curve-block-Dh_xdUj-.js.map → curve-block-S27sXrJQ.js.map} +1 -1
  26. package/{emissive-fragment-DD8cvHyx.js → emissive-fragment-CZMQ0_bF.js} +3 -3
  27. package/emissive-fragment-CZMQ0_bF.js.map +1 -0
  28. package/{esm-shadow-view-DHVS9r7H.js → esm-shadow-view-CUwxbnMR.js} +2 -2
  29. package/{esm-shadow-view-DHVS9r7H.js.map → esm-shadow-view-CUwxbnMR.js.map} +1 -1
  30. package/{esm-shadow-view-15S4JK6p.js → esm-shadow-view-Cl36rOrK.js} +2 -2
  31. package/{esm-shadow-view-15S4JK6p.js.map → esm-shadow-view-Cl36rOrK.js.map} +1 -1
  32. package/{esm-shadow-view-DYAc62Kl.js → esm-shadow-view-DKQ-FSoV.js} +2 -2
  33. package/{esm-shadow-view-DYAc62Kl.js.map → esm-shadow-view-DKQ-FSoV.js.map} +1 -1
  34. package/{gaussian-splatting-pipeline-sh-BvkUhA9V.js → gaussian-splatting-pipeline-sh-DDo7QQ8l.js} +19 -19
  35. package/gaussian-splatting-pipeline-sh-DDo7QQ8l.js.map +1 -0
  36. package/geometry-texture-output-BmuAquio.js +41 -0
  37. package/geometry-texture-output-BmuAquio.js.map +1 -0
  38. package/geometry-view-xWZmq799.js +404 -0
  39. package/geometry-view-xWZmq799.js.map +1 -0
  40. package/{gltf-animation-KnPzeOIY.js → gltf-animation-Bq7k_5HA.js} +6 -6
  41. package/gltf-animation-Bq7k_5HA.js.map +1 -0
  42. package/{gltf-ext-basisu-kmth3UWX.js → gltf-ext-basisu-C5teqxzQ.js} +43 -211
  43. package/gltf-ext-basisu-C5teqxzQ.js.map +1 -0
  44. package/{gltf-ext-node-visibility-BjRRd6si.js → gltf-ext-node-visibility-DnGTKkMf.js} +2 -2
  45. package/{gltf-ext-node-visibility-BjRRd6si.js.map → gltf-ext-node-visibility-DnGTKkMf.js.map} +1 -1
  46. package/{gltf-ext-quantization-CpZyLDIz.js → gltf-ext-quantization-DheC7FhB.js} +4 -3
  47. package/gltf-ext-quantization-DheC7FhB.js.map +1 -0
  48. package/{gltf-ext-uv-transform-MHmR-YyM.js → gltf-ext-uv-transform-DljdVllE.js} +2 -2
  49. package/{gltf-ext-uv-transform-MHmR-YyM.js.map → gltf-ext-uv-transform-DljdVllE.js.map} +1 -1
  50. package/{gltf-feature-animation-pointer-rFqLfbO_.js → gltf-feature-animation-pointer-DVhymFLK.js} +9 -9
  51. package/gltf-feature-animation-pointer-DVhymFLK.js.map +1 -0
  52. package/{gltf-feature-animations-DikONdzi.js → gltf-feature-animations-hxC3y3bJ.js} +2 -2
  53. package/{gltf-feature-animations-DikONdzi.js.map → gltf-feature-animations-hxC3y3bJ.js.map} +1 -1
  54. package/{gltf-feature-draco-yGSMGTE3.js → gltf-feature-draco-B7Q_cMUv.js} +6 -5
  55. package/gltf-feature-draco-B7Q_cMUv.js.map +1 -0
  56. package/{gltf-feature-gpu-instancing-Cj1XjmM6.js → gltf-feature-gpu-instancing-C7sRzWv7.js} +4 -4
  57. package/gltf-feature-gpu-instancing-C7sRzWv7.js.map +1 -0
  58. package/{gltf-feature-lights-punctual-C-0SlGmD.js → gltf-feature-lights-punctual-DF7kya14.js} +5 -5
  59. package/{gltf-feature-lights-punctual-C-0SlGmD.js.map → gltf-feature-lights-punctual-DF7kya14.js.map} +1 -1
  60. package/{gltf-feature-meshopt-Des96YFI.js → gltf-feature-meshopt-DRG9hEqT.js} +7 -6
  61. package/gltf-feature-meshopt-DRG9hEqT.js.map +1 -0
  62. package/{gltf-feature-morph-BAcY14XU.js → gltf-feature-morph-DZydYgWp.js} +4 -4
  63. package/gltf-feature-morph-DZydYgWp.js.map +1 -0
  64. package/{gltf-feature-registry-97sY_x5O.js → gltf-feature-registry-DeYdy3DV.js} +15 -15
  65. package/{gltf-feature-registry-97sY_x5O.js.map → gltf-feature-registry-DeYdy3DV.js.map} +1 -1
  66. package/{gltf-feature-skeleton-lVjkDfIU.js → gltf-feature-skeleton-B9och1W0.js} +3 -3
  67. package/{gltf-feature-skeleton-lVjkDfIU.js.map → gltf-feature-skeleton-B9och1W0.js.map} +1 -1
  68. package/{gltf-feature-variants-BphF4JmV.js → gltf-feature-variants-CY_Qft7f.js} +2 -2
  69. package/{gltf-feature-variants-BphF4JmV.js.map → gltf-feature-variants-CY_Qft7f.js.map} +1 -1
  70. package/{gltf-glb-parser-D6UZWFuC.js → gltf-glb-parser-CqOeXFOz.js} +5 -4
  71. package/gltf-glb-parser-CqOeXFOz.js.map +1 -0
  72. package/{gltf-interleave-C9eBqH_F.js → gltf-interleave-DWf27t-h.js} +14 -15
  73. package/gltf-interleave-DWf27t-h.js.map +1 -0
  74. package/{gltf-pbr-builder-ext-DPC0zg_u.js → gltf-pbr-builder-ext-DvFxuOqN.js} +5 -5
  75. package/gltf-pbr-builder-ext-DvFxuOqN.js.map +1 -0
  76. package/{gltf-variants-CnBEZr0o.js → gltf-variants-CUvzYGYX.js} +4 -4
  77. package/{gltf-variants-CnBEZr0o.js.map → gltf-variants-CUvzYGYX.js.map} +1 -1
  78. package/gpu-task-timer-Dgkff80h.js +236 -0
  79. package/gpu-task-timer-Dgkff80h.js.map +1 -0
  80. package/gpu-timer-CUpqT_hK.js +55 -0
  81. package/gpu-timer-CUpqT_hK.js.map +1 -0
  82. package/{gs-picking-pipeline-Bx8LTav6.js → gs-picking-pipeline-55sM5LzV.js} +14 -14
  83. package/gs-picking-pipeline-55sM5LzV.js.map +1 -0
  84. package/havok-floating-origin-5xp32P-C.js +198 -0
  85. package/havok-floating-origin-5xp32P-C.js.map +1 -0
  86. package/index-C-tEgwbZ.js +41056 -0
  87. package/index-C-tEgwbZ.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 +2490 -108
  93. package/index.js +476 -323
  94. package/{input-block-Coi_aZwl.js → input-block-DbRYCnet.js} +2 -2
  95. package/{input-block-Coi_aZwl.js.map → input-block-DbRYCnet.js.map} +1 -1
  96. package/{iridescence-fragment-DwZcCTdD.js → iridescence-fragment-S3Ko1jvC.js} +2 -2
  97. package/{iridescence-fragment-DwZcCTdD.js.map → iridescence-fragment-S3Ko1jvC.js.map} +1 -1
  98. package/{light-block-Np_h5gPI.js → light-block-CAqWkucp.js} +2 -2
  99. package/{light-block-Np_h5gPI.js.map → light-block-CAqWkucp.js.map} +1 -1
  100. package/{loop-block-BFkLFYGm.js → loop-block-ch-biPFY.js} +2 -2
  101. package/{loop-block-BFkLFYGm.js.map → loop-block-ch-biPFY.js.map} +1 -1
  102. package/{morph-fragment-DqH-w61u.js → morph-fragment-D9he3Ksk.js} +2 -2
  103. package/{morph-fragment-DqH-w61u.js.map → morph-fragment-D9he3Ksk.js.map} +1 -1
  104. package/{multilight-wgsl-B9Mf9d-q.js → multilight-wgsl-74aXpcJG.js} +2 -2
  105. package/{multilight-wgsl-B9Mf9d-q.js.map → multilight-wgsl-74aXpcJG.js.map} +1 -1
  106. package/{node-env-BPZXZzBf.js → node-env-B2bjGcMS.js} +6 -5
  107. package/node-env-B2bjGcMS.js.map +1 -0
  108. package/node-geometry-view-CSXlEAhG.js +291 -0
  109. package/node-geometry-view-CSXlEAhG.js.map +1 -0
  110. package/{node-registry-extra-compat-Ch7ApZHF.js → node-registry-extra-compat-BEQH_ksg.js} +2 -2
  111. package/{node-registry-extra-compat-Ch7ApZHF.js.map → node-registry-extra-compat-BEQH_ksg.js.map} +1 -1
  112. package/{node-registry-extra-math-6ezzTkPj.js → node-registry-extra-math-Bm32WBAa.js} +2 -2
  113. package/{node-registry-extra-math-6ezzTkPj.js.map → node-registry-extra-math-Bm32WBAa.js.map} +1 -1
  114. package/{node-renderable-CS0CmsSp.js → node-renderable-BMHny4tC.js} +15 -13
  115. package/node-renderable-BMHny4tC.js.map +1 -0
  116. package/{node-shadow-CpnrdvtJ.js → node-shadow-BRiz7CT1.js} +7 -7
  117. package/node-shadow-BRiz7CT1.js.map +1 -0
  118. package/{normal-map-fragment-DradEMl-.js → normal-map-fragment-sE3TjF4U.js} +2 -2
  119. package/{normal-map-fragment-DradEMl-.js.map → normal-map-fragment-sE3TjF4U.js.map} +1 -1
  120. package/package.json +3 -10
  121. package/{parse-camera-CgV4bWc0.js → parse-camera-CmZBS423.js} +2 -2
  122. package/{parse-camera-CgV4bWc0.js.map → parse-camera-CmZBS423.js.map} +1 -1
  123. package/pbr-geometry-view-T3vMABM8.js +491 -0
  124. package/pbr-geometry-view-T3vMABM8.js.map +1 -0
  125. package/{pbr-metallic-roughness-block-BFwZj2Nw.js → pbr-metallic-roughness-block-DbozMlHU.js} +2 -2
  126. package/{pbr-metallic-roughness-block-BFwZj2Nw.js.map → pbr-metallic-roughness-block-DbozMlHU.js.map} +1 -1
  127. package/{pbr-metallic-roughness-block-full-5t0HT3xl.js → pbr-metallic-roughness-block-full-CHC8w-Uv.js} +2 -2
  128. package/{pbr-metallic-roughness-block-full-5t0HT3xl.js.map → pbr-metallic-roughness-block-full-CHC8w-Uv.js.map} +1 -1
  129. package/{pbr-mr-helper-core-R5tOZ8Ap.js → pbr-mr-helper-core-DGRgbRXl.js} +2 -2
  130. package/{pbr-mr-helper-core-R5tOZ8Ap.js.map → pbr-mr-helper-core-DGRgbRXl.js.map} +1 -1
  131. package/{pbr-refraction-Dd11HnaI.js → pbr-refraction-CquDP9JO.js} +2 -2
  132. package/{pbr-refraction-Dd11HnaI.js.map → pbr-refraction-CquDP9JO.js.map} +1 -1
  133. package/{pbr-renderable-BHAdF5Vw.js → pbr-renderable-CaHKHU0g.js} +60 -42
  134. package/pbr-renderable-CaHKHU0g.js.map +1 -0
  135. package/{pbr-shadow-fragment-BxUrFJYZ.js → pbr-shadow-fragment-DmnNe6yz.js} +2 -2
  136. package/{pbr-shadow-fragment-BxUrFJYZ.js.map → pbr-shadow-fragment-DmnNe6yz.js.map} +1 -1
  137. package/{pbr-tracking-D6i3yPb7.js → pbr-tracking-Bo7RTANK.js} +2 -2
  138. package/{pbr-tracking-D6i3yPb7.js.map → pbr-tracking-Bo7RTANK.js.map} +1 -1
  139. package/{pbr-transmission-ext-Dll8EYwE.js → pbr-transmission-ext-CoGcJBGE.js} +2 -2
  140. package/{pbr-transmission-ext-Dll8EYwE.js.map → pbr-transmission-ext-CoGcJBGE.js.map} +1 -1
  141. package/recast-navigation.wasm-DG_0AFuk.js +8706 -0
  142. package/recast-navigation.wasm-DG_0AFuk.js.map +1 -0
  143. package/recast-navigation.wasm-compat-C-Bf2ylB.js +8692 -0
  144. package/recast-navigation.wasm-compat-C-Bf2ylB.js.map +1 -0
  145. package/{reflectance-fragment-ejMJ4O1o.js → reflectance-fragment-CExe6qDY.js} +2 -2
  146. package/{reflectance-fragment-ejMJ4O1o.js.map → reflectance-fragment-CExe6qDY.js.map} +1 -1
  147. package/{rgbd-decode-DCvzUYeI.js → rgbd-decode-DkiiiIlt.js} +7 -6
  148. package/rgbd-decode-DkiiiIlt.js.map +1 -0
  149. package/{scene-material-swap-C2ykv55W.js → scene-material-swap-4qM0tpBK.js} +11 -5
  150. package/scene-material-swap-4qM0tpBK.js.map +1 -0
  151. package/screenshot-readback-avr_tYGZ.js +92 -0
  152. package/screenshot-readback-avr_tYGZ.js.map +1 -0
  153. package/{mesh-features-BAJpbMog.js → shader-composer-CZagsJDS.js} +3 -54
  154. package/shader-composer-CZagsJDS.js.map +1 -0
  155. package/{shader-renderable-BMf_vvO0.js → shader-renderable-D5sbgzxt.js} +62 -24
  156. package/shader-renderable-D5sbgzxt.js.map +1 -0
  157. package/{shader-thin-instance-5_WUfi3m.js → shader-thin-instance-CkQ8rrfH.js} +4 -4
  158. package/shader-thin-instance-CkQ8rrfH.js.map +1 -0
  159. package/{sheen-fragment-CS6z29Fs.js → sheen-fragment-BEigjpTX.js} +2 -2
  160. package/{sheen-fragment-CS6z29Fs.js.map → sheen-fragment-BEigjpTX.js.map} +1 -1
  161. package/{singlelight-directional-wgsl-4MIgZMeC.js → singlelight-directional-wgsl-Ccsk-ys3.js} +2 -2
  162. package/{singlelight-directional-wgsl-4MIgZMeC.js.map → singlelight-directional-wgsl-Ccsk-ys3.js.map} +1 -1
  163. package/{singlelight-hemispheric-wgsl-CK-GUYWe.js → singlelight-hemispheric-wgsl-DL-jpc97.js} +2 -2
  164. package/{singlelight-hemispheric-wgsl-CK-GUYWe.js.map → singlelight-hemispheric-wgsl-DL-jpc97.js.map} +1 -1
  165. package/{singlelight-point-wgsl-CYtzqCbP.js → singlelight-point-wgsl-hYmiP6ys.js} +2 -2
  166. package/{singlelight-point-wgsl-CYtzqCbP.js.map → singlelight-point-wgsl-hYmiP6ys.js.map} +1 -1
  167. package/{singlelight-spot-wgsl-DVbaVufF.js → singlelight-spot-wgsl-DSjp1p1C.js} +2 -2
  168. package/{singlelight-spot-wgsl-DVbaVufF.js.map → singlelight-spot-wgsl-DSjp1p1C.js.map} +1 -1
  169. package/{skeleton-fragment-BOVmc8YS.js → skeleton-fragment-B__bUbPK.js} +2 -2
  170. package/{skeleton-fragment-BOVmc8YS.js.map → skeleton-fragment-B__bUbPK.js.map} +1 -1
  171. package/{skybox-renderable-DDcCPSly.js → skybox-renderable-BH6uUkal.js} +7 -8
  172. package/skybox-renderable-BH6uUkal.js.map +1 -0
  173. package/{splat-ply-compressed-BahdBG1r.js → splat-ply-compressed-BGNK6dnh.js} +9 -8
  174. package/splat-ply-compressed-BGNK6dnh.js.map +1 -0
  175. package/{standard-renderable-D1bhoF0K.js → standard-pipeline-BvFynkwL.js} +11 -202
  176. package/standard-pipeline-BvFynkwL.js.map +1 -0
  177. package/standard-renderable-1Q3zemys.js +191 -0
  178. package/standard-renderable-1Q3zemys.js.map +1 -0
  179. package/{std-ambient-fragment-C6WNm8dQ.js → std-ambient-fragment-__F1KTEu.js} +2 -2
  180. package/{std-ambient-fragment-C6WNm8dQ.js.map → std-ambient-fragment-__F1KTEu.js.map} +1 -1
  181. package/{std-cube-reflection-fragment-Bqutpy2q.js → std-cube-reflection-fragment-DidM0byH.js} +2 -2
  182. package/{std-cube-reflection-fragment-Bqutpy2q.js.map → std-cube-reflection-fragment-DidM0byH.js.map} +1 -1
  183. package/{std-emissive-fragment-B-A83rqX.js → std-emissive-fragment-Bj62X4Np.js} +2 -2
  184. package/{std-emissive-fragment-B-A83rqX.js.map → std-emissive-fragment-Bj62X4Np.js.map} +1 -1
  185. package/{std-lightmap-fragment-Df7KJezh.js → std-lightmap-fragment-DXvfWvKc.js} +2 -2
  186. package/{std-lightmap-fragment-Df7KJezh.js.map → std-lightmap-fragment-DXvfWvKc.js.map} +1 -1
  187. package/{std-opacity-fragment-D9et2jip.js → std-opacity-fragment-BzMMb1K_.js} +2 -2
  188. package/{std-opacity-fragment-D9et2jip.js.map → std-opacity-fragment-BzMMb1K_.js.map} +1 -1
  189. package/{std-reflection-fragment-DBJeT-yg.js → std-reflection-fragment-DC9Kvu1C.js} +2 -2
  190. package/{std-reflection-fragment-DBJeT-yg.js.map → std-reflection-fragment-DC9Kvu1C.js.map} +1 -1
  191. package/{std-shadow-fragment-C6fD8rW-.js → std-shadow-fragment-BnMHeF1-.js} +2 -2
  192. package/{std-shadow-fragment-C6fD8rW-.js.map → std-shadow-fragment-BnMHeF1-.js.map} +1 -1
  193. package/{std-specular-fragment-C2ZOss-t.js → std-specular-fragment-Bio681OG.js} +2 -2
  194. package/{std-specular-fragment-C2ZOss-t.js.map → std-specular-fragment-Bio681OG.js.map} +1 -1
  195. package/{std-tracking-C4L4nQGc.js → std-tracking-BTcrry2o.js} +2 -2
  196. package/{std-tracking-C4L4nQGc.js.map → std-tracking-BTcrry2o.js.map} +1 -1
  197. package/{subsurface-fragment-C1H4ytqK.js → subsurface-fragment-DpKib445.js} +2 -2
  198. package/{subsurface-fragment-C1H4ytqK.js.map → subsurface-fragment-DpKib445.js.map} +1 -1
  199. package/swapchain-overlay-UCLilhbq.js +37 -0
  200. package/swapchain-overlay-UCLilhbq.js.map +1 -0
  201. package/{thin-instance-cull-binding-CCxrPNO6.js → thin-instance-cull-binding-DwZi7mlE.js} +12 -12
  202. package/thin-instance-cull-binding-DwZi7mlE.js.map +1 -0
  203. package/{thin-instance-gpu-E8DBd8XL.js → thin-instance-gpu-uY2NOv0J.js} +15 -7
  204. package/thin-instance-gpu-uY2NOv0J.js.map +1 -0
  205. package/{tracking-primitives-w4BVV9p9.js → tracking-primitives-Ck5bgCuo.js} +2 -2
  206. package/{tracking-primitives-w4BVV9p9.js.map → tracking-primitives-Ck5bgCuo.js.map} +1 -1
  207. package/{unlit-fragment-DU9_mhzZ.js → unlit-fragment-nc6hu3Mw.js} +2 -2
  208. package/{unlit-fragment-DU9_mhzZ.js.map → unlit-fragment-nc6hu3Mw.js.map} +1 -1
  209. package/_mat4-storage-f64-Bvh5TymE.js.map +0 -1
  210. package/assets/splat-sort-worker-Crg3CaCc.js.map +0 -1
  211. package/background-dds-skybox-ZjrSIxrT.js.map +0 -1
  212. package/background-ground-B2Mie-MI.js.map +0 -1
  213. package/background-hdr-skybox-DDRJYuT2.js.map +0 -1
  214. package/background-solid-skybox-fjXlnWaD.js.map +0 -1
  215. package/billboard-renderable-DKmlOgbM.js.map +0 -1
  216. package/create-skeleton-BBI5urcj.js.map +0 -1
  217. package/cubemap-skybox-material-DvW81drX.js.map +0 -1
  218. package/emissive-fragment-DD8cvHyx.js.map +0 -1
  219. package/gaussian-splatting-pipeline-sh-BvkUhA9V.js.map +0 -1
  220. package/gltf-animation-KnPzeOIY.js.map +0 -1
  221. package/gltf-ext-basisu-kmth3UWX.js.map +0 -1
  222. package/gltf-ext-quantization-CpZyLDIz.js.map +0 -1
  223. package/gltf-feature-animation-pointer-rFqLfbO_.js.map +0 -1
  224. package/gltf-feature-draco-yGSMGTE3.js.map +0 -1
  225. package/gltf-feature-gpu-instancing-Cj1XjmM6.js.map +0 -1
  226. package/gltf-feature-meshopt-Des96YFI.js.map +0 -1
  227. package/gltf-feature-morph-BAcY14XU.js.map +0 -1
  228. package/gltf-glb-parser-D6UZWFuC.js.map +0 -1
  229. package/gltf-interleave-C9eBqH_F.js.map +0 -1
  230. package/gltf-pbr-builder-ext-DPC0zg_u.js.map +0 -1
  231. package/gs-picking-pipeline-Bx8LTav6.js.map +0 -1
  232. package/index-B7Qhw0xL.js +0 -21232
  233. package/index-B7Qhw0xL.js.map +0 -1
  234. package/mesh-features-BAJpbMog.js.map +0 -1
  235. package/no-color-view-DsyLSL-W.js +0 -8
  236. package/no-color-view-DsyLSL-W.js.map +0 -1
  237. package/node-env-BPZXZzBf.js.map +0 -1
  238. package/node-registry-Bd-AlrgC.js +0 -190
  239. package/node-registry-Bd-AlrgC.js.map +0 -1
  240. package/node-renderable-CS0CmsSp.js.map +0 -1
  241. package/node-shadow-CpnrdvtJ.js.map +0 -1
  242. package/pbr-renderable-BHAdF5Vw.js.map +0 -1
  243. package/rgbd-decode-DCvzUYeI.js.map +0 -1
  244. package/scene-material-swap-C2ykv55W.js.map +0 -1
  245. package/shader-renderable-BMf_vvO0.js.map +0 -1
  246. package/shader-thin-instance-5_WUfi3m.js.map +0 -1
  247. package/skybox-renderable-DDcCPSly.js.map +0 -1
  248. package/splat-ply-compressed-BahdBG1r.js.map +0 -1
  249. package/standard-renderable-D1bhoF0K.js.map +0 -1
  250. package/swapchain-overlay-DcCSFDp7.js +0 -35
  251. package/swapchain-overlay-DcCSFDp7.js.map +0 -1
  252. package/thin-instance-cull-binding-CCxrPNO6.js.map +0 -1
  253. package/thin-instance-gpu-E8DBd8XL.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"gaussian-splatting-pipeline-sh-BvkUhA9V.js","sources":["../src/mesh/GaussianSplatting/gaussian-splatting-pipeline-sh.ts"],"sourcesContent":["/** Gaussian-Splatting SH render pipeline + Renderable.\n *\n * Variant of `gaussian-splatting-pipeline.ts` that adds view-dependent SH\n * shading. Loaded *only* by `loadSplat` (and the SOG / SPZ loaders) via a\n * dynamic `import(...)` when the parsed splat asset includes SH coefficients\n * (`mesh.shDegree > 0`), so plain `.ply` / `.splat` scenes (e.g. scene 120)\n * never pull this module's WGSL or runtime cost into their bundle.\n *\n * WGSL source is generated per-shDegree by `buildShShaderSource`: SH textures,\n * byte-to-vec3 unpacking, and the polynomial evaluation in\n * `computeColorFromSHDegree` all expand to the right size — mirrors the\n * `#if SH_DEGREE > N` blocks in BJS `gaussianSplatting.fx`. Pipeline cache is\n * keyed by `(targetSignatureKey, shDegree)`.\n *\n * The UBO grows by 16 bytes vs the base pipeline to carry `eyePosition`\n * (world-space camera position; see `computeSH(dir)` below).\n *\n * ── Why the Y-flip on the SH direction? ─────────────────────────────────\n * BJS sets `mesh.scaling.y *= -1` to fix coordinate-system handedness; Lite\n * pre-flips Y in `splat-data.ts` at parse time so the runtime mesh transform\n * is identity. World-space splat positions agree across both engines, but\n * the BJS world rotation absorbs an extra `diag(1,-1,1)` factor — i.e.\n * worldRot_bjs = worldRot_user · diag(1,-1,1)\n * which means\n * inverse(worldRot_bjs) · v = diag(1,-1,1) · inverse(worldRot_user) · v\n * so Lite reproduces the BJS SH direction by computing\n * `inverseMat3(worldRot) · (worldPos − eye)` and then negating `.y`. */\n\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { SceneContext } from \"../../scene/scene-core.js\";\nimport type { Renderable, DrawBinding } from \"../../render/renderable.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\nimport { targetSignatureKey } from \"../../engine/render-target.js\";\nimport { getViewMatrix, getProjectionMatrix, getCameraPosition } from \"../../camera/camera.js\";\nimport { getSceneBindGroupLayout } from \"../../render/scene-helpers.js\";\nimport { getRenderTargetSize } from \"../../engine/engine.js\";\nimport { disposeGaussianSplattingMesh, type GaussianSplattingMesh, type GsShaderFragment } from \"./gaussian-splatting-mesh.js\";\nimport { applyGsFragments } from \"./gaussian-splatting-pipeline.js\";\n\ninterface PipelineEntry {\n pipeline: GPURenderPipeline;\n meshBindGroupLayout: GPUBindGroupLayout;\n shTextureCount: number;\n}\n\n// shDegree → number of rgba32uint SH textures: 1→1, 2→2, 3→3, 4→5.\nconst SH_TEXTURE_COUNT = [0, 1, 2, 3, 5];\n\nlet _cache: { device: GPUDevice; modules: Map<string, GPUShaderModule>; entries: Map<string, PipelineEntry> } | null = null;\n\n/** Build the WGSL source for a given SH degree (1..4). Mirrors the BJS\n * preprocessor-driven shader structure: declares only the SH textures used\n * by the degree, emits exactly the byte-stream unpacking for that degree,\n * and inlines only the SH polynomial terms up to that degree. */\nfunction buildShShaderSource(shDegree: number): string {\n const shVectorCount = (shDegree + 1) * (shDegree + 1) - 1;\n const shCoefficientCount = shVectorCount * 3;\n const textureCount = Math.ceil(shCoefficientCount / 16);\n\n // ── SH texture bindings (6, 7, …) ───────────────────────────────\n let textureBindings = \"\";\n for (let i = 0; i < textureCount; i++) {\n textureBindings += `@group(1) @binding(${6 + i}) var shTexture${i}: texture_2d<u32>;\\n`;\n }\n\n // ── textureLoad calls inside readSplat ──────────────────────────\n let textureLoads = \"\";\n for (let i = 0; i < textureCount; i++) {\n textureLoads += ` let sh${i}_u32 = textureLoad(shTexture${i}, splatUVi32, 0);\\n`;\n }\n\n // ── Unpack the byte stream into sh[1..shVectorCount] vec3 values.\n //\n // Each rgba32uint texel carries 16 bytes (4 u32s × 4 bytes). The bytes\n // are stored in BJS-coefficient order: byte j of splat i is the j-th\n // component of the [R0,G0,B0, R1,G1,B1, …, R(N-1),G(N-1),B(N-1)] sequence.\n // sh[k+1] (k = 0..shVectorCount-1) reads bytes [3k, 3k+1, 3k+2]. `decompose`\n // returns `(byte * 2/255) - 1`, matching BJS exactly.\n let shUnpack = ` var sh: array<vec3<f32>, ${shVectorCount + 1}>;\\n sh[0] = vec3<f32>(0.0);\\n`;\n const byteRef = (j: number): string => {\n // texture index, u32 index within texel (0..3), byte index within u32 (0..3 == x/y/z/w).\n const tex = (j / 16) | 0;\n const u32Idx = ((j % 16) / 4) | 0;\n const byteIdx = j % 4;\n const u32Field = [\"x\", \"y\", \"z\", \"w\"][u32Idx]!;\n const byteField = [\"x\", \"y\", \"z\", \"w\"][byteIdx]!;\n return `decompose(sh${tex}_u32.${u32Field}).${byteField}`;\n };\n for (let k = 0; k < shVectorCount; k++) {\n const j = k * 3;\n shUnpack += ` sh[${k + 1}] = vec3<f32>(${byteRef(j)}, ${byteRef(j + 1)}, ${byteRef(j + 2)});\\n`;\n }\n\n // ── Polynomial evaluation, conditional on shDegree ──────────────\n let shPoly = \" result = sh[0];\\n\";\n if (shDegree >= 1) {\n shPoly += ` result += -SH_C1 * y * sh[1] + SH_C1 * z * sh[2] - SH_C1 * x * sh[3];\\n`;\n }\n if (shDegree >= 2) {\n shPoly += ` result +=\\n SH_C2[0] * xy * sh[4] +\\n SH_C2[1] * yz * sh[5] +\\n SH_C2[2] * (2.0 * zz - xx - yy) * sh[6] +\\n SH_C2[3] * xz * sh[7] +\\n SH_C2[4] * (xx - yy) * sh[8];\\n`;\n }\n if (shDegree >= 3) {\n shPoly += ` result +=\\n SH_C3[0] * y * (3.0 * xx - yy) * sh[9] +\\n SH_C3[1] * xy * z * sh[10] +\\n SH_C3[2] * y * (4.0 * zz - xx - yy) * sh[11] +\\n SH_C3[3] * z * (2.0 * zz - 3.0 * xx - 3.0 * yy) * sh[12] +\\n SH_C3[4] * x * (4.0 * zz - xx - yy) * sh[13] +\\n SH_C3[5] * z * (xx - yy) * sh[14] +\\n SH_C3[6] * x * (xx - 3.0 * yy) * sh[15];\\n`;\n }\n if (shDegree >= 4) {\n shPoly += ` result +=\\n SH_C4[0] * x * y * (xx - yy) * sh[16] +\\n SH_C4[1] * y * z * (3.0 * xx - yy) * sh[17] +\\n SH_C4[2] * x * y * (7.0 * zz - 1.0) * sh[18] +\\n SH_C4[3] * y * z * (7.0 * zz - 3.0) * sh[19] +\\n SH_C4[4] * (zz * (35.0 * zz - 30.0) + 3.0) * sh[20] +\\n SH_C4[5] * x * z * (7.0 * zz - 3.0) * sh[21] +\\n SH_C4[6] * (xx - yy) * (7.0 * zz - 1.0) * sh[22] +\\n SH_C4[7] * x * z * (xx - 3.0 * yy) * sh[23] +\\n SH_C4[8] * (xx * (xx - 3.0 * yy) - yy * (3.0 * xx - yy)) * sh[24];\\n`;\n }\n\n // SH_C2..SH_C4 constants — only declare what's referenced (silences\n // WGSL \"unused array\" warnings on lower degrees).\n let constantsBlock = `const SH_C1: f32 = 0.48860251;\\n`;\n if (shDegree >= 2) {\n constantsBlock += `const SH_C2: array<f32, 5> = array<f32, 5>(1.092548430, -1.09254843, 0.315391565, -1.09254843, 0.546274215);\\n`;\n }\n if (shDegree >= 3) {\n constantsBlock += `const SH_C3: array<f32, 7> = array<f32, 7>(-0.59004358, 2.890611442, -0.45704579, 0.373176332, -0.45704579, 1.445305721, -0.59004358);\\n`;\n }\n if (shDegree >= 4) {\n constantsBlock += `const SH_C4: array<f32, 9> = array<f32, 9>(2.5033429418, -1.7701307698, 0.9461746958, -0.6690465436, 0.1057855469, -0.6690465436, 0.4730873479, -1.7701307698, 0.6258357354);\\n`;\n }\n\n return `// Gaussian Splatting — vertex + fragment WGSL (SH degree ${shDegree}).\n// Generated by buildShShaderSource. Mirrors BJS gaussianSplatting.vertex.fx +\n// gaussianSplatting.fx (SH_DEGREE = ${shDegree}, no compound parts).\nstruct U {\n world: mat4x4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n viewport: vec2<f32>,\n focal: vec2<f32>,\n dataSize: vec2<f32>,\n alpha: f32,\n _pad0: f32,\n eyePosition: vec3<f32>,\n _pad1: f32,\n};\n@group(1) @binding(0) var<uniform> u: U;\n@group(1) @binding(1) var samp: sampler;\n@group(1) @binding(2) var centersTex: texture_2d<f32>;\n@group(1) @binding(3) var covATex: texture_2d<f32>;\n@group(1) @binding(4) var covBTex: texture_2d<f32>;\n@group(1) @binding(5) var colorsTex: texture_2d<f32>;\n${textureBindings}\n\nstruct VOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) vColor: vec4<f32>,\n @location(1) vPos: vec2<f32>,\n};\n\n${constantsBlock}\n\nfn dataUv(idx: f32) -> vec2<f32> {\n let y = floor(idx / u.dataSize.x);\n let x = idx - y * u.dataSize.x;\n return vec2<f32>((x + 0.5) / u.dataSize.x, (y + 0.5) / u.dataSize.y);\n}\n\nfn dataUvI(idx: f32) -> vec2<i32> {\n let y = floor(idx / u.dataSize.x);\n let x = idx - y * u.dataSize.x;\n return vec2<i32>(i32(x), i32(y));\n}\n\n// Unpack a u32 of 4 packed bytes into (b0 b1 b2 b3) * 2/255 - 1.\nfn decompose(value: u32) -> vec4<f32> {\n let v = vec4<f32>(\n f32((value >> 0u) & 255u),\n f32((value >> 8u) & 255u),\n f32((value >> 16u) & 255u),\n f32((value >> 24u) & 255u));\n return v * vec4<f32>(2.0 / 255.0) - vec4<f32>(1.0);\n}\n\nfn inverseMat3(m: mat3x3<f32>) -> mat3x3<f32> {\n let a00 = m[0][0]; let a01 = m[0][1]; let a02 = m[0][2];\n let a10 = m[1][0]; let a11 = m[1][1]; let a12 = m[1][2];\n let a20 = m[2][0]; let a21 = m[2][1]; let a22 = m[2][2];\n let b01 = a22 * a11 - a12 * a21;\n let b11 = -a22 * a10 + a12 * a20;\n let b21 = a21 * a10 - a11 * a20;\n let det = a00 * b01 + a01 * b11 + a02 * b21;\n return mat3x3<f32>(\n vec3<f32>(b01 / det, (-a22 * a01 + a02 * a21) / det, (a12 * a01 - a02 * a11) / det),\n vec3<f32>(b11 / det, (a22 * a00 - a02 * a20) / det, (-a12 * a00 + a02 * a10) / det),\n vec3<f32>(b21 / det, (-a21 * a00 + a01 * a20) / det, (a11 * a00 - a01 * a10) / det));\n}\n\nfn computeSH(dir: vec3<f32>, splatUVi32: vec2<i32>) -> vec3<f32> {\n${textureLoads}${shUnpack} let x = dir.x;\n let y = dir.y;\n let z = dir.z;\n let xx = x * x; let yy = y * y; let zz = z * z;\n let xy = x * y; let yz = y * z; let xz = x * z;\n var result: vec3<f32>;\n${shPoly} return result;\n}\n\n@vertex\nfn vs(@location(0) corner: vec2<f32>, @location(1) splatIndex: f32) -> VOut {\n var out: VOut;\n let uv = dataUv(splatIndex);\n let splatUVi32 = dataUvI(splatIndex);\n let center = textureSampleLevel(centersTex, samp, uv, 0.0).xyz;\n let color = textureSampleLevel(colorsTex, samp, uv, 0.0);\n let covA = textureSampleLevel(covATex, samp, uv, 0.0).xyz;\n let covB = textureSampleLevel(covBTex, samp, uv, 0.0).xyz;\n\n let worldPos = u.world * vec4<f32>(center, 1.0);\n let modelView = u.view * u.world;\n let camspace = u.view * worldPos;\n let pos2d = u.projection * camspace;\n\n let bounds = 1.2 * pos2d.w;\n if (pos2d.z < 0.0\n || pos2d.x < -bounds || pos2d.x > bounds\n || pos2d.y < -bounds || pos2d.y > bounds) {\n out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);\n out.vColor = vec4<f32>(0.0);\n out.vPos = vec2<f32>(0.0);\n return out;\n }\n\n // ── View-dependent SH evaluation ───────────────────────────────────\n let worldRot = mat3x3<f32>(u.world[0].xyz, u.world[1].xyz, u.world[2].xyz);\n let normWorldRot = inverseMat3(worldRot);\n var dir = normalize(normWorldRot * (worldPos.xyz - u.eyePosition));\n // Lite-side Y-flip: compensates for our data-path Y pre-flip vs BJS's\n // mesh.scaling.y *= -1 (see file header for derivation).\n dir.y = -dir.y;\n let shColor = computeSH(dir, splatUVi32);\n\n let Vrk = mat3x3<f32>(\n vec3<f32>(covA.x, covA.y, covA.z),\n vec3<f32>(covA.y, covB.x, covB.y),\n vec3<f32>(covA.z, covB.y, covB.z));\n\n let invZ = 1.0 / camspace.z;\n let invZ2 = invZ * invZ;\n let J = mat3x3<f32>(\n vec3<f32>(u.focal.x * invZ, 0.0, -u.focal.x * camspace.x * invZ2),\n vec3<f32>(0.0, u.focal.y * invZ, -u.focal.y * camspace.y * invZ2),\n vec3<f32>(0.0, 0.0, 0.0));\n\n let mv3 = mat3x3<f32>(modelView[0].xyz, modelView[1].xyz, modelView[2].xyz);\n let T = transpose(mv3) * J;\n var cov2d = transpose(T) * Vrk * T;\n\n let kernelSize: f32 = 0.3;\n cov2d[0][0] += kernelSize;\n cov2d[1][1] += kernelSize;\n\n let mid = (cov2d[0][0] + cov2d[1][1]) * 0.5;\n let dxy = (cov2d[0][0] - cov2d[1][1]) * 0.5;\n let radius = length(vec2<f32>(dxy, cov2d[0][1]));\n let epsilon: f32 = 0.0001;\n let lambda1 = mid + radius + epsilon;\n let lambda2 = mid - radius + epsilon;\n if (lambda2 < 0.0) {\n out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);\n out.vColor = vec4<f32>(0.0);\n out.vPos = vec2<f32>(0.0);\n return out;\n }\n\n let diag = normalize(vec2<f32>(cov2d[0][1], lambda1 - cov2d[0][0]));\n let majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diag;\n let minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2<f32>(diag.y, -diag.x);\n\n let vCenter = pos2d.xy;\n out.pos = vec4<f32>(\n vCenter + (corner.x * majorAxis + corner.y * minorAxis) * pos2d.w / u.viewport,\n pos2d.z, pos2d.w);\n out.vColor = vec4<f32>(color.rgb + shColor, color.a * u.alpha);\n out.vPos = corner;\n return out;\n}\n\n/*GS_FRAGMENT_DEFINITIONS*/\n@fragment\nfn fs(in: VOut) -> @location(0) vec4<f32> {\n /*GS_FRAGMENT_MAIN_BEGIN*/\n let A = -dot(in.vPos, in.vPos);\n if (A < -4.0) { discard; }\n let B = exp(A) * in.vColor.a;\n var finalColor = vec4<f32>(in.vColor.rgb, B);\n /*GS_FRAGMENT_BEFORE_FRAGCOLOR*/\n /*GS_FRAGMENT_MAIN_END*/\n return finalColor;\n}\n`;\n}\n\nfunction getOrCreateShPipeline(engine: EngineContext, sig: RenderTargetSignature, shDegree: number, fragments?: readonly GsShaderFragment[]): PipelineEntry {\n const device = engine._device;\n if (!_cache || _cache.device !== device) {\n _cache = { device, modules: new Map(), entries: new Map() };\n }\n const fragKey = fragments && fragments.length > 0 ? \"|\" + fragments.map((f) => f.id).join(\",\") : \"\";\n let module = _cache.modules.get(shDegree + fragKey);\n if (!module) {\n module = device.createShaderModule({\n code: fragments && fragments.length > 0 ? applyGsFragments(buildShShaderSource(shDegree), fragments) : buildShShaderSource(shDegree),\n });\n _cache.modules.set(shDegree + fragKey, module);\n }\n const key = `${targetSignatureKey(sig)}|sh${shDegree}${fragKey}`;\n let entry = _cache.entries.get(key);\n if (entry) {\n return entry;\n }\n const shTextureCount = SH_TEXTURE_COUNT[shDegree]!;\n const layoutEntries: GPUBindGroupLayoutEntry[] = [\n { binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: \"uniform\" } },\n { binding: 1, visibility: GPUShaderStage.VERTEX, sampler: { type: \"non-filtering\" } },\n { binding: 2, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 3, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 4, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 5, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n ];\n for (let i = 0; i < shTextureCount; i++) {\n layoutEntries.push({ binding: 6 + i, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"uint\" } });\n }\n const meshBindGroupLayout = device.createBindGroupLayout({ entries: layoutEntries });\n const pipeline = device.createRenderPipeline({\n layout: device.createPipelineLayout({ bindGroupLayouts: [getSceneBindGroupLayout(engine), meshBindGroupLayout] }),\n vertex: {\n module,\n entryPoint: \"vs\",\n buffers: [\n { arrayStride: 8, stepMode: \"vertex\", attributes: [{ shaderLocation: 0, offset: 0, format: \"float32x2\" }] },\n { arrayStride: 4, stepMode: \"instance\", attributes: [{ shaderLocation: 1, offset: 0, format: \"float32\" }] },\n ],\n },\n fragment: {\n module,\n entryPoint: \"fs\",\n targets: [\n {\n format: sig._colorFormat!,\n blend: {\n color: { srcFactor: \"src-alpha\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n alpha: { srcFactor: \"one\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n },\n writeMask: GPUColorWrite.ALL,\n },\n ],\n },\n primitive: { topology: \"triangle-list\", cullMode: \"none\" },\n depthStencil: {\n format: sig._depthStencilFormat ?? \"depth24plus-stencil8\",\n depthCompare: sig._depthCompare ?? \"greater-equal\",\n depthWriteEnabled: false,\n },\n multisample: { count: sig._sampleCount },\n });\n entry = { pipeline, meshBindGroupLayout, shTextureCount };\n _cache.entries.set(key, entry);\n return entry;\n}\n\n/** Build the Renderable for a GaussianSplattingMesh with SH coefficients.\n * Mirrors `buildGaussianSplattingRenderable` but adds eyePosition to the UBO\n * and binds the SH textures. */\nexport function buildGaussianSplattingRenderableSH(scene: SceneContext, mesh: GaussianSplattingMesh, fragments?: readonly GsShaderFragment[]): Renderable {\n const engine = scene.engine;\n const device = engine._device;\n\n // 3 mat4 + 8 floats (viewport,focal,dataSize,alpha,pad) + 4 floats (eyePosition + pad) = 240 bytes.\n const UBO_BYTES = 16 * 4 * 3 + 8 * 4 + 4 * 4;\n const ubo = device.createBuffer({\n size: UBO_BYTES,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n });\n const cpu = new Float32Array(UBO_BYTES / 4);\n\n cpu[48 + 4] = mesh.textureWidth;\n cpu[48 + 5] = mesh.textureHeight;\n cpu[48 + 6] = 1; // alpha\n cpu[48 + 7] = 0; // pad\n\n const bindGroups = new Map<GPURenderPipeline, GPUBindGroup>();\n\n const getBindGroup = (entry: PipelineEntry): GPUBindGroup => {\n let bg = bindGroups.get(entry.pipeline);\n if (bg) {\n return bg;\n }\n const shViews = mesh._gs._shViews ?? [];\n const entries: GPUBindGroupEntry[] = [\n { binding: 0, resource: { buffer: ubo } },\n { binding: 1, resource: mesh._gs._sampler },\n { binding: 2, resource: mesh._gs._centersView },\n { binding: 3, resource: mesh._gs._covAView },\n { binding: 4, resource: mesh._gs._covBView },\n { binding: 5, resource: mesh._gs._colorsView },\n ];\n for (let i = 0; i < entry.shTextureCount; i++) {\n entries.push({ binding: 6 + i, resource: shViews[i]! });\n }\n bg = device.createBindGroup({ layout: entry.meshBindGroupLayout, entries });\n bindGroups.set(entry.pipeline, bg);\n return bg;\n };\n\n const SORT_EPS = 1e-4;\n\n const update = (): void => {\n const cam = scene.camera;\n if (!cam) {\n return;\n }\n const size = getRenderTargetSize(engine);\n const aspect = size.width / size.height;\n const view = getViewMatrix(cam) as unknown as Float32Array;\n const proj = getProjectionMatrix(cam, aspect) as unknown as Float32Array;\n const world = mesh.worldMatrix as unknown as Float32Array;\n const camPos = getCameraPosition(cam);\n\n cpu.set(world, 0);\n cpu.set(view, 16);\n cpu.set(proj, 32);\n cpu[48] = size.width;\n cpu[48 + 1] = size.height;\n cpu[48 + 2] = size.width * 0.5 * proj[0]!;\n cpu[48 + 3] = size.height * 0.5 * proj[5]!;\n cpu[56] = camPos.x;\n cpu[57] = camPos.y;\n cpu[58] = camPos.z;\n cpu[59] = 0;\n device.queue.writeBuffer(ubo, 0, cpu.buffer, 0, UBO_BYTES);\n\n if (!mesh._canPostToWorker) {\n return;\n }\n\n const cf0 = view[2]!,\n cf1 = view[6]!,\n cf2 = view[10]!;\n\n let dirty = false;\n const lastW = mesh._sortWorldMatrix;\n for (let i = 0; i < 16; i++) {\n if (Math.abs(lastW[i]! - world[i]!) > SORT_EPS) {\n dirty = true;\n break;\n }\n }\n if (!dirty) {\n const lastCf = mesh._sortCameraForward;\n if (Math.abs(lastCf[0]! - cf0) > SORT_EPS || Math.abs(lastCf[1]! - cf1) > SORT_EPS || Math.abs(lastCf[2]! - cf2) > SORT_EPS) {\n dirty = true;\n }\n }\n if (!dirty) {\n const lastCp = mesh._sortCameraPosition;\n if (Math.abs(lastCp[0]! - camPos.x) > SORT_EPS || Math.abs(lastCp[1]! - camPos.y) > SORT_EPS || Math.abs(lastCp[2]! - camPos.z) > SORT_EPS) {\n dirty = true;\n }\n }\n if (!dirty) {\n return;\n }\n\n mesh._sortWorldMatrix.set(world);\n mesh._sortCameraForward[0] = cf0;\n mesh._sortCameraForward[1] = cf1;\n mesh._sortCameraForward[2] = cf2;\n mesh._sortCameraPosition[0] = camPos.x;\n mesh._sortCameraPosition[1] = camPos.y;\n mesh._sortCameraPosition[2] = camPos.z;\n mesh._canPostToWorker = false;\n mesh._worker.postMessage(\n {\n m: new Float32Array(world),\n f: new Float32Array([cf0, cf1, cf2]),\n c: new Float32Array([camPos.x, camPos.y, camPos.z]),\n d: mesh._depthMix,\n },\n [mesh._depthMix.buffer]\n );\n };\n\n const r: Renderable = {\n order: 200,\n isTransparent: true,\n bind(eng: EngineContext, sig: RenderTargetSignature): DrawBinding {\n const entry = getOrCreateShPipeline(eng as EngineContext, sig, mesh.shDegree, fragments);\n const bindGroup = getBindGroup(entry);\n return {\n renderable: r,\n pipeline: entry.pipeline,\n update,\n draw(pass) {\n pass.setBindGroup(1, bindGroup);\n pass.setVertexBuffer(0, mesh._gs._quadBuffer);\n pass.setVertexBuffer(1, mesh._gs._splatIndexBuffer);\n pass.setIndexBuffer(mesh._gs._indexBuffer, \"uint16\");\n pass.drawIndexed(6, mesh.vertexCount);\n return 1;\n },\n };\n },\n };\n return r;\n}\n\n/** SH-aware variant of `attachGaussianSplattingMesh`. Dynamic-imported by\n * `attachParsedSplat` (in `load-splat.ts`) when the parsed asset carries SH\n * coefficients. Reads `mesh.shDegree` (set at mesh construction), creates\n * the `rgba32uint` SH textures (1..5 depending on degree), patches\n * `mesh._gs` in place, and installs the SH renderable. */\nexport function attachGaussianSplattingMeshSH(scene: SceneContext, mesh: GaussianSplattingMesh, shFlat: Uint8Array, fragments?: readonly GsShaderFragment[]): void {\n const engine = scene.engine;\n const device = engine._device;\n const shDegree = mesh.shDegree;\n const shVectorCount = (shDegree + 1) * (shDegree + 1) - 1;\n const shCoefficientCount = shVectorCount * 3;\n const textureCount = Math.ceil(shCoefficientCount / 16);\n const width = mesh.textureWidth;\n const height = mesh.textureHeight;\n\n // Pack the flat SH byte stream into N textures of 16 bytes per splat each.\n // splat i's bytes [i*shCC .. i*shCC + shCC] are split across textures\n // [t=0..textureCount-1], each carrying up to 16 bytes at offset i*16.\n const textures: GPUTexture[] = [];\n const views: GPUTextureView[] = [];\n const vertexCount = mesh.vertexCount;\n for (let t = 0; t < textureCount; t++) {\n const dst = new Uint8Array(width * height * 16);\n const tBase = t * 16;\n const bytesThisTex = Math.min(16, shCoefficientCount - tBase);\n for (let i = 0; i < vertexCount; i++) {\n const srcOff = i * shCoefficientCount + tBase;\n const dstOff = i * 16;\n for (let b = 0; b < bytesThisTex; b++) {\n dst[dstOff + b] = shFlat[srcOff + b]!;\n }\n }\n const tex = device.createTexture({\n size: [width, height],\n format: \"rgba32uint\",\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,\n });\n device.queue.writeTexture({ texture: tex }, dst.buffer, { bytesPerRow: width * 16 }, { width, height });\n textures.push(tex);\n views.push(tex.createView());\n }\n mesh._gs._shTextures = textures;\n mesh._gs._shViews = views;\n\n const ctx = scene as unknown as { _renderables: Renderable[]; _disposables: (() => void)[]; _gsMeshes: GaussianSplattingMesh[] };\n ctx._renderables.push(buildGaussianSplattingRenderableSH(scene, mesh, fragments));\n ctx._gsMeshes.push(mesh);\n ctx._disposables.push(() => {\n const i = ctx._gsMeshes.indexOf(mesh);\n if (i >= 0) {\n ctx._gsMeshes.splice(i, 1);\n }\n disposeGaussianSplattingMesh(mesh);\n });\n}\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"gltf-animation-KnPzeOIY.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 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 Float32Array(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 Float32Array(ibmData._data.buffer, ibmData._data.byteOffset, jointCount * 16);\n }\n const out = new Float32Array(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 Float32Array(numBones * 16);\n const invMeshWorld = mat4Invert(skin.meshWorldMatrix) ?? mat4Identity();\n const tmp = getLoaderTmpAnim() as unknown as Mat4Storage;\n for (let i = 0; i < numBones; i++) {\n mat4MultiplyInto(tmp, 0, invMeshWorld as unknown as Mat4Storage, 0, skin.jointWorldMatrices[i]! as unknown as Mat4Storage, 0);\n mat4MultiplyInto(data, i * 16, tmp, 0, skin.inverseBindMatrices, i * 16);\n }\n return data;\n}\n\n// ─── Animation Parsing ──────────────────────────────────────────────\n\nconst INTERP_MAP: Record<string, 0 | 1 | 2> = {\n LINEAR: INTERP_LINEAR,\n STEP: INTERP_STEP,\n CUBICSPLINE: INTERP_CUBICSPLINE,\n};\n\nconst PATH_MAP: Record<string, 0 | 1 | 2 | 3> = {\n translation: PATH_TRANSLATION,\n rotation: PATH_ROTATION,\n scale: PATH_SCALE,\n weights: PATH_WEIGHTS,\n};\n\n/**\n * Parse glTF animation data: clips, node hierarchy, and skeleton bindings.\n * Returns null if no animations, or no drivable state at all (no skeletons,\n * no morphs, no pointer channels).\n *\n * `nodeMap` (optional) maps glTF node index → SceneNode. It's required to\n * resolve KHR_animation_pointer targets that write to node properties.\n */\nexport function parseAnimationData(\n json: any,\n binChunk: DataView,\n meshes: Mesh[],\n parentMap: Map<number, number>,\n worldMatrixCache: Map<number, Mat4>,\n nodeMap?: readonly (SceneNode | undefined)[]\n): GltfAnimationData | null {\n if (!json.animations || json.animations.length === 0) {\n return null;\n }\n\n let pointerChannelCount = 0;\n\n // Parse animation clips\n const clips: AnimationClip[] = [];\n for (const anim of json.animations) {\n const samplers: AnimationSampler[] = [];\n for (const s of anim.samplers) {\n const inputAcc = resolveAccessor(json, binChunk, s.input);\n const outputAcc = resolveAccessor(json, binChunk, s.output);\n const inNorm = json.accessors[s.input]?.normalized === true;\n const outNorm = json.accessors[s.output]?.normalized === true;\n samplers.push({\n input: toSamplerFloat32(inputAcc._data, inputAcc._count, inNorm),\n output: toSamplerFloat32(outputAcc._data, outputAcc._count * outputAcc._componentCount, outNorm),\n interpolation: INTERP_MAP[s.interpolation ?? \"LINEAR\"] ?? INTERP_LINEAR,\n });\n }\n\n const channels: AnimationChannel[] = [];\n for (const c of anim.channels) {\n // KHR_animation_pointer: delegated to the registered pointer parser\n // (installed by gltf-feature-animation-pointer on side-effect import).\n const ptr = c.target?.extensions?.KHR_animation_pointer?.pointer;\n if (ptr) {\n if (!_parsePointerChannel) {\n continue;\n }\n const ch = _parsePointerChannel(ptr, c, nodeMap);\n if (ch) {\n channels.push(ch);\n pointerChannelCount++;\n }\n continue;\n }\n if (c.target.node === undefined) {\n continue;\n }\n const path = PATH_MAP[c.target.path];\n if (path === undefined) {\n continue;\n }\n channels.push({ samplerIdx: c.sampler, nodeIdx: c.target.node, path });\n }\n\n let duration = 0;\n for (const s of samplers) {\n if (s.input.length > 0) {\n const last = s.input[s.input.length - 1]!;\n if (last > duration) {\n duration = last;\n }\n }\n }\n\n clips.push({ name: anim.name ?? \"\", channels, samplers, duration });\n }\n\n // Build node hierarchy (rest-pose TRS + parent indices)\n const nodeCount = json.nodes?.length ?? 0;\n const nodes: NodeRest[] = [];\n for (let i = 0; i < nodeCount; i++) {\n const n = json.nodes[i];\n const t = n.translation ?? [0, 0, 0];\n const r = n.rotation ?? [0, 0, 0, 1];\n const s = n.scale ?? [1, 1, 1];\n nodes.push({\n parentIdx: findParent(parentMap, i),\n _matrix: n.matrix as Mat4 | undefined,\n tx: t[0],\n ty: t[1],\n tz: t[2],\n rx: r[0],\n ry: r[1],\n rz: r[2],\n rw: r[3],\n sx: s[0],\n sy: s[1],\n sz: s[2],\n });\n }\n\n // Build skeleton bindings (connect skin data to GPU bone textures)\n // First, build node→gpuMesh mapping by replaying extraction order\n const nodeToMeshIndices = new Map<number, number[]>();\n let gpuIdx = 0;\n for (let ni = 0; ni < nodeCount; ni++) {\n const node = json.nodes[ni];\n if (node.mesh === undefined) {\n continue;\n }\n const mesh = json.meshes[node.mesh];\n const indices: number[] = [];\n for (let p = 0; p < mesh.primitives.length; p++) {\n indices.push(gpuIdx++);\n }\n nodeToMeshIndices.set(ni, indices);\n }\n\n const skeletons: SkeletonBinding[] = [];\n for (let nodeIdx = 0; nodeIdx < nodeCount; nodeIdx++) {\n const node = json.nodes[nodeIdx];\n if (node.skin === undefined || !json.skins) {\n continue;\n }\n\n const meshIndices = nodeToMeshIndices.get(nodeIdx);\n if (!meshIndices) {\n continue;\n }\n\n const skin = json.skins[node.skin];\n const jointNodes: number[] = skin.joints;\n const inverseBindMatrices = resolveIBMs(json, binChunk, skin);\n\n const meshWorldMatrix = computeNodeWorldMatrix(json, nodeIdx, parentMap, worldMatrixCache);\n const invMeshWorld = mat4Invert(meshWorldMatrix) ?? mat4Identity();\n\n // Create a binding for EACH mesh primitive of this skinned node\n for (const mi of meshIndices) {\n const mesh = meshes[mi];\n const skeleton = mesh?.skeleton;\n if (!skeleton) {\n continue;\n }\n skeletons.push({\n jointNodes,\n inverseBindMatrices,\n invMeshWorld,\n boneTexture: skeleton.boneTexture,\n boneCount: jointNodes.length,\n boneMatrices: skeleton.boneMatrices,\n runtimeSkeleton: skeleton,\n });\n }\n }\n\n // Build morph bindings (connect morph-target meshes to GPU weight buffers)\n const morphBindings: MorphBinding[] = [];\n for (let nodeIdx = 0; nodeIdx < nodeCount; nodeIdx++) {\n const node = json.nodes[nodeIdx];\n if (node.mesh === undefined) {\n continue;\n }\n const gltfMesh = json.meshes[node.mesh];\n if (!gltfMesh.primitives?.[0]?.targets?.length) {\n continue;\n }\n\n const meshIndices = nodeToMeshIndices.get(nodeIdx);\n if (!meshIndices) {\n continue;\n }\n\n for (const mi of meshIndices) {\n const mesh = meshes[mi];\n const morphTargets = mesh?.morphTargets;\n if (!morphTargets) {\n continue;\n }\n morphBindings.push({\n nodeIdx,\n weightsBuffer: morphTargets.weightsBuffer,\n weights: morphTargets.weights,\n targetCount: morphTargets.count,\n runtimeMorphTargets: morphTargets,\n });\n }\n }\n\n // Build the node-TRS writeback inputs. `nodeTargets` exposes each glTF node's\n // live scene node (via the structural AnimatedNodeTarget view) so the controller\n // can push evaluated local TRS back onto the scene graph, moving non-skinned\n // node-animated meshes and their descendants. `excludedNodeIndices` lists nodes\n // that MUST NOT be written: skin joints (driven by the skeleton path) plus\n // skinned-mesh nodes and all their ancestors — their bone matrices bake an\n // `invMeshWorld` captured at load, so moving them at runtime would\n // double-transform the skinned vertices.\n const nodeTargets: readonly (AnimatedNodeTarget | undefined)[] = (nodeMap as readonly (AnimatedNodeTarget | undefined)[] | undefined) ?? [];\n const excludedNodeIndices = new Set<number>();\n for (const skin of json.skins ?? []) {\n for (const ji of skin.joints ?? []) {\n excludedNodeIndices.add(ji);\n }\n }\n for (let ni = 0; ni < nodeCount; ni++) {\n if (json.nodes[ni]?.skin === undefined) {\n continue;\n }\n let p = ni;\n while (p >= 0 && !excludedNodeIndices.has(p)) {\n excludedNodeIndices.add(p);\n p = findParent(parentMap, p);\n }\n }\n\n if (\n clips.length === 0 ||\n (skeletons.length === 0 && morphBindings.length === 0 && pointerChannelCount === 0 && !hasWritableNodeChannel(clips, nodeTargets, excludedNodeIndices))\n ) {\n return null;\n }\n return { clips, nodes, skeletons, morphBindings, nodeTargets, excludedNodeIndices };\n}\n\n/** True if any clip animates a non-excluded node that has a live scene target —\n * i.e. there is at least one plain node-TRS channel the controller can write\n * back. Lets purely-skinned/morph/pointer assets short-circuit unchanged. */\nfunction hasWritableNodeChannel(clips: readonly AnimationClip[], nodeTargets: readonly (AnimatedNodeTarget | undefined)[], excludedNodeIndices: ReadonlySet<number>): boolean {\n for (const clip of clips) {\n for (const ch of clip.channels) {\n if (\n (ch.path === PATH_TRANSLATION || ch.path === PATH_ROTATION || ch.path === PATH_SCALE) &&\n ch.nodeIdx >= 0 &&\n !excludedNodeIndices.has(ch.nodeIdx) &&\n nodeTargets[ch.nodeIdx]\n ) {\n return true;\n }\n }\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"gltf-ext-basisu-kmth3UWX.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 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: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.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: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.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 Uint8Array(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 Uint8Array(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 Uint8ClampedArray(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 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;\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 Uint8Array(bv.byteLength);\n copy.set(new Uint8Array(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\nfunction readStridedFloat(json: any, binChunk: DataView, accessorIdx: number): Float32Array {\n const accessor = json.accessors[accessorIdx];\n const bufferView = json.bufferViews[accessor.bufferView];\n if (accessor.componentType !== FLOAT) {\n throw new Error(`${NAME}: strided accessor ${accessorIdx} uses unsupported component type: ${accessor.componentType}`);\n }\n const componentCount = TYPE_SIZES[accessor.type] ?? 1;\n const elementBytes = componentCount * 4;\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 baseOffset = binChunk.byteOffset + (bufferView.byteOffset ?? 0) + (accessor.byteOffset ?? 0);\n const view = new DataView(binChunk.buffer);\n const out = new Float32Array(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] = view.getFloat32(src + c * 4, true);\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\n ? new Uint32Array(0)\n : new Uint32Array(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 +0,0 @@
1
- {"version":3,"file":"gltf-ext-quantization-CpZyLDIz.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 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 Uint8Array(out).set(new Uint8Array(binChunk.buffer, binChunk.byteOffset, binChunk.byteLength));\n const outView = new DataView(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 +0,0 @@
1
- {"version":3,"file":"gltf-feature-animation-pointer-rFqLfbO_.js","sources":["../src/loader-gltf/animation-pointer.ts","../src/loader-gltf/gltf-feature-animation-pointer.ts"],"sourcesContent":["/** KHR_animation_pointer — JSON-pointer resolver registry.\n * Handlers are registered incrementally (one per parity scene). Unknown\n * pointers return null and warn once. */\nimport type { SceneNode } from \"../scene/scene-node.js\";\nimport { setSubtreeVisible } from \"../scene/visibility.js\";\n\nexport interface ResolvedPointer {\n writer: (output: Float32Array, offset: number) => void;\n arity: number;\n}\n\nexport interface PointerContext {\n nodes: readonly (SceneNode | undefined)[];\n}\n\ntype PointerFactory = (match: RegExpExecArray, ctx: PointerContext) => ResolvedPointer | null;\n\nconst _registry: [RegExp, PointerFactory][] = [\n // /nodes/{n}/extensions/KHR_node_visibility/visible — scalar (0 = hidden).\n // The setter cascade handles descendants per the KHR_node_visibility spec\n // and bumps the module-scoped visibility epoch so the engine invalidates\n // its cached render bundle.\n [\n /^\\/nodes\\/(\\d+)\\/extensions\\/KHR_node_visibility\\/visible$/,\n (m, ctx) => {\n const n = ctx.nodes[+m[1]!];\n if (!n) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n setSubtreeVisible(n, out[off]! !== 0);\n },\n };\n },\n ],\n];\n\nconst _warned = new Set<string>();\n\nexport function resolveAnimationPointer(pointer: string, ctx: PointerContext): ResolvedPointer | null {\n for (const [rx, make] of _registry) {\n const m = rx.exec(pointer);\n if (m) {\n return make(m, ctx);\n }\n }\n if (!_warned.has(pointer)) {\n _warned.add(pointer);\n\n console.warn(`[babylon-lite] KHR_animation_pointer: no handler for \"${pointer}\"`);\n }\n return null;\n}\n","/** KHR_animation_pointer glTF feature.\n *\n * Registered in load-gltf.ts's feature table gated on\n * `extensionsUsed.includes(\"KHR_animation_pointer\")`, so any scene that\n * doesn't declare the extension pays zero bytes for pointer resolution, the\n * non-Float32 sampler converter, or the visibility cascade helper.\n *\n * On side-effect import this module installs two callbacks into gltf-animation:\n * 1. A pointer-channel parser (resolves the JSON pointer to a writer fn).\n * 2. A sampler converter that handles the non-Float32/misaligned accessor\n * cases the fast path in gltf-animation can't express (e.g. the 11-byte\n * UNSIGNED_BYTE visibility accessor in CubeVisibility.glb). */\n\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport type { AnimationChannel } from \"../animation/types.js\";\nimport { PATH_POINTER } from \"../animation/types.js\";\nimport { resolveAnimationPointer } from \"./animation-pointer.js\";\nimport { _installPointerHandlers } from \"./gltf-animation.js\";\n\n_installPointerHandlers(\n (ptr, c, nodeMap) => {\n if (!nodeMap) {\n return null;\n }\n const resolved = resolveAnimationPointer(ptr, { nodes: nodeMap });\n if (!resolved) {\n return null;\n }\n const ch: AnimationChannel = {\n samplerIdx: c.sampler,\n nodeIdx: -1,\n path: PATH_POINTER,\n pointerWriter: resolved.writer,\n pointerArity: resolved.arity,\n };\n return ch;\n },\n (src, length, normalized) => {\n // Convert any animation-sampler payload to a standalone Float32Array.\n // Handles the cases the aligned-Float32 fast path can't express.\n const out = new Float32Array(length);\n if (src instanceof Float32Array) {\n for (let i = 0; i < length; i++) {\n out[i] = src[i]!;\n }\n } else if (src instanceof Uint8Array) {\n const k = normalized ? 1 / 255 : 1;\n for (let i = 0; i < length; i++) {\n out[i] = src[i]! * k;\n }\n } else if (src instanceof Uint16Array) {\n const k = normalized ? 1 / 65535 : 1;\n for (let i = 0; i < length; i++) {\n out[i] = src[i]! * k;\n }\n } else if (src instanceof Int8Array) {\n for (let i = 0; i < length; i++) {\n out[i] = normalized ? Math.max(src[i]! / 127, -1) : src[i]!;\n }\n } else if (src instanceof Int16Array) {\n for (let i = 0; i < length; i++) {\n out[i] = normalized ? Math.max(src[i]! / 32767, -1) : src[i]!;\n }\n }\n return out;\n }\n);\n\n// No per-asset hook — this feature only installs the seam at import time.\nconst feature: GltfFeature = { id: \"KHR_animation_pointer\" };\nexport default feature;\n"],"names":[],"mappings":";;AAiBA,MAAM,YAAwC;AAAA;AAAA;AAAA;AAAA;AAAA,EAK1C;AAAA,IACI;AAAA,IACA,CAAC,GAAG,QAAQ;AACR,YAAM,IAAI,IAAI,MAAM,CAAC,EAAE,CAAC,CAAE;AAC1B,UAAI,CAAC,GAAG;AACJ,eAAO;AAAA,MACX;AACA,aAAO;AAAA,QACH,OAAO;AAAA,QACP,QAAQ,CAAC,KAAK,QAAQ;AAClB,4BAAkB,GAAG,IAAI,GAAG,MAAO,CAAC;AAAA,QACxC;AAAA,MAAA;AAAA,IAER;AAAA,EAAA;AAER;AAEA,MAAM,8BAAc,IAAA;AAEb,SAAS,wBAAwB,SAAiB,KAA6C;AAClG,aAAW,CAAC,IAAI,IAAI,KAAK,WAAW;AAChC,UAAM,IAAI,GAAG,KAAK,OAAO;AACzB,QAAI,GAAG;AACH,aAAO,KAAK,GAAG,GAAG;AAAA,IACtB;AAAA,EACJ;AACA,MAAI,CAAC,QAAQ,IAAI,OAAO,GAAG;AACvB,YAAQ,IAAI,OAAO;AAEnB,YAAQ,KAAK,yDAAyD,OAAO,GAAG;AAAA,EACpF;AACA,SAAO;AACX;ACnCA;AAAA,EACI,CAAC,KAAK,GAAG,YAAY;AACjB,QAAI,CAAC,SAAS;AACV,aAAO;AAAA,IACX;AACA,UAAM,WAAW,wBAAwB,KAAK,EAAE,OAAO,SAAS;AAChE,QAAI,CAAC,UAAU;AACX,aAAO;AAAA,IACX;AACA,UAAM,KAAuB;AAAA,MACzB,YAAY,EAAE;AAAA,MACd,SAAS;AAAA,MACT,MAAM;AAAA,MACN,eAAe,SAAS;AAAA,MACxB,cAAc,SAAS;AAAA,IAAA;AAE3B,WAAO;AAAA,EACX;AAAA,EACA,CAAC,KAAK,QAAQ,eAAe;AAGzB,UAAM,MAAM,IAAI,aAAa,MAAM;AACnC,QAAI,eAAe,cAAc;AAC7B,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC7B,YAAI,CAAC,IAAI,IAAI,CAAC;AAAA,MAClB;AAAA,IACJ,WAAW,eAAe,YAAY;AAClC,YAAM,IAAI,aAAa,IAAI,MAAM;AACjC,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC7B,YAAI,CAAC,IAAI,IAAI,CAAC,IAAK;AAAA,MACvB;AAAA,IACJ,WAAW,eAAe,aAAa;AACnC,YAAM,IAAI,aAAa,IAAI,QAAQ;AACnC,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC7B,YAAI,CAAC,IAAI,IAAI,CAAC,IAAK;AAAA,MACvB;AAAA,IACJ,WAAW,eAAe,WAAW;AACjC,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC7B,YAAI,CAAC,IAAI,aAAa,KAAK,IAAI,IAAI,CAAC,IAAK,KAAK,EAAE,IAAI,IAAI,CAAC;AAAA,MAC7D;AAAA,IACJ,WAAW,eAAe,YAAY;AAClC,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC7B,YAAI,CAAC,IAAI,aAAa,KAAK,IAAI,IAAI,CAAC,IAAK,OAAO,EAAE,IAAI,IAAI,CAAC;AAAA,MAC/D;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AACJ;AAGA,MAAM,UAAuB,EAAE,IAAI,wBAAA;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"gltf-feature-draco-yGSMGTE3.js","sources":["../src/loader-gltf/draco-decode.ts","../src/loader-gltf/gltf-feature-draco.ts"],"sourcesContent":["/**\n * Lazy KHR_draco_mesh_compression decoder.\n *\n * The Draco decoder (JS glue + WASM) is loaded from `/draco_decoder.js` and\n * `/draco_decoder.wasm` on first use via a `<script>` injection. This keeps\n * bundle size at zero bytes for scenes that do not load Draco-compressed\n * glTF assets — the entire module (including this file) is dynamically\n * imported from extractAllMeshes only when a primitive carries\n * `KHR_draco_mesh_compression`.\n *\n * The decoder output is always 32-bit: Float32 for FLOAT accessors,\n * Uint32Array for indices. Vertex attributes match glTF accessor types\n * (POSITION/NORMAL/TANGENT=VEC3, TEXCOORD_0=VEC2, ...).\n */\n\nimport type { DecodedPrimitive } from \"./gltf-feature.js\";\n\n// Public base URL where the decoder JS + WASM are hosted. Defaults to site root.\nlet dracoBaseUrl = \"/\";\n\n/** Override the base URL where draco_decoder.js and draco_decoder.wasm are hosted. */\nexport function setDracoBaseUrl(url: string): void {\n dracoBaseUrl = url.endsWith(\"/\") ? url : url + \"/\";\n}\n\ninterface DracoModule {\n Decoder: new () => {\n DecodeBufferToMesh(buffer: unknown, mesh: unknown): { ok(): boolean; error_msg(): string };\n GetTrianglesUInt32Array(mesh: unknown, byteLength: number, outPtr: number): void;\n GetAttributeByUniqueId(mesh: unknown, uniqueId: number): unknown;\n GetAttributeDataArrayForAllPoints(mesh: unknown, attr: unknown, dataType: number, byteLength: number, outPtr: number): boolean;\n };\n DecoderBuffer: new () => { Init(data: Uint8Array, size: number): void };\n Mesh: new () => { num_faces(): number; num_points(): number };\n destroy(obj: unknown): void;\n HEAPF32: Float32Array;\n HEAPU32: Uint32Array;\n HEAP32: Int32Array;\n DT_FLOAT32: number;\n DT_INT32: number;\n _malloc(size: number): number;\n _free(ptr: number): void;\n}\n\ntype DracoFactory = (cfg: { locateFile?: (file: string) => string }) => Promise<DracoModule>;\n\nlet modulePromise: Promise<DracoModule> | null = null;\nlet scriptLoadPromise: Promise<DracoFactory> | null = null;\n\nfunction loadDracoScript(): Promise<DracoFactory> {\n if (scriptLoadPromise) {\n return scriptLoadPromise;\n }\n scriptLoadPromise = new Promise<DracoFactory>((resolve, reject) => {\n const existing = (globalThis as { DracoDecoderModule?: DracoFactory }).DracoDecoderModule;\n if (existing) {\n resolve(existing);\n return;\n }\n const script = document.createElement(\"script\");\n script.src = dracoBaseUrl + \"draco_decoder.js\";\n script.onload = () => {\n const factory = (globalThis as { DracoDecoderModule?: DracoFactory }).DracoDecoderModule;\n if (!factory) {\n reject(new Error(\"draco_decoder.js loaded but DracoDecoderModule is undefined\"));\n } else {\n resolve(factory);\n }\n };\n script.onerror = () => reject(new Error(\"Failed to load draco_decoder.js from \" + script.src));\n document.head.appendChild(script);\n });\n return scriptLoadPromise;\n}\n\nasync function getDracoModule(): Promise<DracoModule> {\n if (modulePromise) {\n return modulePromise;\n }\n modulePromise = (async () => {\n const factory = await loadDracoScript();\n return factory({ locateFile: (f: string) => dracoBaseUrl + f });\n })();\n return modulePromise;\n}\n\n/**\n * Decode a KHR_draco_mesh_compression primitive.\n * @param compressed - The raw bytes of the bufferView referenced by the extension.\n * @param attributeMap - Map of glTF attribute name (POSITION, NORMAL, ...) to Draco unique id.\n * @param accessorTypes - Map of glTF attribute name to component count (3 for VEC3, 2 for VEC2, 4 for VEC4).\n */\nexport async function decodeDracoPrimitive(compressed: Uint8Array, attributeMap: Record<string, number>, accessorTypes: Record<string, number>): Promise<DecodedPrimitive> {\n const module = await getDracoModule();\n const decoder = new module.Decoder();\n const buffer = new module.DecoderBuffer();\n buffer.Init(compressed, compressed.byteLength);\n const mesh = new module.Mesh();\n const status = decoder.DecodeBufferToMesh(buffer, mesh);\n if (!status.ok()) {\n const err = status.error_msg();\n module.destroy(buffer);\n module.destroy(mesh);\n module.destroy(decoder);\n throw new Error(\"Draco decode failed: \" + err);\n }\n\n const numPoints = mesh.num_points();\n const numFaces = mesh.num_faces();\n const indexCount = numFaces * 3;\n\n // Indices: Draco returns Uint32 triangles. Always slice() off the heap\n // view because module._malloc may grow the WASM memory and invalidate\n // the typed-array views we already hold.\n const indexByteLength = indexCount * 4;\n const indexPtr = module._malloc(indexByteLength);\n decoder.GetTrianglesUInt32Array(mesh, indexByteLength, indexPtr);\n const indices = new Uint32Array(module.HEAPU32.buffer, indexPtr, indexCount).slice();\n module._free(indexPtr);\n\n const attributes = new Map<string, Float32Array | Uint32Array | Int32Array>();\n for (const name of Object.keys(attributeMap)) {\n const uniqueId = attributeMap[name]!;\n const attr = decoder.GetAttributeByUniqueId(mesh, uniqueId);\n const componentCount = accessorTypes[name] ?? 3;\n const totalComponents = numPoints * componentCount;\n const isIntAttr = name === \"JOINTS_0\" || name === \"JOINTS_1\";\n const bytesPerElement = 4;\n const byteLength = totalComponents * bytesPerElement;\n const ptr = module._malloc(byteLength);\n const dataType = isIntAttr ? module.DT_INT32 : module.DT_FLOAT32;\n decoder.GetAttributeDataArrayForAllPoints(mesh, attr, dataType, byteLength, ptr);\n // Re-read the HEAP view AFTER malloc/decode — the underlying buffer\n // may have been reallocated during decoding.\n if (isIntAttr) {\n attributes.set(name, new Int32Array(module.HEAP32.buffer, ptr, totalComponents).slice());\n } else {\n attributes.set(name, new Float32Array(module.HEAPF32.buffer, ptr, totalComponents).slice());\n }\n module._free(ptr);\n }\n\n module.destroy(buffer);\n module.destroy(mesh);\n module.destroy(decoder);\n\n return { _attributes: attributes, _indices: indices, _vertexCount: numPoints, _indexCount: indexCount };\n}\n\n/**\n * Read the bufferView slice referenced by the Draco extension into a Uint8Array.\n */\nexport function getDracoBufferViewBytes(json: { bufferViews: Array<{ byteOffset?: number; byteLength: number }> }, binChunk: DataView, bufferViewIdx: number): Uint8Array {\n const view = json.bufferViews[bufferViewIdx];\n if (!view) {\n throw new Error(`Draco bufferView ${bufferViewIdx} not found`);\n }\n const offset = binChunk.byteOffset + (view.byteOffset ?? 0);\n return new Uint8Array(binChunk.buffer, offset, view.byteLength);\n}\n","/**\n * KHR_draco_mesh_compression feature.\n *\n * Runs as a `preMesh` hook — before mesh extraction — so the core loader\n * stays unaware of Draco. This module is only dynamic-imported when the\n * asset's `extensionsUsed` lists KHR_draco_mesh_compression, which in turn\n * dynamic-imports the actual Emscripten-based decoder (`draco-decode.ts`).\n */\n\nimport type { DecodedPrimitive, GltfFeature } from \"./gltf-feature.js\";\nimport { decodeDracoPrimitive, getDracoBufferViewBytes } from \"./draco-decode.js\";\n\nconst TYPE_COMPONENT_COUNTS: Record<string, number> = { SCALAR: 1, VEC2: 2, VEC3: 3, VEC4: 4, MAT2: 4, MAT3: 9, MAT4: 16 };\n\nconst feature: GltfFeature = {\n id: \"KHR_draco_mesh_compression\",\n async preMesh(jsonIn, binChunk) {\n const json = jsonIn as {\n meshes?: Array<{\n primitives?: Array<{ attributes?: Record<string, number>; extensions?: Record<string, { bufferView: number; attributes: Record<string, number> }> }>;\n }>;\n accessors?: Array<{ type: string }>;\n };\n const out = new Map<unknown, DecodedPrimitive>();\n for (const mesh of json.meshes ?? []) {\n for (const primitive of mesh.primitives ?? []) {\n const ext = primitive.extensions?.KHR_draco_mesh_compression;\n if (!ext) {\n continue;\n }\n const bytes = getDracoBufferViewBytes(json as { bufferViews: Array<{ byteOffset?: number; byteLength: number }> }, binChunk, ext.bufferView);\n const accessorTypes: Record<string, number> = {};\n for (const name of Object.keys(ext.attributes)) {\n const accIdx = primitive.attributes?.[name];\n if (accIdx !== undefined && json.accessors?.[accIdx]) {\n accessorTypes[name] = TYPE_COMPONENT_COUNTS[json.accessors[accIdx].type] ?? 3;\n }\n }\n const decoded = await decodeDracoPrimitive(bytes, ext.attributes, accessorTypes);\n out.set(primitive, decoded);\n }\n }\n return out;\n },\n};\n\nexport default feature;\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"gltf-feature-gpu-instancing-Cj1XjmM6.js","sources":["../src/loader-gltf/gltf-feature-gpu-instancing.ts"],"sourcesContent":["/** glTF EXT_mesh_gpu_instancing extension.\n *\n * Attaches hardware-instanced thin instances to every mesh that belongs to a\n * node carrying `extensions.EXT_mesh_gpu_instancing`. The extension provides\n * per-instance TRANSLATION / ROTATION / SCALE accessors (all optional); each\n * instance matrix is composed as T·R·S in the node's local frame. The node's\n * own TRS is applied through the regular parent-chain world matrix at render\n * time (`finalWorld = mesh.world * instanceWorld` in thin-instance-fragment),\n * so instance matrices must NOT pre-multiply the node transform.\n *\n * Dynamically imported by load-gltf only when the asset declares the\n * extension in `extensionsUsed`, so bundles pay zero bytes otherwise.\n *\n * Spec: https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md\n */\n\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport type { Mesh } from \"../mesh/mesh.js\";\nimport { resolveAccessor } from \"./gltf-parser.js\";\nimport { computeAabb } from \"../math/compute-aabb.js\";\nimport { mat4ComposeInto } from \"../math/mat4-compose-into.js\";\nimport { mat4Multiply } from \"../math/mat4-multiply.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport type { Mat4Storage } from \"../math/types.js\";\nimport { setThinInstances } from \"../mesh/thin-instance.js\";\nimport { getLoaderTmpInstance } from \"./_loader-scratch.js\";\n\n/** Collect every Mesh child (direct children only — matches buildNodeHierarchy). */\nfunction collectMeshesUnderNode(tn: { children?: unknown[] } | undefined): Mesh[] {\n const out: Mesh[] = [];\n for (const c of tn?.children ?? []) {\n if (c && typeof c === \"object\" && \"material\" in (c as object)) {\n out.push(c as Mesh);\n }\n }\n return out;\n}\n\nfunction buildInstanceMatrices(translation: Float32Array | null, rotation: Float32Array | null, scale: Float32Array | null, count: number): Float32Array {\n const matrices = new Float32Array(count * 16);\n for (let i = 0; i < count; i++) {\n const tx = translation ? translation[i * 3]! : 0;\n const ty = translation ? translation[i * 3 + 1]! : 0;\n const tz = translation ? translation[i * 3 + 2]! : 0;\n const qx = rotation ? rotation[i * 4]! : 0;\n const qy = rotation ? rotation[i * 4 + 1]! : 0;\n const qz = rotation ? rotation[i * 4 + 2]! : 0;\n const qw = rotation ? rotation[i * 4 + 3]! : 1;\n const sx = scale ? scale[i * 3]! : 1;\n const sy = scale ? scale[i * 3 + 1]! : 1;\n const sz = scale ? scale[i * 3 + 2]! : 1;\n mat4ComposeInto(matrices, i * 16, tx, ty, tz, qx, qy, qz, qw, sx, sy, sz);\n }\n return matrices;\n}\n\nconst ext: GltfFeature = {\n id: \"EXT_mesh_gpu_instancing\",\n async applyAsset(_meshes, _root, ctx) {\n const { _json: json, _binChunk: binChunk, _nodeMap: nodeMap } = ctx;\n if (!nodeMap) {\n return {};\n }\n const nodes = json.nodes ?? [];\n for (let nodeIdx = 0; nodeIdx < nodes.length; nodeIdx++) {\n const attrs = nodes[nodeIdx]?.extensions?.EXT_mesh_gpu_instancing?.attributes;\n if (!attrs) {\n continue;\n }\n const tn = nodeMap[nodeIdx];\n if (!tn) {\n continue;\n }\n const meshesForNode = collectMeshesUnderNode(tn as unknown as { children?: unknown[] });\n if (meshesForNode.length === 0) {\n continue;\n }\n\n const tAcc = attrs.TRANSLATION !== undefined ? resolveAccessor(json, binChunk, attrs.TRANSLATION) : null;\n const rAcc = attrs.ROTATION !== undefined ? resolveAccessor(json, binChunk, attrs.ROTATION) : null;\n const sAcc = attrs.SCALE !== undefined ? resolveAccessor(json, binChunk, attrs.SCALE) : null;\n\n let count = 0;\n for (const acc of [tAcc, rAcc, sAcc]) {\n if (!acc) {\n continue;\n }\n if (count === 0) {\n count = acc._count;\n } else if (acc._count !== count) {\n throw new Error(`EXT_mesh_gpu_instancing: accessor count mismatch on node ${nodeIdx}`);\n }\n }\n if (count === 0) {\n continue;\n }\n\n const matrices = buildInstanceMatrices(\n tAcc ? (tAcc._data as Float32Array) : null,\n rAcc ? (rAcc._data as Float32Array) : null,\n sAcc ? (sAcc._data as Float32Array) : null,\n count\n );\n const nodeWorld = ctx._worldMatrixCache.get(nodeIdx);\n for (const mesh of meshesForNode) {\n setThinInstances(mesh, matrices, count);\n expandMeshAabbForInstances(mesh, matrices, count, nodeWorld);\n }\n }\n return {};\n },\n};\nexport default ext;\n\n/** Expand a mesh's world-space AABB to enclose all thin instances so that\n * auto-framing cameras see the full instanced grid, not just the base mesh.\n * Uses the module-level `getLoaderTmpInstance()` scratch for the per-iteration\n * instance world matrix — no per-call allocation. */\nfunction expandMeshAabbForInstances(mesh: Mesh, matrices: Float32Array, count: number, nodeWorld: Mat4 | undefined): void {\n const positions = mesh._cpuPositions;\n if (!positions || !nodeWorld || count === 0) {\n return;\n }\n // Local AABB of the base mesh (before any per-instance / node transform).\n const [lmin, lmax] = computeAabb(positions);\n if (!isFinite(lmin[0]!)) {\n return;\n }\n // 8 corners of the local AABB, packed as 24 floats for computeAabb.\n const corners = new Float32Array([\n lmin[0]!,\n lmin[1]!,\n lmin[2]!,\n lmax[0]!,\n lmin[1]!,\n lmin[2]!,\n lmin[0]!,\n lmax[1]!,\n lmin[2]!,\n lmax[0]!,\n lmax[1]!,\n lmin[2]!,\n lmin[0]!,\n lmin[1]!,\n lmax[2]!,\n lmax[0]!,\n lmin[1]!,\n lmax[2]!,\n lmin[0]!,\n lmax[1]!,\n lmax[2]!,\n lmax[0]!,\n lmax[1]!,\n lmax[2]!,\n ]);\n let wMinX = Infinity,\n wMinY = Infinity,\n wMinZ = Infinity;\n let wMaxX = -Infinity,\n wMaxY = -Infinity,\n wMaxZ = -Infinity;\n const instWorld = getLoaderTmpInstance();\n const instBuf = instWorld as unknown as Mat4Storage;\n for (let i = 0; i < count; i++) {\n for (let k = 0; k < 16; k++) {\n instBuf[k] = matrices[i * 16 + k]!;\n }\n const combined = mat4Multiply(nodeWorld, instWorld);\n const [imin, imax] = computeAabb(corners, combined);\n if (imin[0]! < wMinX) {\n wMinX = imin[0]!;\n }\n if (imin[1]! < wMinY) {\n wMinY = imin[1]!;\n }\n if (imin[2]! < wMinZ) {\n wMinZ = imin[2]!;\n }\n if (imax[0]! > wMaxX) {\n wMaxX = imax[0]!;\n }\n if (imax[1]! > wMaxY) {\n wMaxY = imax[1]!;\n }\n if (imax[2]! > wMaxZ) {\n wMaxZ = imax[2]!;\n }\n }\n mesh.boundMin = [wMinX, wMinY, wMinZ];\n mesh.boundMax = [wMaxX, wMaxY, wMaxZ];\n}\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"gltf-feature-meshopt-Des96YFI.js","sources":["../src/loader-gltf/meshopt-decode.ts","../src/loader-gltf/gltf-feature-meshopt.ts"],"sourcesContent":["/**\n * Lazy EXT_meshopt_compression decoder.\n *\n * The meshoptimizer decoder (JS glue + embedded WASM) is loaded from\n * `/meshopt_decoder.js` on first use via a `<script>` injection — exactly like\n * the Draco decoder. This keeps bundle size at zero bytes for scenes that do\n * not load meshopt-compressed glTF assets: the entire module (including this\n * file) is dynamic-imported from the meshopt feature only when an asset's\n * `extensionsUsed` lists EXT_meshopt_compression.\n */\n\n// Public base URL where meshopt_decoder.js is hosted. Defaults to site root.\nlet meshoptBaseUrl = \"/\";\n\n/** Override the base URL where meshopt_decoder.js is hosted. */\nexport function setMeshoptBaseUrl(url: string): void {\n meshoptBaseUrl = url.endsWith(\"/\") ? url : url + \"/\";\n}\n\n/** Minimal surface of the global `MeshoptDecoder` object we rely on. */\ninterface MeshoptDecoderModule {\n ready: Promise<void>;\n decodeGltfBuffer(target: Uint8Array, count: number, size: number, source: Uint8Array, mode: string, filter?: string): void;\n}\n\nlet scriptLoadPromise: Promise<MeshoptDecoderModule> | null = null;\n\nfunction loadMeshoptScript(): Promise<MeshoptDecoderModule> {\n if (scriptLoadPromise) {\n return scriptLoadPromise;\n }\n scriptLoadPromise = new Promise<MeshoptDecoderModule>((resolve, reject) => {\n const existing = (globalThis as { MeshoptDecoder?: MeshoptDecoderModule }).MeshoptDecoder;\n if (existing) {\n resolve(existing);\n return;\n }\n const script = document.createElement(\"script\");\n script.src = meshoptBaseUrl + \"meshopt_decoder.js\";\n script.onload = () => {\n const mod = (globalThis as { MeshoptDecoder?: MeshoptDecoderModule }).MeshoptDecoder;\n if (!mod) {\n reject(new Error(\"meshopt_decoder.js loaded but MeshoptDecoder is undefined\"));\n } else {\n resolve(mod);\n }\n };\n script.onerror = () => reject(new Error(\"Failed to load meshopt_decoder.js from \" + script.src));\n document.head.appendChild(script);\n });\n return scriptLoadPromise;\n}\n\n/** Resolve the ready meshopt decoder module (WASM instantiated). */\nexport async function getMeshoptDecoder(): Promise<MeshoptDecoderModule> {\n const mod = await loadMeshoptScript();\n await mod.ready;\n return mod;\n}\n","/**\n * EXT_meshopt_compression feature.\n *\n * Runs as a `preParse` hook — before any accessor is read — so the core loader\n * and accessor reader stay unaware of meshopt. This module is only\n * dynamic-imported when the asset's `extensionsUsed` lists\n * EXT_meshopt_compression, which in turn loads the meshoptimizer decoder\n * (`meshopt-decode.ts`) lazily.\n *\n * EXT_meshopt_compression is a bufferView-level codec: each compressed\n * bufferView carries an extension object describing the compressed source\n * (`buffer`/`byteOffset`/`byteLength`), the decoded layout (`count`/`byteStride`)\n * and the codec (`mode`/`filter`). We decode every compressed bufferView, copy\n * through every uncompressed one, and pack the results into a single contiguous\n * binary chunk, rewriting `bufferViews` to point into it. Accessor byteOffsets\n * are bufferView-relative and the per-bufferView layout (count * byteStride) is\n * preserved, so the existing accessor reader resolves the decoded data\n * transparently.\n */\n\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport { getMeshoptDecoder } from \"./meshopt-decode.js\";\n\ninterface MeshoptExt {\n buffer: number;\n byteOffset?: number;\n byteLength: number;\n byteStride: number;\n count: number;\n mode: string;\n filter?: string;\n}\n\ninterface BufferView {\n buffer?: number;\n byteOffset?: number;\n byteLength: number;\n byteStride?: number;\n extensions?: { EXT_meshopt_compression?: MeshoptExt; [k: string]: unknown };\n}\n\n/** Round up to the next 4-byte boundary so relocated bufferViews stay aligned\n * for Float32Array / Uint16Array / Uint32Array views over the packed buffer. */\nfunction align4(n: number): number {\n return (n + 3) & ~3;\n}\n\nconst feature: GltfFeature = {\n id: \"EXT_meshopt_compression\",\n async preParse(json, binChunk) {\n const bufferViews: BufferView[] = json.bufferViews ?? [];\n const decoder = await getMeshoptDecoder();\n\n // Pass 1: materialize each bufferView (decode meshopt ones, copy the rest)\n // and compute the packed-buffer offset for each.\n const materialized: Uint8Array[] = new Array(bufferViews.length);\n const newOffsets: number[] = new Array(bufferViews.length);\n let total = 0;\n for (let i = 0; i < bufferViews.length; i++) {\n const bv = bufferViews[i]!;\n const ext = bv.extensions?.EXT_meshopt_compression;\n let bytes: Uint8Array;\n if (ext) {\n if ((ext.buffer ?? 0) !== 0) {\n throw new Error(`EXT_meshopt_compression: compressed source buffer ${ext.buffer} is not buffer 0 (unsupported)`);\n }\n const source = new Uint8Array(binChunk.buffer, binChunk.byteOffset + (ext.byteOffset ?? 0), ext.byteLength);\n const target = new Uint8Array(ext.count * ext.byteStride);\n decoder.decodeGltfBuffer(target, ext.count, ext.byteStride, source, ext.mode, ext.filter ?? \"NONE\");\n bytes = target;\n } else {\n if ((bv.buffer ?? 0) !== 0) {\n throw new Error(`EXT_meshopt_compression: uncompressed bufferView in buffer ${bv.buffer} is not buffer 0 (unsupported)`);\n }\n bytes = new Uint8Array(binChunk.buffer.slice(binChunk.byteOffset + (bv.byteOffset ?? 0), binChunk.byteOffset + (bv.byteOffset ?? 0) + bv.byteLength));\n }\n materialized[i] = bytes;\n newOffsets[i] = total;\n total = align4(total + bytes.length);\n }\n\n // Pass 2: pack into a single contiguous buffer and rewrite bufferViews.\n const packed = new Uint8Array(total);\n for (let i = 0; i < bufferViews.length; i++) {\n const bv = bufferViews[i]!;\n packed.set(materialized[i]!, newOffsets[i]!);\n bv.buffer = 0;\n bv.byteOffset = newOffsets[i]!;\n bv.byteLength = materialized[i]!.length;\n if (bv.extensions) {\n delete bv.extensions.EXT_meshopt_compression;\n }\n }\n\n return new DataView(packed.buffer);\n },\n};\n\nexport default feature;\n"],"names":[],"mappings":"AAYA,IAAI,iBAAiB;AAarB,IAAI,oBAA0D;AAE9D,SAAS,oBAAmD;AACxD,MAAI,mBAAmB;AACnB,WAAO;AAAA,EACX;AACA,sBAAoB,IAAI,QAA8B,CAAC,SAAS,WAAW;AACvE,UAAM,WAAY,WAAyD;AAC3E,QAAI,UAAU;AACV,cAAQ,QAAQ;AAChB;AAAA,IACJ;AACA,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,MAAM,iBAAiB;AAC9B,WAAO,SAAS,MAAM;AAClB,YAAM,MAAO,WAAyD;AACtE,UAAI,CAAC,KAAK;AACN,eAAO,IAAI,MAAM,2DAA2D,CAAC;AAAA,MACjF,OAAO;AACH,gBAAQ,GAAG;AAAA,MACf;AAAA,IACJ;AACA,WAAO,UAAU,MAAM,OAAO,IAAI,MAAM,4CAA4C,OAAO,GAAG,CAAC;AAC/F,aAAS,KAAK,YAAY,MAAM;AAAA,EACpC,CAAC;AACD,SAAO;AACX;AAGA,eAAsB,oBAAmD;AACrE,QAAM,MAAM,MAAM,kBAAA;AAClB,QAAM,IAAI;AACV,SAAO;AACX;ACfA,SAAS,OAAO,GAAmB;AAC/B,SAAQ,IAAI,IAAK;AACrB;AAEA,MAAM,UAAuB;AAAA,EACzB,IAAI;AAAA,EACJ,MAAM,SAAS,MAAM,UAAU;ADrCnC;ACsCQ,UAAM,cAA4B,KAAK,eAAe,CAAA;AACtD,UAAM,UAAU,MAAM,kBAAA;AAItB,UAAM,eAA6B,IAAI,MAAM,YAAY,MAAM;AAC/D,UAAM,aAAuB,IAAI,MAAM,YAAY,MAAM;AACzD,QAAI,QAAQ;AACZ,aAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AACzC,YAAM,KAAK,YAAY,CAAC;AACxB,YAAM,OAAM,QAAG,eAAH,mBAAe;AAC3B,UAAI;AACJ,UAAI,KAAK;AACL,aAAK,IAAI,UAAU,OAAO,GAAG;AACzB,gBAAM,IAAI,MAAM,qDAAqD,IAAI,MAAM,gCAAgC;AAAA,QACnH;AACA,cAAM,SAAS,IAAI,WAAW,SAAS,QAAQ,SAAS,cAAc,IAAI,cAAc,IAAI,IAAI,UAAU;AAC1G,cAAM,SAAS,IAAI,WAAW,IAAI,QAAQ,IAAI,UAAU;AACxD,gBAAQ,iBAAiB,QAAQ,IAAI,OAAO,IAAI,YAAY,QAAQ,IAAI,MAAM,IAAI,UAAU,MAAM;AAClG,gBAAQ;AAAA,MACZ,OAAO;AACH,aAAK,GAAG,UAAU,OAAO,GAAG;AACxB,gBAAM,IAAI,MAAM,8DAA8D,GAAG,MAAM,gCAAgC;AAAA,QAC3H;AACA,gBAAQ,IAAI,WAAW,SAAS,OAAO,MAAM,SAAS,cAAc,GAAG,cAAc,IAAI,SAAS,cAAc,GAAG,cAAc,KAAK,GAAG,UAAU,CAAC;AAAA,MACxJ;AACA,mBAAa,CAAC,IAAI;AAClB,iBAAW,CAAC,IAAI;AAChB,cAAQ,OAAO,QAAQ,MAAM,MAAM;AAAA,IACvC;AAGA,UAAM,SAAS,IAAI,WAAW,KAAK;AACnC,aAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AACzC,YAAM,KAAK,YAAY,CAAC;AACxB,aAAO,IAAI,aAAa,CAAC,GAAI,WAAW,CAAC,CAAE;AAC3C,SAAG,SAAS;AACZ,SAAG,aAAa,WAAW,CAAC;AAC5B,SAAG,aAAa,aAAa,CAAC,EAAG;AACjC,UAAI,GAAG,YAAY;AACf,eAAO,GAAG,WAAW;AAAA,MACzB;AAAA,IACJ;AAEA,WAAO,IAAI,SAAS,OAAO,MAAM;AAAA,EACrC;AACJ;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"gltf-feature-morph-BAcY14XU.js","sources":["../src/loader-gltf/gltf-feature-morph.ts"],"sourcesContent":["/** Morph target feature. Extracts per-primitive morph targets lazily so the\n * core loader doesn't carry any morph-related code for non-morphed assets. */\n\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport { resolveAccessor } from \"./gltf-parser.js\";\n\nconst feature: GltfFeature = {\n id: \"_morph\",\n async applyMesh(meshData, mesh, ctx) {\n const primitive = meshData._primitive;\n const targets = primitive.targets;\n if (!targets || targets.length === 0) {\n return;\n }\n const { _json: json, _binChunk: binChunk } = ctx;\n const morphTargets: { positions: Float32Array; normals: Float32Array | null }[] = [];\n for (const target of targets) {\n const posAcc = target.POSITION !== undefined ? resolveAccessor(json, binChunk, target.POSITION) : null;\n const normAcc = target.NORMAL !== undefined ? resolveAccessor(json, binChunk, target.NORMAL) : null;\n morphTargets.push({\n positions: posAcc ? (posAcc._data as Float32Array) : new Float32Array(meshData._vertexCount * 3),\n normals: normAcc ? (normAcc._data as Float32Array) : null,\n });\n }\n const parentMesh = json.meshes[json.nodes[meshData._nodeIndex].mesh];\n const morphWeights = parentMesh.weights ?? new Array(targets.length).fill(0);\n const { createMorphTargets } = await import(\"../morph/create-morph-targets.js\");\n mesh.morphTargets = createMorphTargets(ctx._engine, morphTargets, meshData._vertexCount, morphWeights);\n },\n};\nexport default feature;\n"],"names":[],"mappings":";AAMA,MAAM,UAAuB;AAAA,EACzB,IAAI;AAAA,EACJ,MAAM,UAAU,UAAU,MAAM,KAAK;AACjC,UAAM,YAAY,SAAS;AAC3B,UAAM,UAAU,UAAU;AAC1B,QAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AAClC;AAAA,IACJ;AACA,UAAM,EAAE,OAAO,MAAM,WAAW,aAAa;AAC7C,UAAM,eAA4E,CAAA;AAClF,eAAW,UAAU,SAAS;AAC1B,YAAM,SAAS,OAAO,aAAa,SAAY,gBAAgB,MAAM,UAAU,OAAO,QAAQ,IAAI;AAClG,YAAM,UAAU,OAAO,WAAW,SAAY,gBAAgB,MAAM,UAAU,OAAO,MAAM,IAAI;AAC/F,mBAAa,KAAK;AAAA,QACd,WAAW,SAAU,OAAO,QAAyB,IAAI,aAAa,SAAS,eAAe,CAAC;AAAA,QAC/F,SAAS,UAAW,QAAQ,QAAyB;AAAA,MAAA,CACxD;AAAA,IACL;AACA,UAAM,aAAa,KAAK,OAAO,KAAK,MAAM,SAAS,UAAU,EAAE,IAAI;AACnE,UAAM,eAAe,WAAW,WAAW,IAAI,MAAM,QAAQ,MAAM,EAAE,KAAK,CAAC;AAC3E,UAAM,EAAE,mBAAA,IAAuB,MAAM,OAAO,qBAAkC,EAAA,KAAA,OAAA,EAAA,EAAA;AAC9E,SAAK,eAAe,mBAAmB,IAAI,SAAS,cAAc,SAAS,cAAc,YAAY;AAAA,EACzG;AACJ;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"gltf-glb-parser-D6UZWFuC.js","sources":["../src/loader-gltf/gltf-glb-parser.ts"],"sourcesContent":["/** GLB binary container parsing. Kept separate so .gltf-only scenes do not ship it. */\n\nexport function parseGlbContainer(buffer: ArrayBuffer): { json: any; binChunk: DataView } {\n const view = new DataView(buffer);\n\n // Header (12 bytes)\n const magic = view.getUint32(0, true);\n if (magic !== 0x46546c67) {\n throw new Error(\"Not a valid GLB file\");\n }\n // const version = view.getUint32(4, true);\n // const totalLength = view.getUint32(8, true);\n\n // JSON chunk\n let offset = 12;\n const jsonLength = view.getUint32(offset, true);\n const jsonType = view.getUint32(offset + 4, true);\n if (jsonType !== 0x4e4f534a) {\n throw new Error(\"First GLB chunk is not JSON\");\n }\n const jsonStr = new TextDecoder().decode(new Uint8Array(buffer, offset + 8, jsonLength));\n const json = JSON.parse(jsonStr);\n offset += 8 + jsonLength;\n\n // BIN chunk\n const binLength = view.getUint32(offset, true);\n const binType = view.getUint32(offset + 4, true);\n if (binType !== 0x004e4942) {\n throw new Error(\"Second GLB chunk is not BIN\");\n }\n const binChunk = new DataView(buffer, offset + 8, binLength);\n\n return { json, binChunk };\n}\n"],"names":[],"mappings":"AAEO,SAAS,kBAAkB,QAAwD;AACtF,QAAM,OAAO,IAAI,SAAS,MAAM;AAGhC,QAAM,QAAQ,KAAK,UAAU,GAAG,IAAI;AACpC,MAAI,UAAU,YAAY;AACtB,UAAM,IAAI,MAAM,sBAAsB;AAAA,EAC1C;AAKA,MAAI,SAAS;AACb,QAAM,aAAa,KAAK,UAAU,QAAQ,IAAI;AAC9C,QAAM,WAAW,KAAK,UAAU,SAAS,GAAG,IAAI;AAChD,MAAI,aAAa,YAAY;AACzB,UAAM,IAAI,MAAM,6BAA6B;AAAA,EACjD;AACA,QAAM,UAAU,IAAI,YAAA,EAAc,OAAO,IAAI,WAAW,QAAQ,SAAS,GAAG,UAAU,CAAC;AACvF,QAAM,OAAO,KAAK,MAAM,OAAO;AAC/B,YAAU,IAAI;AAGd,QAAM,YAAY,KAAK,UAAU,QAAQ,IAAI;AAC7C,QAAM,UAAU,KAAK,UAAU,SAAS,GAAG,IAAI;AAC/C,MAAI,YAAY,SAAY;AACxB,UAAM,IAAI,MAAM,6BAA6B;AAAA,EACjD;AACA,QAAM,WAAW,IAAI,SAAS,QAAQ,SAAS,GAAG,SAAS;AAE3D,SAAO,EAAE,MAAM,SAAA;AACnB;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"gltf-interleave-C9eBqH_F.js","sources":["../src/loader-gltf/gltf-interleave.ts"],"sourcesContent":["/**\n * Interleaved (strided) glTF vertex-buffer support — dynamically imported.\n *\n * The engine renders interleaved attributes genuinely: the raw strided\n * bufferView slice is uploaded ONCE as a shared GPU buffer and bound to each\n * attribute at its byte offset with the pipeline's vertex `arrayStride` set to\n * the bufferView byteStride. The loader never rewrites the asset.\n *\n * This whole module is loaded via `await import()` only when an asset actually\n * contains an interleaved bufferView, so non-interleaved scenes pay ZERO bundle\n * cost. The tight CPU copy of position/normal/uv (for AABB, picking, CSG, …) is\n * de-strided LAZILY — only on first CPU read via `installLazyCpu` — so scenes\n * that only render never materialize it.\n */\n\nimport type { Mat4 } from \"../math/types.js\";\nimport type { Aabb } from \"../math/aabb.js\";\nimport { computeAabb } from \"../math/compute-aabb.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { Mesh, MeshGPU } from \"../mesh/mesh.js\";\nimport { initMeshTransform } from \"../mesh/mesh.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport { createMappedBuffer } from \"../resource/gpu-buffers.js\";\nimport { resolveAccessor, TYPE_SIZES } from \"./gltf-parser.js\";\nimport type { GltfMeshData } from \"./load-gltf.js\";\n\nconst FLOAT = 5126;\nconst UNSIGNED_SHORT = 5123;\nconst UNSIGNED_INT = 5125;\nconst UNSIGNED_BYTE = 5121;\n\nconst COMP_BYTES: Record<number, number> = { [UNSIGNED_BYTE]: 1, [UNSIGNED_SHORT]: 2, [UNSIGNED_INT]: 4, [FLOAT]: 4 };\n\n/** Interleave descriptor for one attribute sourced from a strided bufferView.\n * The raw slice is shared across attributes of the same bufferView; the\n * pipeline uses `_stride` as arrayStride and binds at `_offset`. */\nexport interface AccessorInterleave {\n /** @internal glTF bufferView index — shared-buffer key (same view → one GPU buffer). */\n _bufferView: number;\n /** @internal Interleave byte stride (bufferView.byteStride) → pipeline arrayStride. */\n _stride: number;\n /** @internal Attribute byte offset within the bufferView → setVertexBuffer bind offset. */\n _offset: number;\n /** @internal glTF component type (FLOAT, UNSIGNED_SHORT, …). */\n _componentType: number;\n /** @internal Components per vertex. */\n _componentCount: number;\n /** @internal Vertex count. */\n _count: number;\n /** @internal Raw bufferView bytes (shared across attributes). Retained after GPU upload\n * so the CPU copy can be de-strided lazily on demand. */\n _slice?: Uint8Array;\n}\n\n/** Per-attribute interleave sources for a primitive (keys mirror MeshVbLayout). */\nexport interface GltfVb {\n /** @internal */\n _p?: AccessorInterleave;\n /** @internal */\n _n?: AccessorInterleave;\n /** @internal */\n _t?: AccessorInterleave;\n /** @internal */\n _u?: AccessorInterleave;\n /** @internal */\n _u2?: AccessorInterleave;\n /** @internal */\n _c?: AccessorInterleave;\n}\n\n/** True if accessor `idx`'s bufferView is interleaved (byteStride present and\n * larger than the attribute's tightly-packed element size). */\nexport function accessorIsStrided(json: any, idx: number): boolean {\n const a = json.accessors[idx];\n const bv = json.bufferViews[a.bufferView];\n const stride: number | undefined = bv.byteStride;\n if (stride === undefined) {\n return false;\n }\n const elemBytes = (TYPE_SIZES[a.type] ?? 1) * (COMP_BYTES[a.componentType] ?? 4);\n return stride !== elemBytes;\n}\n\n/** Resolve a strided accessor into an {@link AccessorInterleave} descriptor. */\nfunction resolveStrided(json: any, binChunk: DataView, accessorIdx: number): AccessorInterleave {\n const accessor = json.accessors[accessorIdx];\n const bufferView = json.bufferViews[accessor.bufferView];\n const ab = binChunk.buffer as ArrayBuffer;\n return {\n _bufferView: accessor.bufferView,\n _stride: bufferView.byteStride,\n _offset: accessor.byteOffset ?? 0,\n _componentType: accessor.componentType,\n _componentCount: TYPE_SIZES[accessor.type] ?? 1,\n _count: accessor.count,\n _slice: new Uint8Array(ab, binChunk.byteOffset + (bufferView.byteOffset ?? 0), bufferView.byteLength),\n };\n}\n\n/** De-stride an interleaved attribute into a tight Float32Array, reading raw\n * component values (no normalization) so the result matches what a tight\n * accessor view would have produced. */\nfunction destrideToTight(il: AccessorInterleave): Float32Array {\n const dv = new DataView(il._slice!.buffer, il._slice!.byteOffset, il._slice!.byteLength);\n const cb = COMP_BYTES[il._componentType] ?? 4;\n const ct = il._componentType;\n const cc = il._componentCount;\n const out = new Float32Array(il._count * cc);\n for (let v = 0; v < il._count; v++) {\n const rowBase = il._offset + v * il._stride;\n for (let c = 0; c < cc; c++) {\n const off = rowBase + c * cb;\n out[v * cc + c] =\n ct === FLOAT ? dv.getFloat32(off, true) : ct === UNSIGNED_SHORT ? dv.getUint16(off, true) : ct === UNSIGNED_INT ? dv.getUint32(off, true) : dv.getUint8(off);\n }\n }\n return out;\n}\n\n/** Build a mesh-data partial for a primitive, but ONLY if it actually sources\n * ≥1 attribute from an interleaved (strided) bufferView. Returns `undefined`\n * for fully-tight primitives so the caller falls back to its tight path.\n *\n * Strided POSITION/NORMAL/TEXCOORD_0 attributes keep their raw slice in `_vb`\n * (for genuine GPU interleaving) and leave the tight CPU field `null` — the\n * de-strided copy is materialized lazily on first CPU read (see\n * {@link installLazyCpu}). Strided TANGENT/TEXCOORD_1/COLOR are eagerly\n * de-strided (they feed device-lost recovery), but no current asset interleaves\n * them. Tight attributes resolve exactly like the core loader. */\nexport function buildInterleavedPartial(json: any, binChunk: DataView, primitive: any, worldMatrix: Mat4, nodeIdx: number): Omit<GltfMeshData, \"_material\"> | undefined {\n const attrs = primitive.attributes;\n\n // Per-primitive gate: bail (→ tight path) unless a vertex attribute is strided.\n let anyStrided = false;\n for (const name in attrs) {\n if (accessorIsStrided(json, attrs[name])) {\n anyStrided = true;\n break;\n }\n }\n if (!anyStrided) {\n return undefined;\n }\n\n const vb: GltfVb = {};\n let vertexCount = 0;\n\n // Resolve one attribute. Returns the interleave descriptor (when the source is\n // strided) and/or a tight CPU array. `eager` de-strides strided sources up-front\n // (TANGENT/UV2/COLOR feed device-lost recovery); lazy ones leave `_tight` null and\n // are de-strided on demand. The caller assigns `vb.<attr>` with a STATIC property\n // name (never a computed `vb[key]`) — a computed write would stay an unmangled\n // literal while every reader uses the mangled static name, corrupting the object\n // across the dynamic-import chunk boundary.\n const resolveOne = (name: string, eager: boolean): { _tight: Float32Array | null; _il?: AccessorInterleave; _count: number } => {\n const idx = attrs[name];\n if (idx === undefined) {\n return { _tight: null, _count: 0 };\n }\n if (accessorIsStrided(json, idx)) {\n const il = resolveStrided(json, binChunk, idx);\n return { _tight: eager ? destrideToTight(il) : null, _il: il, _count: il._count };\n }\n const av = resolveAccessor(json, binChunk, idx);\n return { _tight: av._data as Float32Array, _count: av._count };\n };\n\n const pos = resolveOne(\"POSITION\", false);\n vb._p = pos._il;\n vertexCount = pos._count;\n const nrm = resolveOne(\"NORMAL\", false);\n vb._n = nrm._il;\n const uv = resolveOne(\"TEXCOORD_0\", false);\n vb._u = uv._il;\n const tan = resolveOne(\"TANGENT\", true);\n vb._t = tan._il;\n const uv2 = resolveOne(\"TEXCOORD_1\", true);\n vb._u2 = uv2._il;\n const col = resolveOne(\"COLOR_0\", true);\n vb._c = col._il;\n\n const positions = pos._tight;\n let normals = nrm._tight;\n let uvs = uv._tight;\n const tangents = tan._tight;\n const uv2s = uv2._tight;\n const colors = col._tight;\n\n // Absent (not merely strided) NORMAL/UV need a tight zero-filled buffer so the\n // GPU has a bindable vertex buffer — matches the core loader's tight path.\n if (!normals && !vb._n) {\n normals = new Float32Array(vertexCount * 3);\n }\n if (!uvs && !vb._u) {\n uvs = new Float32Array(vertexCount * 2);\n }\n\n const idxData = primitive.indices !== undefined ? resolveAccessor(json, binChunk, primitive.indices) : null;\n const indices = idxData\n ? idxData._data instanceof Uint32Array\n ? new Uint32Array(idxData._data)\n : idxData._data instanceof Uint8Array\n ? Uint16Array.from(idxData._data)\n : new Uint16Array(idxData._data.buffer, idxData._data.byteOffset, idxData._count)\n : new Uint16Array(0);\n\n return {\n _positions: positions,\n _normals: normals,\n _tangents: tangents,\n _uvs: uvs,\n _uv2s: uv2s,\n _colors: colors,\n _indices: indices,\n _vertexCount: vertexCount,\n _indexCount: idxData?._count ?? 0,\n _worldMatrix: worldMatrix,\n _vb: vb,\n _nodeIndex: nodeIdx,\n _primitive: primitive,\n };\n}\n\n/** Build the GPU geometry for an interleaved mesh: one shared buffer per\n * bufferView for strided attributes (bound at offset with arrayStride), tight\n * attributes get their own buffer — byte-identical to non-interleaved meshes.\n * The raw `_slice` is intentionally retained on `_vb` so the CPU copy can be\n * de-strided lazily later (see {@link installLazyCpu}). */\nfunction buildInterleavedGpu(engine: EngineContext, m: GltfMeshData): MeshGPU {\n const vbsrc = m._vb!;\n const shared = new Map<number, GPUBuffer>();\n const vbuf = (a: AccessorInterleave | undefined, tight: Float32Array | null): GPUBuffer | null => {\n if (!a) {\n return tight ? createMappedBuffer(engine, tight, GPUBufferUsage.VERTEX) : null;\n }\n let b = shared.get(a._bufferView);\n if (!b) {\n shared.set(a._bufferView, (b = createMappedBuffer(engine, a._slice!, GPUBufferUsage.VERTEX)));\n }\n return b;\n };\n return {\n positionBuffer: vbuf(vbsrc._p, m._positions)!,\n normalBuffer: vbuf(vbsrc._n, m._normals)!,\n tangentBuffer: m._tangents ? vbuf(vbsrc._t, m._tangents) : null,\n uvBuffer: vbuf(vbsrc._u, m._uvs)!,\n uv2Buffer: m._uv2s ? vbuf(vbsrc._u2, m._uv2s) : null,\n colorBuffer: m._colors ? vbuf(vbsrc._c, m._colors) : null,\n indexBuffer: createMappedBuffer(engine, m._indices, GPUBufferUsage.INDEX),\n indexCount: m._indexCount,\n indexFormat: (m._indices instanceof Uint32Array ? \"uint32\" : \"uint16\") as GPUIndexFormat,\n _vbLayout: vbsrc,\n _vbKey: `vb${vbsrc._p?._stride ?? 0}.${vbsrc._n?._stride ?? 0}.${vbsrc._t?._stride ?? 0}.${vbsrc._u?._stride ?? 0}`,\n };\n}\n\n/** Build a complete engine mesh from interleaved glTF mesh-data. Owns ALL\n * interleave-specific work (GPU upload, AABB fold, lazy CPU install, device-lost\n * retention) so the core loader's tight path stays byte-identical to the\n * non-interleaved engine — keeping interleave bytes out of every glTF scene that\n * doesn't use it. */\nexport function buildInterleavedMesh(engine: EngineContext, m: GltfMeshData, index: number, material: PbrMaterialProps): Mesh {\n const gpu = buildInterleavedGpu(engine, m);\n\n // AABB: fold strided positions straight from the slice; tight positions normally.\n const [boundMin, boundMax] = m._vb!._p ? computeAabbStrided(m._vb!._p, m._worldMatrix) : computeAabb(m._positions!, m._worldMatrix);\n\n const mesh = {\n name: `gltf_mesh_${index}`,\n material,\n receiveShadows: false,\n boundMin,\n boundMax,\n skeleton: null,\n morphTargets: null,\n _materialDirty: false,\n _gpu: gpu,\n } as unknown as Mesh;\n initMeshTransform(mesh);\n\n // Lazy CPU geometry: the de-strided tight copy is built only on first read.\n installLazyCpu(mesh, m);\n mesh._cpuIndices = m._indices instanceof Uint32Array ? m._indices : new Uint32Array(m._indices);\n engine._dlr?.m(mesh, m._uv2s, m._tangents, m._colors, m._indices, gpu.indexFormat);\n\n return mesh as Mesh;\n}\n\n/** Fold an AABB directly over an interleaved (strided) FLOAT vec3 position\n * source — no tight copy is materialized. Mirrors {@link computeAabb}'s\n * world-transform handling. All current interleaved assets use FLOAT positions. */\nexport function computeAabbStrided(il: AccessorInterleave, world?: Mat4): Aabb {\n const dv = new DataView(il._slice!.buffer, il._slice!.byteOffset, il._slice!.byteLength);\n let minX = Infinity,\n minY = Infinity,\n minZ = Infinity;\n let maxX = -Infinity,\n maxY = -Infinity,\n maxZ = -Infinity;\n for (let v = 0; v < il._count; v++) {\n const base = il._offset + v * il._stride;\n const lx = dv.getFloat32(base, true);\n const ly = dv.getFloat32(base + 4, true);\n const lz = dv.getFloat32(base + 8, true);\n let x = lx,\n y = ly,\n z = lz;\n if (world) {\n x = world[0]! * lx + world[4]! * ly + world[8]! * lz + world[12]!;\n y = world[1]! * lx + world[5]! * ly + world[9]! * lz + world[13]!;\n z = world[2]! * lx + world[6]! * ly + world[10]! * lz + world[14]!;\n }\n if (x < minX) {\n minX = x;\n }\n if (x > maxX) {\n maxX = x;\n }\n if (y < minY) {\n minY = y;\n }\n if (y > maxY) {\n maxY = y;\n }\n if (z < minZ) {\n minZ = z;\n }\n if (z > maxZ) {\n maxZ = z;\n }\n }\n return [\n [minX, minY, minZ],\n [maxX, maxY, maxZ],\n ];\n}\n\n/** Install lazy CPU-geometry accessors on an interleaved mesh. Each of\n * `_cpuPositions/_cpuNormals/_cpuUvs` that comes from a strided source is\n * defined as a getter that de-strides a tight copy on first access and caches\n * it; tight attributes are assigned directly. A mesh that is never picked /\n * CSG'd / navigated never materializes the de-strided arrays.\n *\n * The property names are written as STATIC literals (not a computed key) so the\n * minifier mangles them identically to the static reads in the picking /\n * device-lost code — a computed `defineProperty(mesh, key)` would leave the name\n * an unmangled literal and mismatch those reads across the chunk boundary. */\nexport function installLazyCpu(mesh: any, m: GltfMeshData): void {\n const vb = m._vb!;\n if (vb._p) {\n Object.defineProperty(mesh, \"_cpuPositions\", lazyCpuDesc(vb._p));\n } else if (m._positions) {\n mesh._cpuPositions = m._positions;\n }\n if (vb._n) {\n Object.defineProperty(mesh, \"_cpuNormals\", lazyCpuDesc(vb._n));\n } else if (m._normals) {\n mesh._cpuNormals = m._normals;\n }\n if (vb._u) {\n Object.defineProperty(mesh, \"_cpuUvs\", lazyCpuDesc(vb._u));\n } else if (m._uvs) {\n mesh._cpuUvs = m._uvs;\n }\n}\n\n/** Build a caching lazy-getter descriptor that de-strides `il` on first read. */\nfunction lazyCpuDesc(il: AccessorInterleave): PropertyDescriptor {\n let cached: Float32Array | undefined;\n return {\n configurable: true,\n enumerable: true,\n get(): Float32Array {\n return (cached ??= destrideToTight(il));\n },\n set(v: Float32Array): void {\n cached = v;\n },\n };\n}\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"gltf-pbr-builder-ext-DPC0zg_u.js","sources":["../src/loader-gltf/gltf-pbr-builder-ext.ts"],"sourcesContent":["/** Lazy-loaded slow path for PBR material assembly.\n * Only pulled into bundles whose glTF uses features that require per-texture\n * wrapping (e.g. KHR_texture_transform) or occlusion on UV2 (texCoord=1 with\n * no shared MR image). Scene1 (BoomBox) and any vanilla-PBR glTF skip this\n * module entirely. */\n\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport { cloneTexture2D } from \"../texture/texture-2d.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport { pbrGroupBuilder } from \"../material/pbr/pbr-material.js\";\nimport type { GltfMaterialData } from \"./gltf-material.js\";\nimport { linearToSrgbByte } from \"../math/color.js\";\nimport type { TextureWrapFn, GenerateMipmapsFn } from \"./gltf-pbr-builder.js\";\nimport { uploadTex } from \"./gltf-pbr-builder.js\";\n\nexport interface PbrTexturesExt {\n baseColorTexture: Texture2D;\n ormTexture: Texture2D;\n normalTexture: Texture2D | undefined;\n emissiveTexture: Texture2D | undefined;\n occlusionTexture: Texture2D | undefined;\n}\n\n/** Stamp `_texCoord=1` on a clone when textureInfo selects UV1 and the\n * wrapTex layer didn't already set it (i.e. scene has no KHR_texture_transform). */\nfunction wrapTexCoord(tex: Texture2D, texInfo: unknown): Texture2D {\n if (!texInfo) {\n return tex;\n }\n if ((tex as { _texCoord?: 0 | 1 })._texCoord === 1) {\n return tex;\n }\n const ti = texInfo as { texCoord?: number; extensions?: { KHR_texture_transform?: { texCoord?: number } } };\n const tc = ti.extensions?.KHR_texture_transform?.texCoord ?? ti.texCoord;\n return tc === 1 ? cloneTexture2D(tex, { _texCoord: 1 }) : tex;\n}\n\n/** Build textures with wrapTex + occlusionOnUv2 support. Mirrors master's\n * default texture building but honors per-textureInfo wrapping so\n * KHR_texture_transform can attach per-texture UV state. */\nexport function buildDefaultPbrTexturesExt(\n engine: EngineContext,\n mat: GltfMaterialData,\n sampler: GPUSampler,\n generateMipmaps: GenerateMipmapsFn,\n getCachedTex: (bitmap: ImageBitmap, srgb: boolean) => Texture2D,\n wrapTex: TextureWrapFn\n): PbrTexturesExt {\n const wrap: TextureWrapFn = (tex, ti) => wrapTexCoord(wrapTex(tex, ti), ti);\n const raw = mat._rawMatDef ?? {};\n const pbr = raw.pbrMetallicRoughness ?? {};\n const baseColorTexture = mat._baseColorImage\n ? wrap(getCachedTex(mat._baseColorImage, true), pbr.baseColorTexture)\n : (() => {\n const f = mat._baseColorFactor;\n return uploadTex(\n engine,\n null,\n true,\n sampler,\n generateMipmaps,\n new Uint8Array([linearToSrgbByte(f[0]), linearToSrgbByte(f[1]), linearToSrgbByte(f[2]), Math.round(Math.max(0, Math.min(1, f[3])) * 255)])\n );\n })();\n const normalTexture = mat._normalImage ? wrap(getCachedTex(mat._normalImage, false), raw.normalTexture) : undefined;\n const emissiveTexture = mat._emissiveImage ? wrap(getCachedTex(mat._emissiveImage, true), raw.emissiveTexture) : undefined;\n\n const occlusionOnUv2 = mat._occlusionTexCoord !== 0 && mat._occlusionImage && !mat._metallicRoughnessImage;\n let occlusionTexture: Texture2D | undefined;\n const single = mat._metallicRoughnessImage ?? (occlusionOnUv2 ? null : mat._occlusionImage);\n let ormTexture: Texture2D;\n if (occlusionOnUv2) {\n const clamp = (v: number) => Math.round(Math.max(0, Math.min(1, v)) * 255);\n ormTexture = uploadTex(engine, null, false, sampler, generateMipmaps, new Uint8Array([255, clamp(mat._roughnessFactor), clamp(mat._metallicFactor), 255]));\n occlusionTexture = wrap(getCachedTex(mat._occlusionImage!, false), raw.occlusionTexture);\n } else if (single && (!mat._metallicRoughnessImage || !mat._occlusionImage || mat._metallicRoughnessImage === mat._occlusionImage)) {\n const ormTi = mat._metallicRoughnessImage ? pbr.metallicRoughnessTexture : raw.occlusionTexture;\n ormTexture = wrap(getCachedTex(single, false), ormTi);\n } else if (!single) {\n const clamp = (v: number) => Math.round(Math.max(0, Math.min(1, v)) * 255);\n ormTexture = uploadTex(engine, null, false, sampler, generateMipmaps, new Uint8Array([255, clamp(mat._roughnessFactor), clamp(mat._metallicFactor), 255]));\n } else {\n ormTexture = wrap(getCachedTex(mat._metallicRoughnessImage!, false), pbr.metallicRoughnessTexture);\n }\n return { baseColorTexture, ormTexture, normalTexture, emissiveTexture, occlusionTexture };\n}\n\n/** Slow-path assembly: adds occlusionTexCoord and occlusionTexture props. */\nexport function assemblePbrPropsExt(mat: GltfMaterialData, tex: PbrTexturesExt, extLayers: Partial<PbrMaterialProps> | undefined): PbrMaterialProps {\n const ef = mat._emissiveFactor;\n const defaultFactor = (ef[0] === 1 && ef[1] === 1 && ef[2] === 1) || (ef[0] === 0 && ef[1] === 0 && ef[2] === 0);\n // Precompute UV-transform presence so the renderer doesn't scan 5 textures\n // per mesh. Any wrapped texture with `_hasTx=true` (set by gltf-ext-uv-transform)\n // flips this once at build time; omitted entirely on fast path.\n const hasAnyUvTx =\n !!(tex.baseColorTexture as { _hasTx?: true })._hasTx ||\n !!(tex.normalTexture as { _hasTx?: true } | undefined)?._hasTx ||\n !!(tex.ormTexture as { _hasTx?: true })._hasTx ||\n !!(tex.emissiveTexture as { _hasTx?: true } | undefined)?._hasTx ||\n !!(tex.occlusionTexture as { _hasTx?: true } | undefined)?._hasTx;\n return {\n baseColorTexture: tex.baseColorTexture,\n normalTexture: tex.normalTexture,\n ormTexture: tex.ormTexture,\n emissiveTexture: tex.emissiveTexture,\n ...(mat._baseColorImage && !isDefaultBaseColorFactor(mat._baseColorFactor) ? { baseColorFactor: mat._baseColorFactor } : undefined),\n doubleSided: mat._doubleSided,\n occlusionStrength: mat._occlusionImage ? 1.0 : 0,\n ...(mat._occlusionTexCoord ? { occlusionTexCoord: mat._occlusionTexCoord } : undefined),\n ...(tex.occlusionTexture ? { occlusionTexture: tex.occlusionTexture } : undefined),\n ...(mat._normalScale !== 1 ? { normalTextureScale: mat._normalScale } : undefined),\n ...(mat._metallicRoughnessImage ? { metallicFactor: mat._metallicFactor, roughnessFactor: mat._roughnessFactor } : undefined),\n ...(!defaultFactor ? { emissiveColor: [ef[0], ef[1], ef[2]] as [number, number, number] } : undefined),\n enableSpecularAA: true,\n ...(mat._alphaMode === \"BLEND\" ? { alphaBlend: true, alpha: mat._baseColorFactor[3] } : undefined),\n ...(mat._alphaMode === \"MASK\" ? { alpha: mat._baseColorFactor[3], alphaCutOff: mat._alphaCutoff } : undefined),\n ...(hasAnyUvTx ? { _hasUvTx: true } : undefined),\n ...(mat._rawMatDef?.name ? { name: mat._rawMatDef.name as string } : undefined),\n ...extLayers,\n _buildGroup: pbrGroupBuilder,\n _uboVersion: 0,\n } as PbrMaterialProps;\n}\n\nfunction isDefaultBaseColorFactor(f: readonly number[]): boolean {\n return f[0] === 1 && f[1] === 1 && f[2] === 1 && f[3] === 1;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"gs-picking-pipeline-Bx8LTav6.js","sources":["../src/picking/gs-picking-pipeline.ts"],"sourcesContent":["/** GS GPU-picking pipeline — dynamic-imported by `gpu-picker.ts` when a scene\n * contains a Gaussian-Splatting mesh.\n *\n * The pipeline is a variant of the base Gaussian-splatting render pipeline\n * (`gaussian-splatting.wgsl`) with three modifications, applied via string\n * substitution + the `applyGsFragments` plugin system so the base shader stays\n * untouched:\n *\n * 1. A scene UBO at `@group(0) @binding(0)` carries a `pickMatrix`\n * (column-major 4x4) that zooms NDC onto the pick pixel — same maths as\n * `computePickVP` in `gpu-picker.ts`, but applied *after* the GS-specific\n * projection so the EWA Jacobian / `u.focal` math is untouched.\n * 2. The fragment returns `FsOut { @location(0) color, @location(1) depth }`\n * so the picker can read a pick id + NDC z from the 1×1 render target.\n * 3. `gsGpuPickingFragment` is applied (via `applyGsFragments`) to inject the\n * per-mesh `pickingColor` UBO at `@group(2) @binding(0)` and override the\n * fragment color with the encoded pick id. This mirrors BJS\n * `GaussianSplattingGpuPickingMaterialPlugin`'s `getCustomCode`/`bindForSubMesh`\n * split.\n *\n * The pipeline has no blending and `depthWriteEnabled = true`, so the\n * closest-splat wins at each pick pixel (matching BJS GPU picker behaviour). */\n\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { GaussianSplattingMesh } from \"../mesh/GaussianSplatting/gaussian-splatting-mesh.js\";\nimport { applyGsFragments } from \"../mesh/GaussianSplatting/gaussian-splatting-pipeline.js\";\nimport { gsGpuPickingFragment, encodeIdToColor } from \"../mesh/GaussianSplatting/gs-gpu-picking-fragment.js\";\nimport { getPickingSceneBGL } from \"./picking-pipeline.js\";\nimport { getRenderTargetSize } from \"../engine/engine.js\";\nimport { getViewMatrix, getProjectionMatrix } from \"../camera/camera.js\";\nimport type { SceneContext } from \"../scene/scene-core.js\";\n\ninterface GsPickingCache {\n device: GPUDevice;\n pipeline: GPURenderPipeline;\n meshBGL: GPUBindGroupLayout;\n pickingBGL: GPUBindGroupLayout;\n /** Shared \"pick scene\" UBO holding the 4x4 pickMatrix (set per pick). */\n pickMatrixUbo: GPUBuffer;\n /** Bind group exposing `pickMatrixUbo` at group(0) binding(0). */\n sceneBG: GPUBindGroup;\n}\n\nlet _cache: GsPickingCache | null = null;\n\n/** Build the GS picking WGSL as a self-contained template literal.\n *\n * This is a variant of the base GS shader (`gaussian-splatting.wgsl`) with two\n * modifications baked in directly (rather than string-patched at runtime), so\n * it survives identifier-mangling minification in production bundles:\n *\n * 1. The final `out.pos` is pre-multiplied by `gsPickScene.pickMatrix` (a 4×4\n * UBO at `@group(0) @binding(0)`) — applied *after* the GS-specific\n * projection so the EWA Jacobian / `u.focal` math is untouched.\n * 2. The fragment returns `FsOut { @location(0) color, @location(1) depth }`\n * so the picker can read pick id + NDC z from the 1×1 render target.\n *\n * The fragment keeps the `/* GS_FRAGMENT_* *\\/` slot markers so\n * `gsGpuPickingFragment` is still spliced in via `applyGsFragments` to\n * override `finalColor` with the encoded pick id. Template-literal WGSL\n * goes through `minifyTemplateWgsl` (preserves block comments) in the\n * bundle pipeline, so the slot markers survive minification.\n */\nfunction buildPickingWgsl(): string {\n const wgsl = /* wgsl */ `\nstruct GsPickScene { pickMatrix: mat4x4<f32> };\n@group(0) @binding(0) var<uniform> gsPickScene: GsPickScene;\n\nstruct U {\n world: mat4x4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n viewport: vec2<f32>,\n focal: vec2<f32>,\n dataSize: vec2<f32>,\n alpha: f32,\n _pad: f32,\n};\n@group(1) @binding(0) var<uniform> u: U;\n@group(1) @binding(1) var samp: sampler;\n@group(1) @binding(2) var centersTex: texture_2d<f32>;\n@group(1) @binding(3) var covATex: texture_2d<f32>;\n@group(1) @binding(4) var covBTex: texture_2d<f32>;\n@group(1) @binding(5) var colorsTex: texture_2d<f32>;\n\nstruct VOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) vColor: vec4<f32>,\n @location(1) vPos: vec2<f32>,\n};\n\nfn dataUv(idx: f32) -> vec2<f32> {\n let y = floor(idx / u.dataSize.x);\n let x = idx - y * u.dataSize.x;\n return vec2<f32>((x + 0.5) / u.dataSize.x, (y + 0.5) / u.dataSize.y);\n}\n\n@vertex\nfn vs(@location(0) corner: vec2<f32>, @location(1) splatIndex: f32) -> VOut {\n var out: VOut;\n let uv = dataUv(splatIndex);\n let center = textureSampleLevel(centersTex, samp, uv, 0.0).xyz;\n let color = textureSampleLevel(colorsTex, samp, uv, 0.0);\n let covA = textureSampleLevel(covATex, samp, uv, 0.0).xyz;\n let covB = textureSampleLevel(covBTex, samp, uv, 0.0).xyz;\n\n let worldPos = u.world * vec4<f32>(center, 1.0);\n let modelView = u.view * u.world;\n let camspace = u.view * worldPos;\n let pos2d = u.projection * camspace;\n\n let bounds = 1.2 * pos2d.w;\n if (pos2d.z < 0.0\n || pos2d.x < -bounds || pos2d.x > bounds\n || pos2d.y < -bounds || pos2d.y > bounds) {\n out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);\n out.vColor = vec4<f32>(0.0);\n out.vPos = vec2<f32>(0.0);\n return out;\n }\n\n let Vrk = mat3x3<f32>(\n vec3<f32>(covA.x, covA.y, covA.z),\n vec3<f32>(covA.y, covB.x, covB.y),\n vec3<f32>(covA.z, covB.y, covB.z));\n\n let invZ = 1.0 / camspace.z;\n let invZ2 = invZ * invZ;\n let J = mat3x3<f32>(\n vec3<f32>(u.focal.x * invZ, 0.0, -u.focal.x * camspace.x * invZ2),\n vec3<f32>(0.0, u.focal.y * invZ, -u.focal.y * camspace.y * invZ2),\n vec3<f32>(0.0, 0.0, 0.0));\n\n let mv3 = mat3x3<f32>(modelView[0].xyz, modelView[1].xyz, modelView[2].xyz);\n let T = transpose(mv3) * J;\n var cov2d = transpose(T) * Vrk * T;\n\n let kernelSize: f32 = 0.3;\n cov2d[0][0] += kernelSize;\n cov2d[1][1] += kernelSize;\n\n let mid = (cov2d[0][0] + cov2d[1][1]) * 0.5;\n let dxy = (cov2d[0][0] - cov2d[1][1]) * 0.5;\n let radius = length(vec2<f32>(dxy, cov2d[0][1]));\n let epsilon: f32 = 0.0001;\n let lambda1 = mid + radius + epsilon;\n let lambda2 = mid - radius + epsilon;\n if (lambda2 < 0.0) {\n out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);\n out.vColor = vec4<f32>(0.0);\n out.vPos = vec2<f32>(0.0);\n return out;\n }\n\n let diag = normalize(vec2<f32>(cov2d[0][1], lambda1 - cov2d[0][0]));\n let majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diag;\n let minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2<f32>(diag.y, -diag.x);\n\n let vCenter = pos2d.xy;\n out.pos = gsPickScene.pickMatrix * vec4<f32>(\n vCenter + (corner.x * majorAxis + corner.y * minorAxis) * pos2d.w / u.viewport,\n pos2d.z, pos2d.w);\n out.vColor = vec4<f32>(color.rgb, color.a * u.alpha);\n out.vPos = corner;\n return out;\n}\n\n/*GS_FRAGMENT_DEFINITIONS*/\nstruct FsOut { @location(0) color: vec4<f32>, @location(1) depth: vec4<f32> };\n@fragment\nfn fs(in: VOut) -> FsOut {\n /*GS_FRAGMENT_MAIN_BEGIN*/\n let A = -dot(in.vPos, in.vPos);\n var finalColor: vec4<f32>;\n if (A > -4.0) {\n let B = exp(A) * in.vColor.a;\n finalColor = vec4<f32>(in.vColor.rgb, B);\n } else {\n finalColor = vec4<f32>(0.0);\n }\n /*GS_FRAGMENT_BEFORE_FRAGCOLOR*/\n /*GS_FRAGMENT_MAIN_END*/\n return FsOut(finalColor, vec4<f32>(in.pos.z, 0.0, 0.0, 0.0));\n}\n`;\n return applyGsFragments(wgsl, [gsGpuPickingFragment]);\n}\n\nfunction getCache(engine: EngineContext): GsPickingCache {\n const device = engine._device;\n if (_cache && _cache.device === device) {\n return _cache;\n }\n const meshBGL = device.createBindGroupLayout({\n label: \"gs-picking-mesh-bgl\",\n entries: [\n { binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: \"uniform\" } },\n { binding: 1, visibility: GPUShaderStage.VERTEX, sampler: { type: \"non-filtering\" } },\n { binding: 2, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 3, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 4, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 5, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n ],\n });\n const pickingBGL = device.createBindGroupLayout({\n label: \"gs-picking-pick-bgl\",\n entries: [{ binding: 0, visibility: GPUShaderStage.FRAGMENT, buffer: { type: \"uniform\" } }],\n });\n const module = device.createShaderModule({ label: \"gs-picking-shader\", code: buildPickingWgsl() });\n const pipeline = device.createRenderPipeline({\n label: \"gs-picking-pipeline\",\n layout: device.createPipelineLayout({ bindGroupLayouts: [getPickingSceneBGL(engine), meshBGL, pickingBGL] }),\n vertex: {\n module,\n entryPoint: \"vs\",\n buffers: [\n { arrayStride: 8, stepMode: \"vertex\", attributes: [{ shaderLocation: 0, offset: 0, format: \"float32x2\" }] },\n { arrayStride: 4, stepMode: \"instance\", attributes: [{ shaderLocation: 1, offset: 0, format: \"float32\" }] },\n ],\n },\n fragment: {\n module,\n entryPoint: \"fs\",\n targets: [{ format: \"rgba8unorm\" }, { format: \"r32float\" }],\n },\n primitive: { topology: \"triangle-list\", cullMode: \"none\" },\n depthStencil: { format: \"depth24plus\", depthCompare: \"less\", depthWriteEnabled: true },\n multisample: { count: 1 },\n });\n const pickMatrixUbo = device.createBuffer({ size: 64, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, label: \"gs-picking-scene-ubo\" });\n const sceneBG = device.createBindGroup({\n label: \"gs-picking-scene-bg\",\n layout: getPickingSceneBGL(engine),\n entries: [{ binding: 0, resource: { buffer: pickMatrixUbo } }],\n });\n _cache = { device, pipeline, meshBGL, pickingBGL, pickMatrixUbo, sceneBG };\n return _cache;\n}\n\n/** Write a 4x4 pickMatrix into the shared scene UBO and bind group 0 on `pass`. */\nexport function gsPickWritePickMatrixAndBind(pass: GPURenderPassEncoder, engine: EngineContext, pickMatrix: Float32Array): void {\n const cache = getCache(engine);\n engine._device.queue.writeBuffer(cache.pickMatrixUbo, 0, pickMatrix.buffer, pickMatrix.byteOffset, pickMatrix.byteLength);\n pass.setBindGroup(0, cache.sceneBG);\n}\n\n/** Per-GS-mesh state allocated on first pick of that mesh. */\nexport interface GsPickMeshResources {\n /** Per-mesh UBO (same 224-byte layout as the regular GS pipeline UBO). */\n meshUbo: GPUBuffer;\n /** Group 1 bind group: per-mesh UBO + sampler + 4 textures. */\n meshBG: GPUBindGroup;\n /** Per-pick picking-color UBO (16 bytes: vec3<f32> + pad). */\n pickingUbo: GPUBuffer;\n /** Group 2 bind group with the picking-color UBO. */\n pickingBG: GPUBindGroup;\n /** Scratch buffer for the per-mesh UBO. */\n meshCpu: Float32Array;\n /** Scratch buffer for the picking-color UBO. */\n pickingCpu: Float32Array;\n}\n\nexport function createGsPickMeshResources(engine: EngineContext, mesh: GaussianSplattingMesh): GsPickMeshResources {\n const device = engine._device;\n const cache = getCache(engine);\n\n const UBO_BYTES = 16 * 4 * 3 + 8 * 4;\n const meshUbo = device.createBuffer({ size: UBO_BYTES, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, label: \"gs-picking-mesh-ubo\" });\n const meshCpu = new Float32Array(UBO_BYTES / 4);\n meshCpu[48 + 4] = mesh.textureWidth;\n meshCpu[48 + 5] = mesh.textureHeight;\n meshCpu[48 + 6] = 1;\n\n const meshBG = device.createBindGroup({\n label: \"gs-picking-mesh-bg\",\n layout: cache.meshBGL,\n entries: [\n { binding: 0, resource: { buffer: meshUbo } },\n { binding: 1, resource: mesh._gs._sampler },\n { binding: 2, resource: mesh._gs._centersView },\n { binding: 3, resource: mesh._gs._covAView },\n { binding: 4, resource: mesh._gs._covBView },\n { binding: 5, resource: mesh._gs._colorsView },\n ],\n });\n\n const pickingUbo = device.createBuffer({ size: 16, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, label: \"gs-picking-color-ubo\" });\n const pickingCpu = new Float32Array(4);\n\n const pickingBG = device.createBindGroup({\n label: \"gs-picking-color-bg\",\n layout: cache.pickingBGL,\n entries: [{ binding: 0, resource: { buffer: pickingUbo } }],\n });\n\n return { meshUbo, meshBG, pickingUbo, pickingBG, meshCpu, pickingCpu };\n}\n\nexport function disposeGsPickMeshResources(res: GsPickMeshResources): void {\n res.meshUbo.destroy();\n res.pickingUbo.destroy();\n}\n\n/** Issue a pick draw for a single GS mesh. The caller must have already bound\n * the scene bind group (`pickMatrix` at group 0) on the pass; `pickId` is the\n * 24-bit pick id assigned by the picker. */\nexport function drawGsForPicking(\n pass: GPURenderPassEncoder,\n engine: EngineContext,\n scene: SceneContext,\n mesh: GaussianSplattingMesh,\n res: GsPickMeshResources,\n pickId: number,\n targetWidth: number,\n targetHeight: number\n): void {\n const cache = getCache(engine);\n\n // ── Per-mesh UBO ────────────────────────────────────────────────\n const cam = scene.camera;\n if (!cam) {\n return;\n }\n const size = getRenderTargetSize(engine);\n const aspect = (targetWidth || size.width) / (targetHeight || size.height);\n const view = getViewMatrix(cam) as unknown as Float32Array;\n const proj = getProjectionMatrix(cam, aspect) as unknown as Float32Array;\n const world = mesh.worldMatrix as unknown as Float32Array;\n const cpu = res.meshCpu;\n cpu.set(world, 0);\n cpu.set(view, 16);\n cpu.set(proj, 32);\n // Note: the GS picking pipeline still runs over the full-canvas viewport;\n // the picker output is a 1×1 target reached via the scene pickMatrix.\n cpu[48] = size.width;\n cpu[48 + 1] = size.height;\n cpu[48 + 2] = size.width * 0.5 * proj[0]!;\n cpu[48 + 3] = size.height * 0.5 * proj[5]!;\n // dataSize/alpha already written at construction.\n engine._device.queue.writeBuffer(res.meshUbo, 0, cpu.buffer, 0, cpu.byteLength);\n\n // ── Picking-color UBO ───────────────────────────────────────────\n const [r, g, b] = encodeIdToColor(pickId);\n res.pickingCpu[0] = r;\n res.pickingCpu[1] = g;\n res.pickingCpu[2] = b;\n res.pickingCpu[3] = 0;\n engine._device.queue.writeBuffer(res.pickingUbo, 0, res.pickingCpu.buffer, 0, 16);\n\n pass.setPipeline(cache.pipeline);\n pass.setBindGroup(1, res.meshBG);\n pass.setBindGroup(2, res.pickingBG);\n pass.setVertexBuffer(0, mesh._gs._quadBuffer);\n pass.setVertexBuffer(1, mesh._gs._splatIndexBuffer);\n pass.setIndexBuffer(mesh._gs._indexBuffer, \"uint16\");\n pass.drawIndexed(6, mesh.vertexCount);\n}\n\n/** Compute the pickMatrix for GS picking — same matrix `computePickVP` builds,\n * but applied to the clip-space output of the GS shader rather than the world.\n *\n * Maps canvas-NDC (px, py) ↦ (0, 0), and scales by (w, h) so a single canvas\n * pixel covers the full 1×1 pick render target. */\nexport function computeGsPickMatrix(out: Float32Array, px: number, py: number, w: number, h: number): void {\n const ndcX = (2 * (px + 0.5)) / w - 1;\n const ndcY = 1 - (2 * (py + 0.5)) / h;\n // column-major mat4\n out[0] = w;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = h;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 1;\n out[11] = 0;\n out[12] = -ndcX * w;\n out[13] = -ndcY * h;\n out[14] = 0;\n out[15] = 1;\n}\n"],"names":[],"mappings":"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"}