@roomle/web-sdk 4.0.0 → 4.1.0-alpha.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 (127) hide show
  1. package/lib/{BufferGeometry-CnbfgBmz.mjs → BufferGeometry-DcRNeLZD.mjs} +2 -2
  2. package/lib/{BufferGeometry-CnbfgBmz.mjs.map → BufferGeometry-DcRNeLZD.mjs.map} +1 -1
  3. package/lib/{GLTFExporter-BxcjPMva.mjs → GLTFExporter-DdzTpCjW.mjs} +46 -46
  4. package/lib/{GLTFExporter-BxcjPMva.mjs.map → GLTFExporter-DdzTpCjW.mjs.map} +1 -1
  5. package/lib/{GaussianBlurNode-8gO-I1qG.mjs → GaussianBlurNode-CLuzhfDu.mjs} +19 -19
  6. package/lib/{GaussianBlurNode-8gO-I1qG.mjs.map → GaussianBlurNode-CLuzhfDu.mjs.map} +1 -1
  7. package/lib/{Object3D-DMaDdv-D.mjs → Object3D-CEXK2mMb.mjs} +1 -1
  8. package/lib/{Object3D-DMaDdv-D.mjs.map → Object3D-CEXK2mMb.mjs.map} +1 -1
  9. package/lib/Pass-C7MZilDW.mjs +53 -0
  10. package/lib/Pass-C7MZilDW.mjs.map +1 -0
  11. package/lib/{PointLightHelper-CahXSxiA.mjs → PointLightHelper-dDeo1kUI.mjs} +4 -4
  12. package/lib/{PointLightHelper-CahXSxiA.mjs.map → PointLightHelper-dDeo1kUI.mjs.map} +1 -1
  13. package/lib/{SpotLightHelper-BEqeYq1p.mjs → SpotLightHelper-BsMEPgVo.mjs} +3 -3
  14. package/lib/{SpotLightHelper-BEqeYq1p.mjs.map → SpotLightHelper-BsMEPgVo.mjs.map} +1 -1
  15. package/lib/{USDZExporter-ZZoG1mne.mjs → USDZExporter-BIDQSKG4.mjs} +3 -3
  16. package/lib/{USDZExporter-ZZoG1mne.mjs.map → USDZExporter-BIDQSKG4.mjs.map} +1 -1
  17. package/lib/{Vector4-BkA_VGid.mjs → Vector4-D-4p8rfn.mjs} +2 -2
  18. package/lib/{Vector4-BkA_VGid.mjs.map → Vector4-D-4p8rfn.mjs.map} +1 -1
  19. package/lib/{api-CUyBdNba.mjs → api-BEszDVqh.mjs} +10 -10
  20. package/lib/{api-CUyBdNba.mjs.map → api-BEszDVqh.mjs.map} +1 -1
  21. package/lib/{asset-loader.worker-C_5RQYHp.mjs → asset-loader.worker-eqHzNAwa.mjs} +1 -1
  22. package/lib/asset-loader.worker-eqHzNAwa.mjs.map +1 -0
  23. package/lib/{banana-for-scale-B77S3z9R.mjs → banana-for-scale-CiCouumi.mjs} +4 -4
  24. package/lib/{banana-for-scale-B77S3z9R.mjs.map → banana-for-scale-CiCouumi.mjs.map} +1 -1
  25. package/lib/{budgeteer.sw-DxeAvd0v.mjs → budgeteer.sw-BUMElkO1.mjs} +1 -1
  26. package/lib/budgeteer.sw-BUMElkO1.mjs.map +1 -0
  27. package/lib/{common-utils-BiOW17Ao.mjs → common-utils-CCzT4Gnn.mjs} +2 -2
  28. package/lib/{common-utils-BiOW17Ao.mjs.map → common-utils-CCzT4Gnn.mjs.map} +1 -1
  29. package/lib/{component-dimensioning-DPyPzSsa.mjs → component-dimensioning-DWEZ4jZg.mjs} +7 -7
  30. package/lib/{component-dimensioning-DPyPzSsa.mjs.map → component-dimensioning-DWEZ4jZg.mjs.map} +1 -1
  31. package/lib/{component-raycast-helper-RiQIybsX.mjs → component-raycast-helper-D2hyLpdX.mjs} +17 -17
  32. package/lib/{component-raycast-helper-RiQIybsX.mjs.map → component-raycast-helper-D2hyLpdX.mjs.map} +1 -1
  33. package/lib/configurator-BENT3shs.mjs +2 -0
  34. package/lib/{configurator-C_rsqn9l.mjs → configurator-BjLLdSf8.mjs} +16 -16
  35. package/lib/{configurator-C_rsqn9l.mjs.map → configurator-BjLLdSf8.mjs.map} +1 -1
  36. package/lib/{continuous-drawing-helper-C_Yc0uuv.mjs → continuous-drawing-helper-CCuU99Vh.mjs} +3 -3
  37. package/lib/{continuous-drawing-helper-C_Yc0uuv.mjs.map → continuous-drawing-helper-CCuU99Vh.mjs.map} +1 -1
  38. package/lib/{dat.gui.module-BLjoST8r.mjs → dat.gui.module-B2PXSbre.mjs} +1 -1
  39. package/lib/{dat.gui.module-BLjoST8r.mjs.map → dat.gui.module-B2PXSbre.mjs.map} +1 -1
  40. package/lib/{decorate-BAtqSPNS.mjs → decorate-CX1ZGuFY.mjs} +1 -1
  41. package/lib/{decorate-BAtqSPNS.mjs.map → decorate-CX1ZGuFY.mjs.map} +1 -1
  42. package/lib/{dimensioning-helper-D9oxGkry.mjs → dimensioning-helper-CjuQqjBn.mjs} +14 -14
  43. package/lib/{dimensioning-helper-D9oxGkry.mjs.map → dimensioning-helper-CjuQqjBn.mjs.map} +1 -1
  44. package/lib/dimensioning-helper-ImsWfczi.mjs +2 -0
  45. package/lib/{dist-DGov-RNo.mjs → dist-Blgk0vU0.mjs} +1 -1
  46. package/lib/{dist-DGov-RNo.mjs.map → dist-Blgk0vU0.mjs.map} +1 -1
  47. package/lib/{fflate.module-CTnSdWOb.mjs → fflate.module-DTkA0kF8.mjs} +1 -1
  48. package/lib/{fflate.module-CTnSdWOb.mjs.map → fflate.module-DTkA0kF8.mjs.map} +1 -1
  49. package/lib/{glb-viewer-A5vSLFZ5.mjs → glb-viewer-9Ata6ZNJ.mjs} +59 -45
  50. package/lib/glb-viewer-9Ata6ZNJ.mjs.map +1 -0
  51. package/lib/glb-viewer-CGqSGT38.mjs +2 -0
  52. package/lib/{highlight-coordinator-CZEJGeXA.mjs → highlight-coordinator-PyWNABN9.mjs} +3 -3
  53. package/lib/{highlight-coordinator-CZEJGeXA.mjs.map → highlight-coordinator-PyWNABN9.mjs.map} +1 -1
  54. package/lib/{homag-intelligence-BdCDX7LF.mjs → homag-intelligence-BNqPqVgE.mjs} +3 -3
  55. package/lib/{homag-intelligence-BdCDX7LF.mjs.map → homag-intelligence-BNqPqVgE.mjs.map} +1 -1
  56. package/lib/{imos-ix-poc-export-helper-CaXXDNvP.mjs → imos-ix-poc-export-helper-C1LfrtjM.mjs} +3 -3
  57. package/lib/{imos-ix-poc-export-helper-CaXXDNvP.mjs.map → imos-ix-poc-export-helper-C1LfrtjM.mjs.map} +1 -1
  58. package/lib/{kernel-utils-BYEsHVYJ.mjs → kernel-utils-Cn4evFqF.mjs} +2 -2
  59. package/lib/{kernel-utils-BYEsHVYJ.mjs.map → kernel-utils-Cn4evFqF.mjs.map} +1 -1
  60. package/lib/{layer-CIWL5ZW3.mjs → layer-DvZF9ur3.mjs} +1 -1
  61. package/lib/{layer-CIWL5ZW3.mjs.map → layer-DvZF9ur3.mjs.map} +1 -1
  62. package/lib/{main-BUl8iCi1.mjs → main-n3n3jdja.mjs} +1097 -1017
  63. package/lib/{main-BUl8iCi1.mjs.map → main-n3n3jdja.mjs.map} +1 -1
  64. package/lib/{material-viewer-C4SqVaGG.mjs → material-viewer-Cv5Awgwm.mjs} +24 -24
  65. package/lib/{material-viewer-C4SqVaGG.mjs.map → material-viewer-Cv5Awgwm.mjs.map} +1 -1
  66. package/lib/{packages-C9gO5mKk.mjs → packages-B3bi3adH.mjs} +5 -5
  67. package/lib/{packages-C9gO5mKk.mjs.map → packages-B3bi3adH.mjs.map} +1 -1
  68. package/lib/planner-DIT2VvMG.mjs +44 -0
  69. package/lib/{planner-t4QH26WW.mjs.map → planner-DIT2VvMG.mjs.map} +1 -1
  70. package/lib/planner-DaI8ZwEe.mjs +2 -0
  71. package/lib/{plugin-system-COZJdJH_.mjs → plugin-system-FuZpDWqv.mjs} +3 -3
  72. package/lib/{plugin-system-COZJdJH_.mjs.map → plugin-system-FuZpDWqv.mjs.map} +1 -1
  73. package/lib/roomle-headless-setup-CMHahWyC.mjs +612 -0
  74. package/lib/roomle-headless-setup-CMHahWyC.mjs.map +1 -0
  75. package/lib/roomle-headless.d.ts +113 -34
  76. package/lib/roomle-headless.js +433 -84
  77. package/lib/roomle-headless.js.map +1 -1
  78. package/lib/{roomle-renderer-DhLUaHJZ.mjs → roomle-renderer-BR0UKz2y.mjs} +2 -2
  79. package/lib/{roomle-renderer-DhLUaHJZ.mjs.map → roomle-renderer-BR0UKz2y.mjs.map} +1 -1
  80. package/lib/roomle-sdk.d.ts +37 -9
  81. package/lib/roomle-sdk.js +8 -8
  82. package/lib/{roomle-webgpu-renderer-CRGcdahn.mjs → roomle-webgpu-renderer-fOYJoKJU.mjs} +175 -173
  83. package/lib/roomle-webgpu-renderer-fOYJoKJU.mjs.map +1 -0
  84. package/lib/{scene-renderer-D5CfxCag.mjs → scene-renderer-CAzAJ4pS.mjs} +212 -211
  85. package/lib/{scene-renderer-D5CfxCag.mjs.map → scene-renderer-CAzAJ4pS.mjs.map} +1 -1
  86. package/lib/{script-loader-D6IuUFjw.mjs → script-loader-BAWHLt9q.mjs} +3 -3
  87. package/lib/{script-loader-D6IuUFjw.mjs.map → script-loader-BAWHLt9q.mjs.map} +1 -1
  88. package/lib/{shading-settings-BEMqEGzB.mjs → shading-settings-BPpgt0Fq.mjs} +101 -146
  89. package/lib/shading-settings-BPpgt0Fq.mjs.map +1 -0
  90. package/lib/{stats-helper-DAfbSToL.mjs → stats-helper-CqiTcJuc.mjs} +3 -3
  91. package/lib/{stats-helper-DAfbSToL.mjs.map → stats-helper-CqiTcJuc.mjs.map} +1 -1
  92. package/lib/{svgo.browser-DYieWzyw.mjs → svgo.browser-EB1zkPfG.mjs} +1 -1
  93. package/lib/{svgo.browser-DYieWzyw.mjs.map → svgo.browser-EB1zkPfG.mjs.map} +1 -1
  94. package/lib/{three.core-DjCexDCp.mjs → three.core-CmmDf_BZ.mjs} +73 -38
  95. package/lib/{three.core-DjCexDCp.mjs.map → three.core-CmmDf_BZ.mjs.map} +1 -1
  96. package/lib/{three.module-CuRNgijg.mjs → three.module-BkkLbA6n.mjs} +857 -857
  97. package/lib/{three.module-CuRNgijg.mjs.map → three.module-BkkLbA6n.mjs.map} +1 -1
  98. package/lib/three.tsl-8HwZJGJ8.mjs +2 -0
  99. package/lib/{three.tsl-BIBER8nk.mjs → three.tsl-Cw9IeeKW.mjs} +64 -52
  100. package/lib/{three.tsl-BIBER8nk.mjs.map → three.tsl-Cw9IeeKW.mjs.map} +1 -1
  101. package/lib/three.webgpu-Bw4_U6Q1.mjs +3 -0
  102. package/lib/{three.webgpu-Bz4Xtk0X.mjs → three.webgpu-DL5l_0xI.mjs} +1742 -1728
  103. package/lib/{three.webgpu-Bz4Xtk0X.mjs.map → three.webgpu-DL5l_0xI.mjs.map} +1 -1
  104. package/lib/{threejs-utils-Dpvg3Czz.mjs → threejs-utils-PRhv_eX3.mjs} +63 -63
  105. package/lib/{threejs-utils-Dpvg3Czz.mjs.map → threejs-utils-PRhv_eX3.mjs.map} +1 -1
  106. package/lib/{tools-core-BDOFf9le.mjs → tools-core-CmrXkw3J.mjs} +3 -3
  107. package/lib/{tools-core-BDOFf9le.mjs.map → tools-core-CmrXkw3J.mjs.map} +1 -1
  108. package/lib/webgpu-wkXAkJ6p.mjs +5084 -0
  109. package/lib/webgpu-wkXAkJ6p.mjs.map +1 -0
  110. package/lib/workers-YGDNEfpU.mjs +6 -0
  111. package/lib/{workers-DcgrO-z7.mjs.map → workers-YGDNEfpU.mjs.map} +1 -1
  112. package/package.json +5 -4
  113. package/lib/asset-loader.worker-C_5RQYHp.mjs.map +0 -1
  114. package/lib/budgeteer.sw-DxeAvd0v.mjs.map +0 -1
  115. package/lib/configurator-BBlZVIId.mjs +0 -2
  116. package/lib/dimensioning-helper-Bzf1sbpy.mjs +0 -2
  117. package/lib/glb-viewer-A5vSLFZ5.mjs.map +0 -1
  118. package/lib/glb-viewer-B4ILlvw0.mjs +0 -2
  119. package/lib/planner-49YwTdiA.mjs +0 -2
  120. package/lib/planner-t4QH26WW.mjs +0 -44
  121. package/lib/roomle-headless-setup-Cc8EAnVe.mjs +0 -1204
  122. package/lib/roomle-headless-setup-Cc8EAnVe.mjs.map +0 -1
  123. package/lib/roomle-webgpu-renderer-CRGcdahn.mjs.map +0 -1
  124. package/lib/shading-settings-BEMqEGzB.mjs.map +0 -1
  125. package/lib/three.tsl-Q-21y0pO.mjs +0 -2
  126. package/lib/three.webgpu-dtN0kDKB.mjs +0 -3
  127. package/lib/workers-DcgrO-z7.mjs +0 -6
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webgpu-wkXAkJ6p.mjs","names":["shapecastFunc","temp1","IS_GT_REVISION_169","IS_LT_REVISION_161","_uvA","_uvB","_uvC","_normalA","_normalB","_normalC","iterateOverTriangles","_raycast","_xyzFields","_raycastFirst","boundingBox","triangle","triangle2","invertedMat","obb","obb2","_intersectsGeometry","tempMatrix","obb","obb2","temp1","temp2","temp3","temp4","obb","obb2","_ray","_inverseMatrix","iterateOverTriangles","_matrix","_inverseMatrix","_vec","_ray","_inverseMatrix","_vec","transformStruct","nodeProxyConstructor","transformStruct","rngInit","rand2","rngNextBounce","rngInit","rand2","rngInit","rand2","rngInit","CommonGLSL.util_functions","getTextureHash","rngInit","rand2","intersectionResultStruct","rand1","getTextureHash","rand2"],"sources":["../../../../node_modules/three-mesh-bvh/src/core/Constants.js","../../../../node_modules/three-mesh-bvh/src/utils/ArrayBoxUtilities.js","../../../../node_modules/three-mesh-bvh/src/core/utils/nodeBufferUtils.js","../../../../node_modules/three-mesh-bvh/src/core/build/computeBoundsUtils.js","../../../../node_modules/three-mesh-bvh/src/core/build/splitUtils.js","../../../../node_modules/three-mesh-bvh/src/core/BVHNode.js","../../../../node_modules/three-mesh-bvh/src/core/build/sortUtils.js","../../../../node_modules/three-mesh-bvh/src/core/build/buildUtils.js","../../../../node_modules/three-mesh-bvh/src/core/build/buildTree.js","../../../../node_modules/three-mesh-bvh/src/utils/PrimitivePool.js","../../../../node_modules/three-mesh-bvh/src/core/utils/BufferStack.js","../../../../node_modules/three-mesh-bvh/src/core/cast/shapecast.js","../../../../node_modules/three-mesh-bvh/src/core/cast/bvhcast.js","../../../../node_modules/three-mesh-bvh/src/core/BVHTraversalHelper.js","../../../../node_modules/three-mesh-bvh/src/core/BVH.js","../../../../node_modules/three-mesh-bvh/src/utils/BufferUtils.js","../../../../node_modules/three-mesh-bvh/src/core/build/geometryUtils.js","../../../../node_modules/three-mesh-bvh/src/core/GeometryBVH.js","../../../../node_modules/three-mesh-bvh/src/math/SeparatingAxisBounds.js","../../../../node_modules/three-mesh-bvh/src/math/MathUtilities.js","../../../../node_modules/three-mesh-bvh/src/math/ExtendedTriangle.js","../../../../node_modules/three-mesh-bvh/src/math/OrientedBox.js","../../../../node_modules/three-mesh-bvh/src/utils/ExtendedTrianglePool.js","../../../../node_modules/three-mesh-bvh/src/core/cast/closestPointToPoint.js","../../../../node_modules/three-mesh-bvh/src/utils/ThreeRayIntersectUtilities.js","../../../../node_modules/three-mesh-bvh/src/utils/TriangleUtilities.js","../../../../node_modules/three-mesh-bvh/src/core/utils/iterationUtils.generated.js","../../../../node_modules/three-mesh-bvh/src/core/cast/refit.generated.js","../../../../node_modules/three-mesh-bvh/src/core/utils/intersectUtils.js","../../../../node_modules/three-mesh-bvh/src/core/utils/iterationUtils_indirect.generated.js","../../../../node_modules/three-mesh-bvh/src/core/cast/raycast.generated.js","../../../../node_modules/three-mesh-bvh/src/core/cast/raycastFirst.generated.js","../../../../node_modules/three-mesh-bvh/src/core/cast/intersectsGeometry.generated.js","../../../../node_modules/three-mesh-bvh/src/core/cast/closestPointToGeometry.generated.js","../../../../node_modules/three-mesh-bvh/src/core/cast/refit_indirect.generated.js","../../../../node_modules/three-mesh-bvh/src/core/cast/raycast_indirect.generated.js","../../../../node_modules/three-mesh-bvh/src/core/cast/raycastFirst_indirect.generated.js","../../../../node_modules/three-mesh-bvh/src/core/cast/intersectsGeometry_indirect.generated.js","../../../../node_modules/three-mesh-bvh/src/core/cast/closestPointToGeometry_indirect.generated.js","../../../../node_modules/three-mesh-bvh/src/utils/GeometryRayIntersectUtilities.js","../../../../node_modules/three-mesh-bvh/src/core/MeshBVH.js","../../../../node_modules/three-mesh-bvh/src/core/ObjectBVH.js","../../../../node_modules/three-mesh-bvh/src/core/SkinnedMeshBVH.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/tsl/structs.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/nodes/NodeProxy.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/utils/toObjectBVH.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/utils/packBVHBufferUtils.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/nodes/WGSLTagFnNode.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/tsl/constants.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/shapecastFns/getShapecastFn.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/tsl/fns.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/shapecastFns/getRaycastFirstHitFn.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/shapecastFns/getSampleTrianglePointFn.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/shapecastFns/getClosestPointToPointFn.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/lib/three-mesh-bvh/BVHComputeData.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/materials/RenderToScreenMaterial.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/compute/ComputeKernel.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/nodes/random.wgsl.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/nodes/structs.wgsl.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/nodes/utils.wgsl.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/nodes/sampling.wgsl.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/compute/PathTracerMegaKernel.js","../../../../node_modules/three-gpu-pathtracer/src/utils/TextureUtils.js","../../../../node_modules/three-gpu-pathtracer/src/uniforms/EquirectHdrInfoUniform.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/compute/ZeroOutKernel.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/PathTracerBackend.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/MegaKernelPathTracer.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/compute/wavefront/structs.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/compute/wavefront/PrimeRayGenerationDispatchKernel.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/compute/wavefront/RayGenerationKernel.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/compute/wavefront/RayIntersectionKernel.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/compute/wavefront/UpdateRayQueueParamsKernel.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/compute/ZeroOutBufferKernel.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/compute/wavefront/ProcessHitsKernel.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/WaveFrontPathTracer.js","../../../../node_modules/three-gpu-pathtracer/src/shader/common/util_functions.glsl.js","../../../../node_modules/three-gpu-pathtracer/src/utils/CubeToEquirectGenerator.js","../../../../node_modules/three-gpu-pathtracer/src/core/utils/sceneUpdateUtils.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/nodes/ggx.wgsl.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/nodes/material.wgsl.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/AtlasTexture.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/nodes/PathtracerBVHComputeData.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/materials/debug/AtlasDebugMaterial.js","../../../../node_modules/three-gpu-pathtracer/src/core/utils/GeometryPreparationUtils.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/materials/PathtracingMaterial.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/materials/GltfCompliantMaterial.js","../../../../node_modules/three-gpu-pathtracer/src/webgpu/WebGPUPathTracer.js"],"sourcesContent":["// Split strategy constants\n\n/**\n * Option for splitting each BVH node down the center of the longest axis of the bounds.\n *\n * This is the fastest construction option and will yield a good, performant bounds.\n * @type {number}\n */\nexport const CENTER = 0;\n\n/**\n * Option for splitting each BVH node at the average point along the longest axis for\n * all triangle centroids in the bounds.\n *\n * This strategy may be better than `CENTER` with some geometry.\n * @type {number}\n */\nexport const AVERAGE = 1;\n\n/**\n * Option to use a Surface Area Heuristic to split the bounds more optimally. This SAH\n * implementation tests 32 discrete splits in each node along each axis to determine\n * which split is the lowest cost.\n *\n * This is the slowest construction option but will yield the best bounds of the three\n * options and use the least memory.\n * @type {number}\n */\nexport const SAH = 2;\n\n// Traversal constants\n\n/**\n * Indicates the shape did not intersect the given bounding box.\n * @type {number}\n */\nexport const NOT_INTERSECTED = 0;\n\n/**\n * Indicates the shape did intersect the given bounding box.\n * @type {number}\n */\nexport const INTERSECTED = 1;\n\n/**\n * Indicate the shape entirely contains the given bounding box.\n * @type {number}\n */\nexport const CONTAINED = 2;\n\n// SAH cost constants\n// TODO: hone these costs more. The relative difference between them should be the\n// difference in measured time to perform a primitive intersection vs traversing\n// bounds.\n// TODO: could be tuned per primitive type (triangles vs lines vs points)\nexport const PRIMITIVE_INTERSECT_COST = 1.25;\nexport const TRAVERSAL_COST = 1;\n\n\n// Build constants\nexport const BYTES_PER_NODE = 6 * 4 + 4 + 4;\nexport const UINT32_PER_NODE = BYTES_PER_NODE / 4;\nexport const IS_LEAFNODE_FLAG = 0xFFFF;\n\n// Bit masks for 32 bit node data\nexport const LEAFNODE_MASK_32 = IS_LEAFNODE_FLAG << 16;\n\n// EPSILON for computing floating point error during build\n// https://en.wikipedia.org/wiki/Machine_epsilon#Values_for_standard_hardware_floating_point_arithmetics\nexport const FLOAT32_EPSILON = Math.pow( 2, - 24 );\n\nexport const SKIP_GENERATION = Symbol( 'SKIP_GENERATION' );\n\nexport const DEFAULT_OPTIONS = {\n\tstrategy: CENTER,\n\tmaxDepth: 40,\n\ttargetLeafSize: 10,\n\tuseSharedArrayBuffer: false,\n\tsetBoundingBox: true,\n\tonProgress: null,\n\tindirect: false,\n\tverbose: true,\n\trange: null,\n\t[ SKIP_GENERATION ]: false,\n};\n\n","export function arrayToBox( nodeIndex32, array, target ) {\n\n\ttarget.min.x = array[ nodeIndex32 ];\n\ttarget.min.y = array[ nodeIndex32 + 1 ];\n\ttarget.min.z = array[ nodeIndex32 + 2 ];\n\n\ttarget.max.x = array[ nodeIndex32 + 3 ];\n\ttarget.max.y = array[ nodeIndex32 + 4 ];\n\ttarget.max.z = array[ nodeIndex32 + 5 ];\n\n\treturn target;\n\n}\n\nexport function makeEmptyBounds( target ) {\n\n\ttarget[ 0 ] = target[ 1 ] = target[ 2 ] = Infinity;\n\ttarget[ 3 ] = target[ 4 ] = target[ 5 ] = - Infinity;\n\n}\n\nexport function getLongestEdgeIndex( bounds ) {\n\n\tlet splitDimIdx = - 1;\n\tlet splitDist = - Infinity;\n\n\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\tconst dist = bounds[ i + 3 ] - bounds[ i ];\n\t\tif ( dist > splitDist ) {\n\n\t\t\tsplitDist = dist;\n\t\t\tsplitDimIdx = i;\n\n\t\t}\n\n\t}\n\n\treturn splitDimIdx;\n\n}\n\n// copies bounds a into bounds b\nexport function copyBounds( source, target ) {\n\n\ttarget.set( source );\n\n}\n\n// sets bounds target to the union of bounds a and b\nexport function unionBounds( a, b, target ) {\n\n\tlet aVal, bVal;\n\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\tconst d3 = d + 3;\n\n\t\t// set the minimum values\n\t\taVal = a[ d ];\n\t\tbVal = b[ d ];\n\t\ttarget[ d ] = aVal < bVal ? aVal : bVal;\n\n\t\t// set the max values\n\t\taVal = a[ d3 ];\n\t\tbVal = b[ d3 ];\n\t\ttarget[ d3 ] = aVal > bVal ? aVal : bVal;\n\n\t}\n\n}\n\n// expands the given bounds by the provided primitive bounds\nexport function expandByPrimitiveBounds( startIndex, primitiveBounds, bounds ) {\n\n\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\tconst tCenter = primitiveBounds[ startIndex + 2 * d ];\n\t\tconst tHalf = primitiveBounds[ startIndex + 2 * d + 1 ];\n\n\t\tconst tMin = tCenter - tHalf;\n\t\tconst tMax = tCenter + tHalf;\n\n\t\tif ( tMin < bounds[ d ] ) {\n\n\t\t\tbounds[ d ] = tMin;\n\n\t\t}\n\n\t\tif ( tMax > bounds[ d + 3 ] ) {\n\n\t\t\tbounds[ d + 3 ] = tMax;\n\n\t\t}\n\n\t}\n\n}\n\n// compute bounds surface area\nexport function computeSurfaceArea( bounds ) {\n\n\tconst d0 = bounds[ 3 ] - bounds[ 0 ];\n\tconst d1 = bounds[ 4 ] - bounds[ 1 ];\n\tconst d2 = bounds[ 5 ] - bounds[ 2 ];\n\n\treturn 2 * ( d0 * d1 + d1 * d2 + d2 * d0 );\n\n}\n","import { IS_LEAFNODE_FLAG, UINT32_PER_NODE } from '../Constants.js';\n\nexport function IS_LEAF( n16, uint16Array ) {\n\n\treturn uint16Array[ n16 + 15 ] === IS_LEAFNODE_FLAG;\n\n}\n\nexport function OFFSET( n32, uint32Array ) {\n\n\treturn uint32Array[ n32 + 6 ];\n\n}\n\nexport function COUNT( n16, uint16Array ) {\n\n\treturn uint16Array[ n16 + 14 ];\n\n}\n\n// Returns the uint32-aligned offset of the left child node for performance\nexport function LEFT_NODE( n32 ) {\n\n\treturn n32 + UINT32_PER_NODE;\n\n}\n\n// Returns the uint32-aligned offset of the right child node for performance\nexport function RIGHT_NODE( n32, uint32Array ) {\n\n\t// stored value is relative offset from parent, convert to absolute uint32 index\n\tconst relativeOffset = uint32Array[ n32 + 6 ];\n\treturn n32 + relativeOffset * UINT32_PER_NODE;\n\n}\n\nexport function SPLIT_AXIS( n32, uint32Array ) {\n\n\treturn uint32Array[ n32 + 7 ];\n\n}\n\nexport function BOUNDING_DATA_INDEX( n32 ) {\n\n\treturn n32;\n\n}\n","// computes the union of the bounds of all of the given primitives and puts the resulting box in \"target\".\n// A bounding box is computed for the centroids of the primitives, as well, and placed in \"centroidTarget\".\n// These are computed together to avoid redundant accesses to bounds array.\nexport function getBounds( primitiveBounds, offset, count, target, centroidTarget ) {\n\n\tlet minx = Infinity;\n\tlet miny = Infinity;\n\tlet minz = Infinity;\n\tlet maxx = - Infinity;\n\tlet maxy = - Infinity;\n\tlet maxz = - Infinity;\n\n\tlet cminx = Infinity;\n\tlet cminy = Infinity;\n\tlet cminz = Infinity;\n\tlet cmaxx = - Infinity;\n\tlet cmaxy = - Infinity;\n\tlet cmaxz = - Infinity;\n\n\tconst boundsOffset = primitiveBounds.offset || 0;\n\tfor ( let i = ( offset - boundsOffset ) * 6, end = ( offset + count - boundsOffset ) * 6; i < end; i += 6 ) {\n\n\t\tconst cx = primitiveBounds[ i + 0 ];\n\t\tconst hx = primitiveBounds[ i + 1 ];\n\t\tconst lx = cx - hx;\n\t\tconst rx = cx + hx;\n\t\tif ( lx < minx ) minx = lx;\n\t\tif ( rx > maxx ) maxx = rx;\n\t\tif ( cx < cminx ) cminx = cx;\n\t\tif ( cx > cmaxx ) cmaxx = cx;\n\n\t\tconst cy = primitiveBounds[ i + 2 ];\n\t\tconst hy = primitiveBounds[ i + 3 ];\n\t\tconst ly = cy - hy;\n\t\tconst ry = cy + hy;\n\t\tif ( ly < miny ) miny = ly;\n\t\tif ( ry > maxy ) maxy = ry;\n\t\tif ( cy < cminy ) cminy = cy;\n\t\tif ( cy > cmaxy ) cmaxy = cy;\n\n\t\tconst cz = primitiveBounds[ i + 4 ];\n\t\tconst hz = primitiveBounds[ i + 5 ];\n\t\tconst lz = cz - hz;\n\t\tconst rz = cz + hz;\n\t\tif ( lz < minz ) minz = lz;\n\t\tif ( rz > maxz ) maxz = rz;\n\t\tif ( cz < cminz ) cminz = cz;\n\t\tif ( cz > cmaxz ) cmaxz = cz;\n\n\t}\n\n\ttarget[ 0 ] = minx;\n\ttarget[ 1 ] = miny;\n\ttarget[ 2 ] = minz;\n\n\ttarget[ 3 ] = maxx;\n\ttarget[ 4 ] = maxy;\n\ttarget[ 5 ] = maxz;\n\n\tcentroidTarget[ 0 ] = cminx;\n\tcentroidTarget[ 1 ] = cminy;\n\tcentroidTarget[ 2 ] = cminz;\n\n\tcentroidTarget[ 3 ] = cmaxx;\n\tcentroidTarget[ 4 ] = cmaxy;\n\tcentroidTarget[ 5 ] = cmaxz;\n\n}\n","import { getLongestEdgeIndex, computeSurfaceArea, copyBounds, unionBounds, expandByPrimitiveBounds } from '../../utils/ArrayBoxUtilities.js';\nimport { CENTER, AVERAGE, SAH, PRIMITIVE_INTERSECT_COST, TRAVERSAL_COST } from '../Constants.js';\n\nconst BIN_COUNT = 32;\nconst binsSort = ( a, b ) => a.candidate - b.candidate;\nconst sahBins = /* @__PURE__ */ new Array( BIN_COUNT ).fill().map( () => {\n\n\treturn {\n\n\t\tcount: 0,\n\t\tbounds: new Float32Array( 6 ),\n\t\trightCacheBounds: new Float32Array( 6 ),\n\t\tleftCacheBounds: new Float32Array( 6 ),\n\t\tcandidate: 0,\n\n\t};\n\n} );\nconst leftBounds = /* @__PURE__ */ new Float32Array( 6 );\n\nexport function getOptimalSplit( nodeBoundingData, centroidBoundingData, primitiveBounds, offset, count, strategy ) {\n\n\tlet axis = - 1;\n\tlet pos = 0;\n\n\t// Center\n\tif ( strategy === CENTER ) {\n\n\t\taxis = getLongestEdgeIndex( centroidBoundingData );\n\t\tif ( axis !== - 1 ) {\n\n\t\t\tpos = ( centroidBoundingData[ axis ] + centroidBoundingData[ axis + 3 ] ) / 2;\n\n\t\t}\n\n\t} else if ( strategy === AVERAGE ) {\n\n\t\taxis = getLongestEdgeIndex( nodeBoundingData );\n\t\tif ( axis !== - 1 ) {\n\n\t\t\tpos = getAverage( primitiveBounds, offset, count, axis );\n\n\t\t}\n\n\t} else if ( strategy === SAH ) {\n\n\t\tconst rootSurfaceArea = computeSurfaceArea( nodeBoundingData );\n\t\tlet bestCost = PRIMITIVE_INTERSECT_COST * count;\n\n\t\t// iterate over all axes\n\t\tconst boundsOffset = primitiveBounds.offset || 0;\n\t\tconst cStart = ( offset - boundsOffset ) * 6;\n\t\tconst cEnd = ( offset + count - boundsOffset ) * 6;\n\t\tfor ( let a = 0; a < 3; a ++ ) {\n\n\t\t\tconst axisLeft = centroidBoundingData[ a ];\n\t\t\tconst axisRight = centroidBoundingData[ a + 3 ];\n\t\t\tconst axisLength = axisRight - axisLeft;\n\t\t\tconst binWidth = axisLength / BIN_COUNT;\n\n\t\t\t// If we have fewer primitives than we're planning to split then just check all\n\t\t\t// the primitive positions because it will be faster.\n\t\t\tif ( count < BIN_COUNT / 4 ) {\n\n\t\t\t\t// initialize the bin candidates\n\t\t\t\tconst truncatedBins = [ ...sahBins ];\n\t\t\t\ttruncatedBins.length = count;\n\n\t\t\t\t// set the candidates\n\t\t\t\tlet b = 0;\n\t\t\t\tfor ( let c = cStart; c < cEnd; c += 6, b ++ ) {\n\n\t\t\t\t\tconst bin = truncatedBins[ b ];\n\t\t\t\t\tbin.candidate = primitiveBounds[ c + 2 * a ];\n\t\t\t\t\tbin.count = 0;\n\n\t\t\t\t\tconst {\n\t\t\t\t\t\tbounds,\n\t\t\t\t\t\tleftCacheBounds,\n\t\t\t\t\t\trightCacheBounds,\n\t\t\t\t\t} = bin;\n\t\t\t\t\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\t\t\t\t\trightCacheBounds[ d ] = Infinity;\n\t\t\t\t\t\trightCacheBounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t\tleftCacheBounds[ d ] = Infinity;\n\t\t\t\t\t\tleftCacheBounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t\tbounds[ d ] = Infinity;\n\t\t\t\t\t\tbounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t}\n\n\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bounds );\n\n\t\t\t\t}\n\n\t\t\t\ttruncatedBins.sort( binsSort );\n\n\t\t\t\t// remove redundant splits\n\t\t\t\tlet splitCount = count;\n\t\t\t\tfor ( let bi = 0; bi < splitCount; bi ++ ) {\n\n\t\t\t\t\tconst bin = truncatedBins[ bi ];\n\t\t\t\t\twhile ( bi + 1 < splitCount && truncatedBins[ bi + 1 ].candidate === bin.candidate ) {\n\n\t\t\t\t\t\ttruncatedBins.splice( bi + 1, 1 );\n\t\t\t\t\t\tsplitCount --;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// find the appropriate bin for each primitive and expand the bounds.\n\t\t\t\tfor ( let c = cStart; c < cEnd; c += 6 ) {\n\n\t\t\t\t\tconst center = primitiveBounds[ c + 2 * a ];\n\t\t\t\t\tfor ( let bi = 0; bi < splitCount; bi ++ ) {\n\n\t\t\t\t\t\tconst bin = truncatedBins[ bi ];\n\t\t\t\t\t\tif ( center >= bin.candidate ) {\n\n\t\t\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bin.rightCacheBounds );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bin.leftCacheBounds );\n\t\t\t\t\t\t\tbin.count ++;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// expand all the bounds\n\t\t\t\tfor ( let bi = 0; bi < splitCount; bi ++ ) {\n\n\t\t\t\t\tconst bin = truncatedBins[ bi ];\n\t\t\t\t\tconst leftCount = bin.count;\n\t\t\t\t\tconst rightCount = count - bin.count;\n\n\t\t\t\t\t// check the cost of this split\n\t\t\t\t\tconst leftBounds = bin.leftCacheBounds;\n\t\t\t\t\tconst rightBounds = bin.rightCacheBounds;\n\n\t\t\t\t\tlet leftProb = 0;\n\t\t\t\t\tif ( leftCount !== 0 ) {\n\n\t\t\t\t\t\tleftProb = computeSurfaceArea( leftBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tlet rightProb = 0;\n\t\t\t\t\tif ( rightCount !== 0 ) {\n\n\t\t\t\t\t\trightProb = computeSurfaceArea( rightBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst cost = TRAVERSAL_COST + PRIMITIVE_INTERSECT_COST * (\n\t\t\t\t\t\tleftProb * leftCount + rightProb * rightCount\n\t\t\t\t\t);\n\n\t\t\t\t\tif ( cost < bestCost ) {\n\n\t\t\t\t\t\taxis = a;\n\t\t\t\t\t\tbestCost = cost;\n\t\t\t\t\t\tpos = bin.candidate;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// reset the bins\n\t\t\t\tfor ( let i = 0; i < BIN_COUNT; i ++ ) {\n\n\t\t\t\t\tconst bin = sahBins[ i ];\n\t\t\t\t\tbin.count = 0;\n\t\t\t\t\tbin.candidate = axisLeft + binWidth + i * binWidth;\n\n\t\t\t\t\tconst bounds = bin.bounds;\n\t\t\t\t\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\t\t\t\t\tbounds[ d ] = Infinity;\n\t\t\t\t\t\tbounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// iterate over all center positions\n\t\t\t\tfor ( let c = cStart; c < cEnd; c += 6 ) {\n\n\t\t\t\t\tconst triCenter = primitiveBounds[ c + 2 * a ];\n\t\t\t\t\tconst relativeCenter = triCenter - axisLeft;\n\n\t\t\t\t\t// in the partition function if the centroid lies on the split plane then it is\n\t\t\t\t\t// considered to be on the right side of the split\n\t\t\t\t\tlet binIndex = ~ ~ ( relativeCenter / binWidth );\n\t\t\t\t\tif ( binIndex >= BIN_COUNT ) binIndex = BIN_COUNT - 1;\n\n\t\t\t\t\tconst bin = sahBins[ binIndex ];\n\t\t\t\t\tbin.count ++;\n\n\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bin.bounds );\n\n\t\t\t\t}\n\n\t\t\t\t// cache the unioned bounds from right to left so we don't have to regenerate them each time\n\t\t\t\tconst lastBin = sahBins[ BIN_COUNT - 1 ];\n\t\t\t\tcopyBounds( lastBin.bounds, lastBin.rightCacheBounds );\n\t\t\t\tfor ( let i = BIN_COUNT - 2; i >= 0; i -- ) {\n\n\t\t\t\t\tconst bin = sahBins[ i ];\n\t\t\t\t\tconst nextBin = sahBins[ i + 1 ];\n\t\t\t\t\tunionBounds( bin.bounds, nextBin.rightCacheBounds, bin.rightCacheBounds );\n\n\t\t\t\t}\n\n\t\t\t\tlet leftCount = 0;\n\t\t\t\tfor ( let i = 0; i < BIN_COUNT - 1; i ++ ) {\n\n\t\t\t\t\tconst bin = sahBins[ i ];\n\t\t\t\t\tconst binCount = bin.count;\n\t\t\t\t\tconst bounds = bin.bounds;\n\n\t\t\t\t\tconst nextBin = sahBins[ i + 1 ];\n\t\t\t\t\tconst rightBounds = nextBin.rightCacheBounds;\n\n\t\t\t\t\t// don't do anything with the bounds if the new bounds have no primitives\n\t\t\t\t\tif ( binCount !== 0 ) {\n\n\t\t\t\t\t\tif ( leftCount === 0 ) {\n\n\t\t\t\t\t\t\tcopyBounds( bounds, leftBounds );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tunionBounds( bounds, leftBounds, leftBounds );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tleftCount += binCount;\n\n\t\t\t\t\t// check the cost of this split\n\t\t\t\t\tlet leftProb = 0;\n\t\t\t\t\tlet rightProb = 0;\n\n\t\t\t\t\tif ( leftCount !== 0 ) {\n\n\t\t\t\t\t\tleftProb = computeSurfaceArea( leftBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst rightCount = count - leftCount;\n\t\t\t\t\tif ( rightCount !== 0 ) {\n\n\t\t\t\t\t\trightProb = computeSurfaceArea( rightBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst cost = TRAVERSAL_COST + PRIMITIVE_INTERSECT_COST * (\n\t\t\t\t\t\tleftProb * leftCount + rightProb * rightCount\n\t\t\t\t\t);\n\n\t\t\t\t\tif ( cost < bestCost ) {\n\n\t\t\t\t\t\taxis = a;\n\t\t\t\t\t\tbestCost = cost;\n\t\t\t\t\t\tpos = bin.candidate;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t} else {\n\n\t\tconsole.warn( `BVH: Invalid build strategy value ${ strategy } used.` );\n\n\t}\n\n\treturn { axis, pos };\n\n}\n\n// returns the average coordinate on the specified axis of all the provided primitives\nfunction getAverage( primitiveBounds, offset, count, axis ) {\n\n\tlet avg = 0;\n\tconst boundsOffset = primitiveBounds.offset;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tavg += primitiveBounds[ ( i - boundsOffset ) * 6 + axis * 2 ];\n\n\t}\n\n\treturn avg / count;\n\n}\n","export class BVHNode {\n\n\tconstructor() {\n\n\t\t// internal nodes have boundingData, left, right, and splitAxis\n\t\t// leaf nodes have offset and count (referring to primitives in the mesh geometry)\n\n\t\tthis.boundingData = new Float32Array( 6 );\n\n\t}\n\n}\n","// reorders the partition buffer such that for `count` elements after `offset`, elements on the left side of the split\n// will be on the left and elements on the right side of the split will be on the right. returns the index\n// of the first element on the right side, or offset + count if there are no elements on the right side.\nexport function partition( buffer, stride, primitiveBounds, offset, count, split ) {\n\n\tlet left = offset;\n\tlet right = offset + count - 1;\n\tconst pos = split.pos;\n\tconst axisOffset = split.axis * 2;\n\tconst boundsOffset = primitiveBounds.offset || 0;\n\n\t// hoare partitioning, see e.g. https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme\n\twhile ( true ) {\n\n\t\twhile ( left <= right && primitiveBounds[ ( left - boundsOffset ) * 6 + axisOffset ] < pos ) {\n\n\t\t\tleft ++;\n\n\t\t}\n\n\t\t// if a primitive center lies on the partition plane it is considered to be on the right side\n\t\twhile ( left <= right && primitiveBounds[ ( right - boundsOffset ) * 6 + axisOffset ] >= pos ) {\n\n\t\t\tright --;\n\n\t\t}\n\n\t\tif ( left < right ) {\n\n\t\t\t// we need to swap all of the information associated with the primitives at index\n\t\t\t// left and right; that's the elements in the partition buffer and the bounds\n\t\t\tfor ( let i = 0; i < stride; i ++ ) {\n\n\t\t\t\tlet t0 = buffer[ left * stride + i ];\n\t\t\t\tbuffer[ left * stride + i ] = buffer[ right * stride + i ];\n\t\t\t\tbuffer[ right * stride + i ] = t0;\n\n\t\t\t}\n\n\t\t\t// swap bounds\n\t\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\t\tconst l = left - boundsOffset;\n\t\t\t\tconst r = right - boundsOffset;\n\t\t\t\tconst tb = primitiveBounds[ l * 6 + i ];\n\t\t\t\tprimitiveBounds[ l * 6 + i ] = primitiveBounds[ r * 6 + i ];\n\t\t\t\tprimitiveBounds[ r * 6 + i ] = tb;\n\n\t\t\t}\n\n\t\t\tleft ++;\n\t\t\tright --;\n\n\t\t} else {\n\n\t\t\treturn left;\n\n\t\t}\n\n\t}\n\n}\n","import { BYTES_PER_NODE, IS_LEAFNODE_FLAG } from '../Constants.js';\n\nlet float32Array, uint32Array, uint16Array, uint8Array;\nconst MAX_POINTER = Math.pow( 2, 32 );\n\nexport function countNodes( node ) {\n\n\tif ( 'count' in node ) {\n\n\t\treturn 1;\n\n\t} else {\n\n\t\treturn 1 + countNodes( node.left ) + countNodes( node.right );\n\n\t}\n\n}\n\nexport function populateBuffer( byteOffset, node, buffer ) {\n\n\tfloat32Array = new Float32Array( buffer );\n\tuint32Array = new Uint32Array( buffer );\n\tuint16Array = new Uint16Array( buffer );\n\tuint8Array = new Uint8Array( buffer );\n\n\treturn _populateBuffer( byteOffset, node );\n\n}\n\n// pack structure\n// boundingData \t\t\t\t: 6 float32\n// right / offset \t\t\t\t: 1 uint32\n// splitAxis / isLeaf + count \t: 1 uint32 / 2 uint16\nfunction _populateBuffer( byteOffset, node ) {\n\n\tconst node32Index = byteOffset / 4;\n\tconst node16Index = byteOffset / 2;\n\tconst isLeaf = 'count' in node;\n\tconst boundingData = node.boundingData;\n\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\tfloat32Array[ node32Index + i ] = boundingData[ i ];\n\n\t}\n\n\tif ( isLeaf ) {\n\n\t\tif ( node.buffer ) {\n\n\t\t\tuint8Array.set( new Uint8Array( node.buffer ), byteOffset );\n\t\t\treturn byteOffset + node.buffer.byteLength;\n\n\t\t} else {\n\n\t\t\tuint32Array[ node32Index + 6 ] = node.offset;\n\t\t\tuint16Array[ node16Index + 14 ] = node.count;\n\t\t\tuint16Array[ node16Index + 15 ] = IS_LEAFNODE_FLAG;\n\t\t\treturn byteOffset + BYTES_PER_NODE;\n\n\t\t}\n\n\t} else {\n\n\t\tconst { left, right, splitAxis } = node;\n\n\t\t// fill in the left node contents\n\t\tconst leftByteOffset = byteOffset + BYTES_PER_NODE;\n\t\tlet rightByteOffset = _populateBuffer( leftByteOffset, left );\n\n\t\t// calculate relative offset from parent to right child\n\t\tconst currentNodeIndex = byteOffset / BYTES_PER_NODE;\n\t\tconst rightNodeIndex = rightByteOffset / BYTES_PER_NODE;\n\t\tconst relativeRightIndex = rightNodeIndex - currentNodeIndex;\n\n\t\t// check if the relative offset is too high\n\t\tif ( relativeRightIndex > MAX_POINTER ) {\n\n\t\t\tthrow new Error( 'MeshBVH: Cannot store relative child node offset greater than 32 bits.' );\n\n\t\t}\n\n\t\t// fill in the right node contents (store as relative offset)\n\t\tuint32Array[ node32Index + 6 ] = relativeRightIndex;\n\t\tuint32Array[ node32Index + 7 ] = splitAxis;\n\n\t\t// return the next available buffer pointer\n\t\treturn _populateBuffer( rightByteOffset, right );\n\n\t}\n\n}\n","import { getBounds } from './computeBoundsUtils.js';\nimport { getOptimalSplit } from './splitUtils.js';\nimport { getLongestEdgeIndex } from '../../utils/ArrayBoxUtilities.js';\nimport { BVHNode } from '../BVHNode.js';\nimport { BYTES_PER_NODE } from '../Constants.js';\n\nimport { partition } from './sortUtils.js';\nimport { countNodes, populateBuffer } from './buildUtils.js';\n\nexport function buildTree( bvh, primitiveBounds, offset, count, options, loadRange ) {\n\n\t// expand variables\n\tconst {\n\t\tmaxDepth,\n\t\tverbose,\n\t\ttargetLeafSize,\n\t\t_strictLeafSize = Infinity,\n\t\tstrategy,\n\t\tonProgress,\n\t} = options;\n\n\tconst partitionBuffer = bvh.primitiveBuffer;\n\tconst partitionStride = bvh.primitiveBufferStride;\n\n\t// generate intermediate variables\n\tconst cacheCentroidBoundingData = new Float32Array( 6 );\n\tlet reachedMaxDepth = false;\n\n\tconst root = new BVHNode();\n\tgetBounds( primitiveBounds, offset, count, root.boundingData, cacheCentroidBoundingData );\n\tsplitNode( root, offset, count, cacheCentroidBoundingData );\n\treturn root;\n\n\tfunction triggerProgress( primitivesProcessed ) {\n\n\t\tif ( onProgress ) {\n\n\t\t\tonProgress( ( primitivesProcessed - loadRange.offset ) / loadRange.count );\n\n\t\t}\n\n\t}\n\n\t// either recursively splits the given node, creating left and right subtrees for it, or makes it a leaf node,\n\t// recording the offset and count of its primitives and writing them into the reordered geometry index.\n\tfunction splitNode( node, offset, count, centroidBoundingData = null, depth = 0 ) {\n\n\t\tif ( ! reachedMaxDepth && depth >= maxDepth ) {\n\n\t\t\treachedMaxDepth = true;\n\t\t\tif ( verbose ) {\n\n\t\t\t\tconsole.warn( `BVH: Max depth of ${ maxDepth } reached when generating BVH. Consider increasing maxDepth.` );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// A hard guarantee that no leaf exceeds \"_strictLeafSize\" primitives. When this node is over\n\t\t// that limit it must keep splitting regardless of the heuristic.\n\t\tconst mustSplit = count > _strictLeafSize;\n\n\t\t// early out if we've met our capacity - unless the strict guarantee still requires a split\n\t\tif ( ( count <= targetLeafSize && ! mustSplit ) || depth >= maxDepth ) {\n\n\t\t\ttriggerProgress( offset + count );\n\t\t\tnode.offset = offset;\n\t\t\tnode.count = count;\n\t\t\treturn node;\n\n\t\t}\n\n\t\t// Find where to split the volume\n\t\tconst split = getOptimalSplit( node.boundingData, centroidBoundingData, primitiveBounds, offset, count, strategy );\n\t\tlet splitOffset = split.axis === - 1 ? - 1 : partition( partitionBuffer, partitionStride, primitiveBounds, offset, count, split );\n\n\t\t// If the heuristic can't produce a usable split then make a leaf unless the strict guarantee requires the split -\n\t\t// in which case force an arbitrary median split. The axis comes from the node bounds so parallel and serial\n\t\t// builds produce identical trees.\n\t\tif ( split.axis === - 1 || splitOffset === offset || splitOffset === offset + count ) {\n\n\t\t\tif ( ! mustSplit ) {\n\n\t\t\t\ttriggerProgress( offset + count );\n\t\t\t\tnode.offset = offset;\n\t\t\t\tnode.count = count;\n\t\t\t\treturn node;\n\n\t\t\t}\n\n\t\t\tsplit.axis = Math.max( 0, getLongestEdgeIndex( node.boundingData ) );\n\t\t\tsplitOffset = offset + Math.max( 1, Math.floor( count / 2 ) );\n\n\t\t}\n\n\t\t// create the two new child nodes\n\t\tnode.splitAxis = split.axis;\n\n\t\t// create the left child and compute its bounding box\n\t\tconst left = new BVHNode();\n\t\tconst lstart = offset;\n\t\tconst lcount = splitOffset - offset;\n\t\tnode.left = left;\n\n\t\tgetBounds( primitiveBounds, lstart, lcount, left.boundingData, cacheCentroidBoundingData );\n\t\tsplitNode( left, lstart, lcount, cacheCentroidBoundingData, depth + 1 );\n\n\t\t// repeat for right\n\t\tconst right = new BVHNode();\n\t\tconst rstart = splitOffset;\n\t\tconst rcount = count - lcount;\n\t\tnode.right = right;\n\n\t\tgetBounds( primitiveBounds, rstart, rcount, right.boundingData, cacheCentroidBoundingData );\n\t\tsplitNode( right, rstart, rcount, cacheCentroidBoundingData, depth + 1 );\n\n\t\treturn node;\n\n\t}\n\n}\n\nexport function buildPackedTree( bvh, options ) {\n\n\tconst BufferConstructor = options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer;\n\n\t// get the range of buffer data to construct / arrange\n\tconst rootRanges = bvh.getRootRanges( options.range );\n\tconst firstRange = rootRanges[ 0 ];\n\tconst lastRange = rootRanges[ rootRanges.length - 1 ];\n\tconst fullRange = {\n\t\toffset: firstRange.offset,\n\t\tcount: lastRange.offset + lastRange.count - firstRange.offset,\n\t};\n\n\t// construct the primitive bounds for sorting\n\tconst primitiveBounds = new Float32Array( 6 * fullRange.count );\n\tprimitiveBounds.offset = fullRange.offset;\n\tbvh.computePrimitiveBounds( fullRange.offset, fullRange.count, primitiveBounds );\n\n\t// Build BVH roots\n\tbvh._roots = rootRanges.map( range => {\n\n\t\tconst root = buildTree( bvh, primitiveBounds, range.offset, range.count, options, fullRange );\n\t\tconst nodeCount = countNodes( root );\n\t\tconst buffer = new BufferConstructor( BYTES_PER_NODE * nodeCount );\n\t\tpopulateBuffer( 0, root, buffer );\n\t\treturn buffer;\n\n\t} );\n\n}\n","export class PrimitivePool {\n\n\tconstructor( getNewPrimitive ) {\n\n\t\tthis._getNewPrimitive = getNewPrimitive;\n\t\tthis._primitives = [];\n\n\t}\n\n\tgetPrimitive() {\n\n\t\tconst primitives = this._primitives;\n\t\tif ( primitives.length === 0 ) {\n\n\t\t\treturn this._getNewPrimitive();\n\n\t\t} else {\n\n\t\t\treturn primitives.pop();\n\n\t\t}\n\n\t}\n\n\treleasePrimitive( primitive ) {\n\n\t\tthis._primitives.push( primitive );\n\n\t}\n\n}\n","class _BufferStack {\n\n\tconstructor() {\n\n\t\tthis.float32Array = null;\n\t\tthis.uint16Array = null;\n\t\tthis.uint32Array = null;\n\n\t\tconst stack = [];\n\t\tlet prevBuffer = null;\n\t\tthis.setBuffer = buffer => {\n\n\t\t\tif ( prevBuffer ) {\n\n\t\t\t\tstack.push( prevBuffer );\n\n\t\t\t}\n\n\t\t\tprevBuffer = buffer;\n\t\t\tthis.float32Array = new Float32Array( buffer );\n\t\t\tthis.uint16Array = new Uint16Array( buffer );\n\t\t\tthis.uint32Array = new Uint32Array( buffer );\n\n\t\t};\n\n\t\tthis.clearBuffer = () => {\n\n\t\t\tprevBuffer = null;\n\t\t\tthis.float32Array = null;\n\t\t\tthis.uint16Array = null;\n\t\t\tthis.uint32Array = null;\n\n\t\t\tif ( stack.length !== 0 ) {\n\n\t\t\t\tthis.setBuffer( stack.pop() );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n}\n\nexport const BufferStack = /* @__PURE__ */ new _BufferStack();\n","import { Box3 } from 'three';\nimport { CONTAINED, UINT32_PER_NODE } from '../Constants.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { PrimitivePool } from '../../utils/PrimitivePool.js';\nimport { COUNT, OFFSET, LEFT_NODE, RIGHT_NODE, IS_LEAF, BOUNDING_DATA_INDEX } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\n\nlet _box1, _box2;\nconst boxStack = [];\nconst boxPool = /* @__PURE__ */ new PrimitivePool( () => new Box3() );\n\nexport function shapecast( bvh, root, intersectsBounds, intersectsRange, boundsTraverseOrder, nodeOffset ) {\n\n\t// setup\n\t_box1 = boxPool.getPrimitive();\n\t_box2 = boxPool.getPrimitive();\n\tboxStack.push( _box1, _box2 );\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\n\tconst result = shapecastTraverse( 0, bvh.geometry, intersectsBounds, intersectsRange, boundsTraverseOrder, nodeOffset );\n\n\t// cleanup\n\tBufferStack.clearBuffer();\n\tboxPool.releasePrimitive( _box1 );\n\tboxPool.releasePrimitive( _box2 );\n\tboxStack.pop();\n\tboxStack.pop();\n\n\tconst length = boxStack.length;\n\tif ( length > 0 ) {\n\n\t\t_box2 = boxStack[ length - 1 ];\n\t\t_box1 = boxStack[ length - 2 ];\n\n\t}\n\n\treturn result;\n\n}\n\nfunction shapecastTraverse(\n\tnodeIndex32,\n\tgeometry,\n\tintersectsBoundsFunc,\n\tintersectsRangeFunc,\n\tnodeScoreFunc = null,\n\tnodeIndexOffset = 0, // offset for unique node identifier\n\tdepth = 0\n) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( nodeIndex32 ), float32Array, _box1 );\n\t\treturn intersectsRangeFunc( offset, count, false, depth, nodeIndexOffset + nodeIndex32 / UINT32_PER_NODE, _box1 );\n\n\t} else {\n\n\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\tlet c1 = left;\n\t\tlet c2 = right;\n\n\t\tlet score1, score2;\n\t\tlet box1, box2;\n\t\tif ( nodeScoreFunc ) {\n\n\t\t\tbox1 = _box1;\n\t\t\tbox2 = _box2;\n\n\t\t\t// bounding data is not offset\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( c1 ), float32Array, box1 );\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( c2 ), float32Array, box2 );\n\n\t\t\tscore1 = nodeScoreFunc( box1 );\n\t\t\tscore2 = nodeScoreFunc( box2 );\n\n\t\t\tif ( score2 < score1 ) {\n\n\t\t\t\tc1 = right;\n\t\t\t\tc2 = left;\n\n\t\t\t\tconst temp = score1;\n\t\t\t\tscore1 = score2;\n\t\t\t\tscore2 = temp;\n\n\t\t\t\tbox1 = box2;\n\t\t\t\t// box2 is always set before use below\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Check box 1 intersection\n\t\tif ( ! box1 ) {\n\n\t\t\tbox1 = _box1;\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( c1 ), float32Array, box1 );\n\n\t\t}\n\n\t\tconst isC1Leaf = IS_LEAF( c1 * 2, uint16Array );\n\t\tconst c1Intersection = intersectsBoundsFunc( box1, isC1Leaf, score1, depth + 1, nodeIndexOffset + c1 / UINT32_PER_NODE );\n\n\t\tlet c1StopTraversal;\n\t\tif ( c1Intersection === CONTAINED ) {\n\n\t\t\tconst offset = getLeftOffset( c1 );\n\t\t\tconst end = getRightEndOffset( c1 );\n\t\t\tconst count = end - offset;\n\n\t\t\tc1StopTraversal = intersectsRangeFunc( offset, count, true, depth + 1, nodeIndexOffset + c1 / UINT32_PER_NODE, box1 );\n\n\t\t} else {\n\n\t\t\tc1StopTraversal =\n\t\t\t\tc1Intersection &&\n\t\t\t\tshapecastTraverse(\n\t\t\t\t\tc1,\n\t\t\t\t\tgeometry,\n\t\t\t\t\tintersectsBoundsFunc,\n\t\t\t\t\tintersectsRangeFunc,\n\t\t\t\t\tnodeScoreFunc,\n\t\t\t\t\tnodeIndexOffset,\n\t\t\t\t\tdepth + 1\n\t\t\t\t);\n\n\t\t}\n\n\t\tif ( c1StopTraversal ) return true;\n\n\t\t// Check box 2 intersection\n\t\t// cached box2 will have been overwritten by previous traversal\n\t\tbox2 = _box2;\n\t\tarrayToBox( BOUNDING_DATA_INDEX( c2 ), float32Array, box2 );\n\n\t\tconst isC2Leaf = IS_LEAF( c2 * 2, uint16Array );\n\t\tconst c2Intersection = intersectsBoundsFunc( box2, isC2Leaf, score2, depth + 1, nodeIndexOffset + c2 / UINT32_PER_NODE );\n\n\t\tlet c2StopTraversal;\n\t\tif ( c2Intersection === CONTAINED ) {\n\n\t\t\tconst offset = getLeftOffset( c2 );\n\t\t\tconst end = getRightEndOffset( c2 );\n\t\t\tconst count = end - offset;\n\n\t\t\tc2StopTraversal = intersectsRangeFunc( offset, count, true, depth + 1, nodeIndexOffset + c2 / UINT32_PER_NODE, box2 );\n\n\t\t} else {\n\n\t\t\tc2StopTraversal =\n\t\t\t\tc2Intersection &&\n\t\t\t\tshapecastTraverse(\n\t\t\t\t\tc2,\n\t\t\t\t\tgeometry,\n\t\t\t\t\tintersectsBoundsFunc,\n\t\t\t\t\tintersectsRangeFunc,\n\t\t\t\t\tnodeScoreFunc,\n\t\t\t\t\tnodeIndexOffset,\n\t\t\t\t\tdepth + 1\n\t\t\t\t);\n\n\t\t}\n\n\t\tif ( c2StopTraversal ) return true;\n\n\t\treturn false;\n\n\t\t// Define these inside the function so it has access to the local variables needed\n\t\t// when converting to the buffer equivalents\n\t\tfunction getLeftOffset( nodeIndex32 ) {\n\n\t\t\tconst { uint16Array, uint32Array } = BufferStack;\n\t\t\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t// traverse until we find a leaf\n\t\t\twhile ( ! IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\t\tnodeIndex32 = LEFT_NODE( nodeIndex32 );\n\t\t\t\tnodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t}\n\n\t\t\treturn OFFSET( nodeIndex32, uint32Array );\n\n\t\t}\n\n\t\tfunction getRightEndOffset( nodeIndex32 ) {\n\n\t\t\tconst { uint16Array, uint32Array } = BufferStack;\n\t\t\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t// traverse until we find a leaf\n\t\t\twhile ( ! IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\t\t// adjust offset to point to the right node\n\t\t\t\tnodeIndex32 = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\t\t\tnodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t}\n\n\t\t\t// return the end offset of the triangle range\n\t\t\treturn OFFSET( nodeIndex32, uint32Array ) + COUNT( nodeIndex16, uint16Array );\n\n\t\t}\n\n\t}\n\n}\n","import { Box3, Matrix4 } from 'three';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { BOUNDING_DATA_INDEX, COUNT, IS_LEAF, LEFT_NODE, OFFSET, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { PrimitivePool } from '../../utils/PrimitivePool.js';\nimport { BYTES_PER_NODE, UINT32_PER_NODE } from '../Constants.js';\n\nconst _bufferStack1 = /* @__PURE__ */ new BufferStack.constructor();\nconst _bufferStack2 = /* @__PURE__ */ new BufferStack.constructor();\nconst _boxPool = /* @__PURE__ */ new PrimitivePool( () => new Box3() );\nconst _leftBox1 = /* @__PURE__ */ new Box3();\nconst _rightBox1 = /* @__PURE__ */ new Box3();\n\nconst _leftBox2 = /* @__PURE__ */ new Box3();\nconst _rightBox2 = /* @__PURE__ */ new Box3();\n\nlet _active = false;\n\nexport function bvhcast( bvh, otherBvh, matrixToLocal, intersectsRanges ) {\n\n\tif ( _active ) {\n\n\t\tthrow new Error( 'MeshBVH: Recursive calls to bvhcast not supported.' );\n\n\t}\n\n\t_active = true;\n\n\tconst roots = bvh._roots;\n\tconst otherRoots = otherBvh._roots;\n\tlet result;\n\tlet nodeOffset1 = 0;\n\tlet nodeOffset2 = 0;\n\tconst invMat = new Matrix4().copy( matrixToLocal ).invert();\n\n\t// iterate over the first set of roots\n\tfor ( let i = 0, il = roots.length; i < il; i ++ ) {\n\n\t\t_bufferStack1.setBuffer( roots[ i ] );\n\t\tnodeOffset2 = 0;\n\n\t\t// prep the initial root box\n\t\tconst localBox = _boxPool.getPrimitive();\n\t\tarrayToBox( BOUNDING_DATA_INDEX( 0 ), _bufferStack1.float32Array, localBox );\n\t\tlocalBox.applyMatrix4( invMat );\n\n\t\t// iterate over the second set of roots\n\t\tfor ( let j = 0, jl = otherRoots.length; j < jl; j ++ ) {\n\n\t\t\t_bufferStack2.setBuffer( otherRoots[ j ] );\n\n\t\t\tresult = _traverse(\n\t\t\t\t0, 0, matrixToLocal, invMat, intersectsRanges,\n\t\t\t\tnodeOffset1, nodeOffset2, 0, 0,\n\t\t\t\tlocalBox,\n\t\t\t);\n\n\t\t\t_bufferStack2.clearBuffer();\n\t\t\tnodeOffset2 += otherRoots[ j ].byteLength / BYTES_PER_NODE;\n\n\t\t\tif ( result ) {\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// release stack info\n\t\t_boxPool.releasePrimitive( localBox );\n\t\t_bufferStack1.clearBuffer();\n\t\tnodeOffset1 += roots[ i ].byteLength / BYTES_PER_NODE;\n\n\t\tif ( result ) {\n\n\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\t_active = false;\n\treturn result;\n\n}\n\nfunction _traverse(\n\tnode1Index32,\n\tnode2Index32,\n\tmatrix2to1,\n\tmatrix1to2,\n\tintersectsRangesFunc,\n\n\t// offsets for ids\n\tnode1IndexOffset = 0,\n\tnode2IndexOffset = 0,\n\n\t// tree depth\n\tdepth1 = 0,\n\tdepth2 = 0,\n\n\tcurrBox = null,\n\treversed = false,\n\n) {\n\n\t// get the buffer stacks associated with the current indices\n\tlet bufferStack1, bufferStack2;\n\tif ( reversed ) {\n\n\t\tbufferStack1 = _bufferStack2;\n\t\tbufferStack2 = _bufferStack1;\n\n\t} else {\n\n\t\tbufferStack1 = _bufferStack1;\n\t\tbufferStack2 = _bufferStack2;\n\n\t}\n\n\t// get the local instances of the typed buffers\n\tconst\n\t\tfloat32Array1 = bufferStack1.float32Array,\n\t\tuint32Array1 = bufferStack1.uint32Array,\n\t\tuint16Array1 = bufferStack1.uint16Array,\n\t\tfloat32Array2 = bufferStack2.float32Array,\n\t\tuint32Array2 = bufferStack2.uint32Array,\n\t\tuint16Array2 = bufferStack2.uint16Array;\n\n\tconst node1Index16 = node1Index32 * 2;\n\tconst node2Index16 = node2Index32 * 2;\n\tconst isLeaf1 = IS_LEAF( node1Index16, uint16Array1 );\n\tconst isLeaf2 = IS_LEAF( node2Index16, uint16Array2 );\n\tlet result = false;\n\tif ( isLeaf2 && isLeaf1 ) {\n\n\t\t// if both bounds are leaf nodes then fire the callback if the boxes intersect\n\t\t// Note the \"nodeIndex\" values are just intended to be used as unique identifiers in the tree and\n\t\t// not used for accessing data\n\t\tif ( reversed ) {\n\n\t\t\tresult = intersectsRangesFunc(\n\t\t\t\tOFFSET( node2Index32, uint32Array2 ), COUNT( node2Index32 * 2, uint16Array2 ),\n\t\t\t\tOFFSET( node1Index32, uint32Array1 ), COUNT( node1Index32 * 2, uint16Array1 ),\n\t\t\t\tdepth2, node2IndexOffset + node2Index32 / UINT32_PER_NODE,\n\t\t\t\tdepth1, node1IndexOffset + node1Index32 / UINT32_PER_NODE,\n\t\t\t);\n\n\t\t} else {\n\n\t\t\tresult = intersectsRangesFunc(\n\t\t\t\tOFFSET( node1Index32, uint32Array1 ), COUNT( node1Index32 * 2, uint16Array1 ),\n\t\t\t\tOFFSET( node2Index32, uint32Array2 ), COUNT( node2Index32 * 2, uint16Array2 ),\n\t\t\t\tdepth1, node1IndexOffset + node1Index32 / UINT32_PER_NODE,\n\t\t\t\tdepth2, node2IndexOffset + node2Index32 / UINT32_PER_NODE,\n\t\t\t);\n\n\t\t}\n\n\t} else if ( isLeaf2 ) {\n\n\t\t// SWAP\n\t\t// If we've traversed to the leaf node on the other bvh then we need to swap over\n\t\t// to traverse down the first one\n\n\t\t// get the new box to use\n\t\tconst newBox = _boxPool.getPrimitive();\n\t\tarrayToBox( BOUNDING_DATA_INDEX( node2Index32 ), float32Array2, newBox );\n\t\tnewBox.applyMatrix4( matrix2to1 );\n\n\t\t// get the child bounds to check before traversal\n\t\tconst cl1 = LEFT_NODE( node1Index32 );\n\t\tconst cr1 = RIGHT_NODE( node1Index32, uint32Array1 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cl1 ), float32Array1, _leftBox1 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cr1 ), float32Array1, _rightBox1 );\n\n\t\t// precompute the intersections otherwise the global boxes will be modified during traversal\n\t\tconst intersectCl1 = newBox.intersectsBox( _leftBox1 );\n\t\tconst intersectCr1 = newBox.intersectsBox( _rightBox1 );\n\t\tresult = (\n\t\t\tintersectCl1 && _traverse(\n\t\t\t\tnode2Index32, cl1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\tnewBox, ! reversed,\n\t\t\t)\n\t\t) || (\n\t\t\tintersectCr1 && _traverse(\n\t\t\t\tnode2Index32, cr1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\tnewBox, ! reversed,\n\t\t\t)\n\t\t);\n\n\t\t_boxPool.releasePrimitive( newBox );\n\n\t} else {\n\n\t\t// if neither are leaves then we should swap if one of the children does not\n\t\t// intersect with the current bounds\n\n\t\t// get the child bounds to check\n\t\tconst cl2 = LEFT_NODE( node2Index32 );\n\t\tconst cr2 = RIGHT_NODE( node2Index32, uint32Array2 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cl2 ), float32Array2, _leftBox2 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cr2 ), float32Array2, _rightBox2 );\n\n\t\tconst leftIntersects = currBox.intersectsBox( _leftBox2 );\n\t\tconst rightIntersects = currBox.intersectsBox( _rightBox2 );\n\t\tif ( leftIntersects && rightIntersects ) {\n\n\t\t\t// continue to traverse both children if they both intersect\n\t\t\tresult = _traverse(\n\t\t\t\tnode1Index32, cl2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\tcurrBox, reversed,\n\t\t\t) || _traverse(\n\t\t\t\tnode1Index32, cr2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\tcurrBox, reversed,\n\t\t\t);\n\n\t\t} else if ( leftIntersects ) {\n\n\t\t\tif ( isLeaf1 ) {\n\n\t\t\t\t// if the current box is a leaf then just continue\n\t\t\t\tresult = _traverse(\n\t\t\t\t\tnode1Index32, cl2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\t\tcurrBox, reversed,\n\t\t\t\t);\n\n\t\t\t} else {\n\n\t\t\t\t// SWAP\n\t\t\t\t// if only one box intersects then we have to swap to the other bvh to continue\n\t\t\t\tconst newBox = _boxPool.getPrimitive();\n\t\t\t\tnewBox.copy( _leftBox2 ).applyMatrix4( matrix2to1 );\n\n\t\t\t\tconst cl1 = LEFT_NODE( node1Index32 );\n\t\t\t\tconst cr1 = RIGHT_NODE( node1Index32, uint32Array1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cl1 ), float32Array1, _leftBox1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cr1 ), float32Array1, _rightBox1 );\n\n\t\t\t\t// precompute the intersections otherwise the global boxes will be modified during traversal\n\t\t\t\tconst intersectCl1 = newBox.intersectsBox( _leftBox1 );\n\t\t\t\tconst intersectCr1 = newBox.intersectsBox( _rightBox1 );\n\t\t\t\tresult = (\n\t\t\t\t\tintersectCl1 && _traverse(\n\t\t\t\t\t\tcl2, cl1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t) || (\n\t\t\t\t\tintersectCr1 && _traverse(\n\t\t\t\t\t\tcl2, cr1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\t\t_boxPool.releasePrimitive( newBox );\n\n\t\t\t}\n\n\t\t} else if ( rightIntersects ) {\n\n\t\t\tif ( isLeaf1 ) {\n\n\t\t\t\t// if the current box is a leaf then just continue\n\t\t\t\tresult = _traverse(\n\t\t\t\t\tnode1Index32, cr2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\t\tcurrBox, reversed,\n\t\t\t\t);\n\n\t\t\t} else {\n\n\t\t\t\t// SWAP\n\t\t\t\t// if only one box intersects then we have to swap to the other bvh to continue\n\t\t\t\tconst newBox = _boxPool.getPrimitive();\n\t\t\t\tnewBox.copy( _rightBox2 ).applyMatrix4( matrix2to1 );\n\n\t\t\t\tconst cl1 = LEFT_NODE( node1Index32 );\n\t\t\t\tconst cr1 = RIGHT_NODE( node1Index32, uint32Array1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cl1 ), float32Array1, _leftBox1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cr1 ), float32Array1, _rightBox1 );\n\n\t\t\t\t// precompute the intersections otherwise the global boxes will be modified during traversal\n\t\t\t\tconst intersectCl1 = newBox.intersectsBox( _leftBox1 );\n\t\t\t\tconst intersectCr1 = newBox.intersectsBox( _rightBox1 );\n\t\t\t\tresult = (\n\t\t\t\t\tintersectCl1 && _traverse(\n\t\t\t\t\t\tcr2, cl1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t) || (\n\t\t\t\t\tintersectCr1 && _traverse(\n\t\t\t\t\t\tcr2, cr1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\t\t_boxPool.releasePrimitive( newBox );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn result;\n\n}\n\n","import { COUNT, IS_LEAF, LEFT_NODE, OFFSET, RIGHT_NODE, SPLIT_AXIS } from './utils/nodeBufferUtils.js';\n\nexport const BVHTraversalHelper = new ( class {\n\n\tconstructor() {\n\n\t\tlet buffer = null;\n\t\tlet uint32Array = null;\n\t\tlet uint16Array = null;\n\t\tlet traversing = false;\n\n\t\tthis.root = null;\n\t\tthis.buffer = null;\n\t\tthis.uint32Array = null;\n\t\tthis.uint16Array = null;\n\n\t\tthis.setBVH = ( bvh, root ) => {\n\n\t\t\tif ( traversing ) {\n\n\t\t\t\tthrow new Error( 'BVHTraversalHelper: cannot call setBVH during an active traversal.' );\n\n\t\t\t}\n\n\t\t\tthis.root = root;\n\t\t\tthis.buffer = buffer = bvh._roots[ root ];\n\t\t\tthis.uint16Array = uint16Array = new Uint16Array( buffer );\n\t\t\tthis.uint32Array = uint32Array = new Uint32Array( buffer );\n\n\t\t};\n\n\t\tthis.reset = () => {\n\n\t\t\tthis.root = null;\n\t\t\tthis.buffer = buffer = null;\n\t\t\tthis.uint16Array = uint16Array = null;\n\t\t\tthis.uint32Array = uint32Array = null;\n\n\t\t};\n\n\t\tthis.getRangeStart = node32Index => {\n\n\t\t\tlet node16Index = node32Index * 2;\n\t\t\twhile ( ! IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\tnode32Index = LEFT_NODE( node32Index );\n\t\t\t\tnode16Index = node32Index * 2;\n\n\t\t\t}\n\n\t\t\treturn OFFSET( node32Index, uint32Array );\n\n\t\t};\n\n\t\tthis.getRangeEnd = node32Index => {\n\n\t\t\tlet node16Index = node32Index * 2;\n\t\t\twhile ( ! IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\tnode32Index = RIGHT_NODE( node32Index, uint32Array );\n\t\t\t\tnode16Index = node32Index * 2;\n\n\t\t\t}\n\n\t\t\treturn OFFSET( node32Index, uint32Array ) + COUNT( node16Index, uint16Array );\n\n\t\t};\n\n\t\t// internal recursive walk - the public \"traverseBuffer\" wraps this with the re-entrancy guard\n\t\tconst walk = ( callback, node32Index, depth ) => {\n\n\t\t\tconst node16Index = node32Index * 2;\n\t\t\tconst isLeaf = IS_LEAF( node16Index, uint16Array );\n\t\t\tconst stopTraversal = callback( depth, isLeaf, node32Index );\n\t\t\tif ( ! stopTraversal && ! isLeaf ) {\n\n\t\t\t\tconst left = LEFT_NODE( node32Index );\n\t\t\t\tconst right = RIGHT_NODE( node32Index, uint32Array );\n\t\t\t\twalk( callback, left, depth + 1 );\n\t\t\t\twalk( callback, right, depth + 1 );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.traverseBuffer = callback => {\n\n\t\t\tif ( traversing ) {\n\n\t\t\t\tthrow new Error( 'BVHTraversalHelper: cannot start a traversal during an active traversal.' );\n\n\t\t\t}\n\n\t\t\ttraversing = true;\n\t\t\ttry {\n\n\t\t\t\twalk( callback, 0, 0 );\n\n\t\t\t} finally {\n\n\t\t\t\ttraversing = false;\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.traverse = callback => {\n\n\t\t\tthis.traverseBuffer( ( depth, isLeaf, node32Index ) => {\n\n\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\tconst node16Index = node32Index * 2;\n\t\t\t\t\tconst offset = uint32Array[ node32Index + 6 ];\n\t\t\t\t\tconst count = uint16Array[ node16Index + 14 ];\n\t\t\t\t\treturn callback( depth, isLeaf, new Float32Array( buffer, node32Index * 4, 6 ), offset, count );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst splitAxis = SPLIT_AXIS( node32Index, uint32Array );\n\t\t\t\t\treturn callback( depth, isLeaf, new Float32Array( buffer, node32Index * 4, 6 ), splitAxis );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t};\n\n\t}\n\n} )();\n","/** @import { Matrix4 } from 'three' */\nimport { Box3 } from 'three';\nimport { BYTES_PER_NODE, UINT32_PER_NODE, DEFAULT_OPTIONS, FLOAT32_EPSILON } from './Constants.js';\nimport { arrayToBox } from '../utils/ArrayBoxUtilities.js';\nimport { IS_LEAF, LEFT_NODE, RIGHT_NODE, COUNT, OFFSET } from './utils/nodeBufferUtils.js';\nimport { buildPackedTree } from './build/buildTree.js';\nimport { shapecast as shapecastFunc } from './cast/shapecast.js';\nimport { bvhcast } from './cast/bvhcast.js';\nimport { BVHTraversalHelper } from './BVHTraversalHelper.js';\n\nconst _tempBox = /* @__PURE__ */ new Box3();\nconst _tempBuffer = /* @__PURE__ */ new Float32Array( 6 );\n\n/**\n * @callback BoundsTraverseOrderCallback\n * @param {Box3} box\n * @returns {number}\n */\n\n/**\n * @callback IntersectsBoundsCallback\n * @param {Box3} box\n * @param {boolean} isLeaf\n * @param {number|undefined} score\n * @param {number} depth\n * @param {number} nodeIndex\n * @returns {number}\n */\n\n/**\n * @callback IntersectsRangeCallback\n * @param {number} offset\n * @param {number} count\n * @param {boolean} contained\n * @param {number} depth\n * @param {number} nodeIndex\n * @param {Box3} box\n * @returns {boolean}\n */\n\n/**\n * @callback IntersectsRangesCallback\n * @param {number} offset1\n * @param {number} count1\n * @param {number} offset2\n * @param {number} count2\n * @param {number} depth1\n * @param {number} nodeIndex1\n * @param {number} depth2\n * @param {number} nodeIndex2\n * @returns {boolean}\n */\n\n/**\n * Abstract base class for BVH implementations. Provides core tree traversal and spatial query\n * methods. Subclasses implement primitive-specific logic by overriding `writePrimitiveBounds`\n * and related internal methods.\n */\nexport class BVH {\n\n\tconstructor() {\n\n\t\tthis._roots = null;\n\t\tthis.primitiveBuffer = null;\n\t\tthis.primitiveBufferStride = null;\n\n\t}\n\n\tinit( options ) {\n\n\t\toptions = {\n\t\t\t...DEFAULT_OPTIONS,\n\t\t\t...options,\n\t\t};\n\n\t\tif ( 'maxLeafSize' in options ) {\n\n\t\t\tconsole.warn( 'BVH: \"maxLeafSize\" option has been deprecated. Use \"targetLeafSize\", instead.' );\n\t\t\toptions = {\n\t\t\t\t...options,\n\t\t\t\ttargetLeafSize: options.maxLeafSize,\n\t\t\t};\n\n\t\t}\n\n\t\tbuildPackedTree( this, options );\n\n\t}\n\n\tgetRootRanges( /* range */ ) {\n\n\t\t// TODO: can we avoid passing range in here?\n\t\tthrow new Error( 'BVH: getRootRanges() not implemented' );\n\n\t}\n\n\t// write the i-th primitive bounds in a 6-value min / max format to the buffer\n\t// starting at the given \"writeOffset\"\n\twritePrimitiveBounds( /* i, buffer, writeOffset */ ) {\n\n\t\tthrow new Error( 'BVH: writePrimitiveBounds() not implemented' );\n\n\t}\n\n\t// writes the union bounds of all primitives in the given range in a min / max format\n\t// to the buffer\n\twritePrimitiveRangeBounds( offset, count, targetBuffer, baseIndex ) {\n\n\t\t// Initialize bounds\n\t\tlet minX = Infinity;\n\t\tlet minY = Infinity;\n\t\tlet minZ = Infinity;\n\t\tlet maxX = - Infinity;\n\t\tlet maxY = - Infinity;\n\t\tlet maxZ = - Infinity;\n\n\t\t// compute union of all bounds\n\t\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\t\tthis.writePrimitiveBounds( i, _tempBuffer, 0 );\n\n\t\t\t// compute union\n\t\t\tconst [ lx, ly, lz, rx, ry, rz ] = _tempBuffer;\n\t\t\tif ( lx < minX ) minX = lx;\n\t\t\tif ( rx > maxX ) maxX = rx;\n\t\t\tif ( ly < minY ) minY = ly;\n\t\t\tif ( ry > maxY ) maxY = ry;\n\t\t\tif ( lz < minZ ) minZ = lz;\n\t\t\tif ( rz > maxZ ) maxZ = rz;\n\n\t\t}\n\n\t\t// write bounds\n\t\ttargetBuffer[ baseIndex + 0 ] = minX;\n\t\ttargetBuffer[ baseIndex + 1 ] = minY;\n\t\ttargetBuffer[ baseIndex + 2 ] = minZ;\n\t\ttargetBuffer[ baseIndex + 3 ] = maxX;\n\t\ttargetBuffer[ baseIndex + 4 ] = maxY;\n\t\ttargetBuffer[ baseIndex + 5 ] = maxZ;\n\n\t\treturn targetBuffer;\n\n\t}\n\n\tcomputePrimitiveBounds( offset, count, targetBuffer ) {\n\n\t\tconst boundsOffset = targetBuffer.offset || 0;\n\t\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\t\tthis.writePrimitiveBounds( i, _tempBuffer, 0 );\n\n\t\t\t// construction primitive bounds requires a center + half extents format\n\t\t\tconst [ lx, ly, lz, rx, ry, rz ] = _tempBuffer;\n\n\t\t\tconst cx = ( lx + rx ) / 2;\n\t\t\tconst cy = ( ly + ry ) / 2;\n\t\t\tconst cz = ( lz + rz ) / 2;\n\n\t\t\tconst hx = ( rx - lx ) / 2;\n\t\t\tconst hy = ( ry - ly ) / 2;\n\t\t\tconst hz = ( rz - lz ) / 2;\n\n\t\t\tconst baseIndex = ( i - boundsOffset ) * 6;\n\t\t\ttargetBuffer[ baseIndex + 0 ] = cx;\n\t\t\ttargetBuffer[ baseIndex + 1 ] = hx + ( Math.abs( cx ) + hx ) * FLOAT32_EPSILON;\n\t\t\ttargetBuffer[ baseIndex + 2 ] = cy;\n\t\t\ttargetBuffer[ baseIndex + 3 ] = hy + ( Math.abs( cy ) + hy ) * FLOAT32_EPSILON;\n\t\t\ttargetBuffer[ baseIndex + 4 ] = cz;\n\t\t\ttargetBuffer[ baseIndex + 5 ] = hz + ( Math.abs( cz ) + hz ) * FLOAT32_EPSILON;\n\n\t\t}\n\n\t\treturn targetBuffer;\n\n\t}\n\n\t/**\n\t * Adjusts all primitive offsets stored in the BVH leaf nodes by the given value. Useful when\n\t * geometry buffers have been shifted or compacted (e.g. when merging geometries).\n\t * @param {number} offset\n\t */\n\tshiftPrimitiveOffsets( offset ) {\n\n\t\tconst indirectBuffer = this._indirectBuffer;\n\t\tif ( indirectBuffer ) {\n\n\t\t\t// the offsets are embedded in the indirect buffer\n\t\t\tfor ( let i = 0, l = indirectBuffer.length; i < l; i ++ ) {\n\n\t\t\t\tindirectBuffer[ i ] += offset;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// offsets are embedded in the leaf nodes\n\t\t\tconst roots = this._roots;\n\t\t\tfor ( let rootIndex = 0; rootIndex < roots.length; rootIndex ++ ) {\n\n\t\t\t\tconst root = roots[ rootIndex ];\n\t\t\t\tconst uint32Array = new Uint32Array( root );\n\t\t\t\tconst uint16Array = new Uint16Array( root );\n\t\t\t\tconst totalNodes = root.byteLength / BYTES_PER_NODE;\n\t\t\t\tfor ( let node = 0; node < totalNodes; node ++ ) {\n\n\t\t\t\t\tconst node32Index = UINT32_PER_NODE * node;\n\t\t\t\t\tconst node16Index = 2 * node32Index;\n\t\t\t\t\tif ( IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\t\t\t// offset value\n\t\t\t\t\t\tuint32Array[ node32Index + 6 ] += offset;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Traverses all nodes of the BVH, invoking a callback for each node.\n\t *\n\t * For leaf nodes the callback receives `( depth, isLeaf, boundingData, offset, count )`.\n\t * For internal nodes it receives `( depth, isLeaf, boundingData, splitAxis )` and may\n\t * return `true` to stop descending into that node's children.\n\t *\n\t * @param {Function} callback\n\t * @param {number} [rootIndex=0]\n\t */\n\ttraverse( callback, rootIndex = 0 ) {\n\n\t\tBVHTraversalHelper.setBVH( this, rootIndex );\n\t\tBVHTraversalHelper.traverse( callback );\n\t\tBVHTraversalHelper.reset();\n\n\t}\n\n\t/**\n\t * Refits all BVH node bounds to reflect the current primitive positions. Faster than\n\t * rebuilding the BVH but produces a less optimal tree after large vertex deformations.\n\t */\n\trefit( /* nodeIndices = null */ ) {\n\n\t\t// TODO: add support for \"nodeIndices\"\n\t\t// if ( nodeIndices && Array.isArray( nodeIndices ) ) {\n\n\t\t// \tnodeIndices = new Set( nodeIndices );\n\n\t\t// }\n\n\t\tconst roots = this._roots;\n\t\tfor ( let rootIndex = 0, rootCount = roots.length; rootIndex < rootCount; rootIndex ++ ) {\n\n\t\t\tconst buffer = roots[ rootIndex ];\n\t\t\tconst uint32Array = new Uint32Array( buffer );\n\t\t\tconst uint16Array = new Uint16Array( buffer );\n\t\t\tconst float32Array = new Float32Array( buffer );\n\t\t\tconst totalNodes = buffer.byteLength / BYTES_PER_NODE;\n\n\t\t\t// Traverse nodes from right to left so children are updated before parents\n\t\t\tfor ( let nodeIndex = totalNodes - 1; nodeIndex >= 0; nodeIndex -- ) {\n\n\t\t\t\tconst nodeIndex32 = nodeIndex * UINT32_PER_NODE;\n\t\t\t\tconst nodeIndex16 = nodeIndex32 * 2;\n\t\t\t\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\n\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\t// get the bounds\n\t\t\t\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\t\t\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\t\t\t\t\tthis.writePrimitiveRangeBounds( offset, count, _tempBuffer, 0 );\n\n\t\t\t\t\t// write directly to node bounds (already in min/max format)\n\t\t\t\t\tfloat32Array.set( _tempBuffer, nodeIndex32 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\t\t\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t\t\t\t// Union the bounds of left and right children\n\t\t\t\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\tconst leftMin = float32Array[ left + i ];\n\t\t\t\t\t\tconst leftMax = float32Array[ left + i + 3 ];\n\t\t\t\t\t\tconst rightMin = float32Array[ right + i ];\n\t\t\t\t\t\tconst rightMax = float32Array[ right + i + 3 ];\n\n\t\t\t\t\t\tfloat32Array[ nodeIndex32 + i ] = leftMin < rightMin ? leftMin : rightMin;\n\t\t\t\t\t\tfloat32Array[ nodeIndex32 + i + 3 ] = leftMax > rightMax ? leftMax : rightMax;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Computes the axis-aligned bounding box of all primitives in the BVH.\n\t * @param {Box3} target - Target box to write the result into.\n\t * @returns {Box3}\n\t */\n\tgetBoundingBox( target ) {\n\n\t\ttarget.makeEmpty();\n\n\t\tconst roots = this._roots;\n\t\troots.forEach( buffer => {\n\n\t\t\tarrayToBox( 0, new Float32Array( buffer ), _tempBox );\n\t\t\ttarget.union( _tempBox );\n\n\t\t} );\n\n\t\treturn target;\n\n\t}\n\n\t/**\n\t * A generalized traversal function for performing spatial queries against the BVH. Returns\n\t * `true` as soon as a primitive has been reported as intersected. The tree is traversed\n\t * depth-first; `boundsTraverseOrder` controls which child is visited first. Returning\n\t * `CONTAINED` from `intersectsBounds` skips further child traversal and intersects all\n\t * primitives in that subtree immediately.\n\t *\n\t * @param {Object} callbacks\n\t * @param {IntersectsBoundsCallback} callbacks.intersectsBounds\n\t * @param {IntersectsRangeCallback} [callbacks.intersectsRange]\n\t * @param {BoundsTraverseOrderCallback} [callbacks.boundsTraverseOrder]\n\t * @returns {boolean}\n\t */\n\t// TODO: see if we can get rid of \"iterateFunc\" here as well as the primitive so the function\n\t// API aligns with the \"shapecast\" implementation\n\tshapecast( callbacks ) {\n\n\t\t// TODO: can we get rid of \"scratchPrimitive\" and / or \"iterate\"? Or merge them somehow\n\t\tlet {\n\t\t\tboundsTraverseOrder,\n\t\t\tintersectsBounds,\n\t\t\tintersectsRange,\n\t\t\tintersectsPrimitive,\n\t\t\tscratchPrimitive,\n\t\t\titerate,\n\t\t} = callbacks;\n\n\t\t// wrap the intersectsRange function\n\t\tif ( intersectsRange && intersectsPrimitive ) {\n\n\t\t\tconst originalIntersectsRange = intersectsRange;\n\t\t\tintersectsRange = ( offset, count, contained, depth, nodeIndex ) => {\n\n\t\t\t\tif ( ! originalIntersectsRange( offset, count, contained, depth, nodeIndex ) ) {\n\n\t\t\t\t\treturn iterate( offset, count, this, intersectsPrimitive, contained, depth, scratchPrimitive );\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t} else if ( ! intersectsRange ) {\n\n\t\t\tif ( intersectsPrimitive ) {\n\n\t\t\t\tintersectsRange = ( offset, count, contained, depth ) => {\n\n\t\t\t\t\treturn iterate( offset, count, this, intersectsPrimitive, contained, depth, scratchPrimitive );\n\n\t\t\t\t};\n\n\t\t\t} else {\n\n\t\t\t\tintersectsRange = ( offset, count, contained ) => {\n\n\t\t\t\t\treturn contained;\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t}\n\n\t\t// run shapecast\n\t\tlet result = false;\n\t\tlet nodeOffset = 0;\n\t\tconst roots = this._roots;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\tconst root = roots[ i ];\n\t\t\tresult = shapecastFunc( this, i, intersectsBounds, intersectsRange, boundsTraverseOrder, nodeOffset );\n\n\t\t\tif ( result ) {\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tnodeOffset += root.byteLength / BYTES_PER_NODE;\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * Simultaneously traverses two BVH structures to find intersecting primitive pairs. Returns\n\t * `true` as soon as any intersection is reported. Both trees are traversed depth-first with\n\t * alternating descent. `matrixToLocal` transforms `otherBvh` into the local space of this BVH.\n\t *\n\t * @param {BVH} otherBvh\n\t * @param {Matrix4} matrixToLocal\n\t * @param {Object} callbacks\n\t * @param {IntersectsRangesCallback} callbacks.intersectsRanges\n\t * @returns {boolean}\n\t */\n\tbvhcast( otherBvh, matrixToLocal, callbacks ) {\n\n\t\tlet { intersectsRanges } = callbacks;\n\t\treturn bvhcast( this, otherBvh, matrixToLocal, intersectsRanges );\n\n\n\t}\n\n}\n","export function isSharedArrayBufferSupported() {\n\n\treturn typeof SharedArrayBuffer !== 'undefined';\n\n}\n\nexport function convertToBufferType( array, BufferConstructor ) {\n\n\tif ( array === null ) {\n\n\t\treturn array;\n\n\t} else if ( array.buffer ) {\n\n\t\tconst buffer = array.buffer;\n\t\tif ( buffer.constructor === BufferConstructor ) {\n\n\t\t\treturn array;\n\n\t\t}\n\n\t\tconst ArrayConstructor = array.constructor;\n\t\tconst result = new ArrayConstructor( new BufferConstructor( buffer.byteLength ) );\n\t\tresult.set( array );\n\t\treturn result;\n\n\t} else {\n\n\t\tif ( array.constructor === BufferConstructor ) {\n\n\t\t\treturn array;\n\n\t\t}\n\n\t\tconst result = new BufferConstructor( array.byteLength );\n\t\tnew Uint8Array( result ).set( new Uint8Array( array ) );\n\t\treturn result;\n\n\t}\n\n}\n","import { BufferAttribute } from 'three';\n\nexport function getVertexCount( geo ) {\n\n\treturn geo.index ? geo.index.count : geo.attributes.position.count;\n\n}\n\nexport function getTriCount( geo ) {\n\n\treturn getVertexCount( geo ) / 3;\n\n}\n\nexport function getIndexArray( vertexCount, BufferConstructor = ArrayBuffer ) {\n\n\tif ( vertexCount > 65535 ) {\n\n\t\treturn new Uint32Array( new BufferConstructor( 4 * vertexCount ) );\n\n\t} else {\n\n\t\treturn new Uint16Array( new BufferConstructor( 2 * vertexCount ) );\n\n\t}\n\n}\n\n// ensures that an index is present on the geometry\nexport function ensureIndex( geo, options ) {\n\n\tif ( ! geo.index ) {\n\n\t\tconst vertexCount = geo.attributes.position.count;\n\t\tconst BufferConstructor = options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer;\n\t\tconst index = getIndexArray( vertexCount, BufferConstructor );\n\t\tgeo.setIndex( new BufferAttribute( index, 1 ) );\n\n\t\tfor ( let i = 0; i < vertexCount; i ++ ) {\n\n\t\t\tindex[ i ] = i;\n\n\t\t}\n\n\t}\n\n}\n\n// Computes the set of { offset, count } ranges which need independent BVH roots. Each\n// region in the geometry index that belongs to a different set of material groups requires\n// a separate BVH root, so that triangles indices belonging to one group never get swapped\n// with triangle indices belongs to another group. For example, if the groups were like this:\n//\n// [-------------------------------------------------------------]\n// |__________________|\n// g0 = [0, 20] |______________________||_____________________|\n// g1 = [16, 40] g2 = [41, 60]\n//\n// we would need four BVH roots: [0, 15], [16, 20], [21, 40], [41, 60].\nfunction getFullPrimitiveRange( geo, range, stride ) {\n\n\tconst primitiveCount = getVertexCount( geo ) / stride;\n\tconst drawRange = range ? range : geo.drawRange;\n\tconst start = drawRange.start / stride;\n\tconst end = ( drawRange.start + drawRange.count ) / stride;\n\n\tconst offset = Math.max( 0, start );\n\tconst count = Math.min( primitiveCount, end ) - offset;\n\treturn {\n\t\toffset: Math.floor( offset ),\n\t\tcount: Math.floor( count ),\n\t};\n\n}\n\nfunction getPrimitiveGroupRanges( geo, stride ) {\n\n\treturn geo.groups.map( group => ( {\n\t\toffset: group.start / stride,\n\t\tcount: group.count / stride,\n\t} ));\n\n}\n\n// Function that extracts a set of mutually exclusive ranges representing the primitives being\n// drawn as determined by the geometry groups, draw range, and user specified range\nexport function getRootPrimitiveRanges( geo, range, stride ) {\n\n\tconst drawRange = getFullPrimitiveRange( geo, range, stride );\n\tconst primitiveRanges = getPrimitiveGroupRanges( geo, stride );\n\tif ( ! primitiveRanges.length ) {\n\n\t\treturn [ drawRange ];\n\n\t}\n\n\tconst ranges = [];\n\tconst drawRangeStart = drawRange.offset;\n\tconst drawRangeEnd = drawRange.offset + drawRange.count;\n\n\t// Create events for group boundaries\n\tconst primitiveCount = getVertexCount( geo ) / stride;\n\tconst events = [];\n\tfor ( const group of primitiveRanges ) {\n\n\t\t// Account for cases where group size is set to Infinity\n\t\tconst { offset, count } = group;\n\t\tconst groupStart = offset;\n\t\tconst groupCount = isFinite( count ) ? count : ( primitiveCount - offset );\n\t\tconst groupEnd = ( offset + groupCount );\n\n\t\t// Only add events if the group intersects with the draw range\n\t\tif ( groupStart < drawRangeEnd && groupEnd > drawRangeStart ) {\n\n\t\t\tevents.push( { pos: Math.max( drawRangeStart, groupStart ), isStart: true } );\n\t\t\tevents.push( { pos: Math.min( drawRangeEnd, groupEnd ), isStart: false } );\n\n\t\t}\n\n\t}\n\n\t// Sort events by position, with 'end' events before 'start' events at the same position\n\tevents.sort( ( a, b ) => {\n\n\t\tif ( a.pos !== b.pos ) {\n\n\t\t\treturn a.pos - b.pos;\n\n\t\t} else {\n\n\t\t\treturn a.type === 'end' ? - 1 : 1;\n\n\t\t}\n\n\t} );\n\n\t// sweep through events and create ranges where activeGroups > 0\n\tlet activeGroups = 0;\n\tlet lastPos = null;\n\tfor ( const event of events ) {\n\n\t\tconst newPos = event.pos;\n\t\tif ( activeGroups !== 0 && newPos !== lastPos ) {\n\n\t\t\tranges.push( {\n\t\t\t\toffset: lastPos,\n\t\t\t\tcount: newPos - lastPos,\n\t\t\t} );\n\n\t\t}\n\n\t\tactiveGroups += event.isStart ? 1 : - 1;\n\t\tlastPos = newPos;\n\n\t}\n\n\treturn ranges;\n\n}\n","/** @import { BufferGeometry } from 'three' */\nimport { Box3 } from 'three';\nimport { SKIP_GENERATION, DEFAULT_OPTIONS } from './Constants.js';\nimport { isSharedArrayBufferSupported } from '../utils/BufferUtils.js';\nimport { ensureIndex, getRootPrimitiveRanges } from './build/geometryUtils.js';\nimport { BVH } from './BVH.js';\n\n// construct a new buffer that points to the set of triangles represented by the given ranges\nexport function generateIndirectBuffer( ranges, useSharedArrayBuffer ) {\n\n\tconst lastRange = ranges[ ranges.length - 1 ];\n\tconst useUint32 = lastRange.offset + lastRange.count > 2 ** 16;\n\n\t// use getRootIndexRanges which excludes gaps\n\tconst length = ranges.reduce( ( acc, val ) => acc + val.count, 0 );\n\tconst byteCount = useUint32 ? 4 : 2;\n\tconst buffer = useSharedArrayBuffer ? new SharedArrayBuffer( length * byteCount ) : new ArrayBuffer( length * byteCount );\n\tconst indirectBuffer = useUint32 ? new Uint32Array( buffer ) : new Uint16Array( buffer );\n\n\t// construct a compact form of the triangles in these ranges\n\tlet index = 0;\n\tfor ( let r = 0; r < ranges.length; r ++ ) {\n\n\t\tconst { offset, count } = ranges[ r ];\n\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\tindirectBuffer[ index + i ] = offset + i;\n\n\t\t}\n\n\t\tindex += count;\n\n\t}\n\n\treturn indirectBuffer;\n\n}\n\n/**\n * Abstract base class for geometry-backed BVH implementations. Handles geometry\n * indexing, indirect mode, and bounding box initialization. Subclasses implement\n * primitive-specific bounds computation and raycasting via `writePrimitiveBounds`\n * and `raycastObject3D`.\n *\n * @param {BufferGeometry} geometry\n * @param {Object} [options]\n * @param {number} [options.strategy=CENTER] - Split strategy: `CENTER`, `AVERAGE`, or `SAH`.\n * @param {number} [options.maxDepth=40] - Maximum tree depth. Note that this can cause the target leaf size to not\n * be met if the tree is truncated.\n * @param {number} [options.targetLeafSize=10] - The target number of primitives per leaf node. Note that this is\n * a soft limit and generation strategies like SAH will terminate early if the heuristic determines.\n * @param {boolean} [options.setBoundingBox=true] - Set `geometry.boundingBox` if not already present.\n * @param {boolean} [options.useSharedArrayBuffer=false] - Use `SharedArrayBuffer` for BVH root buffers.\n * @param {boolean} [options.indirect=false] - Build using an indirect buffer, leaving the original index unmodified.\n * @param {boolean} [options.verbose=true] - Log build progress to the console.\n * @param {Function|null} [options.onProgress=null] - Called with a progress value in [0, 1] during build.\n * @param {Object|null} [options.range=null] - Restrict the BVH to a specific geometry group range.\n * @extends BVH\n */\nexport class GeometryBVH extends BVH {\n\n\t/**\n\t * Whether the BVH was built in indirect mode.\n\t * @type {boolean}\n\t * @readonly\n\t */\n\tget indirect() {\n\n\t\treturn ! ! this._indirectBuffer;\n\n\t}\n\n\tget primitiveStride() {\n\n\t\treturn null;\n\n\t}\n\n\tget primitiveBufferStride() {\n\n\t\treturn this.indirect ? 1 : this.primitiveStride;\n\n\t}\n\tset primitiveBufferStride( v ) {}\n\n\tget primitiveBuffer() {\n\n\t\treturn this.indirect ? this._indirectBuffer : this.geometry.index.array;\n\n\t}\n\tset primitiveBuffer( v ) {}\n\n\tconstructor( geometry, options = {} ) {\n\n\t\tif ( ! geometry.isBufferGeometry ) {\n\n\t\t\tthrow new Error( 'BVH: Only BufferGeometries are supported.' );\n\n\t\t} else if ( geometry.index && geometry.index.isInterleavedBufferAttribute ) {\n\n\t\t\tthrow new Error( 'BVH: InterleavedBufferAttribute is not supported for the index attribute.' );\n\n\t\t}\n\n\t\tif ( options.useSharedArrayBuffer && ! isSharedArrayBufferSupported() ) {\n\n\t\t\tthrow new Error( 'BVH: SharedArrayBuffer is not available.' );\n\n\t\t}\n\n\t\tsuper();\n\n\t\t// retain references to the geometry so we can use them it without having to\n\t\t// take a geometry reference in every function.\n\n\t\t/**\n\t\t * The geometry this BVH was built from.\n\t\t * @type {BufferGeometry}\n\t\t * @readonly\n\t\t */\n\t\tthis.geometry = geometry;\n\t\tthis.resolvePrimitiveIndex = options.indirect ? i => this._indirectBuffer[ i ] : i => i;\n\t\tthis.primitiveBuffer = null;\n\t\tthis.primitiveBufferStride = null;\n\t\tthis._indirectBuffer = null;\n\n\t\toptions = {\n\t\t\t...DEFAULT_OPTIONS,\n\t\t\t...options,\n\t\t};\n\n\t\t// build the BVH unless we're deserializing\n\t\tif ( ! options[ SKIP_GENERATION ] ) {\n\n\t\t\tthis.init( options );\n\n\t\t}\n\n\t}\n\n\tinit( options ) {\n\n\t\tconst { geometry, primitiveStride } = this;\n\n\t\tif ( options.indirect ) {\n\n\t\t\t// construct an buffer that is indirectly sorts the triangles used for the BVH\n\t\t\tconst ranges = getRootPrimitiveRanges( geometry, options.range, primitiveStride );\n\t\t\tconst indirectBuffer = generateIndirectBuffer( ranges, options.useSharedArrayBuffer );\n\t\t\tthis._indirectBuffer = indirectBuffer;\n\n\t\t} else {\n\n\t\t\tensureIndex( geometry, options );\n\n\t\t}\n\n\t\tsuper.init( options );\n\n\t\tif ( ! geometry.boundingBox && options.setBoundingBox ) {\n\n\t\t\tgeometry.boundingBox = this.getBoundingBox( new Box3() );\n\n\t\t}\n\n\t}\n\n\t// Abstract methods to be implemented by subclasses\n\tgetRootRanges( range ) {\n\n\t\t// TODO: can we avoid passing options in here\n\t\tif ( this.indirect ) {\n\n\t\t\treturn [ { offset: 0, count: this._indirectBuffer.length } ];\n\n\n\t\t} else {\n\n\t\t\treturn getRootPrimitiveRanges( this.geometry, range, this.primitiveStride );\n\n\t\t}\n\n\t}\n\n\traycastObject3D( /* object, raycaster, intersects = [] */ ) {\n\n\t\tthrow new Error( 'BVH: raycastObject3D() not implemented' );\n\n\t}\n\n}\n","import { Vector3 } from 'three';\n\nexport class SeparatingAxisBounds {\n\n\tconstructor() {\n\n\t\tthis.min = Infinity;\n\t\tthis.max = - Infinity;\n\n\t}\n\n\tsetFromPointsField( points, field ) {\n\n\t\tlet min = Infinity;\n\t\tlet max = - Infinity;\n\t\tfor ( let i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\tconst p = points[ i ];\n\t\t\tconst val = p[ field ];\n\t\t\tmin = val < min ? val : min;\n\t\t\tmax = val > max ? val : max;\n\n\t\t}\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t}\n\n\tsetFromPoints( axis, points ) {\n\n\t\tlet min = Infinity;\n\t\tlet max = - Infinity;\n\t\tfor ( let i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\tconst p = points[ i ];\n\t\t\tconst val = axis.dot( p );\n\t\t\tmin = val < min ? val : min;\n\t\t\tmax = val > max ? val : max;\n\n\t\t}\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t}\n\n\tisSeparated( other ) {\n\n\t\treturn this.min > other.max || other.min > this.max;\n\n\t}\n\n}\n\nSeparatingAxisBounds.prototype.setFromBox = ( function () {\n\n\tconst p = /* @__PURE__ */ new Vector3();\n\treturn function setFromBox( axis, box ) {\n\n\t\tconst boxMin = box.min;\n\t\tconst boxMax = box.max;\n\t\tlet min = Infinity;\n\t\tlet max = - Infinity;\n\t\tfor ( let x = 0; x <= 1; x ++ ) {\n\n\t\t\tfor ( let y = 0; y <= 1; y ++ ) {\n\n\t\t\t\tfor ( let z = 0; z <= 1; z ++ ) {\n\n\t\t\t\t\tp.x = boxMin.x * x + boxMax.x * ( 1 - x );\n\t\t\t\t\tp.y = boxMin.y * y + boxMax.y * ( 1 - y );\n\t\t\t\t\tp.z = boxMin.z * z + boxMax.z * ( 1 - z );\n\n\t\t\t\t\tconst val = axis.dot( p );\n\t\t\t\t\tmin = Math.min( val, min );\n\t\t\t\t\tmax = Math.max( val, max );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t};\n\n} )();\n\nexport const areIntersecting = ( function () {\n\n\tconst cacheSatBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\treturn function areIntersecting( shape1, shape2 ) {\n\n\t\tconst points1 = shape1.points;\n\t\tconst satAxes1 = shape1.satAxes;\n\t\tconst satBounds1 = shape1.satBounds;\n\n\t\tconst points2 = shape2.points;\n\t\tconst satAxes2 = shape2.satAxes;\n\t\tconst satBounds2 = shape2.satBounds;\n\n\t\t// check axes of the first shape\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = satBounds1[ i ];\n\t\t\tconst sa = satAxes1[ i ];\n\t\t\tcacheSatBounds.setFromPoints( sa, points2 );\n\t\t\tif ( sb.isSeparated( cacheSatBounds ) ) return false;\n\n\t\t}\n\n\t\t// check axes of the second shape\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = satBounds2[ i ];\n\t\t\tconst sa = satAxes2[ i ];\n\t\t\tcacheSatBounds.setFromPoints( sa, points1 );\n\t\t\tif ( sb.isSeparated( cacheSatBounds ) ) return false;\n\n\t\t}\n\n\t};\n\n} )();\n","import { Vector3, Vector2, Plane, Line3 } from 'three';\n\nexport const closestPointLineToLine = ( function () {\n\n\t// https://github.com/juj/MathGeoLib/blob/master/src/Geometry/Line.cpp#L56\n\tconst dir1 = /* @__PURE__ */ new Vector3();\n\tconst dir2 = /* @__PURE__ */ new Vector3();\n\tconst v02 = /* @__PURE__ */ new Vector3();\n\treturn function closestPointLineToLine( l1, l2, result ) {\n\n\t\tconst v0 = l1.start;\n\t\tconst v10 = dir1;\n\t\tconst v2 = l2.start;\n\t\tconst v32 = dir2;\n\n\t\tv02.subVectors( v0, v2 );\n\t\tdir1.subVectors( l1.end, l1.start );\n\t\tdir2.subVectors( l2.end, l2.start );\n\n\t\t// float d0232 = v02.Dot(v32);\n\t\tconst d0232 = v02.dot( v32 );\n\n\t\t// float d3210 = v32.Dot(v10);\n\t\tconst d3210 = v32.dot( v10 );\n\n\t\t// float d3232 = v32.Dot(v32);\n\t\tconst d3232 = v32.dot( v32 );\n\n\t\t// float d0210 = v02.Dot(v10);\n\t\tconst d0210 = v02.dot( v10 );\n\n\t\t// float d1010 = v10.Dot(v10);\n\t\tconst d1010 = v10.dot( v10 );\n\n\t\t// float denom = d1010*d3232 - d3210*d3210;\n\t\tconst denom = d1010 * d3232 - d3210 * d3210;\n\n\t\tlet d, d2;\n\t\tif ( denom !== 0 ) {\n\n\t\t\td = ( d0232 * d3210 - d0210 * d3232 ) / denom;\n\n\t\t} else {\n\n\t\t\td = 0;\n\n\t\t}\n\n\t\td2 = ( d0232 + d * d3210 ) / d3232;\n\n\t\tresult.x = d;\n\t\tresult.y = d2;\n\n\t};\n\n} )();\n\nexport const closestPointsSegmentToSegment = ( function () {\n\n\t// https://github.com/juj/MathGeoLib/blob/master/src/Geometry/LineSegment.cpp#L187\n\tconst paramResult = /* @__PURE__ */ new Vector2();\n\tconst temp1 = /* @__PURE__ */ new Vector3();\n\tconst temp2 = /* @__PURE__ */ new Vector3();\n\treturn function closestPointsSegmentToSegment( l1, l2, target1, target2 ) {\n\n\t\tclosestPointLineToLine( l1, l2, paramResult );\n\n\t\tlet d = paramResult.x;\n\t\tlet d2 = paramResult.y;\n\t\tif ( d >= 0 && d <= 1 && d2 >= 0 && d2 <= 1 ) {\n\n\t\t\tl1.at( d, target1 );\n\t\t\tl2.at( d2, target2 );\n\n\t\t\treturn;\n\n\t\t} else if ( d >= 0 && d <= 1 ) {\n\n\t\t\t// Only d2 is out of bounds.\n\t\t\tif ( d2 < 0 ) {\n\n\t\t\t\tl2.at( 0, target2 );\n\n\t\t\t} else {\n\n\t\t\t\tl2.at( 1, target2 );\n\n\t\t\t}\n\n\t\t\tl1.closestPointToPoint( target2, true, target1 );\n\t\t\treturn;\n\n\t\t} else if ( d2 >= 0 && d2 <= 1 ) {\n\n\t\t\t// Only d is out of bounds.\n\t\t\tif ( d < 0 ) {\n\n\t\t\t\tl1.at( 0, target1 );\n\n\t\t\t} else {\n\n\t\t\t\tl1.at( 1, target1 );\n\n\t\t\t}\n\n\t\t\tl2.closestPointToPoint( target1, true, target2 );\n\t\t\treturn;\n\n\t\t} else {\n\n\t\t\t// Both u and u2 are out of bounds.\n\t\t\tlet p;\n\t\t\tif ( d < 0 ) {\n\n\t\t\t\tp = l1.start;\n\n\t\t\t} else {\n\n\t\t\t\tp = l1.end;\n\n\t\t\t}\n\n\t\t\tlet p2;\n\t\t\tif ( d2 < 0 ) {\n\n\t\t\t\tp2 = l2.start;\n\n\t\t\t} else {\n\n\t\t\t\tp2 = l2.end;\n\n\t\t\t}\n\n\t\t\tconst closestPoint = temp1;\n\t\t\tconst closestPoint2 = temp2;\n\t\t\tl1.closestPointToPoint( p2, true, temp1 );\n\t\t\tl2.closestPointToPoint( p, true, temp2 );\n\n\t\t\tif ( closestPoint.distanceToSquared( p2 ) <= closestPoint2.distanceToSquared( p ) ) {\n\n\t\t\t\ttarget1.copy( closestPoint );\n\t\t\t\ttarget2.copy( p2 );\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\ttarget1.copy( p );\n\t\t\t\ttarget2.copy( closestPoint2 );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n} )();\n\n\nexport const sphereIntersectTriangle = ( function () {\n\n\t// https://stackoverflow.com/questions/34043955/detect-collision-between-sphere-and-triangle-in-three-js\n\tconst closestPointTemp = /* @__PURE__ */ new Vector3();\n\tconst projectedPointTemp = /* @__PURE__ */ new Vector3();\n\tconst planeTemp = /* @__PURE__ */ new Plane();\n\tconst lineTemp = /* @__PURE__ */ new Line3();\n\treturn function sphereIntersectTriangle( sphere, triangle ) {\n\n\t\tconst { radius, center } = sphere;\n\t\tconst { a, b, c } = triangle;\n\n\t\t// phase 1\n\t\tlineTemp.start = a;\n\t\tlineTemp.end = b;\n\t\tconst closestPoint1 = lineTemp.closestPointToPoint( center, true, closestPointTemp );\n\t\tif ( closestPoint1.distanceTo( center ) <= radius ) return true;\n\n\t\tlineTemp.start = a;\n\t\tlineTemp.end = c;\n\t\tconst closestPoint2 = lineTemp.closestPointToPoint( center, true, closestPointTemp );\n\t\tif ( closestPoint2.distanceTo( center ) <= radius ) return true;\n\n\t\tlineTemp.start = b;\n\t\tlineTemp.end = c;\n\t\tconst closestPoint3 = lineTemp.closestPointToPoint( center, true, closestPointTemp );\n\t\tif ( closestPoint3.distanceTo( center ) <= radius ) return true;\n\n\t\t// phase 2\n\t\tconst plane = triangle.getPlane( planeTemp );\n\t\tconst dp = Math.abs( plane.distanceToPoint( center ) );\n\t\tif ( dp <= radius ) {\n\n\t\t\tconst pp = plane.projectPoint( center, projectedPointTemp );\n\t\t\tconst cp = triangle.containsPoint( pp );\n\t\t\tif ( cp ) return true;\n\n\t\t}\n\n\t\treturn false;\n\n\t};\n\n} )();\n","/** @import { Sphere } from 'three' */\nimport { Triangle, Vector3, Vector2, Line3, Plane } from 'three';\nimport { SeparatingAxisBounds } from './SeparatingAxisBounds.js';\nimport { closestPointsSegmentToSegment, sphereIntersectTriangle } from './MathUtilities.js';\n\nconst componentKeys = [ 'x', 'y', 'z' ];\nconst ZERO_EPSILON = 1e-15;\nconst ZERO_EPSILON_SQR = ZERO_EPSILON * ZERO_EPSILON;\nfunction isNearZero( value ) {\n\n\treturn Math.abs( value ) < ZERO_EPSILON;\n\n}\n\n/**\n * An extended version of three.js' Triangle class. A variety of derivative values are cached on\n * the object to accelerate the intersection functions. `.needsUpdate` must be set to true when\n * modifying the triangle parameters.\n * @extends Triangle\n */\nexport class ExtendedTriangle extends Triangle {\n\n\tconstructor( ...args ) {\n\n\t\tsuper( ...args );\n\n\t\tthis.isExtendedTriangle = true;\n\t\tthis.satAxes = new Array( 4 ).fill().map( () => new Vector3() );\n\t\tthis.satBounds = new Array( 4 ).fill().map( () => new SeparatingAxisBounds() );\n\t\tthis.points = [ this.a, this.b, this.c ];\n\t\tthis.plane = new Plane();\n\t\tthis.isDegenerateIntoSegment = false;\n\t\tthis.isDegenerateIntoPoint = false;\n\t\tthis.degenerateSegment = new Line3();\n\n\t\t/**\n\t\t * Indicates that the triangle fields have changed so cached variables to accelerate other\n\t\t * function execution can be updated. Must be set to true after modifying the triangle\n\t\t * `a`, `b`, `c` fields.\n\t\t * @type {boolean}\n\t\t */\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\t/**\n\t * Returns whether the triangle intersects the given sphere.\n\t * @param {Sphere} sphere\n\t * @returns {boolean}\n\t */\n\tintersectsSphere( sphere ) {\n\n\t\treturn sphereIntersectTriangle( sphere, this );\n\n\t}\n\n\tupdate() {\n\n\t\tconst a = this.a;\n\t\tconst b = this.b;\n\t\tconst c = this.c;\n\t\tconst points = this.points;\n\n\t\tconst satAxes = this.satAxes;\n\t\tconst satBounds = this.satBounds;\n\n\t\tconst axis0 = satAxes[ 0 ];\n\t\tconst sab0 = satBounds[ 0 ];\n\t\tthis.getNormal( axis0 );\n\t\tsab0.setFromPoints( axis0, points );\n\n\t\tconst axis1 = satAxes[ 1 ];\n\t\tconst sab1 = satBounds[ 1 ];\n\t\taxis1.subVectors( a, b );\n\t\tsab1.setFromPoints( axis1, points );\n\n\t\tconst axis2 = satAxes[ 2 ];\n\t\tconst sab2 = satBounds[ 2 ];\n\t\taxis2.subVectors( b, c );\n\t\tsab2.setFromPoints( axis2, points );\n\n\t\tconst axis3 = satAxes[ 3 ];\n\t\tconst sab3 = satBounds[ 3 ];\n\t\taxis3.subVectors( c, a );\n\t\tsab3.setFromPoints( axis3, points );\n\n\t\tconst lengthAB = axis1.length();\n\t\tconst lengthBC = axis2.length();\n\t\tconst lengthCA = axis3.length();\n\n\t\tthis.isDegenerateIntoPoint = false;\n\t\tthis.isDegenerateIntoSegment = false;\n\n\t\tif ( lengthAB < ZERO_EPSILON ) {\n\n\t\t\tif ( lengthBC < ZERO_EPSILON || lengthCA < ZERO_EPSILON ) {\n\n\t\t\t\tthis.isDegenerateIntoPoint = true;\n\n\t\t\t} else {\n\n\t\t\t\tthis.isDegenerateIntoSegment = true;\n\t\t\t\tthis.degenerateSegment.start.copy( a );\n\t\t\t\tthis.degenerateSegment.end.copy( c );\n\n\t\t\t}\n\n\t\t} else if ( lengthBC < ZERO_EPSILON ) {\n\n\t\t\tif ( lengthCA < ZERO_EPSILON ) {\n\n\t\t\t\tthis.isDegenerateIntoPoint = true;\n\n\t\t\t} else {\n\n\t\t\t\tthis.isDegenerateIntoSegment = true;\n\t\t\t\tthis.degenerateSegment.start.copy( b );\n\t\t\t\tthis.degenerateSegment.end.copy( a );\n\n\t\t\t}\n\n\t\t} else if ( lengthCA < ZERO_EPSILON ) {\n\n\t\t\tthis.isDegenerateIntoSegment = true;\n\t\t\tthis.degenerateSegment.start.copy( c );\n\t\t\tthis.degenerateSegment.end.copy( b );\n\n\t\t}\n\n\t\tthis.plane.setFromNormalAndCoplanarPoint( axis0, a );\n\n\t\tthis.needsUpdate = false;\n\n\t}\n\n}\n\n/**\n * Returns the distance to the provided line segment. `target1` and `target2` are set to the\n * closest points on the triangle and segment respectively.\n * @function\n * @param {Line3} segment\n * @param {Vector3} [target1]\n * @param {Vector3} [target2]\n * @returns {number}\n */\nExtendedTriangle.prototype.closestPointToSegment = ( function () {\n\n\tconst point1 = /* @__PURE__ */ new Vector3();\n\tconst point2 = /* @__PURE__ */ new Vector3();\n\tconst edge = /* @__PURE__ */ new Line3();\n\n\treturn function distanceToSegment( segment, target1 = null, target2 = null ) {\n\n\t\tconst { start, end } = segment;\n\t\tconst points = this.points;\n\t\tlet distSq;\n\t\tlet closestDistanceSq = Infinity;\n\n\t\t// check the triangle edges\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst nexti = ( i + 1 ) % 3;\n\t\t\tedge.start.copy( points[ i ] );\n\t\t\tedge.end.copy( points[ nexti ] );\n\n\t\t\tclosestPointsSegmentToSegment( edge, segment, point1, point2 );\n\n\t\t\tdistSq = point1.distanceToSquared( point2 );\n\t\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = distSq;\n\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// check end points\n\t\tthis.closestPointToPoint( start, point1 );\n\t\tdistSq = start.distanceToSquared( point1 );\n\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\tclosestDistanceSq = distSq;\n\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\tif ( target2 ) target2.copy( start );\n\n\t\t}\n\n\t\tthis.closestPointToPoint( end, point1 );\n\t\tdistSq = end.distanceToSquared( point1 );\n\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\tclosestDistanceSq = distSq;\n\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\tif ( target2 ) target2.copy( end );\n\n\t\t}\n\n\t\treturn Math.sqrt( closestDistanceSq );\n\n\t};\n\n} )();\n\n/**\n * Returns whether the triangles intersect. `target` is set to the line segment representing\n * the intersection.\n * @function\n * @param {Triangle} other\n * @param {Line3} [target]\n * @param {boolean} [suppressLog=false]\n * @returns {boolean}\n */\nExtendedTriangle.prototype.intersectsTriangle = ( function () {\n\n\tconst saTri2 = /* @__PURE__ */ new ExtendedTriangle();\n\tconst cachedSatBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst cachedSatBounds2 = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst tmpVec = /* @__PURE__ */ new Vector3();\n\tconst dir1 = /* @__PURE__ */ new Vector3();\n\tconst dir2 = /* @__PURE__ */ new Vector3();\n\tconst tempDir = /* @__PURE__ */ new Vector3();\n\tconst edge1 = /* @__PURE__ */ new Line3();\n\tconst edge2 = /* @__PURE__ */ new Line3();\n\tconst tempPoint = /* @__PURE__ */ new Vector3();\n\tconst bounds1 = /* @__PURE__ */ new Vector2();\n\tconst bounds2 = /* @__PURE__ */ new Vector2();\n\n\tfunction coplanarIntersectsTriangle( self, other, target, suppressLog ) {\n\n\t\t// Perform separating axis intersection test only for coplanar triangles\n\t\t// There should be at least one non-degenerate triangle when calling this\n\t\t// Otherwise we won't know the plane normal\n\t\tconst planeNormal = tmpVec;\n\t\tif ( ! self.isDegenerateIntoPoint && ! self.isDegenerateIntoSegment ) {\n\n\t\t\tplaneNormal.copy( self.plane.normal );\n\n\t\t} else {\n\n\t\t\tplaneNormal.copy( other.plane.normal );\n\n\t\t}\n\n\t\tconst satBounds1 = self.satBounds;\n\t\tconst satAxes1 = self.satAxes;\n\t\tfor ( let i = 1; i < 4; i ++ ) {\n\n\t\t\tconst sb = satBounds1[ i ];\n\t\t\tconst sa = satAxes1[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, other.points );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t\ttempDir.copy( planeNormal ).cross( sa );\n\t\t\tcachedSatBounds.setFromPoints( tempDir, self.points );\n\t\t\tcachedSatBounds2.setFromPoints( tempDir, other.points );\n\t\t\tif ( cachedSatBounds.isSeparated( cachedSatBounds2 ) ) return false;\n\n\t\t}\n\n\t\tconst satBounds2 = other.satBounds;\n\t\tconst satAxes2 = other.satAxes;\n\t\tfor ( let i = 1; i < 4; i ++ ) {\n\n\t\t\tconst sb = satBounds2[ i ];\n\t\t\tconst sa = satAxes2[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, self.points );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t\ttempDir.crossVectors( planeNormal, sa );\n\t\t\tcachedSatBounds.setFromPoints( tempDir, self.points );\n\t\t\tcachedSatBounds2.setFromPoints( tempDir, other.points );\n\t\t\tif ( cachedSatBounds.isSeparated( cachedSatBounds2 ) ) return false;\n\n\t\t}\n\n\t\tif ( target ) {\n\n\t\t\t// TODO find two points that intersect on the edges and make that the result\n\t\t\tif ( ! suppressLog ) {\n\n\t\t\t\tconsole.warn( 'ExtendedTriangle.intersectsTriangle: Triangles are coplanar which does not support an output edge. Setting edge to 0, 0, 0.' );\n\n\t\t\t}\n\n\t\t\ttarget.start.set( 0, 0, 0 );\n\t\t\ttarget.end.set( 0, 0, 0 );\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tfunction findSingleBounds( a, b, c, aProj, bProj, cProj, aDist, bDist, cDist, bounds, edge ) {\n\n\t\tlet t = aDist / ( aDist - bDist );\n\t\tbounds.x = aProj + ( bProj - aProj ) * t;\n\t\tedge.start.subVectors( b, a ).multiplyScalar( t ).add( a );\n\n\t\tt = aDist / ( aDist - cDist );\n\t\tbounds.y = aProj + ( cProj - aProj ) * t;\n\t\tedge.end.subVectors( c, a ).multiplyScalar( t ).add( a );\n\n\t}\n\n\t/**\n\t * Calculates intersection segment of a triangle with intersection line.\n\t * Intersection line is snapped to its biggest component.\n\t * And triangle points are passed as a projection on that component.\n\t * @returns {boolean} whether this is a coplanar case or not\n\t */\n\tfunction findIntersectionLineBounds( self, aProj, bProj, cProj, abDist, acDist, aDist, bDist, cDist, bounds, edge ) {\n\n\t\tif ( abDist > 0 ) {\n\n\t\t\t// then bcDist < 0\n\t\t\tfindSingleBounds( self.c, self.a, self.b, cProj, aProj, bProj, cDist, aDist, bDist, bounds, edge );\n\n\t\t} else if ( acDist > 0 ) {\n\n\t\t\tfindSingleBounds( self.b, self.a, self.c, bProj, aProj, cProj, bDist, aDist, cDist, bounds, edge );\n\n\t\t} else if ( bDist * cDist > 0 || aDist != 0 ) {\n\n\t\t\tfindSingleBounds( self.a, self.b, self.c, aProj, bProj, cProj, aDist, bDist, cDist, bounds, edge );\n\n\t\t} else if ( bDist != 0 ) {\n\n\t\t\tfindSingleBounds( self.b, self.a, self.c, bProj, aProj, cProj, bDist, aDist, cDist, bounds, edge );\n\n\t\t} else if ( cDist != 0 ) {\n\n\t\t\tfindSingleBounds( self.c, self.a, self.b, cProj, aProj, bProj, cDist, aDist, bDist, bounds, edge );\n\n\t\t} else {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\tfunction intersectTriangleSegment( triangle, degenerateTriangle, target, suppressLog ) {\n\n\t\tconst segment = degenerateTriangle.degenerateSegment;\n\t\tconst startDist = triangle.plane.distanceToPoint( segment.start );\n\t\tconst endDist = triangle.plane.distanceToPoint( segment.end );\n\t\tif ( isNearZero( startDist ) ) {\n\n\t\t\tif ( isNearZero( endDist ) ) {\n\n\t\t\t\treturn coplanarIntersectsTriangle( triangle, degenerateTriangle, target, suppressLog );\n\n\t\t\t} else {\n\n\t\t\t\t// Is this fine to modify target even if there might be no intersection?\n\t\t\t\tif ( target ) {\n\n\t\t\t\t\ttarget.start.copy( segment.start );\n\t\t\t\t\ttarget.end.copy( segment.start );\n\n\t\t\t\t}\n\n\t\t\t\treturn triangle.containsPoint( segment.start );\n\n\t\t\t}\n\n\t\t} else if ( isNearZero( endDist ) ) {\n\n\t\t\tif ( target ) {\n\n\t\t\t\ttarget.start.copy( segment.end );\n\t\t\t\ttarget.end.copy( segment.end );\n\n\t\t\t}\n\n\t\t\treturn triangle.containsPoint( segment.end );\n\n\t\t} else {\n\n\t\t\tif ( triangle.plane.intersectLine( segment, tmpVec ) != null ) {\n\n\t\t\t\tif ( target ) {\n\n\t\t\t\t\ttarget.start.copy( tmpVec );\n\t\t\t\t\ttarget.end.copy( tmpVec );\n\n\t\t\t\t}\n\n\t\t\t\treturn triangle.containsPoint( tmpVec );\n\n\t\t\t} else {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tfunction intersectTrianglePoint( triangle, degenerateTriangle, target ) {\n\n\t\tconst point = degenerateTriangle.a;\n\n\t\tif ( isNearZero( triangle.plane.distanceToPoint( point ) ) && triangle.containsPoint( point ) ) {\n\n\t\t\tif ( target ) {\n\n\t\t\t\ttarget.start.copy( point );\n\t\t\t\ttarget.end.copy( point );\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t} else {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t}\n\n\tfunction intersectSegmentPoint( segmentTri, pointTri, target ) {\n\n\t\tconst segment = segmentTri.degenerateSegment;\n\t\tconst point = pointTri.a;\n\n\t\tsegment.closestPointToPoint( point, true, tmpVec );\n\n\t\tif ( point.distanceToSquared( tmpVec ) < ZERO_EPSILON_SQR ) {\n\n\t\t\tif ( target ) {\n\n\t\t\t\ttarget.start.copy( point );\n\t\t\t\ttarget.end.copy( point );\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t} else {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t}\n\n\tfunction handleDegenerateCases( self, other, target, suppressLog ) {\n\n\t\tif ( self.isDegenerateIntoSegment ) {\n\n\t\t\tif ( other.isDegenerateIntoSegment ) {\n\n\t\t\t\t// TODO: replace with Line.distanceSqToLine3 after r179\n\t\t\t\tconst segment1 = self.degenerateSegment;\n\t\t\t\tconst segment2 = other.degenerateSegment;\n\t\t\t\tconst delta1 = dir1;\n\t\t\t\tconst delta2 = dir2;\n\t\t\t\tsegment1.delta( delta1 );\n\t\t\t\tsegment2.delta( delta2 );\n\t\t\t\tconst startDelta = tmpVec.subVectors( segment2.start, segment1.start );\n\n\t\t\t\tconst denom = delta1.x * delta2.y - delta1.y * delta2.x;\n\t\t\t\tif ( isNearZero( denom ) ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t\tconst t = ( startDelta.x * delta2.y - startDelta.y * delta2.x ) / denom;\n\t\t\t\tconst u = - ( delta1.x * startDelta.y - delta1.y * startDelta.x ) / denom;\n\n\t\t\t\tif ( t < 0 || t > 1 || u < 0 || u > 1 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t\tconst z1 = segment1.start.z + delta1.z * t;\n\t\t\t\tconst z2 = segment2.start.z + delta2.z * u;\n\n\t\t\t\tif ( isNearZero( z1 - z2 ) ) {\n\n\t\t\t\t\tif ( target ) {\n\n\t\t\t\t\t\ttarget.start.copy( segment1.start ).addScaledVector( delta1, t );\n\t\t\t\t\t\ttarget.end.copy( segment1.start ).addScaledVector( delta1, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} else if ( other.isDegenerateIntoPoint ) {\n\n\t\t\t\treturn intersectSegmentPoint( self, other, target );\n\n\t\t\t} else {\n\n\t\t\t\treturn intersectTriangleSegment( other, self, target, suppressLog );\n\n\t\t\t}\n\n\t\t} else if ( self.isDegenerateIntoPoint ) {\n\n\t\t\tif ( other.isDegenerateIntoPoint ) {\n\n\t\t\t\tif ( other.a.distanceToSquared( self.a ) < ZERO_EPSILON_SQR ) {\n\n\t\t\t\t\tif ( target ) {\n\n\t\t\t\t\t\ttarget.start.copy( self.a );\n\t\t\t\t\t\ttarget.end.copy( self.a );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} else if ( other.isDegenerateIntoSegment ) {\n\n\t\t\t\treturn intersectSegmentPoint( other, self, target );\n\n\t\t\t} else {\n\n\t\t\t\treturn intersectTrianglePoint( other, self, target );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tif ( other.isDegenerateIntoPoint ) {\n\n\t\t\t\treturn intersectTrianglePoint( self, other, target );\n\n\t\t\t} else if ( other.isDegenerateIntoSegment ) {\n\n\t\t\t\treturn intersectTriangleSegment( self, other, target, suppressLog );\n\n\t\t\t} /* else this is a general triangle-traingle case, so return undefined */\n\n\t\t}\n\n\t}\n\n\t/* TODO: If the triangles are coplanar and intersecting the target is nonsensical. It should at least\n\t * be a line contained by both triangles if not a different special case somehow represented in the return result.\n\t *\n\t * General triangle intersection code is based on Moller's algorithm from here: https://web.stanford.edu/class/cs277/resources/papers/Moller1997b.pdf\n\t * Reference implementation from here: https://github.com/erich666/jgt-code/blob/master/Volume_08/Number_1/Shen2003/tri_tri_test/include/Moller97.c#L570\n\t * All degeneracies are handled before the general algorithm.\n\t * Coplanar check is different from Moller's and based on SAT tests.\n\t */\n\treturn function intersectsTriangle( other, target = null, suppressLog = false ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tif ( ! other.isExtendedTriangle ) {\n\n\t\t\tsaTri2.copy( other );\n\t\t\tsaTri2.update();\n\t\t\tother = saTri2;\n\n\t\t} else if ( other.needsUpdate ) {\n\n\t\t\tother.update();\n\n\t\t}\n\n\t\tconst res = handleDegenerateCases( this, other, target, suppressLog );\n\t\tif ( res !== undefined ) {\n\n\t\t\treturn res;\n\n\t\t}\n\n\t\tconst plane1 = this.plane;\n\t\tconst plane2 = other.plane;\n\n\t\tlet a1Dist = plane2.distanceToPoint( this.a );\n\t\tlet b1Dist = plane2.distanceToPoint( this.b );\n\t\tlet c1Dist = plane2.distanceToPoint( this.c );\n\n\t\tif ( isNearZero( a1Dist ) )\n\t\t\ta1Dist = 0;\n\n\t\tif ( isNearZero( b1Dist ) )\n\t\t\tb1Dist = 0;\n\n\t\tif ( isNearZero( c1Dist ) )\n\t\t\tc1Dist = 0;\n\n\t\tconst a1b1Dist = a1Dist * b1Dist;\n\t\tconst a1c1Dist = a1Dist * c1Dist;\n\t\tif ( a1b1Dist > 0 && a1c1Dist > 0 ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tlet a2Dist = plane1.distanceToPoint( other.a );\n\t\tlet b2Dist = plane1.distanceToPoint( other.b );\n\t\tlet c2Dist = plane1.distanceToPoint( other.c );\n\n\t\tif ( isNearZero( a2Dist ) )\n\t\t\ta2Dist = 0;\n\n\t\tif ( isNearZero( b2Dist ) )\n\t\t\tb2Dist = 0;\n\n\t\tif ( isNearZero( c2Dist ) )\n\t\t\tc2Dist = 0;\n\n\t\tconst a2b2Dist = a2Dist * b2Dist;\n\t\tconst a2c2Dist = a2Dist * c2Dist;\n\t\tif ( a2b2Dist > 0 && a2c2Dist > 0 ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tdir1.copy( plane1.normal );\n\t\tdir2.copy( plane2.normal );\n\t\tconst intersectionLine = dir1.cross( dir2 );\n\n\t\tlet componentIndex = 0;\n\t\tlet maxComponent = Math.abs( intersectionLine.x );\n\t\tconst comp1 = Math.abs( intersectionLine.y );\n\t\tif ( comp1 > maxComponent ) {\n\n\t\t\tmaxComponent = comp1;\n\t\t\tcomponentIndex = 1;\n\n\t\t}\n\n\t\tconst comp2 = Math.abs( intersectionLine.z );\n\t\tif ( comp2 > maxComponent ) {\n\n\t\t\tcomponentIndex = 2;\n\n\t\t}\n\n\t\tconst key = componentKeys[ componentIndex ];\n\t\tconst a1Proj = this.a[ key ];\n\t\tconst b1Proj = this.b[ key ];\n\t\tconst c1Proj = this.c[ key ];\n\n\t\tconst a2Proj = other.a[ key ];\n\t\tconst b2Proj = other.b[ key ];\n\t\tconst c2Proj = other.c[ key ];\n\n\t\tif ( findIntersectionLineBounds( this, a1Proj, b1Proj, c1Proj, a1b1Dist, a1c1Dist, a1Dist, b1Dist, c1Dist, bounds1, edge1 ) ) {\n\n\t\t\treturn coplanarIntersectsTriangle( this, other, target, suppressLog );\n\n\t\t}\n\n\t\tif ( findIntersectionLineBounds( other, a2Proj, b2Proj, c2Proj, a2b2Dist, a2c2Dist, a2Dist, b2Dist, c2Dist, bounds2, edge2 ) ) {\n\n\t\t\treturn coplanarIntersectsTriangle( this, other, target, suppressLog );\n\n\t\t}\n\n\t\tif ( bounds1.y < bounds1.x ) {\n\n\t\t\tconst tmp = bounds1.y;\n\t\t\tbounds1.y = bounds1.x;\n\t\t\tbounds1.x = tmp;\n\n\t\t\ttempPoint.copy( edge1.start );\n\t\t\tedge1.start.copy( edge1.end );\n\t\t\tedge1.end.copy( tempPoint );\n\n\t\t}\n\n\t\tif ( bounds2.y < bounds2.x ) {\n\n\t\t\tconst tmp = bounds2.y;\n\t\t\tbounds2.y = bounds2.x;\n\t\t\tbounds2.x = tmp;\n\n\t\t\ttempPoint.copy( edge2.start );\n\t\t\tedge2.start.copy( edge2.end );\n\t\t\tedge2.end.copy( tempPoint );\n\n\t\t}\n\n\t\tif ( bounds1.y < bounds2.x || bounds2.y < bounds1.x ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tif ( target ) {\n\n\t\t\tif ( bounds2.x > bounds1.x ) {\n\n\t\t\t\ttarget.start.copy( edge2.start );\n\n\t\t\t} else {\n\n\t\t\t\ttarget.start.copy( edge1.start );\n\n\t\t\t}\n\n\t\t\tif ( bounds2.y < bounds1.y ) {\n\n\t\t\t\ttarget.end.copy( edge2.end );\n\n\t\t\t} else {\n\n\t\t\t\ttarget.end.copy( edge1.end );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t};\n\n} )();\n\n\n/**\n * Returns the distance to the provided point.\n * @function\n * @param {Vector3} point\n * @returns {number}\n */\nExtendedTriangle.prototype.distanceToPoint = ( function () {\n\n\tconst target = /* @__PURE__ */ new Vector3();\n\treturn function distanceToPoint( point ) {\n\n\t\tthis.closestPointToPoint( point, target );\n\t\treturn point.distanceTo( target );\n\n\t};\n\n} )();\n\n\n/**\n * Returns the distance to the provided triangle.\n * @function\n * @param {Triangle} other\n * @param {Vector3} [target1]\n * @param {Vector3} [target2]\n * @returns {number}\n */\nExtendedTriangle.prototype.distanceToTriangle = ( function () {\n\n\tconst point = /* @__PURE__ */ new Vector3();\n\tconst point2 = /* @__PURE__ */ new Vector3();\n\tconst cornerFields = [ 'a', 'b', 'c' ];\n\tconst line1 = /* @__PURE__ */ new Line3();\n\tconst line2 = /* @__PURE__ */ new Line3();\n\n\treturn function distanceToTriangle( other, target1 = null, target2 = null ) {\n\n\t\tconst lineTarget = target1 || target2 ? line1 : null;\n\t\t// `intersectsTriangle` returns a zero-length segment for coplanar\n\t\t// intersecting triangles, which is fine for our purposes here. We\n\t\t// don't need the segment itself in this function. So we can suppress\n\t\t// the warning about coplanar triangles.\n\t\tif ( this.intersectsTriangle( other, lineTarget, true ) ) {\n\n\t\t\tif ( target1 || target2 ) {\n\n\t\t\t\tif ( target1 ) lineTarget.getCenter( target1 );\n\t\t\t\tif ( target2 ) lineTarget.getCenter( target2 );\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t\tlet closestDistanceSq = Infinity;\n\n\t\t// check all point distances\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tlet dist;\n\t\t\tconst field = cornerFields[ i ];\n\t\t\tconst otherVec = other[ field ];\n\t\t\tthis.closestPointToPoint( otherVec, point );\n\n\t\t\tdist = otherVec.distanceToSquared( point );\n\n\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\tif ( target1 ) target1.copy( point );\n\t\t\t\tif ( target2 ) target2.copy( otherVec );\n\n\t\t\t}\n\n\n\t\t\tconst thisVec = this[ field ];\n\t\t\tother.closestPointToPoint( thisVec, point );\n\n\t\t\tdist = thisVec.distanceToSquared( point );\n\n\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\tif ( target1 ) target1.copy( thisVec );\n\t\t\t\tif ( target2 ) target2.copy( point );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst f11 = cornerFields[ i ];\n\t\t\tconst f12 = cornerFields[ ( i + 1 ) % 3 ];\n\t\t\tline1.set( this[ f11 ], this[ f12 ] );\n\t\t\tfor ( let i2 = 0; i2 < 3; i2 ++ ) {\n\n\t\t\t\tconst f21 = cornerFields[ i2 ];\n\t\t\t\tconst f22 = cornerFields[ ( i2 + 1 ) % 3 ];\n\t\t\t\tline2.set( other[ f21 ], other[ f22 ] );\n\n\t\t\t\tclosestPointsSegmentToSegment( line1, line2, point, point2 );\n\n\t\t\t\tconst dist = point.distanceToSquared( point2 );\n\t\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\t\tif ( target1 ) target1.copy( point );\n\t\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Math.sqrt( closestDistanceSq );\n\n\t};\n\n} )();\n","/** @import { Box3, Triangle } from 'three' */\nimport { Vector3, Matrix4, Line3 } from 'three';\nimport { SeparatingAxisBounds } from './SeparatingAxisBounds.js';\nimport { ExtendedTriangle } from './ExtendedTriangle.js';\nimport { closestPointsSegmentToSegment } from './MathUtilities.js';\n\n/**\n * An oriented version of three.js' Box3 class. A variety of derivative values are cached on the\n * object to accelerate the intersection functions. `.needsUpdate` must be set to true when\n * modifying the box parameters.\n *\n * @param {Vector3} [min]\n * @param {Vector3} [max]\n * @param {Matrix4} [matrix]\n */\nexport class OrientedBox {\n\n\tconstructor( min, max, matrix ) {\n\n\t\tthis.isOrientedBox = true;\n\n\t\t/** @type {Vector3} */\n\t\tthis.min = new Vector3();\n\n\t\t/** @type {Vector3} */\n\t\tthis.max = new Vector3();\n\n\t\t/**\n\t\t * Matrix transformation applied to the box.\n\t\t * @type {Matrix4}\n\t\t */\n\t\tthis.matrix = new Matrix4();\n\t\tthis.invMatrix = new Matrix4();\n\t\tthis.points = new Array( 8 ).fill().map( () => new Vector3() );\n\t\tthis.satAxes = new Array( 3 ).fill().map( () => new Vector3() );\n\t\tthis.satBounds = new Array( 3 ).fill().map( () => new SeparatingAxisBounds() );\n\t\tthis.alignedSatBounds = new Array( 3 ).fill().map( () => new SeparatingAxisBounds() );\n\t\t/**\n\t\t * Indicates that the bounding box fields have changed so cached variables to accelerate\n\t\t * other function execution can be updated. Must be set to true after modifying the\n\t\t * oriented box `min`, `max`, `matrix` fields.\n\t\t * @type {boolean}\n\t\t */\n\t\tthis.needsUpdate = false;\n\n\t\tif ( min ) this.min.copy( min );\n\t\tif ( max ) this.max.copy( max );\n\t\tif ( matrix ) this.matrix.copy( matrix );\n\n\t}\n\n\t/**\n\t * Sets the oriented box parameters.\n\t * @param {Vector3} min\n\t * @param {Vector3} max\n\t * @param {Matrix4} matrix\n\t */\n\tset( min, max, matrix ) {\n\n\t\tthis.min.copy( min );\n\t\tthis.max.copy( max );\n\t\tthis.matrix.copy( matrix );\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tcopy( other ) {\n\n\t\tthis.min.copy( other.min );\n\t\tthis.max.copy( other.max );\n\t\tthis.matrix.copy( other.matrix );\n\t\tthis.needsUpdate = true;\n\n\t}\n\n}\n\nOrientedBox.prototype.update = ( function () {\n\n\treturn function update() {\n\n\t\tconst matrix = this.matrix;\n\t\tconst min = this.min;\n\t\tconst max = this.max;\n\n\t\tconst points = this.points;\n\t\tfor ( let x = 0; x <= 1; x ++ ) {\n\n\t\t\tfor ( let y = 0; y <= 1; y ++ ) {\n\n\t\t\t\tfor ( let z = 0; z <= 1; z ++ ) {\n\n\t\t\t\t\tconst i = ( ( 1 << 0 ) * x ) | ( ( 1 << 1 ) * y ) | ( ( 1 << 2 ) * z );\n\t\t\t\t\tconst v = points[ i ];\n\t\t\t\t\tv.x = x ? max.x : min.x;\n\t\t\t\t\tv.y = y ? max.y : min.y;\n\t\t\t\t\tv.z = z ? max.z : min.z;\n\n\t\t\t\t\tv.applyMatrix4( matrix );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst satBounds = this.satBounds;\n\t\tconst satAxes = this.satAxes;\n\t\tconst minVec = points[ 0 ];\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst axis = satAxes[ i ];\n\t\t\tconst sb = satBounds[ i ];\n\t\t\tconst index = 1 << i;\n\t\t\tconst pi = points[ index ];\n\n\t\t\taxis.subVectors( minVec, pi );\n\t\t\tsb.setFromPoints( axis, points );\n\n\t\t}\n\n\t\tconst alignedSatBounds = this.alignedSatBounds;\n\t\talignedSatBounds[ 0 ].setFromPointsField( points, 'x' );\n\t\talignedSatBounds[ 1 ].setFromPointsField( points, 'y' );\n\t\talignedSatBounds[ 2 ].setFromPointsField( points, 'z' );\n\n\t\tthis.invMatrix.copy( this.matrix ).invert();\n\t\tthis.needsUpdate = false;\n\n\t};\n\n} )();\n\n/**\n * Returns true if intersecting with the provided box.\n * @function\n * @param {Box3} box\n * @returns {boolean}\n */\nOrientedBox.prototype.intersectsBox = ( function () {\n\n\tconst aabbBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\treturn function intersectsBox( box ) {\n\n\t\t// TODO: should this be doing SAT against the AABB?\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tconst min = box.min;\n\t\tconst max = box.max;\n\t\tconst satBounds = this.satBounds;\n\t\tconst satAxes = this.satAxes;\n\t\tconst alignedSatBounds = this.alignedSatBounds;\n\n\t\taabbBounds.min = min.x;\n\t\taabbBounds.max = max.x;\n\t\tif ( alignedSatBounds[ 0 ].isSeparated( aabbBounds ) ) return false;\n\n\t\taabbBounds.min = min.y;\n\t\taabbBounds.max = max.y;\n\t\tif ( alignedSatBounds[ 1 ].isSeparated( aabbBounds ) ) return false;\n\n\t\taabbBounds.min = min.z;\n\t\taabbBounds.max = max.z;\n\t\tif ( alignedSatBounds[ 2 ].isSeparated( aabbBounds ) ) return false;\n\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst axis = satAxes[ i ];\n\t\t\tconst sb = satBounds[ i ];\n\t\t\taabbBounds.setFromBox( axis, box );\n\t\t\tif ( sb.isSeparated( aabbBounds ) ) return false;\n\n\t\t}\n\n\t\treturn true;\n\n\t};\n\n} )();\n\n/**\n * Returns true if intersecting with the provided triangle.\n * @function\n * @param {Triangle} triangle\n * @returns {boolean}\n */\nOrientedBox.prototype.intersectsTriangle = ( function () {\n\n\tconst saTri = /* @__PURE__ */ new ExtendedTriangle();\n\tconst pointsArr = /* @__PURE__ */ new Array( 3 );\n\tconst cachedSatBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst cachedSatBounds2 = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst cachedAxis = /* @__PURE__ */ new Vector3();\n\treturn function intersectsTriangle( triangle ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tif ( ! triangle.isExtendedTriangle ) {\n\n\t\t\tsaTri.copy( triangle );\n\t\t\tsaTri.update();\n\t\t\ttriangle = saTri;\n\n\t\t} else if ( triangle.needsUpdate ) {\n\n\t\t\ttriangle.update();\n\n\t\t}\n\n\t\tconst satBounds = this.satBounds;\n\t\tconst satAxes = this.satAxes;\n\n\t\tpointsArr[ 0 ] = triangle.a;\n\t\tpointsArr[ 1 ] = triangle.b;\n\t\tpointsArr[ 2 ] = triangle.c;\n\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = satBounds[ i ];\n\t\t\tconst sa = satAxes[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, pointsArr );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t}\n\n\t\tconst triSatBounds = triangle.satBounds;\n\t\tconst triSatAxes = triangle.satAxes;\n\t\tconst points = this.points;\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = triSatBounds[ i ];\n\t\t\tconst sa = triSatAxes[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, points );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t}\n\n\t\t// check crossed axes\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sa1 = satAxes[ i ];\n\t\t\tfor ( let i2 = 0; i2 < 4; i2 ++ ) {\n\n\t\t\t\tconst sa2 = triSatAxes[ i2 ];\n\t\t\t\tcachedAxis.crossVectors( sa1, sa2 );\n\t\t\t\tcachedSatBounds.setFromPoints( cachedAxis, pointsArr );\n\t\t\t\tcachedSatBounds2.setFromPoints( cachedAxis, points );\n\t\t\t\tif ( cachedSatBounds.isSeparated( cachedSatBounds2 ) ) return false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t};\n\n} )();\n\n/**\n * Returns the distance to the provided point. Sets `target` to the closest point on the surface\n * of the box if provided.\n * @function\n * @param {Vector3} point\n * @param {Vector3} target\n * @returns {number}\n */\nOrientedBox.prototype.closestPointToPoint = ( function () {\n\n\treturn function closestPointToPoint( point, target1 ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\ttarget1\n\t\t\t.copy( point )\n\t\t\t.applyMatrix4( this.invMatrix )\n\t\t\t.clamp( this.min, this.max )\n\t\t\t.applyMatrix4( this.matrix );\n\n\t\treturn target1;\n\n\t};\n\n} )();\n\n/**\n * Returns the distance to the provided point.\n * @function\n * @param {Vector3} point\n * @returns {number}\n */\nOrientedBox.prototype.distanceToPoint = ( function () {\n\n\tconst target = new Vector3();\n\treturn function distanceToPoint( point ) {\n\n\t\tthis.closestPointToPoint( point, target );\n\t\treturn point.distanceTo( target );\n\n\t};\n\n} )();\n\n/**\n * Returns the distance to the provided box. `threshold` is an optional distance to return early\n * if the distance is found to be within it. `target1` and `target2` are set to the points on the\n * surface of this box and the `box` argument respectively.\n * @function\n * @param {Box3} box\n * @param {number} [threshold=0]\n * @param {Vector3} [target1]\n * @param {Vector3} [target2]\n * @returns {number}\n */\nOrientedBox.prototype.distanceToBox = ( function () {\n\n\tconst xyzFields = [ 'x', 'y', 'z' ];\n\tconst segments1 = /* @__PURE__ */ new Array( 12 ).fill().map( () => new Line3() );\n\tconst segments2 = /* @__PURE__ */ new Array( 12 ).fill().map( () => new Line3() );\n\n\tconst point1 = /* @__PURE__ */ new Vector3();\n\tconst point2 = /* @__PURE__ */ new Vector3();\n\n\t// early out if we find a value below threshold\n\treturn function distanceToBox( box, threshold = 0, target1 = null, target2 = null ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tif ( this.intersectsBox( box ) ) {\n\n\t\t\tif ( target1 || target2 ) {\n\n\t\t\t\tbox.getCenter( point2 );\n\t\t\t\tthis.closestPointToPoint( point2, point1 );\n\t\t\t\tbox.closestPointToPoint( point1, point2 );\n\n\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t\tconst threshold2 = threshold * threshold;\n\t\tconst min = box.min;\n\t\tconst max = box.max;\n\t\tconst points = this.points;\n\n\n\t\t// iterate over every edge and compare distances\n\t\tlet closestDistanceSq = Infinity;\n\n\t\t// check over all these points\n\t\tfor ( let i = 0; i < 8; i ++ ) {\n\n\t\t\tconst p = points[ i ];\n\t\t\tpoint2.copy( p ).clamp( min, max );\n\n\t\t\tconst dist = p.distanceToSquared( point2 );\n\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\tif ( target1 ) target1.copy( p );\n\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\tif ( dist < threshold2 ) return Math.sqrt( dist );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate and check all line segment distances\n\t\tlet count = 0;\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tfor ( let i1 = 0; i1 <= 1; i1 ++ ) {\n\n\t\t\t\tfor ( let i2 = 0; i2 <= 1; i2 ++ ) {\n\n\t\t\t\t\tconst nextIndex = ( i + 1 ) % 3;\n\t\t\t\t\tconst nextIndex2 = ( i + 2 ) % 3;\n\n\t\t\t\t\t// get obb line segments\n\t\t\t\t\tconst index = i1 << nextIndex | i2 << nextIndex2;\n\t\t\t\t\tconst index2 = 1 << i | i1 << nextIndex | i2 << nextIndex2;\n\t\t\t\t\tconst p1 = points[ index ];\n\t\t\t\t\tconst p2 = points[ index2 ];\n\t\t\t\t\tconst line1 = segments1[ count ];\n\t\t\t\t\tline1.set( p1, p2 );\n\n\n\t\t\t\t\t// get aabb line segments\n\t\t\t\t\tconst f1 = xyzFields[ i ];\n\t\t\t\t\tconst f2 = xyzFields[ nextIndex ];\n\t\t\t\t\tconst f3 = xyzFields[ nextIndex2 ];\n\t\t\t\t\tconst line2 = segments2[ count ];\n\t\t\t\t\tconst start = line2.start;\n\t\t\t\t\tconst end = line2.end;\n\n\t\t\t\t\tstart[ f1 ] = min[ f1 ];\n\t\t\t\t\tstart[ f2 ] = i1 ? min[ f2 ] : max[ f2 ];\n\t\t\t\t\tstart[ f3 ] = i2 ? min[ f3 ] : max[ f2 ];\n\n\t\t\t\t\tend[ f1 ] = max[ f1 ];\n\t\t\t\t\tend[ f2 ] = i1 ? min[ f2 ] : max[ f2 ];\n\t\t\t\t\tend[ f3 ] = i2 ? min[ f3 ] : max[ f2 ];\n\n\t\t\t\t\tcount ++;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// check all the other boxes point\n\t\tfor ( let x = 0; x <= 1; x ++ ) {\n\n\t\t\tfor ( let y = 0; y <= 1; y ++ ) {\n\n\t\t\t\tfor ( let z = 0; z <= 1; z ++ ) {\n\n\t\t\t\t\tpoint2.x = x ? max.x : min.x;\n\t\t\t\t\tpoint2.y = y ? max.y : min.y;\n\t\t\t\t\tpoint2.z = z ? max.z : min.z;\n\n\t\t\t\t\tthis.closestPointToPoint( point2, point1 );\n\t\t\t\t\tconst dist = point2.distanceToSquared( point1 );\n\t\t\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\t\t\tif ( dist < threshold2 ) return Math.sqrt( dist );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( let i = 0; i < 12; i ++ ) {\n\n\t\t\tconst l1 = segments1[ i ];\n\t\t\tfor ( let i2 = 0; i2 < 12; i2 ++ ) {\n\n\t\t\t\tconst l2 = segments2[ i2 ];\n\t\t\t\tclosestPointsSegmentToSegment( l1, l2, point1, point2 );\n\t\t\t\tconst dist = point1.distanceToSquared( point2 );\n\t\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\t\tif ( dist < threshold2 ) return Math.sqrt( dist );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Math.sqrt( closestDistanceSq );\n\n\t};\n\n} )();\n","import { ExtendedTriangle } from '../math/ExtendedTriangle.js';\nimport { PrimitivePool } from './PrimitivePool.js';\n\nclass ExtendedTrianglePoolBase extends PrimitivePool {\n\n\tconstructor() {\n\n\t\tsuper( () => new ExtendedTriangle() );\n\n\t}\n\n}\n\nexport const ExtendedTrianglePool = /* @__PURE__ */ new ExtendedTrianglePoolBase();\n","import { Vector3 } from 'three';\n\nconst temp = /* @__PURE__ */ new Vector3();\nconst temp1 = /* @__PURE__ */ new Vector3();\n\nexport function closestPointToPoint(\n\tbvh,\n\tpoint,\n\ttarget = { },\n\tminThreshold = 0,\n\tmaxThreshold = Infinity,\n) {\n\n\t// early out if under minThreshold\n\t// skip checking if over maxThreshold\n\t// set minThreshold = maxThreshold to quickly check if a point is within a threshold\n\t// returns Infinity if no value found\n\tconst minThresholdSq = minThreshold * minThreshold;\n\tconst maxThresholdSq = maxThreshold * maxThreshold;\n\tlet closestDistanceSq = Infinity;\n\tlet closestDistanceTriIndex = null;\n\tbvh.shapecast(\n\n\t\t{\n\n\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\ttemp.copy( point ).clamp( box.min, box.max );\n\t\t\t\treturn temp.distanceToSquared( point );\n\n\t\t\t},\n\n\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\treturn score < closestDistanceSq && score < maxThresholdSq;\n\n\t\t\t},\n\n\t\t\tintersectsTriangle: ( tri, triIndex ) => {\n\n\t\t\t\ttri.closestPointToPoint( point, temp );\n\t\t\t\tconst distSq = point.distanceToSquared( temp );\n\t\t\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\t\t\ttemp1.copy( temp );\n\t\t\t\t\tclosestDistanceSq = distSq;\n\t\t\t\t\tclosestDistanceTriIndex = triIndex;\n\n\t\t\t\t}\n\n\t\t\t\tif ( distSq < minThresholdSq ) {\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t}\n\n\t);\n\n\tif ( closestDistanceSq === Infinity ) return null;\n\n\tconst closestDistance = Math.sqrt( closestDistanceSq );\n\n\tif ( ! target.point ) target.point = temp1.clone();\n\telse target.point.copy( temp1 );\n\ttarget.distance = closestDistance,\n\ttarget.faceIndex = closestDistanceTriIndex;\n\n\treturn target;\n\n}\n","import { Vector3, Vector2, Triangle, DoubleSide, BackSide, REVISION } from 'three';\n\nconst IS_GT_REVISION_169 = parseInt( REVISION ) >= 169;\nconst IS_LT_REVISION_161 = parseInt( REVISION ) <= 161;\n\n// Ripped and modified From THREE.js Mesh raycast\n// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L115\nconst _vA = /* @__PURE__ */ new Vector3();\nconst _vB = /* @__PURE__ */ new Vector3();\nconst _vC = /* @__PURE__ */ new Vector3();\n\nconst _uvA = /* @__PURE__ */ new Vector2();\nconst _uvB = /* @__PURE__ */ new Vector2();\nconst _uvC = /* @__PURE__ */ new Vector2();\n\nconst _normalA = /* @__PURE__ */ new Vector3();\nconst _normalB = /* @__PURE__ */ new Vector3();\nconst _normalC = /* @__PURE__ */ new Vector3();\n\nconst _intersectionPoint = /* @__PURE__ */ new Vector3();\nfunction checkIntersection( ray, pA, pB, pC, point, side, near, far ) {\n\n\tlet intersect;\n\tif ( side === BackSide ) {\n\n\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t} else {\n\n\t\tintersect = ray.intersectTriangle( pA, pB, pC, side !== DoubleSide, point );\n\n\t}\n\n\tif ( intersect === null ) return null;\n\n\tconst distance = ray.origin.distanceTo( point );\n\n\tif ( distance < near || distance > far ) return null;\n\n\treturn {\n\n\t\tdistance: distance,\n\t\tpoint: point.clone(),\n\n\t};\n\n}\n\nfunction checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side, near, far ) {\n\n\t_vA.fromBufferAttribute( position, a );\n\t_vB.fromBufferAttribute( position, b );\n\t_vC.fromBufferAttribute( position, c );\n\n\tconst intersection = checkIntersection( ray, _vA, _vB, _vC, _intersectionPoint, side, near, far );\n\n\tif ( intersection ) {\n\n\t\tif ( uv ) {\n\n\t\t\t_uvA.fromBufferAttribute( uv, a );\n\t\t\t_uvB.fromBufferAttribute( uv, b );\n\t\t\t_uvC.fromBufferAttribute( uv, c );\n\n\t\t\tintersection.uv = new Vector2();\n\t\t\tconst res = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, intersection.uv );\n\t\t\tif ( ! IS_GT_REVISION_169 ) {\n\n\t\t\t\tintersection.uv = res;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( uv1 ) {\n\n\t\t\t_uvA.fromBufferAttribute( uv1, a );\n\t\t\t_uvB.fromBufferAttribute( uv1, b );\n\t\t\t_uvC.fromBufferAttribute( uv1, c );\n\n\t\t\tintersection.uv1 = new Vector2();\n\t\t\tconst res = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, intersection.uv1 );\n\t\t\tif ( ! IS_GT_REVISION_169 ) {\n\n\t\t\t\tintersection.uv1 = res;\n\n\t\t\t}\n\n\t\t\tif ( IS_LT_REVISION_161 ) {\n\n\t\t\t\tintersection.uv2 = intersection.uv1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( normal ) {\n\n\t\t\t_normalA.fromBufferAttribute( normal, a );\n\t\t\t_normalB.fromBufferAttribute( normal, b );\n\t\t\t_normalC.fromBufferAttribute( normal, c );\n\n\t\t\tintersection.normal = new Vector3();\n\t\t\tconst res = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _normalA, _normalB, _normalC, intersection.normal );\n\t\t\tif ( intersection.normal.dot( ray.direction ) > 0 ) {\n\n\t\t\t\tintersection.normal.multiplyScalar( - 1 );\n\n\t\t\t}\n\n\t\t\tif ( ! IS_GT_REVISION_169 ) {\n\n\t\t\t\tintersection.normal = res;\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst face = {\n\t\t\ta: a,\n\t\t\tb: b,\n\t\t\tc: c,\n\t\t\tnormal: new Vector3(),\n\t\t\tmaterialIndex: 0\n\t\t};\n\n\t\tTriangle.getNormal( _vA, _vB, _vC, face.normal );\n\n\t\tintersection.face = face;\n\t\tintersection.faceIndex = a;\n\n\t\tif ( IS_GT_REVISION_169 ) {\n\n\t\t\tconst barycoord = new Vector3();\n\t\t\tTriangle.getBarycoord( _intersectionPoint, _vA, _vB, _vC, barycoord );\n\n\t\t\tintersection.barycoord = barycoord;\n\n\t\t}\n\n\t}\n\n\treturn intersection;\n\n}\n\nfunction getSide( materialOrSide ) {\n\n\treturn materialOrSide && materialOrSide.isMaterial ? materialOrSide.side : materialOrSide;\n\n}\n\n// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L258\nexport function intersectTri( geometry, materialOrSide, ray, tri, intersections, near, far ) {\n\n\tconst triOffset = tri * 3;\n\tlet a = triOffset + 0;\n\tlet b = triOffset + 1;\n\tlet c = triOffset + 2;\n\n\tconst { index, groups } = geometry;\n\tif ( geometry.index ) {\n\n\t\ta = index.getX( a );\n\t\tb = index.getX( b );\n\t\tc = index.getX( c );\n\n\t}\n\n\tconst { position, normal, uv, uv1 } = geometry.attributes;\n\tif ( Array.isArray( materialOrSide ) ) {\n\n\t\t// check which groups a triangle is present in and run the intersections\n\t\t// TODO: we shouldn't need to run and intersection test multiple times\n\t\tconst firstIndex = tri * 3;\n\t\tfor ( let i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tconst { start, count, materialIndex } = groups[ i ];\n\t\t\tif ( firstIndex >= start && firstIndex < start + count ) {\n\n\t\t\t\tconst side = getSide( materialOrSide[ materialIndex ] );\n\t\t\t\tconst intersection = checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side, near, far );\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tintersection.faceIndex = tri;\n\t\t\t\t\tintersection.face.materialIndex = materialIndex;\n\n\t\t\t\t\tif ( intersections ) {\n\n\t\t\t\t\t\tintersections.push( intersection );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn intersection;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t} else {\n\n\t\t// run the intersection for the single material\n\t\tconst side = getSide( materialOrSide );\n\t\tconst intersection = checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side, near, far );\n\t\tif ( intersection ) {\n\n\t\t\tintersection.faceIndex = tri;\n\t\t\tintersection.face.materialIndex = 0;\n\n\t\t\tif ( intersections ) {\n\n\t\t\t\tintersections.push( intersection );\n\n\t\t\t} else {\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn null;\n\n}\n","/** @import { BufferGeometry } from 'three' */\nimport { Vector2, Vector3, Triangle } from 'three';\n\n// sets the vertices of triangle `tri` with the 3 vertices after i\nexport function setTriangle( tri, i, index, pos ) {\n\n\tconst ta = tri.a;\n\tconst tb = tri.b;\n\tconst tc = tri.c;\n\n\tlet i0 = i;\n\tlet i1 = i + 1;\n\tlet i2 = i + 2;\n\tif ( index ) {\n\n\t\ti0 = index.getX( i0 );\n\t\ti1 = index.getX( i1 );\n\t\ti2 = index.getX( i2 );\n\n\t}\n\n\tta.x = pos.getX( i0 );\n\tta.y = pos.getY( i0 );\n\tta.z = pos.getZ( i0 );\n\n\ttb.x = pos.getX( i1 );\n\ttb.y = pos.getY( i1 );\n\ttb.z = pos.getZ( i1 );\n\n\ttc.x = pos.getX( i2 );\n\ttc.y = pos.getY( i2 );\n\ttc.z = pos.getZ( i2 );\n\n}\n\nconst tempV1 = /* @__PURE__ */ new Vector3();\nconst tempV2 = /* @__PURE__ */ new Vector3();\nconst tempV3 = /* @__PURE__ */ new Vector3();\nconst tempUV1 = /* @__PURE__ */ new Vector2();\nconst tempUV2 = /* @__PURE__ */ new Vector2();\nconst tempUV3 = /* @__PURE__ */ new Vector2();\n\n/**\n * @typedef {Object} HitTriangleInfo\n * @property {{ a: number, b: number, c: number, materialIndex: number, normal: Vector3 }} face\n * Triangle vertex indices, material index, and face normal.\n * @property {Vector2|null} uv - UV coordinates at the hit point, or `null` if no UV attribute is present.\n * @property {Vector3} barycoord - Barycentric coordinates of the hit point within the triangle.\n */\n\n/**\n * Computes hit-point information for a point on a triangle within a `BufferGeometry`. Returns\n * the face vertex indices, face normal, material index, UV coordinates, and barycentric coordinates.\n * Useful for retrieving detailed hit data after a call to `MeshBVH.closestPointToPoint` or\n * `MeshBVH.closestPointToGeometry`.\n *\n * @section Functions\n * @param {Vector3} point - The point on the triangle surface (in the geometry's local space).\n * @param {BufferGeometry} geometry - The geometry containing the triangle.\n * @param {number} triangleIndex - The index of the triangle within the geometry.\n * @param {HitTriangleInfo} [target] - Optional object to write results into. Reuses existing\n * `face`, `uv`, and `barycoord` sub-objects if present.\n * @returns {HitTriangleInfo}\n */\nexport function getTriangleHitPointInfo( point, geometry, triangleIndex, target ) {\n\n\tconst indices = geometry.getIndex().array;\n\tconst positions = geometry.getAttribute( 'position' );\n\tconst uvs = geometry.getAttribute( 'uv' );\n\n\tconst a = indices[ triangleIndex * 3 ];\n\tconst b = indices[ triangleIndex * 3 + 1 ];\n\tconst c = indices[ triangleIndex * 3 + 2 ];\n\n\ttempV1.fromBufferAttribute( positions, a );\n\ttempV2.fromBufferAttribute( positions, b );\n\ttempV3.fromBufferAttribute( positions, c );\n\n\t// find the associated material index\n\tlet materialIndex = 0;\n\tconst groups = geometry.groups;\n\tconst firstVertexIndex = triangleIndex * 3;\n\tfor ( let i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\t\tconst { start, count } = group;\n\t\tif ( firstVertexIndex >= start && firstVertexIndex < start + count ) {\n\n\t\t\tmaterialIndex = group.materialIndex;\n\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\t// extract barycoord\n\tconst barycoord = target && target.barycoord ? target.barycoord : new Vector3();\n\tTriangle.getBarycoord( point, tempV1, tempV2, tempV3, barycoord );\n\n\t// extract uvs\n\tlet uv = null;\n\tif ( uvs ) {\n\n\t\ttempUV1.fromBufferAttribute( uvs, a );\n\t\ttempUV2.fromBufferAttribute( uvs, b );\n\t\ttempUV3.fromBufferAttribute( uvs, c );\n\n\t\tif ( target && target.uv ) uv = target.uv;\n\t\telse uv = new Vector2();\n\n\t\tTriangle.getInterpolation( point, tempV1, tempV2, tempV3, tempUV1, tempUV2, tempUV3, uv );\n\n\t}\n\n\t// adjust the provided target or create a new one\n\tif ( target ) {\n\n\t\tif ( ! target.face ) target.face = { };\n\t\ttarget.face.a = a;\n\t\ttarget.face.b = b;\n\t\ttarget.face.c = c;\n\t\ttarget.face.materialIndex = materialIndex;\n\t\tif ( ! target.face.normal ) target.face.normal = new Vector3();\n\t\tTriangle.getNormal( tempV1, tempV2, tempV3, target.face.normal );\n\n\t\tif ( uv ) target.uv = uv;\n\t\ttarget.barycoord = barycoord;\n\n\t\treturn target;\n\n\t} else {\n\n\t\treturn {\n\t\t\tface: {\n\t\t\t\ta: a,\n\t\t\t\tb: b,\n\t\t\t\tc: c,\n\t\t\t\tmaterialIndex: materialIndex,\n\t\t\t\tnormal: Triangle.getNormal( tempV1, tempV2, tempV3, new Vector3() )\n\t\t\t},\n\t\t\tuv: uv,\n\t\t\tbarycoord: barycoord,\n\t\t};\n\n\t}\n\n}\n","import { intersectTri } from '../../utils/ThreeRayIntersectUtilities.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\n\n/*************************************************************/\n/* This file is generated from \"iterationUtils.template.js\". */\n/*************************************************************/\n\nfunction intersectTris( bvh, materialOrSide, ray, offset, count, intersections, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\n\t\tintersectTri( geometry, materialOrSide, ray, i, intersections, near, far );\n\n\n\t}\n\n}\n\nfunction intersectClosestTri( bvh, materialOrSide, ray, offset, count, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tlet dist = Infinity;\n\tlet res = null;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tlet intersection;\n\n\t\tintersection = intersectTri( geometry, materialOrSide, ray, i, null, near, far );\n\n\n\t\tif ( intersection && intersection.distance < dist ) {\n\n\t\t\tres = intersection;\n\t\t\tdist = intersection.distance;\n\n\t\t}\n\n\t}\n\n\treturn res;\n\n}\n\nfunction iterateOverTriangles(\n\toffset,\n\tcount,\n\tbvh,\n\tintersectsTriangleFunc,\n\tcontained,\n\tdepth,\n\ttriangle\n) {\n\n\tconst { geometry } = bvh;\n\tconst { index } = geometry;\n\tconst pos = geometry.attributes.position;\n\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\tlet tri;\n\n\t\ttri = i;\n\n\t\tsetTriangle( triangle, tri * 3, index, pos );\n\t\ttriangle.needsUpdate = true;\n\n\t\tif ( intersectsTriangleFunc( triangle, tri, contained, depth ) ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t}\n\n\treturn false;\n\n}\n\nexport { intersectClosestTri, intersectTris, iterateOverTriangles };\n","import { UINT32_PER_NODE, BYTES_PER_NODE } from '../Constants.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\n\n/****************************************************/\n/* This file is generated from \"refit.template.js\". */\n/****************************************************/\n\nfunction refit( bvh, nodeIndices = null ) {\n\n\tif ( nodeIndices && Array.isArray( nodeIndices ) ) {\n\n\t\tnodeIndices = new Set( nodeIndices );\n\n\t}\n\n\tconst geometry = bvh.geometry;\n\tconst indexArr = geometry.index ? geometry.index.array : null;\n\tconst posAttr = geometry.attributes.position;\n\n\tlet buffer, uint32Array, uint16Array, float32Array;\n\tlet byteOffset = 0;\n\tconst roots = bvh._roots;\n\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\tbuffer = roots[ i ];\n\t\tuint32Array = new Uint32Array( buffer );\n\t\tuint16Array = new Uint16Array( buffer );\n\t\tfloat32Array = new Float32Array( buffer );\n\n\t\t_traverse( 0, byteOffset );\n\t\tbyteOffset += buffer.byteLength;\n\n\t}\n\n\tfunction _traverse( nodeIndex32, byteOffset, force = false ) {\n\n\t\tconst nodeIndex16 = nodeIndex32 * 2;\n\t\tif ( IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t\tlet minx = Infinity;\n\t\t\tlet miny = Infinity;\n\t\t\tlet minz = Infinity;\n\t\t\tlet maxx = - Infinity;\n\t\t\tlet maxy = - Infinity;\n\t\t\tlet maxz = - Infinity;\n\n\n\t\t\tfor ( let i = 3 * offset, l = 3 * ( offset + count ); i < l; i ++ ) {\n\n\t\t\t\tlet index = indexArr[ i ];\n\t\t\t\tconst x = posAttr.getX( index );\n\t\t\t\tconst y = posAttr.getY( index );\n\t\t\t\tconst z = posAttr.getZ( index );\n\n\t\t\t\tif ( x < minx ) minx = x;\n\t\t\t\tif ( x > maxx ) maxx = x;\n\n\t\t\t\tif ( y < miny ) miny = y;\n\t\t\t\tif ( y > maxy ) maxy = y;\n\n\t\t\t\tif ( z < minz ) minz = z;\n\t\t\t\tif ( z > maxz ) maxz = z;\n\n\t\t\t}\n\n\n\t\t\tif (\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] !== minx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] !== miny ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] !== minz ||\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] !== maxx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] !== maxy ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] !== maxz\n\t\t\t) {\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] = minx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] = miny;\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] = minz;\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] = maxx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] = maxy;\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] = maxz;\n\n\t\t\t\treturn true;\n\n\t\t\t} else {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t\t// the identifying node indices provided by the shapecast function include offsets of all\n\t\t\t// root buffers to guarantee they're unique between roots so offset left and right indices here.\n\t\t\tlet forceChildren = force;\n\t\t\tlet includesLeft = false;\n\t\t\tlet includesRight = false;\n\n\t\t\tif ( nodeIndices ) {\n\n\t\t\t\t// if we see that neither the left or right child are included in the set that need to be updated\n\t\t\t\t// then we assume that all children need to be updated.\n\t\t\t\tif ( ! forceChildren ) {\n\n\t\t\t\t\tconst leftNodeId = left / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tconst rightNodeId = right / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tincludesLeft = nodeIndices.has( leftNodeId );\n\t\t\t\t\tincludesRight = nodeIndices.has( rightNodeId );\n\t\t\t\t\tforceChildren = ! includesLeft && ! includesRight;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tincludesLeft = true;\n\t\t\t\tincludesRight = true;\n\n\t\t\t}\n\n\t\t\tconst traverseLeft = forceChildren || includesLeft;\n\t\t\tconst traverseRight = forceChildren || includesRight;\n\n\t\t\tlet leftChange = false;\n\t\t\tif ( traverseLeft ) {\n\n\t\t\t\tleftChange = _traverse( left, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tlet rightChange = false;\n\t\t\tif ( traverseRight ) {\n\n\t\t\t\trightChange = _traverse( right, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tconst didChange = leftChange || rightChange;\n\t\t\tif ( didChange ) {\n\n\t\t\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\tconst left_i = left + i;\n\t\t\t\t\tconst right_i = right + i;\n\t\t\t\t\tconst minLeftValue = float32Array[ left_i ];\n\t\t\t\t\tconst maxLeftValue = float32Array[ left_i + 3 ];\n\t\t\t\t\tconst minRightValue = float32Array[ right_i ];\n\t\t\t\t\tconst maxRightValue = float32Array[ right_i + 3 ];\n\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i ] = minLeftValue < minRightValue ? minLeftValue : minRightValue;\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i + 3 ] = maxLeftValue > maxRightValue ? maxLeftValue : maxRightValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn didChange;\n\n\t\t}\n\n\t}\n\n}\n\nexport { refit };\n","\nexport function intersectsNodeBounds( nodeIndex32, array, ray, near, far ) {\n\n\t// This function performs intersection tests similar to Ray.intersectBox in three.js,\n\t// with the difference that the box values are read from an array to improve performance.\n\n\tlet tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\tconst invdirx = 1 / ray.direction.x,\n\t\tinvdiry = 1 / ray.direction.y,\n\t\tinvdirz = 1 / ray.direction.z;\n\n\tconst ox = ray.origin.x;\n\tconst oy = ray.origin.y;\n\tconst oz = ray.origin.z;\n\n\tlet minx = array[ nodeIndex32 ];\n\tlet maxx = array[ nodeIndex32 + 3 ];\n\n\tlet miny = array[ nodeIndex32 + 1 ];\n\tlet maxy = array[ nodeIndex32 + 3 + 1 ];\n\n\tlet minz = array[ nodeIndex32 + 2 ];\n\tlet maxz = array[ nodeIndex32 + 3 + 2 ];\n\n\tif ( invdirx >= 0 ) {\n\n\t\ttmin = ( minx - ox ) * invdirx;\n\t\ttmax = ( maxx - ox ) * invdirx;\n\n\t} else {\n\n\t\ttmin = ( maxx - ox ) * invdirx;\n\t\ttmax = ( minx - ox ) * invdirx;\n\n\t}\n\n\tif ( invdiry >= 0 ) {\n\n\t\ttymin = ( miny - oy ) * invdiry;\n\t\ttymax = ( maxy - oy ) * invdiry;\n\n\t} else {\n\n\t\ttymin = ( maxy - oy ) * invdiry;\n\t\ttymax = ( miny - oy ) * invdiry;\n\n\t}\n\n\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return false;\n\n\tif ( tymin > tmin || isNaN( tmin ) ) tmin = tymin;\n\n\tif ( tymax < tmax || isNaN( tmax ) ) tmax = tymax;\n\n\tif ( invdirz >= 0 ) {\n\n\t\ttzmin = ( minz - oz ) * invdirz;\n\t\ttzmax = ( maxz - oz ) * invdirz;\n\n\t} else {\n\n\t\ttzmin = ( maxz - oz ) * invdirz;\n\t\ttzmax = ( minz - oz ) * invdirz;\n\n\t}\n\n\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return false;\n\n\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t//return point closest to the ray (positive side)\n\n\treturn tmin <= far && tmax >= near;\n\n}\n","import { intersectTri } from '../../utils/ThreeRayIntersectUtilities.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\n\n/*************************************************************/\n/* This file is generated from \"iterationUtils.template.js\". */\n/*************************************************************/\n\nfunction intersectTris_indirect( bvh, materialOrSide, ray, offset, count, intersections, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tlet vi = _indirectBuffer ? _indirectBuffer[ i ] : i;\n\t\tintersectTri( geometry, materialOrSide, ray, vi, intersections, near, far );\n\n\n\t}\n\n}\n\nfunction intersectClosestTri_indirect( bvh, materialOrSide, ray, offset, count, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tlet dist = Infinity;\n\tlet res = null;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tlet intersection;\n\t\tintersection = intersectTri( geometry, materialOrSide, ray, _indirectBuffer ? _indirectBuffer[ i ] : i, null, near, far );\n\n\n\t\tif ( intersection && intersection.distance < dist ) {\n\n\t\t\tres = intersection;\n\t\t\tdist = intersection.distance;\n\n\t\t}\n\n\t}\n\n\treturn res;\n\n}\n\nfunction iterateOverTriangles_indirect(\n\toffset,\n\tcount,\n\tbvh,\n\tintersectsTriangleFunc,\n\tcontained,\n\tdepth,\n\ttriangle\n) {\n\n\tconst { geometry } = bvh;\n\tconst { index } = geometry;\n\tconst pos = geometry.attributes.position;\n\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\tlet tri;\n\t\ttri = bvh.resolveTriangleIndex( i );\n\n\t\tsetTriangle( triangle, tri * 3, index, pos );\n\t\ttriangle.needsUpdate = true;\n\n\t\tif ( intersectsTriangleFunc( triangle, tri, contained, depth ) ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t}\n\n\treturn false;\n\n}\n\nexport { intersectClosestTri_indirect, intersectTris_indirect, iterateOverTriangles_indirect };\n","import { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { intersectTris } from '../utils/iterationUtils.generated.js';\nimport '../utils/iterationUtils_indirect.generated.js';\n\n/******************************************************/\n/* This file is generated from \"raycast.template.js\". */\n/******************************************************/\n\nfunction raycast( bvh, root, materialOrSide, ray, intersects, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\t_raycast( 0, bvh, materialOrSide, ray, intersects, near, far );\n\tBufferStack.clearBuffer();\n\n}\n\nfunction _raycast( nodeIndex32, bvh, materialOrSide, ray, intersects, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tconst nodeIndex16 = nodeIndex32 * 2;\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\n\t\tintersectTris( bvh, materialOrSide, ray, offset, count, intersects, near, far );\n\n\n\t} else {\n\n\t\tconst leftIndex = LEFT_NODE( nodeIndex32 );\n\t\tif ( intersectsNodeBounds( leftIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( leftIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t\tconst rightIndex = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\tif ( intersectsNodeBounds( rightIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( rightIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycast };\n","import { IS_LEAF, OFFSET, COUNT, SPLIT_AXIS, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport { intersectClosestTri } from '../utils/iterationUtils.generated.js';\nimport '../utils/iterationUtils_indirect.generated.js';\n\n/***********************************************************/\n/* This file is generated from \"raycastFirst.template.js\". */\n/***********************************************************/\n\nconst _xyzFields = [ 'x', 'y', 'z' ];\n\nfunction raycastFirst( bvh, root, materialOrSide, ray, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _raycastFirst( 0, bvh, materialOrSide, ray, near, far );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _raycastFirst( nodeIndex32, bvh, materialOrSide, ray, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\n\t\t// eslint-disable-next-line no-unreachable\n\t\treturn intersectClosestTri( bvh, materialOrSide, ray, offset, count, near, far );\n\n\n\t} else {\n\n\t\t// consider the position of the split plane with respect to the oncoming ray; whichever direction\n\t\t// the ray is coming from, look for an intersection among that side of the tree first\n\t\tconst splitAxis = SPLIT_AXIS( nodeIndex32, uint32Array );\n\t\tconst xyzAxis = _xyzFields[ splitAxis ];\n\t\tconst rayDir = ray.direction[ xyzAxis ];\n\t\tconst leftToRight = rayDir >= 0;\n\n\t\t// c1 is the child to check first\n\t\tlet c1, c2;\n\t\tif ( leftToRight ) {\n\n\t\t\tc1 = LEFT_NODE( nodeIndex32 );\n\t\t\tc2 = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t} else {\n\n\t\t\tc1 = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\t\tc2 = LEFT_NODE( nodeIndex32 );\n\n\t\t}\n\n\t\tconst c1Intersection = intersectsNodeBounds( c1, float32Array, ray, near, far );\n\t\tconst c1Result = c1Intersection ? _raycastFirst( c1, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\t// if we got an intersection in the first node and it's closer than the second node's bounding\n\t\t// box, we don't need to consider the second node because it couldn't possibly be a better result\n\t\tif ( c1Result ) {\n\n\t\t\t// check if the point is within the second bounds\n\t\t\t// \"point\" is in the local frame of the bvh\n\t\t\tconst point = c1Result.point[ xyzAxis ];\n\t\t\tconst isOutside = leftToRight ?\n\t\t\t\tpoint <= float32Array[ c2 + splitAxis ] : // min bounding data\n\t\t\t\tpoint >= float32Array[ c2 + splitAxis + 3 ]; // max bounding data\n\n\t\t\tif ( isOutside ) {\n\n\t\t\t\treturn c1Result;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// either there was no intersection in the first node, or there could still be a closer\n\t\t// intersection in the second, so check the second node and then take the better of the two\n\t\tconst c2Intersection = intersectsNodeBounds( c2, float32Array, ray, near, far );\n\t\tconst c2Result = c2Intersection ? _raycastFirst( c2, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\tif ( c1Result && c2Result ) {\n\n\t\t\treturn c1Result.distance <= c2Result.distance ? c1Result : c2Result;\n\n\t\t} else {\n\n\t\t\treturn c1Result || c2Result || null;\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycastFirst };\n","import { Box3, Matrix4 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { ExtendedTriangle } from '../../math/ExtendedTriangle.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { IS_LEAF, OFFSET, COUNT, BOUNDING_DATA_INDEX, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { getTriCount } from '../build/geometryUtils.js';\n\n/*****************************************************************/\n/* This file is generated from \"intersectsGeometry.template.js\". */\n/*****************************************************************/\n/* eslint-disable indent */\n\nconst boundingBox = /* @__PURE__ */ new Box3();\nconst triangle = /* @__PURE__ */ new ExtendedTriangle();\nconst triangle2 = /* @__PURE__ */ new ExtendedTriangle();\nconst invertedMat = /* @__PURE__ */ new Matrix4();\n\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\n\nfunction intersectsGeometry( bvh, root, otherGeometry, geometryToBvh ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _intersectsGeometry( 0, bvh, otherGeometry, geometryToBvh );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _intersectsGeometry( nodeIndex32, bvh, otherGeometry, geometryToBvh, cachedObb = null ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tif ( cachedObb === null ) {\n\n\t\tif ( ! otherGeometry.boundingBox ) {\n\n\t\t\totherGeometry.computeBoundingBox();\n\n\t\t}\n\n\t\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\t\tcachedObb = obb;\n\n\t}\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst thisGeometry = bvh.geometry;\n\t\tconst thisIndex = thisGeometry.index;\n\t\tconst thisPos = thisGeometry.attributes.position;\n\n\t\tconst otherIndex = otherGeometry.index;\n\t\tconst otherPos = otherGeometry.attributes.position;\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t// get the inverse of the geometry matrix so we can transform our triangles into the\n\t\t// geometry space we're trying to test. We assume there are fewer triangles being checked\n\t\t// here.\n\t\tinvertedMat.copy( geometryToBvh ).invert();\n\n\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t// if there's a bounds tree\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( nodeIndex32 ), float32Array, obb2 );\n\t\t\tobb2.matrix.copy( invertedMat );\n\t\t\tobb2.needsUpdate = true;\n\n\t\t\t// TODO: use a triangle iteration function here\n\t\t\tconst res = otherGeometry.boundsTree.shapecast( {\n\n\t\t\t\tintersectsBounds: box => obb2.intersectsBox( box ),\n\n\t\t\t\tintersectsTriangle: tri => {\n\n\t\t\t\t\ttri.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.needsUpdate = true;\n\n\n\t\t\t\t\tfor ( let i = offset * 3, l = ( count + offset ) * 3; i < l; i += 3 ) {\n\n\t\t\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\t\t\tsetTriangle( triangle2, i, thisIndex, thisPos );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\t\t\t\t\t\tif ( tri.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\treturn res;\n\n\t\t} else {\n\n\t\t\t// if we're just dealing with raw geometry\n\t\t\tconst otherTriangleCount = getTriCount( otherGeometry );\n\n\n\t\t\tfor ( let i = offset * 3, l = ( count + offset ) * 3; i < l; i += 3 ) {\n\n\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\tsetTriangle( triangle, i, thisIndex, thisPos );\n\n\n\t\t\t\ttriangle.a.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.b.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.c.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\tfor ( let i2 = 0, l2 = otherTriangleCount * 3; i2 < l2; i2 += 3 ) {\n\n\t\t\t\t\tsetTriangle( triangle2, i2, otherIndex, otherPos );\n\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\tif ( triangle.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t}\n\n\n\t\t}\n\n\t} else {\n\n\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( left ), float32Array, boundingBox );\n\t\tconst leftIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( left, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( leftIntersection ) return true;\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( right ), float32Array, boundingBox );\n\t\tconst rightIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( right, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( rightIntersection ) return true;\n\n\t\treturn false;\n\n\t}\n\n}\n\nexport { intersectsGeometry };\n","import { Matrix4, Vector3 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { getTriCount } from '../build/geometryUtils.js';\nimport { ExtendedTrianglePool } from '../../utils/ExtendedTrianglePool.js';\n\n/*********************************************************************/\n/* This file is generated from \"closestPointToGeometry.template.js\". */\n/*********************************************************************/\n\nconst tempMatrix = /* @__PURE__ */ new Matrix4();\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\nconst temp1 = /* @__PURE__ */ new Vector3();\nconst temp2 = /* @__PURE__ */ new Vector3();\nconst temp3 = /* @__PURE__ */ new Vector3();\nconst temp4 = /* @__PURE__ */ new Vector3();\n\nfunction closestPointToGeometry(\n\tbvh,\n\totherGeometry,\n\tgeometryToBvh,\n\ttarget1 = { },\n\ttarget2 = { },\n\tminThreshold = 0,\n\tmaxThreshold = Infinity,\n) {\n\n\tif ( ! otherGeometry.boundingBox ) {\n\n\t\totherGeometry.computeBoundingBox();\n\n\t}\n\n\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\tobb.needsUpdate = true;\n\n\tconst geometry = bvh.geometry;\n\tconst pos = geometry.attributes.position;\n\tconst index = geometry.index;\n\tconst otherPos = otherGeometry.attributes.position;\n\tconst otherIndex = otherGeometry.index;\n\tconst triangle = ExtendedTrianglePool.getPrimitive();\n\tconst triangle2 = ExtendedTrianglePool.getPrimitive();\n\n\tlet tempTarget1 = temp1;\n\tlet tempTargetDest1 = temp2;\n\tlet tempTarget2 = null;\n\tlet tempTargetDest2 = null;\n\n\tif ( target2 ) {\n\n\t\ttempTarget2 = temp3;\n\t\ttempTargetDest2 = temp4;\n\n\t}\n\n\tlet closestDistance = Infinity;\n\tlet closestDistanceTriIndex = null;\n\tlet closestDistanceOtherTriIndex = null;\n\ttempMatrix.copy( geometryToBvh ).invert();\n\tobb2.matrix.copy( tempMatrix );\n\tbvh.shapecast(\n\t\t{\n\n\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\treturn obb.distanceToBox( box );\n\n\t\t\t},\n\n\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\tif ( score < closestDistance && score < maxThreshold ) {\n\n\t\t\t\t\t// if we know the triangles of this bounds will be intersected next then\n\t\t\t\t\t// save the bounds to use during triangle checks.\n\t\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\t\tobb2.min.copy( box.min );\n\t\t\t\t\t\tobb2.max.copy( box.max );\n\t\t\t\t\t\tobb2.needsUpdate = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t},\n\n\t\t\tintersectsRange: ( offset, count ) => {\n\n\t\t\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t\t\t// if the other geometry has a bvh then use the accelerated path where we use shapecast to find\n\t\t\t\t\t// the closest bounds in the other geometry to check.\n\t\t\t\t\tconst otherBvh = otherGeometry.boundsTree;\n\t\t\t\t\treturn otherBvh.shapecast( {\n\t\t\t\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\t\t\t\treturn obb2.distanceToBox( box );\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\t\t\t\treturn score < closestDistance && score < maxThreshold;\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsRange: ( otherOffset, otherCount ) => {\n\n\t\t\t\t\t\t\tfor ( let i2 = otherOffset, l2 = otherOffset + otherCount; i2 < l2; i2 ++ ) {\n\n\n\t\t\t\t\t\t\t\tsetTriangle( triangle2, 3 * i2, otherIndex, otherPos );\n\n\t\t\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\n\t\t\t\t\t\t\t\t\tsetTriangle( triangle, 3 * i, index, pos );\n\n\t\t\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t},\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// If no bounds tree then we'll just check every triangle.\n\t\t\t\t\tconst triCount = getTriCount( otherGeometry );\n\t\t\t\t\tfor ( let i2 = 0, l2 = triCount; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\t\tsetTriangle( triangle2, 3 * i2, otherIndex, otherPos );\n\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\n\t\t\t\t\t\t\tsetTriangle( triangle, 3 * i, index, pos );\n\n\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t}\n\n\t);\n\n\tExtendedTrianglePool.releasePrimitive( triangle );\n\tExtendedTrianglePool.releasePrimitive( triangle2 );\n\n\tif ( closestDistance === Infinity ) {\n\n\t\treturn null;\n\n\t}\n\n\tif ( ! target1.point ) {\n\n\t\ttarget1.point = tempTargetDest1.clone();\n\n\t} else {\n\n\t\ttarget1.point.copy( tempTargetDest1 );\n\n\t}\n\n\ttarget1.distance = closestDistance,\n\ttarget1.faceIndex = closestDistanceTriIndex;\n\n\tif ( target2 ) {\n\n\t\tif ( ! target2.point ) target2.point = tempTargetDest2.clone();\n\t\telse target2.point.copy( tempTargetDest2 );\n\t\ttarget2.point.applyMatrix4( tempMatrix );\n\t\ttempTargetDest1.applyMatrix4( tempMatrix );\n\t\ttarget2.distance = tempTargetDest1.sub( target2.point ).length();\n\t\ttarget2.faceIndex = closestDistanceOtherTriIndex;\n\n\t}\n\n\treturn target1;\n\n}\n\nexport { closestPointToGeometry };\n","import { UINT32_PER_NODE, BYTES_PER_NODE } from '../Constants.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\n\n/****************************************************/\n/* This file is generated from \"refit.template.js\". */\n/****************************************************/\n\nfunction refit_indirect( bvh, nodeIndices = null ) {\n\n\tif ( nodeIndices && Array.isArray( nodeIndices ) ) {\n\n\t\tnodeIndices = new Set( nodeIndices );\n\n\t}\n\n\tconst geometry = bvh.geometry;\n\tconst indexArr = geometry.index ? geometry.index.array : null;\n\tconst posAttr = geometry.attributes.position;\n\n\tlet buffer, uint32Array, uint16Array, float32Array;\n\tlet byteOffset = 0;\n\tconst roots = bvh._roots;\n\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\tbuffer = roots[ i ];\n\t\tuint32Array = new Uint32Array( buffer );\n\t\tuint16Array = new Uint16Array( buffer );\n\t\tfloat32Array = new Float32Array( buffer );\n\n\t\t_traverse( 0, byteOffset );\n\t\tbyteOffset += buffer.byteLength;\n\n\t}\n\n\tfunction _traverse( nodeIndex32, byteOffset, force = false ) {\n\n\t\tconst nodeIndex16 = nodeIndex32 * 2;\n\t\tif ( IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t\tlet minx = Infinity;\n\t\t\tlet miny = Infinity;\n\t\t\tlet minz = Infinity;\n\t\t\tlet maxx = - Infinity;\n\t\t\tlet maxy = - Infinity;\n\t\t\tlet maxz = - Infinity;\n\n\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\t\tconst t = 3 * bvh.resolveTriangleIndex( i );\n\t\t\t\tfor ( let j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tlet index = t + j;\n\t\t\t\t\tindex = indexArr ? indexArr[ index ] : index;\n\n\t\t\t\t\tconst x = posAttr.getX( index );\n\t\t\t\t\tconst y = posAttr.getY( index );\n\t\t\t\t\tconst z = posAttr.getZ( index );\n\n\t\t\t\t\tif ( x < minx ) minx = x;\n\t\t\t\t\tif ( x > maxx ) maxx = x;\n\n\t\t\t\t\tif ( y < miny ) miny = y;\n\t\t\t\t\tif ( y > maxy ) maxy = y;\n\n\t\t\t\t\tif ( z < minz ) minz = z;\n\t\t\t\t\tif ( z > maxz ) maxz = z;\n\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tif (\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] !== minx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] !== miny ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] !== minz ||\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] !== maxx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] !== maxy ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] !== maxz\n\t\t\t) {\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] = minx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] = miny;\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] = minz;\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] = maxx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] = maxy;\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] = maxz;\n\n\t\t\t\treturn true;\n\n\t\t\t} else {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t\t// the identifying node indices provided by the shapecast function include offsets of all\n\t\t\t// root buffers to guarantee they're unique between roots so offset left and right indices here.\n\t\t\tlet forceChildren = force;\n\t\t\tlet includesLeft = false;\n\t\t\tlet includesRight = false;\n\n\t\t\tif ( nodeIndices ) {\n\n\t\t\t\t// if we see that neither the left or right child are included in the set that need to be updated\n\t\t\t\t// then we assume that all children need to be updated.\n\t\t\t\tif ( ! forceChildren ) {\n\n\t\t\t\t\tconst leftNodeId = left / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tconst rightNodeId = right / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tincludesLeft = nodeIndices.has( leftNodeId );\n\t\t\t\t\tincludesRight = nodeIndices.has( rightNodeId );\n\t\t\t\t\tforceChildren = ! includesLeft && ! includesRight;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tincludesLeft = true;\n\t\t\t\tincludesRight = true;\n\n\t\t\t}\n\n\t\t\tconst traverseLeft = forceChildren || includesLeft;\n\t\t\tconst traverseRight = forceChildren || includesRight;\n\n\t\t\tlet leftChange = false;\n\t\t\tif ( traverseLeft ) {\n\n\t\t\t\tleftChange = _traverse( left, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tlet rightChange = false;\n\t\t\tif ( traverseRight ) {\n\n\t\t\t\trightChange = _traverse( right, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tconst didChange = leftChange || rightChange;\n\t\t\tif ( didChange ) {\n\n\t\t\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\tconst left_i = left + i;\n\t\t\t\t\tconst right_i = right + i;\n\t\t\t\t\tconst minLeftValue = float32Array[ left_i ];\n\t\t\t\t\tconst maxLeftValue = float32Array[ left_i + 3 ];\n\t\t\t\t\tconst minRightValue = float32Array[ right_i ];\n\t\t\t\t\tconst maxRightValue = float32Array[ right_i + 3 ];\n\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i ] = minLeftValue < minRightValue ? minLeftValue : minRightValue;\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i + 3 ] = maxLeftValue > maxRightValue ? maxLeftValue : maxRightValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn didChange;\n\n\t\t}\n\n\t}\n\n}\n\nexport { refit_indirect };\n","import { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport '../utils/iterationUtils.generated.js';\nimport { intersectTris_indirect } from '../utils/iterationUtils_indirect.generated.js';\n\n/******************************************************/\n/* This file is generated from \"raycast.template.js\". */\n/******************************************************/\n\nfunction raycast_indirect( bvh, root, materialOrSide, ray, intersects, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\t_raycast( 0, bvh, materialOrSide, ray, intersects, near, far );\n\tBufferStack.clearBuffer();\n\n}\n\nfunction _raycast( nodeIndex32, bvh, materialOrSide, ray, intersects, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tconst nodeIndex16 = nodeIndex32 * 2;\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\tintersectTris_indirect( bvh, materialOrSide, ray, offset, count, intersects, near, far );\n\n\n\t} else {\n\n\t\tconst leftIndex = LEFT_NODE( nodeIndex32 );\n\t\tif ( intersectsNodeBounds( leftIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( leftIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t\tconst rightIndex = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\tif ( intersectsNodeBounds( rightIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( rightIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycast_indirect };\n","import { IS_LEAF, OFFSET, COUNT, SPLIT_AXIS, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport '../utils/iterationUtils.generated.js';\nimport { intersectClosestTri_indirect } from '../utils/iterationUtils_indirect.generated.js';\n\n/***********************************************************/\n/* This file is generated from \"raycastFirst.template.js\". */\n/***********************************************************/\n\nconst _xyzFields = [ 'x', 'y', 'z' ];\n\nfunction raycastFirst_indirect( bvh, root, materialOrSide, ray, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _raycastFirst( 0, bvh, materialOrSide, ray, near, far );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _raycastFirst( nodeIndex32, bvh, materialOrSide, ray, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\treturn intersectClosestTri_indirect( bvh, materialOrSide, ray, offset, count, near, far );\n\n\n\t} else {\n\n\t\t// consider the position of the split plane with respect to the oncoming ray; whichever direction\n\t\t// the ray is coming from, look for an intersection among that side of the tree first\n\t\tconst splitAxis = SPLIT_AXIS( nodeIndex32, uint32Array );\n\t\tconst xyzAxis = _xyzFields[ splitAxis ];\n\t\tconst rayDir = ray.direction[ xyzAxis ];\n\t\tconst leftToRight = rayDir >= 0;\n\n\t\t// c1 is the child to check first\n\t\tlet c1, c2;\n\t\tif ( leftToRight ) {\n\n\t\t\tc1 = LEFT_NODE( nodeIndex32 );\n\t\t\tc2 = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t} else {\n\n\t\t\tc1 = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\t\tc2 = LEFT_NODE( nodeIndex32 );\n\n\t\t}\n\n\t\tconst c1Intersection = intersectsNodeBounds( c1, float32Array, ray, near, far );\n\t\tconst c1Result = c1Intersection ? _raycastFirst( c1, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\t// if we got an intersection in the first node and it's closer than the second node's bounding\n\t\t// box, we don't need to consider the second node because it couldn't possibly be a better result\n\t\tif ( c1Result ) {\n\n\t\t\t// check if the point is within the second bounds\n\t\t\t// \"point\" is in the local frame of the bvh\n\t\t\tconst point = c1Result.point[ xyzAxis ];\n\t\t\tconst isOutside = leftToRight ?\n\t\t\t\tpoint <= float32Array[ c2 + splitAxis ] : // min bounding data\n\t\t\t\tpoint >= float32Array[ c2 + splitAxis + 3 ]; // max bounding data\n\n\t\t\tif ( isOutside ) {\n\n\t\t\t\treturn c1Result;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// either there was no intersection in the first node, or there could still be a closer\n\t\t// intersection in the second, so check the second node and then take the better of the two\n\t\tconst c2Intersection = intersectsNodeBounds( c2, float32Array, ray, near, far );\n\t\tconst c2Result = c2Intersection ? _raycastFirst( c2, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\tif ( c1Result && c2Result ) {\n\n\t\t\treturn c1Result.distance <= c2Result.distance ? c1Result : c2Result;\n\n\t\t} else {\n\n\t\t\treturn c1Result || c2Result || null;\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycastFirst_indirect };\n","import { Box3, Matrix4 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { ExtendedTriangle } from '../../math/ExtendedTriangle.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { IS_LEAF, OFFSET, COUNT, BOUNDING_DATA_INDEX, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { getTriCount } from '../build/geometryUtils.js';\n\n/*****************************************************************/\n/* This file is generated from \"intersectsGeometry.template.js\". */\n/*****************************************************************/\n/* eslint-disable indent */\n\nconst boundingBox = /* @__PURE__ */ new Box3();\nconst triangle = /* @__PURE__ */ new ExtendedTriangle();\nconst triangle2 = /* @__PURE__ */ new ExtendedTriangle();\nconst invertedMat = /* @__PURE__ */ new Matrix4();\n\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\n\nfunction intersectsGeometry_indirect( bvh, root, otherGeometry, geometryToBvh ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _intersectsGeometry( 0, bvh, otherGeometry, geometryToBvh );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _intersectsGeometry( nodeIndex32, bvh, otherGeometry, geometryToBvh, cachedObb = null ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tif ( cachedObb === null ) {\n\n\t\tif ( ! otherGeometry.boundingBox ) {\n\n\t\t\totherGeometry.computeBoundingBox();\n\n\t\t}\n\n\t\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\t\tcachedObb = obb;\n\n\t}\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst thisGeometry = bvh.geometry;\n\t\tconst thisIndex = thisGeometry.index;\n\t\tconst thisPos = thisGeometry.attributes.position;\n\n\t\tconst otherIndex = otherGeometry.index;\n\t\tconst otherPos = otherGeometry.attributes.position;\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t// get the inverse of the geometry matrix so we can transform our triangles into the\n\t\t// geometry space we're trying to test. We assume there are fewer triangles being checked\n\t\t// here.\n\t\tinvertedMat.copy( geometryToBvh ).invert();\n\n\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t// if there's a bounds tree\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( nodeIndex32 ), float32Array, obb2 );\n\t\t\tobb2.matrix.copy( invertedMat );\n\t\t\tobb2.needsUpdate = true;\n\n\t\t\t// TODO: use a triangle iteration function here\n\t\t\tconst res = otherGeometry.boundsTree.shapecast( {\n\n\t\t\t\tintersectsBounds: box => obb2.intersectsBox( box ),\n\n\t\t\t\tintersectsTriangle: tri => {\n\n\t\t\t\t\ttri.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.needsUpdate = true;\n\n\t\t\t\t\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\t\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\t\t\tsetTriangle( triangle2, 3 * bvh.resolveTriangleIndex( i ), thisIndex, thisPos );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\t\t\t\t\t\tif ( tri.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\treturn res;\n\n\t\t} else {\n\n\t\t\t// if we're just dealing with raw geometry\n\t\t\tconst otherTriangleCount = getTriCount( otherGeometry );\n\n\t\t\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\tconst ti = bvh.resolveTriangleIndex( i );\n\t\t\t\tsetTriangle( triangle, 3 * ti, thisIndex, thisPos );\n\n\n\t\t\t\ttriangle.a.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.b.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.c.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\tfor ( let i2 = 0, l2 = otherTriangleCount * 3; i2 < l2; i2 += 3 ) {\n\n\t\t\t\t\tsetTriangle( triangle2, i2, otherIndex, otherPos );\n\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\tif ( triangle.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t}\n\n\t} else {\n\n\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( left ), float32Array, boundingBox );\n\t\tconst leftIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( left, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( leftIntersection ) return true;\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( right ), float32Array, boundingBox );\n\t\tconst rightIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( right, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( rightIntersection ) return true;\n\n\t\treturn false;\n\n\t}\n\n}\n\nexport { intersectsGeometry_indirect };\n","import { Matrix4, Vector3 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { getTriCount } from '../build/geometryUtils.js';\nimport { ExtendedTrianglePool } from '../../utils/ExtendedTrianglePool.js';\n\n/*********************************************************************/\n/* This file is generated from \"closestPointToGeometry.template.js\". */\n/*********************************************************************/\n\nconst tempMatrix = /* @__PURE__ */ new Matrix4();\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\nconst temp1 = /* @__PURE__ */ new Vector3();\nconst temp2 = /* @__PURE__ */ new Vector3();\nconst temp3 = /* @__PURE__ */ new Vector3();\nconst temp4 = /* @__PURE__ */ new Vector3();\n\nfunction closestPointToGeometry_indirect(\n\tbvh,\n\totherGeometry,\n\tgeometryToBvh,\n\ttarget1 = { },\n\ttarget2 = { },\n\tminThreshold = 0,\n\tmaxThreshold = Infinity,\n) {\n\n\tif ( ! otherGeometry.boundingBox ) {\n\n\t\totherGeometry.computeBoundingBox();\n\n\t}\n\n\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\tobb.needsUpdate = true;\n\n\tconst geometry = bvh.geometry;\n\tconst pos = geometry.attributes.position;\n\tconst index = geometry.index;\n\tconst otherPos = otherGeometry.attributes.position;\n\tconst otherIndex = otherGeometry.index;\n\tconst triangle = ExtendedTrianglePool.getPrimitive();\n\tconst triangle2 = ExtendedTrianglePool.getPrimitive();\n\n\tlet tempTarget1 = temp1;\n\tlet tempTargetDest1 = temp2;\n\tlet tempTarget2 = null;\n\tlet tempTargetDest2 = null;\n\n\tif ( target2 ) {\n\n\t\ttempTarget2 = temp3;\n\t\ttempTargetDest2 = temp4;\n\n\t}\n\n\tlet closestDistance = Infinity;\n\tlet closestDistanceTriIndex = null;\n\tlet closestDistanceOtherTriIndex = null;\n\ttempMatrix.copy( geometryToBvh ).invert();\n\tobb2.matrix.copy( tempMatrix );\n\tbvh.shapecast(\n\t\t{\n\n\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\treturn obb.distanceToBox( box );\n\n\t\t\t},\n\n\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\tif ( score < closestDistance && score < maxThreshold ) {\n\n\t\t\t\t\t// if we know the triangles of this bounds will be intersected next then\n\t\t\t\t\t// save the bounds to use during triangle checks.\n\t\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\t\tobb2.min.copy( box.min );\n\t\t\t\t\t\tobb2.max.copy( box.max );\n\t\t\t\t\t\tobb2.needsUpdate = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t},\n\n\t\t\tintersectsRange: ( offset, count ) => {\n\n\t\t\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t\t\t// if the other geometry has a bvh then use the accelerated path where we use shapecast to find\n\t\t\t\t\t// the closest bounds in the other geometry to check.\n\t\t\t\t\tconst otherBvh = otherGeometry.boundsTree;\n\t\t\t\t\treturn otherBvh.shapecast( {\n\t\t\t\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\t\t\t\treturn obb2.distanceToBox( box );\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\t\t\t\treturn score < closestDistance && score < maxThreshold;\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsRange: ( otherOffset, otherCount ) => {\n\n\t\t\t\t\t\t\tfor ( let i2 = otherOffset, l2 = otherOffset + otherCount; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\t\t\t\tconst ti2 = otherBvh.resolveTriangleIndex( i2 );\n\t\t\t\t\t\t\t\tsetTriangle( triangle2, 3 * ti2, otherIndex, otherPos );\n\n\t\t\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tconst ti = bvh.resolveTriangleIndex( i );\n\t\t\t\t\t\t\t\t\tsetTriangle( triangle, 3 * ti, index, pos );\n\n\t\t\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t},\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// If no bounds tree then we'll just check every triangle.\n\t\t\t\t\tconst triCount = getTriCount( otherGeometry );\n\t\t\t\t\tfor ( let i2 = 0, l2 = triCount; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\t\tsetTriangle( triangle2, 3 * i2, otherIndex, otherPos );\n\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tconst ti = bvh.resolveTriangleIndex( i );\n\t\t\t\t\t\t\tsetTriangle( triangle, 3 * ti, index, pos );\n\n\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t}\n\n\t);\n\n\tExtendedTrianglePool.releasePrimitive( triangle );\n\tExtendedTrianglePool.releasePrimitive( triangle2 );\n\n\tif ( closestDistance === Infinity ) {\n\n\t\treturn null;\n\n\t}\n\n\tif ( ! target1.point ) {\n\n\t\ttarget1.point = tempTargetDest1.clone();\n\n\t} else {\n\n\t\ttarget1.point.copy( tempTargetDest1 );\n\n\t}\n\n\ttarget1.distance = closestDistance,\n\ttarget1.faceIndex = closestDistanceTriIndex;\n\n\tif ( target2 ) {\n\n\t\tif ( ! target2.point ) target2.point = tempTargetDest2.clone();\n\t\telse target2.point.copy( tempTargetDest2 );\n\t\ttarget2.point.applyMatrix4( tempMatrix );\n\t\ttempTargetDest1.applyMatrix4( tempMatrix );\n\t\ttarget2.distance = tempTargetDest1.sub( target2.point ).length();\n\t\ttarget2.faceIndex = closestDistanceOtherTriIndex;\n\n\t}\n\n\treturn target1;\n\n}\n\nexport { closestPointToGeometry_indirect };\n","// converts the given BVH raycast intersection to align with the three.js raycast\n// structure (include object, world space distance and point).\nexport function convertRaycastIntersect( hit, object, raycaster ) {\n\n\tif ( hit === null ) {\n\n\t\treturn null;\n\n\t}\n\n\thit.point.applyMatrix4( object.matrixWorld );\n\thit.distance = hit.point.distanceTo( raycaster.ray.origin );\n\thit.object = object;\n\n\treturn hit;\n\n}\n","/** @import { BufferGeometry, Sphere, Box3, Intersection, Material, Object3D, Raycaster } from 'three' */\n/** @import { ExtendedTriangle } from '../math/ExtendedTriangle.js' */\n/** @import { IntersectsBoundsCallback, IntersectsRangeCallback, BoundsTraverseOrderCallback, IntersectsRangesCallback } from './BVH.js' */\nimport { BufferAttribute, FrontSide, Ray, Vector3, Matrix4 } from 'three';\nimport { SKIP_GENERATION, BYTES_PER_NODE, UINT32_PER_NODE, FLOAT32_EPSILON } from './Constants.js';\nimport { OrientedBox } from '../math/OrientedBox.js';\nimport { ExtendedTrianglePool } from '../utils/ExtendedTrianglePool.js';\nimport { closestPointToPoint } from './cast/closestPointToPoint.js';\nimport { IS_LEAF } from './utils/nodeBufferUtils.js';\n\nimport { iterateOverTriangles } from './utils/iterationUtils.generated.js';\nimport { refit } from './cast/refit.generated.js';\nimport { raycast } from './cast/raycast.generated.js';\nimport { raycastFirst } from './cast/raycastFirst.generated.js';\nimport { intersectsGeometry } from './cast/intersectsGeometry.generated.js';\nimport { closestPointToGeometry } from './cast/closestPointToGeometry.generated.js';\n\nimport { iterateOverTriangles_indirect } from './utils/iterationUtils_indirect.generated.js';\nimport { refit_indirect } from './cast/refit_indirect.generated.js';\nimport { raycast_indirect } from './cast/raycast_indirect.generated.js';\nimport { raycastFirst_indirect } from './cast/raycastFirst_indirect.generated.js';\nimport { intersectsGeometry_indirect } from './cast/intersectsGeometry_indirect.generated.js';\nimport { closestPointToGeometry_indirect } from './cast/closestPointToGeometry_indirect.generated.js';\nimport { setTriangle } from '../utils/TriangleUtilities.js';\nimport { convertRaycastIntersect } from '../utils/GeometryRayIntersectUtilities.js';\nimport { GeometryBVH } from './GeometryBVH.js';\n\nconst _obb = /* @__PURE__ */ new OrientedBox();\nconst _ray = /* @__PURE__ */ new Ray();\nconst _direction = /* @__PURE__ */ new Vector3();\nconst _inverseMatrix = /* @__PURE__ */ new Matrix4();\nconst _worldScale = /* @__PURE__ */ new Vector3();\nconst _getters = [ 'getX', 'getY', 'getZ' ];\n\n/**\n * @callback IntersectsTriangleCallback\n * @param {ExtendedTriangle} triangle - The triangle primitive in local space.\n * @param {number} triangleIndex - The index of the triangle in the geometry.\n * @param {boolean} contained - Whether the node bounds are fully contained by the query shape.\n * @param {number} depth - The depth of the node in the tree.\n * @returns {boolean} Return `true` to stop traversal.\n */\n\n/**\n * @callback IntersectsTrianglesCallback\n * @param {ExtendedTriangle} triangle1 - Triangle from this BVH in local space.\n * @param {ExtendedTriangle} triangle2 - Triangle from `otherBvh`, transformed into local space.\n * @param {number} triangleIndex1 - Triangle index in the first geometry.\n * @param {number} triangleIndex2 - Triangle index in the second geometry.\n * @param {number} depth1 - Depth of the node in the first BVH.\n * @param {number} nodeIndex1 - Node index in the first BVH.\n * @param {number} depth2 - Depth of the node in the second BVH.\n * @param {number} nodeIndex2 - Node index in the second BVH.\n * @returns {boolean} Return `true` to stop traversal.\n */\n\n/**\n * Plain-object representation of a `MeshBVH` produced by `MeshBVH.serialize` and\n * consumed by `MeshBVH.deserialize`. Suitable for transfer across WebWorker boundaries\n * or storage, with optional buffer sharing via `SharedArrayBuffer`.\n *\n * @typedef {Object} SerializedBVH\n * @property {Array<ArrayBuffer>} roots - BVH root node buffers.\n * @property {Int32Array|Uint32Array|Uint16Array|null} index - Serialized geometry index buffer.\n * @property {Uint32Array|Uint16Array|null} indirectBuffer - Indirect primitive index buffer, or `null`\n * if the BVH was not built in indirect mode.\n */\n\n/**\n * @typedef {Object} HitPointInfo\n * @property {Vector3} point - The closest point on the mesh surface.\n * @property {number} distance - Distance from the query point to the closest point.\n * @property {number} faceIndex - Index of the triangle containing the closest point. Can be\n * passed to `getTriangleHitPointInfo` to retrieve UV, normal, and material index.\n */\n\n/**\n * The MeshBVH generation process modifies the geometry's index bufferAttribute in place to save\n * memory. The BVH construction will use the geometry's boundingBox if it exists or set it if it\n * does not. The BVH will no longer work correctly if the index buffer is modified.\n *\n * Only triangles within the geometry's draw range (or provided `range` option) are included in the\n * BVH. When a geometry has multiple groups, only triangles within the defined group ranges are\n * included. Triangles in gaps between groups are excluded.\n *\n * Note that all query functions expect arguments in local space of the BVH and return results in\n * local space, as well. If world space results are needed they must be transformed into world space\n * using `object.matrixWorld`.\n *\n * @param {BufferGeometry} geometry\n * @param {Object} [options] - Same options as {@link GeometryBVH}.\n * @extends GeometryBVH\n */\nexport class MeshBVH extends GeometryBVH {\n\n\t/**\n\t * Generates a representation of the complete bounds tree and the geometry index buffer which\n\t * can be used to recreate a bounds tree using the `deserialize` function. The `serialize` and\n\t * `deserialize` functions can be used to generate a MeshBVH asynchronously in a background web\n\t * worker to prevent the main thread from stuttering. The BVH roots buffer stored in the\n\t * serialized representation are the same as the ones used by the original BVH so they should\n\t * not be modified. If `SharedArrayBuffers` are used then the same BVH memory can be used for\n\t * multiple BVH in multiple WebWorkers.\n\t *\n\t * @static\n\t * @param {MeshBVH} bvh - The BVH to serialize.\n\t * @param {Object} [options]\n\t * @param {boolean} [options.cloneBuffers=true] - If `true`, the index and BVH root buffers\n\t * are cloned so the serialized data is independent of the live BVH.\n\t * @returns {SerializedBVH}\n\t */\n\tstatic serialize( bvh, options = {} ) {\n\n\t\toptions = {\n\t\t\tcloneBuffers: true,\n\t\t\t...options,\n\t\t};\n\n\t\tconst geometry = bvh.geometry;\n\t\tconst rootData = bvh._roots;\n\t\tconst indirectBuffer = bvh._indirectBuffer;\n\t\tconst indexAttribute = geometry.getIndex();\n\t\tconst result = {\n\t\t\tversion: 1,\n\t\t\troots: null,\n\t\t\tindex: null,\n\t\t\tindirectBuffer: null,\n\t\t};\n\t\tif ( options.cloneBuffers ) {\n\n\t\t\tresult.roots = rootData.map( root => root.slice() );\n\t\t\tresult.index = indexAttribute ? indexAttribute.array.slice() : null;\n\t\t\tresult.indirectBuffer = indirectBuffer ? indirectBuffer.slice() : null;\n\n\t\t} else {\n\n\t\t\tresult.roots = rootData;\n\t\t\tresult.index = indexAttribute ? indexAttribute.array : null;\n\t\t\tresult.indirectBuffer = indirectBuffer;\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * Returns a new MeshBVH instance from the serialized data. `geometry` is the geometry used\n\t * to generate the original BVH `data` was derived from. The root buffers stored in `data`\n\t * are set directly on the new BVH so the memory is shared.\n\t *\n\t * @static\n\t * @param {SerializedBVH} data - Serialized BVH data.\n\t * @param {BufferGeometry} geometry - The geometry the BVH was originally built from.\n\t * @param {Object} [options]\n\t * @param {boolean} [options.setIndex=true] - If `true`, sets `geometry.index` from the\n\t * serialized index buffer (creating one if none exists).\n\t * @returns {MeshBVH}\n\t */\n\tstatic deserialize( data, geometry, options = {} ) {\n\n\t\toptions = {\n\t\t\tsetIndex: true,\n\t\t\tindirect: Boolean( data.indirectBuffer ),\n\t\t\t...options,\n\t\t};\n\n\t\tconst { index, roots, indirectBuffer } = data;\n\n\t\t// handle backwards compatibility by fixing up the buffer roots\n\t\t// see issue gkjohnson/three-mesh-bvh#759\n\t\tif ( ! data.version ) {\n\n\t\t\tconsole.warn(\n\t\t\t\t'MeshBVH.deserialize: Serialization format has been changed and will be fixed up. ' +\n\t\t\t\t'It is recommended to regenerate any stored serialized data.'\n\t\t\t);\n\t\t\tfixupVersion0( roots );\n\n\t\t}\n\n\t\tconst bvh = new MeshBVH( geometry, { ...options, [ SKIP_GENERATION ]: true } );\n\t\tbvh._roots = roots;\n\t\tbvh._indirectBuffer = indirectBuffer || null;\n\n\t\tif ( options.setIndex ) {\n\n\t\t\tconst indexAttribute = geometry.getIndex();\n\t\t\tif ( indexAttribute === null ) {\n\n\t\t\t\tconst newIndex = new BufferAttribute( data.index, 1, false );\n\t\t\t\tgeometry.setIndex( newIndex );\n\n\t\t\t} else if ( indexAttribute.array !== index ) {\n\n\t\t\t\tindexAttribute.array.set( index );\n\t\t\t\tindexAttribute.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn bvh;\n\n\t\t// convert version 0 serialized data (uint32 indices) to version 1 (node indices)\n\t\tfunction fixupVersion0( roots ) {\n\n\t\t\tfor ( let rootIndex = 0; rootIndex < roots.length; rootIndex ++ ) {\n\n\t\t\t\tconst root = roots[ rootIndex ];\n\t\t\t\tconst uint32Array = new Uint32Array( root );\n\t\t\t\tconst uint16Array = new Uint16Array( root );\n\n\t\t\t\t// iterate over nodes and convert right child offsets\n\t\t\t\tfor ( let node = 0, l = root.byteLength / BYTES_PER_NODE; node < l; node ++ ) {\n\n\t\t\t\t\tconst node32Index = UINT32_PER_NODE * node;\n\t\t\t\t\tconst node16Index = 2 * node32Index;\n\t\t\t\t\tif ( ! IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\t\t\t// convert absolute right child offset to relative offset\n\t\t\t\t\t\tuint32Array[ node32Index + 6 ] = uint32Array[ node32Index + 6 ] / UINT32_PER_NODE - node;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tget primitiveStride() {\n\n\t\treturn 3;\n\n\t}\n\n\t/**\n\t * Helper function for use when `indirect` is set to true. This function takes a triangle\n\t * index in the BVH layout and returns the associated triangle index in the geometry index\n\t * buffer or position attribute.\n\t * @type {function(number): number}\n\t * @readonly\n\t */\n\tget resolveTriangleIndex() {\n\n\t\treturn this.resolvePrimitiveIndex;\n\n\t}\n\n\tconstructor( geometry, options = {} ) {\n\n\t\tif ( options.maxLeafTris ) {\n\n\t\t\tconsole.warn( 'MeshBVH: \"maxLeafTris\" option has been deprecated. Use \"targetLeafSize\", instead.' );\n\t\t\toptions = {\n\t\t\t\t...options,\n\t\t\t\ttargetLeafSize: options.maxLeafTris,\n\t\t\t};\n\n\t\t}\n\n\t\tsuper( geometry, options );\n\n\t}\n\n\t/**\n\t * Adjusts all triangle offsets stored in the BVH by the given offset. This is useful when the\n\t * triangle data has been compacted or shifted in the geometry buffers (e.g. in `BatchedMesh`\n\t * when geometries are compacted using the 'optimize' function or constructing a 'merged' BVH).\n\t * This function only adjusts the BVH to point to different triangles in the geometry. The\n\t * geometry's index buffer and/or position attributes must be updated separately to match.\n\t *\n\t * @param {number} offset\n\t * @returns {void}\n\t */\n\t// implement abstract methods from BVH base class\n\tshiftTriangleOffsets( offset ) {\n\n\t\treturn super.shiftPrimitiveOffsets( offset );\n\n\t}\n\n\t// write primitive bounds to the buffer - used only for validateBounds at the moment\n\twritePrimitiveBounds( i, targetBuffer, baseIndex ) {\n\n\t\tconst geometry = this.geometry;\n\t\tconst indirectBuffer = this._indirectBuffer;\n\t\tconst posAttr = geometry.attributes.position;\n\t\tconst index = geometry.index ? geometry.index.array : null;\n\n\t\tconst tri = indirectBuffer ? indirectBuffer[ i ] : i;\n\t\tconst tri3 = tri * 3;\n\n\t\tlet ai = tri3 + 0;\n\t\tlet bi = tri3 + 1;\n\t\tlet ci = tri3 + 2;\n\n\t\tif ( index ) {\n\n\t\t\tai = index[ ai ];\n\t\t\tbi = index[ bi ];\n\t\t\tci = index[ ci ];\n\n\t\t}\n\n\t\tfor ( let el = 0; el < 3; el ++ ) {\n\n\t\t\tconst a = posAttr[ _getters[ el ] ]( ai );\n\t\t\tconst b = posAttr[ _getters[ el ] ]( bi );\n\t\t\tconst c = posAttr[ _getters[ el ] ]( ci );\n\n\t\t\tlet min = a;\n\t\t\tif ( b < min ) min = b;\n\t\t\tif ( c < min ) min = c;\n\n\t\t\tlet max = a;\n\t\t\tif ( b > max ) max = b;\n\t\t\tif ( c > max ) max = c;\n\n\t\t\t// Write in min/max format [minx, miny, minz, maxx, maxy, maxz]\n\t\t\ttargetBuffer[ baseIndex + el ] = min;\n\t\t\ttargetBuffer[ baseIndex + el + 3 ] = max;\n\n\t\t}\n\n\t\treturn targetBuffer;\n\n\t}\n\n\t// precomputes the bounding box for each triangle; required for quickly calculating tree splits.\n\t// result is an array of size count * 6 where triangle i maps to a\n\t// [x_center, x_delta, y_center, y_delta, z_center, z_delta] tuple starting at index (i - offset) * 6,\n\t// representing the center and half-extent in each dimension of triangle i\n\tcomputePrimitiveBounds( offset, count, targetBuffer ) {\n\n\t\tconst geometry = this.geometry;\n\t\tconst indirectBuffer = this._indirectBuffer;\n\t\tconst posAttr = geometry.attributes.position;\n\t\tconst index = geometry.index ? geometry.index.array : null;\n\t\tconst normalized = posAttr.normalized;\n\n\t\tif ( offset < 0 || count + offset - targetBuffer.offset > targetBuffer.length / 6 ) {\n\n\t\t\tthrow new Error( 'MeshBVH: compute triangle bounds range is invalid.' );\n\n\t\t}\n\n\t\t// used for non-normalized positions\n\t\tconst posArr = posAttr.array;\n\n\t\t// support for an interleaved position buffer\n\t\tconst bufferOffset = posAttr.offset || 0;\n\t\tlet stride = 3;\n\t\tif ( posAttr.isInterleavedBufferAttribute ) {\n\n\t\t\tstride = posAttr.data.stride;\n\n\t\t}\n\n\t\t// used for normalized positions\n\t\tconst getters = [ 'getX', 'getY', 'getZ' ];\n\t\tconst writeOffset = targetBuffer.offset;\n\n\t\t// iterate over the triangle range\n\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\tconst tri = indirectBuffer ? indirectBuffer[ i ] : i;\n\t\t\tconst tri3 = tri * 3;\n\t\t\tconst boundsIndexOffset = ( i - writeOffset ) * 6;\n\n\t\t\tlet ai = tri3 + 0;\n\t\t\tlet bi = tri3 + 1;\n\t\t\tlet ci = tri3 + 2;\n\n\t\t\tif ( index ) {\n\n\t\t\t\tai = index[ ai ];\n\t\t\t\tbi = index[ bi ];\n\t\t\t\tci = index[ ci ];\n\n\t\t\t}\n\n\t\t\t// we add the stride and offset here since we access the array directly\n\t\t\t// below for the sake of performance\n\t\t\tif ( ! normalized ) {\n\n\t\t\t\tai = ai * stride + bufferOffset;\n\t\t\t\tbi = bi * stride + bufferOffset;\n\t\t\t\tci = ci * stride + bufferOffset;\n\n\t\t\t}\n\n\t\t\tfor ( let el = 0; el < 3; el ++ ) {\n\n\t\t\t\tlet a, b, c;\n\n\t\t\t\tif ( normalized ) {\n\n\t\t\t\t\ta = posAttr[ getters[ el ] ]( ai );\n\t\t\t\t\tb = posAttr[ getters[ el ] ]( bi );\n\t\t\t\t\tc = posAttr[ getters[ el ] ]( ci );\n\n\t\t\t\t} else {\n\n\t\t\t\t\ta = posArr[ ai + el ];\n\t\t\t\t\tb = posArr[ bi + el ];\n\t\t\t\t\tc = posArr[ ci + el ];\n\n\t\t\t\t}\n\n\t\t\t\tlet min = a;\n\t\t\t\tif ( b < min ) min = b;\n\t\t\t\tif ( c < min ) min = c;\n\n\t\t\t\tlet max = a;\n\t\t\t\tif ( b > max ) max = b;\n\t\t\t\tif ( c > max ) max = c;\n\n\t\t\t\t// Increase the bounds size by float32 epsilon to avoid precision errors when\n\t\t\t\t// converting to 32 bit float. Scale the epsilon by the size of the numbers being\n\t\t\t\t// worked with.\n\t\t\t\tconst halfExtents = ( max - min ) / 2;\n\t\t\t\tconst el2 = el * 2;\n\t\t\t\ttargetBuffer[ boundsIndexOffset + el2 + 0 ] = min + halfExtents;\n\t\t\t\ttargetBuffer[ boundsIndexOffset + el2 + 1 ] = halfExtents + ( Math.abs( min ) + halfExtents ) * FLOAT32_EPSILON;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn targetBuffer;\n\n\t}\n\n\t/**\n\t * A convenience function for performing a raycast based on a mesh. Results are formed like\n\t * three.js raycast results in world frame.\n\t *\n\t * @param {Object3D} object\n\t * @param {Raycaster} raycaster\n\t * @param {Array<Intersection>} [intersects=[]]\n\t * @returns {Array<Intersection>}\n\t */\n\traycastObject3D( object, raycaster, intersects = [] ) {\n\n\t\tconst { material } = object;\n\t\tif ( material === undefined ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\t_inverseMatrix.copy( object.matrixWorld ).invert();\n\t\t_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );\n\n\t\t_worldScale.setFromMatrixScale( object.matrixWorld );\n\t\t_direction.copy( _ray.direction ).multiply( _worldScale );\n\n\t\tconst scaleFactor = _direction.length();\n\t\tconst near = raycaster.near / scaleFactor;\n\t\tconst far = raycaster.far / scaleFactor;\n\n\t\tif ( raycaster.firstHitOnly === true ) {\n\n\t\t\tlet hit = this.raycastFirst( _ray, material, near, far );\n\t\t\thit = convertRaycastIntersect( hit, object, raycaster );\n\t\t\tif ( hit ) {\n\n\t\t\t\tintersects.push( hit );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst hits = this.raycast( _ray, material, near, far );\n\t\t\tfor ( let i = 0, l = hits.length; i < l; i ++ ) {\n\n\t\t\t\tconst hit = convertRaycastIntersect( hits[ i ], object, raycaster );\n\t\t\t\tif ( hit ) {\n\n\t\t\t\t\tintersects.push( hit );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn intersects;\n\n\t}\n\n\t/**\n\t * Refit the node bounds to the current triangle positions. This is quicker than regenerating\n\t * a new BVH but will not be optimal after significant changes to the vertices. `nodeIndices`\n\t * is a set of node indices (provided by the `shapecast` function) that need to be refit\n\t * including all internal nodes.\n\t *\n\t * @param {Set<number>|Array<number>|null} [nodeIndices=null]\n\t */\n\trefit( nodeIndices = null ) {\n\n\t\tconst refitFunc = this.indirect ? refit_indirect : refit;\n\t\treturn refitFunc( this, nodeIndices );\n\n\t}\n\n\t/* Core Cast Functions */\n\n\t/**\n\t * Returns all raycast triangle hits in unsorted order. It is expected that `ray` is in the\n\t * frame of the BVH already. Likewise the returned results are also provided in the local\n\t * frame of the BVH. The `side` identifier is used to determine the side to check when\n\t * raycasting or a material with the given side field can be passed. If an array of materials\n\t * is provided then it is expected that the geometry has groups and the appropriate material\n\t * side is used per group.\n\t *\n\t * Note that unlike three.js' Raycaster results the points and distances in the intersections\n\t * returned from this function are relative to the local frame of the MeshBVH. When using the\n\t * `acceleratedRaycast` function as an override for `Mesh.raycast` they are transformed into\n\t * world space to be consistent with three's results.\n\t *\n\t * @param {Ray} ray\n\t * @param {number|Material|Array<Material>} [materialOrSide=FrontSide]\n\t * @param {number} [near=0]\n\t * @param {number} [far=Infinity]\n\t * @returns {Array<Intersection>}\n\t */\n\traycast( ray, materialOrSide = FrontSide, near = 0, far = Infinity ) {\n\n\t\tconst roots = this._roots;\n\t\tconst intersects = [];\n\t\tconst raycastFunc = this.indirect ? raycast_indirect : raycast;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\traycastFunc( this, i, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t\treturn intersects;\n\n\t}\n\n\t/**\n\t * Returns the first raycast hit in the model. This is typically much faster than returning\n\t * all hits. See `raycast` for information on the side and material options as well as the\n\t * frame of the returned intersections.\n\t *\n\t * @param {Ray} ray\n\t * @param {number|Material|Array<Material>} [materialOrSide=FrontSide]\n\t * @param {number} [near=0]\n\t * @param {number} [far=Infinity]\n\t * @returns {Intersection|null}\n\t */\n\traycastFirst( ray, materialOrSide = FrontSide, near = 0, far = Infinity ) {\n\n\t\tconst roots = this._roots;\n\t\tlet closestResult = null;\n\n\t\tconst raycastFirstFunc = this.indirect ? raycastFirst_indirect : raycastFirst;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\tconst result = raycastFirstFunc( this, i, materialOrSide, ray, near, far );\n\t\t\tif ( result != null && ( closestResult == null || result.distance < closestResult.distance ) ) {\n\n\t\t\t\tclosestResult = result;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn closestResult;\n\n\t}\n\n\t/**\n\t * Returns whether or not the mesh intersects the given geometry.\n\t *\n\t * The `geometryToBvh` parameter is the transform of the geometry in the BVH's local frame.\n\t *\n\t * Performance improves considerably if the provided geometry also has a `boundsTree`.\n\t *\n\t * @param {BufferGeometry} otherGeometry\n\t * @param {Matrix4} geometryToBvh - Transform of `otherGeometry` into the local space of\n\t * this BVH.\n\t * @returns {boolean}\n\t */\n\tintersectsGeometry( otherGeometry, geomToMesh ) {\n\n\t\tlet result = false;\n\t\tconst roots = this._roots;\n\t\tconst intersectsGeometryFunc = this.indirect ? intersectsGeometry_indirect : intersectsGeometry;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\tresult = intersectsGeometryFunc( this, i, otherGeometry, geomToMesh );\n\n\t\t\tif ( result ) {\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * A generalized cast function that can be used to implement intersection logic for custom\n\t * shapes. This is used internally for `intersectsBox`, `intersectsSphere`, and more. The\n\t * function returns as soon as a triangle has been reported as intersected and returns `true`\n\t * if a triangle has been intersected.\n\t *\n\t * @param {Object} callbacks\n\t * @param {IntersectsBoundsCallback} callbacks.intersectsBounds\n\t * @param {IntersectsTriangleCallback} [callbacks.intersectsTriangle]\n\t * @param {IntersectsRangeCallback} [callbacks.intersectsRange]\n\t * @param {BoundsTraverseOrderCallback} [callbacks.boundsTraverseOrder]\n\t * @returns {boolean}\n\t */\n\tshapecast( callbacks ) {\n\n\t\tconst triangle = ExtendedTrianglePool.getPrimitive();\n\t\tconst result = super.shapecast(\n\t\t\t{\n\t\t\t\t...callbacks,\n\t\t\t\tintersectsPrimitive: callbacks.intersectsTriangle,\n\t\t\t\tscratchPrimitive: triangle,\n\n\t\t\t\t// TODO: is the performance significant enough for the added complexity here?\n\t\t\t\t// can we just use one function?\n\t\t\t\titerate: this.indirect ? iterateOverTriangles_indirect : iterateOverTriangles,\n\t\t\t}\n\t\t);\n\t\tExtendedTrianglePool.releasePrimitive( triangle );\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * A generalized cast function that traverses two BVH structures simultaneously to perform\n\t * intersection tests between them. This is used internally by `intersectsGeometry`. The\n\t * function returns `true` as soon as a triangle pair has been reported as intersected by\n\t * the callbacks.\n\t *\n\t * `matrixToLocal` is a Matrix4 that transforms `otherBvh` into the local space of this BVH.\n\t * The other BVH's triangles are transformed by this matrix before intersection tests.\n\t *\n\t * @param {MeshBVH} otherBvh\n\t * @param {Matrix4} matrixToLocal - Transforms `otherBvh` into the local space of this BVH.\n\t * @param {Object} callbacks\n\t * @param {IntersectsRangesCallback} [callbacks.intersectsRanges]\n\t * @param {IntersectsTrianglesCallback} [callbacks.intersectsTriangles]\n\t * @returns {boolean}\n\t */\n\tbvhcast( otherBvh, matrixToLocal, callbacks ) {\n\n\t\tlet {\n\t\t\tintersectsRanges,\n\t\t\tintersectsTriangles,\n\t\t} = callbacks;\n\n\t\tconst triangle1 = ExtendedTrianglePool.getPrimitive();\n\t\tconst indexAttr1 = this.geometry.index;\n\t\tconst positionAttr1 = this.geometry.attributes.position;\n\t\tconst assignTriangle1 = this.indirect ?\n\t\t\ti1 => {\n\n\n\t\t\t\tconst ti = this.resolveTriangleIndex( i1 );\n\t\t\t\tsetTriangle( triangle1, ti * 3, indexAttr1, positionAttr1 );\n\n\t\t\t} :\n\t\t\ti1 => {\n\n\t\t\t\tsetTriangle( triangle1, i1 * 3, indexAttr1, positionAttr1 );\n\n\t\t\t};\n\n\t\tconst triangle2 = ExtendedTrianglePool.getPrimitive();\n\t\tconst indexAttr2 = otherBvh.geometry.index;\n\t\tconst positionAttr2 = otherBvh.geometry.attributes.position;\n\t\tconst assignTriangle2 = otherBvh.indirect ?\n\t\t\ti2 => {\n\n\t\t\t\tconst ti2 = otherBvh.resolveTriangleIndex( i2 );\n\t\t\t\tsetTriangle( triangle2, ti2 * 3, indexAttr2, positionAttr2 );\n\n\t\t\t} :\n\t\t\ti2 => {\n\n\t\t\t\tsetTriangle( triangle2, i2 * 3, indexAttr2, positionAttr2 );\n\n\t\t\t};\n\n\t\t// generate triangle callback if needed\n\t\tif ( intersectsTriangles ) {\n\n\t\t\tif ( ! ( otherBvh instanceof MeshBVH ) ) {\n\n\t\t\t\tthrow new Error( 'MeshBVH: \"intersectsTriangles\" callback can only be used with another MeshBVH.' );\n\n\t\t\t}\n\n\t\t\tconst iterateOverDoubleTriangles = ( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 ) => {\n\n\t\t\t\tfor ( let i2 = offset2, l2 = offset2 + count2; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\tassignTriangle2( i2 );\n\n\t\t\t\t\ttriangle2.a.applyMatrix4( matrixToLocal );\n\t\t\t\t\ttriangle2.b.applyMatrix4( matrixToLocal );\n\t\t\t\t\ttriangle2.c.applyMatrix4( matrixToLocal );\n\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\tfor ( let i1 = offset1, l1 = offset1 + count1; i1 < l1; i1 ++ ) {\n\n\t\t\t\t\t\tassignTriangle1( i1 );\n\n\t\t\t\t\t\ttriangle1.needsUpdate = true;\n\n\t\t\t\t\t\tif ( intersectsTriangles( triangle1, triangle2, i1, i2, depth1, nodeIndex1, depth2, nodeIndex2 ) ) {\n\n\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t\tif ( intersectsRanges ) {\n\n\t\t\t\tconst originalIntersectsRanges = intersectsRanges;\n\t\t\t\tintersectsRanges = function ( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 ) {\n\n\t\t\t\t\tif ( ! originalIntersectsRanges( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 ) ) {\n\n\t\t\t\t\t\treturn iterateOverDoubleTriangles( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t};\n\n\t\t\t} else {\n\n\t\t\t\tintersectsRanges = iterateOverDoubleTriangles;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn super.bvhcast( otherBvh, matrixToLocal, { intersectsRanges } );\n\n\t}\n\n\n\t/* Derived Cast Functions */\n\n\t/**\n\t * Returns whether or not the mesh intersects the given box.\n\t *\n\t * The `boxToBvh` parameter is the transform of the box in the meshes frame.\n\t *\n\t * @param {Box3} box\n\t * @param {Matrix4} boxToBvh - Transform of the box in the local space of this BVH.\n\t * @returns {boolean}\n\t */\n\tintersectsBox( box, boxToMesh ) {\n\n\t\t_obb.set( box.min, box.max, boxToMesh );\n\t\t_obb.needsUpdate = true;\n\n\t\treturn this.shapecast(\n\t\t\t{\n\t\t\t\tintersectsBounds: box => _obb.intersectsBox( box ),\n\t\t\t\tintersectsTriangle: tri => _obb.intersectsTriangle( tri )\n\t\t\t}\n\t\t);\n\n\t}\n\n\t/**\n\t * Returns whether or not the mesh intersects the given sphere.\n\t *\n\t * @param {Sphere} sphere\n\t * @returns {boolean}\n\t */\n\tintersectsSphere( sphere ) {\n\n\t\treturn this.shapecast(\n\t\t\t{\n\t\t\t\tintersectsBounds: box => sphere.intersectsBox( box ),\n\t\t\t\tintersectsTriangle: tri => tri.intersectsSphere( sphere )\n\t\t\t}\n\t\t);\n\n\t}\n\n\t/**\n\t * Computes the closest distance from the geometry to the mesh and puts the closest point on\n\t * the mesh in `target1` (in the frame of the BVH) and the closest point on the other\n\t * geometry in `target2` (in the geometry frame). If `target1` is not provided a new Object\n\t * is created and returned from the function.\n\t *\n\t * The `geometryToBvh` parameter is the transform of the geometry in the BVH's local frame.\n\t *\n\t * If a point is found that is closer than `minThreshold` then the function will return that\n\t * result early. Any triangles or points outside of `maxThreshold` are ignored. If no point\n\t * is found within the min / max thresholds then `null` is returned and the target objects\n\t * are not modified.\n\t *\n\t * The returned faceIndex in `target1` and `target2` can be used with the standalone function\n\t * `getTriangleHitPointInfo` to obtain more information like UV coordinates, triangle normal\n\t * and materialIndex.\n\t *\n\t * _Note that this function can be very slow if `geometry` does not have a\n\t * `geometry.boundsTree` computed._\n\t *\n\t * @param {BufferGeometry} otherGeometry\n\t * @param {Matrix4} geometryToBvh - Transform of `otherGeometry` into the local space of\n\t * this BVH.\n\t * @param {HitPointInfo} [target1={}]\n\t * @param {HitPointInfo} [target2={}]\n\t * @param {number} [minThreshold=0]\n\t * @param {number} [maxThreshold=Infinity]\n\t * @returns {HitPointInfo|null}\n\t */\n\tclosestPointToGeometry( otherGeometry, geometryToBvh, target1 = { }, target2 = { }, minThreshold = 0, maxThreshold = Infinity ) {\n\n\t\tconst closestPointToGeometryFunc = this.indirect ? closestPointToGeometry_indirect : closestPointToGeometry;\n\t\treturn closestPointToGeometryFunc(\n\t\t\tthis,\n\t\t\totherGeometry,\n\t\t\tgeometryToBvh,\n\t\t\ttarget1,\n\t\t\ttarget2,\n\t\t\tminThreshold,\n\t\t\tmaxThreshold,\n\t\t);\n\n\t}\n\n\t/**\n\t * Computes the closest distance from the point to the mesh and gives additional information\n\t * in `target`. The target can be left undefined to default to a new object which is\n\t * ultimately returned by the function.\n\t *\n\t * If a point is found that is closer than `minThreshold` then the function will return that\n\t * result early. Any triangles or points outside of `maxThreshold` are ignored. If no point\n\t * is found within the min / max thresholds then `null` is returned and the `target` object\n\t * is not modified.\n\t *\n\t * The returned faceIndex can be used with the standalone function `getTriangleHitPointInfo`\n\t * to obtain more information like UV coordinates, triangle normal and materialIndex.\n\t *\n\t * @param {Vector3} point\n\t * @param {HitPointInfo} [target={}]\n\t * @param {number} [minThreshold=0]\n\t * @param {number} [maxThreshold=Infinity]\n\t * @returns {HitPointInfo|null}\n\t */\n\tclosestPointToPoint( point, target = { }, minThreshold = 0, maxThreshold = Infinity ) {\n\n\t\treturn closestPointToPoint(\n\t\t\tthis,\n\t\t\tpoint,\n\t\t\ttarget,\n\t\t\tminThreshold,\n\t\t\tmaxThreshold,\n\t\t);\n\n\t}\n\n}\n","/** @import { Object3D } from 'three' */\n/** @import { IntersectsBoundsCallback, IntersectsRangeCallback, BoundsTraverseOrderCallback } from './BVH.js' */\nimport { Box3, BufferGeometry, Matrix4, Mesh, Vector3, Ray, Sphere } from 'three';\nimport { BVH } from './BVH.js';\nimport { INTERSECTED, NOT_INTERSECTED } from './Constants.js';\n\nconst _geometry = /* @__PURE__ */ new BufferGeometry();\nconst _matrix = /* @__PURE__ */ new Matrix4();\nconst _inverseMatrix = /* @__PURE__ */ new Matrix4();\nconst _box = /* @__PURE__ */ new Box3();\nconst _sphere = /* @__PURE__ */ new Sphere();\nconst _vec = /* @__PURE__ */ new Vector3();\nconst _ray = /* @__PURE__ */ new Ray();\nconst _mesh = /* @__PURE__ */ new Mesh();\nconst _geometryRange = {};\n\n/**\n * @callback IntersectsObjectCallback\n * @param {Object3D} object - The scene object whose bounds were intersected.\n * @param {number} instanceId - Instance index for InstancedMesh/BatchedMesh, or 0 for regular objects.\n * @param {boolean} contained - Whether the node bounds are fully contained by the query shape.\n * @param {number} depth - The depth of the node in the tree.\n * @returns {boolean} Return `true` to stop traversal.\n */\n\n/**\n * BVH built from a scene hierarchy rather than a single geometry. Each leaf holds\n * one Object3D (or one instance of an InstancedMesh/BatchedMesh), enabling\n * accelerated raycasting and spatial queries across many objects at once.\n *\n * @param {Object3D | Array<Object3D>} root - Root object or array of objects.\n * @param {Object} [options] - Accepts all standard BVH options plus:\n * @param {boolean} [options.precise=false] - Use vertex-level bounds instead of cached bounding boxes.\n * @param {boolean} [options.includeInstances=true] - Treat each instance of InstancedMesh/BatchedMesh as a separate primitive.\n * @extends BVH\n */\nexport class ObjectBVH extends BVH {\n\n\tconstructor( root, options = {} ) {\n\n\t\toptions = {\n\t\t\tprecise: false,\n\t\t\tincludeInstances: true,\n\t\t\tmatrixWorld: Array.isArray( root ) ? new Matrix4() : root.matrixWorld,\n\t\t\ttargetLeafSize: 1,\n\t\t\t...options,\n\t\t};\n\n\t\tsuper();\n\n\t\t// collect all the leaf node objects in the geometries\n\t\tconst objectSet = new Set();\n\t\tcollectObjects( root, objectSet );\n\n\t\t// calculate the number of bits required for the primary id, leaving the remainder\n\t\t// for the instanceId count\n\t\tconst objects = Array.from( objectSet );\n\t\tconst idBits = Math.ceil( Math.log2( objects.length ) );\n\t\tconst idMask = ( 1 << idBits ) - 1;\n\n\t\tthis.objects = objects;\n\t\tthis.idBits = idBits;\n\t\tthis.idMask = idMask;\n\t\tthis.primitiveBuffer = null;\n\t\tthis.primitiveBufferStride = 1;\n\n\t\t// settings\n\t\tthis.precise = options.precise;\n\t\tthis.includeInstances = options.includeInstances;\n\t\tthis.matrixWorld = options.matrixWorld;\n\n\t\tthis.init( options );\n\n\t}\n\n\t/**\n\t * Returns the `Object3D` associated with a composite id as provided to `intersectsObject`.\n\t * @param {number} compositeId\n\t * @returns {Object3D}\n\t */\n\tgetObjectFromId( compositeId ) {\n\n\t\tconst { idMask, objects } = this;\n\t\tconst id = getObjectId( compositeId, idMask );\n\t\treturn objects[ id ];\n\n\t}\n\n\t/**\n\t * Returns the instance index associated with a composite id as provided to `intersectsObject`.\n\t * @param {number} compositeId\n\t * @returns {number}\n\t */\n\tgetInstanceFromId( compositeId ) {\n\n\t\tconst { idMask, idBits } = this;\n\t\treturn getInstanceId( compositeId, idBits, idMask );\n\n\t}\n\n\tinit( options ) {\n\n\t\tconst { objects, idBits, matrixWorld } = this;\n\n\t\t// pre-cache the inverse matrix for use in the \"getPrimitiveBoundingBox\" function\n\t\t_inverseMatrix.copy( matrixWorld ).invert();\n\n\t\tthis.primitiveBuffer = new Uint32Array( this._countPrimitives( objects ) );\n\t\tthis._fillPrimitiveBuffer( objects, idBits, this.primitiveBuffer );\n\n\t\tsuper.init( options );\n\n\t}\n\n\trefit( ...args ) {\n\n\t\t// pre-cache the inverse matrix for use in the \"getPrimitiveBoundingBox\" function\n\t\t_inverseMatrix.copy( this.matrixWorld ).invert();\n\n\t\tsuper.refit( ...args );\n\n\t}\n\n\twritePrimitiveBounds( i, targetBuffer, writeOffset ) {\n\n\t\tconst { primitiveBuffer } = this;\n\t\tthis._getPrimitiveBoundingBox( primitiveBuffer[ i ], _inverseMatrix, _box );\n\n\t\tconst { min, max } = _box;\n\t\ttargetBuffer[ writeOffset + 0 ] = min.x;\n\t\ttargetBuffer[ writeOffset + 1 ] = min.y;\n\t\ttargetBuffer[ writeOffset + 2 ] = min.z;\n\t\ttargetBuffer[ writeOffset + 3 ] = max.x;\n\t\ttargetBuffer[ writeOffset + 4 ] = max.y;\n\t\ttargetBuffer[ writeOffset + 5 ] = max.z;\n\n\t}\n\n\tgetRootRanges() {\n\n\t\treturn [ { offset: 0, count: this.primitiveBuffer.length } ];\n\n\t}\n\n\t/**\n\t * Performs a spatial query against the BVH. Extends the base `shapecast` with an\n\t * `intersectsObject` callback that is called once per object primitive in leaf nodes.\n\t *\n\t * @param {Object} callbacks\n\t * @param {IntersectsBoundsCallback} callbacks.intersectsBounds\n\t * @param {IntersectsObjectCallback} [callbacks.intersectsObject]\n\t * @param {IntersectsRangeCallback} [callbacks.intersectsRange]\n\t * @param {BoundsTraverseOrderCallback} [callbacks.boundsTraverseOrder]\n\t * @returns {boolean}\n\t */\n\tshapecast( callbacks ) {\n\n\t\treturn super.shapecast( {\n\t\t\t...callbacks,\n\n\t\t\tintersectsPrimitive: callbacks.intersectsObject,\n\t\t\tscratchPrimitive: null,\n\t\t\titerate: iterateOverObjects,\n\t\t} );\n\n\t}\n\n\t// TODO: this is out of sync with the MeshBVH raycast signature.\n\t// Change this to \"raycastObject3D\"? Or add an equivalent?\n\traycast( raycaster, intersects = [] ) {\n\n\t\tconst { matrixWorld, includeInstances } = this;\n\t\tconst { firstHitOnly } = raycaster;\n\t\tconst localIntersects = [];\n\n\t\t// transform the ray into the local bvh frame\n\t\t_inverseMatrix.copy( matrixWorld ).invert();\n\t\t_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );\n\n\t\tlet closestDistance = Infinity;\n\t\tlet closestHit = null;\n\n\t\tthis.shapecast( {\n\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\treturn box.distanceToPoint( _ray.origin );\n\n\t\t\t},\n\t\t\tintersectsBounds: box => {\n\n\t\t\t\tif ( firstHitOnly ) {\n\n\t\t\t\t\tif ( ! _ray.intersectBox( box, _vec ) ) {\n\n\t\t\t\t\t\treturn NOT_INTERSECTED;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tlet dist;\n\t\t\t\t\tif ( box.containsPoint( _ray.origin ) ) {\n\n\t\t\t\t\t\tdist = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_vec.applyMatrix4( matrixWorld );\n\t\t\t\t\t\tdist = raycaster.ray.origin.distanceTo( _vec );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// early out if the box is further than the closest raycast\n\t\t\t\t\treturn dist < closestDistance ? INTERSECTED : NOT_INTERSECTED;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn _ray.intersectsBox( box ) ? INTERSECTED : NOT_INTERSECTED;\n\n\t\t\t\t}\n\n\t\t\t},\n\t\t\tintersectsObject( object, instanceId ) {\n\n\t\t\t\t// skip non visible objects\n\t\t\t\tif ( ! object.visible ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tlocalIntersects.length = 0;\n\n\t\t\t\tif ( object.isInstancedMesh && includeInstances ) {\n\n\t\t\t\t\t// raycast the instance\n\t\t\t\t\t_mesh.geometry = object.geometry;\n\t\t\t\t\t_mesh.material = object.material;\n\n\t\t\t\t\tobject.getMatrixAt( instanceId, _mesh.matrixWorld );\n\t\t\t\t\t_mesh.matrixWorld.premultiply( object.matrixWorld );\n\t\t\t\t\t_mesh.raycast( raycaster, localIntersects );\n\n\t\t\t\t\tlocalIntersects.forEach( hit => {\n\n\t\t\t\t\t\thit.object = object;\n\t\t\t\t\t\thit.instanceId = instanceId;\n\n\t\t\t\t\t} );\n\n\t\t\t\t\t_mesh.material = null;\n\n\t\t\t\t} else if ( object.isBatchedMesh && includeInstances ) {\n\n\t\t\t\t\tif ( ! object.getVisibleAt( instanceId ) ) {\n\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// extract the geometry & material\n\t\t\t\t\tconst geometryId = object.getGeometryIdAt( instanceId );\n\t\t\t\t\tconst geometryRange = object.getGeometryRangeAt( geometryId, _geometryRange );\n\n\t\t\t\t\t_geometry.index = object.geometry.index;\n\t\t\t\t\t_geometry.attributes = object.geometry.attributes;\n\t\t\t\t\t_geometry.setDrawRange( geometryRange.start, geometryRange.count );\n\n\t\t\t\t\t_mesh.geometry = _geometry;\n\t\t\t\t\t_mesh.material = object.material;\n\n\t\t\t\t\t// perform a raycast against the proxy mesh\n\t\t\t\t\tobject.getMatrixAt( instanceId, _mesh.matrixWorld );\n\t\t\t\t\t_mesh.matrixWorld.premultiply( object.matrixWorld );\n\t\t\t\t\t_mesh.raycast( raycaster, localIntersects );\n\n\t\t\t\t\t// fix up the fields\n\t\t\t\t\tlocalIntersects.forEach( hit => {\n\n\t\t\t\t\t\thit.object = object;\n\t\t\t\t\t\thit.batchId = instanceId;\n\n\t\t\t\t\t} );\n\n\t\t\t\t\t_mesh.material = null;\n\t\t\t\t\t_geometry.index = null;\n\t\t\t\t\t_geometry.attributes = null;\n\t\t\t\t\t_geometry.setDrawRange( 0, Infinity );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tobject.raycast( raycaster, localIntersects );\n\n\t\t\t\t}\n\n\t\t\t\t// find the closest hit to track\n\t\t\t\tif ( firstHitOnly ) {\n\n\t\t\t\t\tlocalIntersects.forEach( hit => {\n\n\t\t\t\t\t\tif ( hit.distance < closestDistance ) {\n\n\t\t\t\t\t\t\tclosestDistance = hit.distance;\n\t\t\t\t\t\t\tclosestHit = hit;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersects.push( ...localIntersects );\n\n\t\t\t\t}\n\n\t\t\t},\n\t\t} );\n\n\t\t// save the closest hit only if firstHitOnly = true\n\t\tif ( firstHitOnly && closestHit ) {\n\n\t\t\tintersects.push( closestHit );\n\n\t\t}\n\n\t\treturn intersects;\n\n\t}\n\n\t// get the bounding box of a primitive node accounting for the bvh options\n\t_getPrimitiveBoundingBox( compositeId, inverseMatrixWorld, target ) {\n\n\t\tconst { objects, idMask, idBits, precise, includeInstances } = this;\n\t\tconst id = getObjectId( compositeId, idMask );\n\t\tconst instanceId = getInstanceId( compositeId, idBits, idMask );\n\t\tconst object = objects[ id ];\n\n\t\tif ( ! includeInstances && ( object.isInstancedMesh || object.isBatchedMesh ) ) {\n\n\t\t\t// if we're not using instances then just account for the overall bounds of the BatchedMesh and InstancedMesh\n\t\t\tif ( ! object.boundingBox ) {\n\n\t\t\t\tobject.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( ! object.boundingSphere ) {\n\n\t\t\t\tobject.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\t_matrix\n\t\t\t\t.copy( object.matrixWorld )\n\t\t\t\t.premultiply( inverseMatrixWorld );\n\n\t\t\t_sphere\n\t\t\t\t.copy( object.boundingSphere )\n\t\t\t\t.applyMatrix4( _matrix );\n\n\t\t\ttarget\n\t\t\t\t.copy( object.boundingBox )\n\t\t\t\t.applyMatrix4( _matrix );\n\n\t\t\tshrinkToSphere( target, _sphere );\n\n\t\t} else if ( precise ) {\n\n\t\t\t// calculate precise bounds if necessary by calculating the bounds of all vertices\n\t\t\t// in the bvh frame\n\t\t\tif ( object.isInstancedMesh ) {\n\n\t\t\t\tobject\n\t\t\t\t\t.getMatrixAt( instanceId, _matrix );\n\n\t\t\t\t_matrix\n\t\t\t\t\t.premultiply( object.matrixWorld )\n\t\t\t\t\t.premultiply( inverseMatrixWorld );\n\n\t\t\t\tgetPreciseBounds( object.geometry, _matrix, target );\n\n\t\t\t} else if ( object.isBatchedMesh ) {\n\n\t\t\t\tconst geometryId = object.getGeometryIdAt( instanceId );\n\t\t\t\tconst geometryRange = object.getGeometryRangeAt( geometryId, _geometryRange );\n\n\t\t\t\t_geometry.index = object.geometry.index;\n\t\t\t\t_geometry.attributes = object.geometry.attributes;\n\t\t\t\t_geometry.setDrawRange( geometryRange.start, geometryRange.count );\n\n\t\t\t\tobject\n\t\t\t\t\t.getMatrixAt( instanceId, _matrix );\n\n\t\t\t\t_matrix\n\t\t\t\t\t.premultiply( object.matrixWorld )\n\t\t\t\t\t.premultiply( inverseMatrixWorld );\n\n\t\t\t\tgetPreciseBounds( _geometry, _matrix, target );\n\n\t\t\t\t_geometry.attributes = null;\n\n\t\t\t} else {\n\n\t\t\t\t_matrix\n\t\t\t\t\t.copy( object.matrixWorld )\n\t\t\t\t\t.premultiply( inverseMatrixWorld );\n\n\t\t\t\ttarget.setFromObject( object, true ).applyMatrix4( inverseMatrixWorld );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// otherwise use the fast path of extracting the cached, AABB bounds and transforming them\n\t\t\t// into the local BVH frame\n\t\t\tif ( object.isInstancedMesh ) {\n\n\t\t\t\tif ( ! object.geometry.boundingBox ) {\n\n\t\t\t\t\tobject.geometry.computeBoundingBox();\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! object.geometry.boundingSphere ) {\n\n\t\t\t\t\tobject.geometry.computeBoundingSphere();\n\n\t\t\t\t}\n\n\t\t\t\tobject\n\t\t\t\t\t.getMatrixAt( instanceId, _matrix );\n\n\t\t\t\t_matrix\n\t\t\t\t\t.premultiply( object.matrixWorld )\n\t\t\t\t\t.premultiply( inverseMatrixWorld );\n\n\t\t\t\t_sphere\n\t\t\t\t\t.copy( object.geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( _matrix );\n\n\t\t\t\ttarget\n\t\t\t\t\t.copy( object.geometry.boundingBox )\n\t\t\t\t\t.applyMatrix4( _matrix );\n\n\t\t\t\tshrinkToSphere( target, _sphere );\n\n\t\t\t} else if ( object.isBatchedMesh ) {\n\n\t\t\t\tconst geometryId = object.getGeometryIdAt( instanceId );\n\n\t\t\t\tobject\n\t\t\t\t\t.getMatrixAt( instanceId, _matrix );\n\n\t\t\t\t_matrix\n\t\t\t\t\t.premultiply( object.matrixWorld )\n\t\t\t\t\t.premultiply( inverseMatrixWorld );\n\n\t\t\t\tobject\n\t\t\t\t\t.getBoundingSphereAt( geometryId, _sphere )\n\t\t\t\t\t.applyMatrix4( _matrix );\n\n\t\t\t\tobject\n\t\t\t\t\t.getBoundingBoxAt( geometryId, target )\n\t\t\t\t\t.applyMatrix4( _matrix );\n\n\t\t\t\tshrinkToSphere( target, _sphere );\n\n\t\t\t} else {\n\n\t\t\t\ttarget\n\t\t\t\t\t.setFromObject( object, false )\n\t\t\t\t\t.applyMatrix4( inverseMatrixWorld );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// counts the total number of primitives required by the objects in given array of objects\n\t_countPrimitives( objects ) {\n\n\t\tconst { includeInstances } = this;\n\t\tlet total = 0;\n\t\tobjects.forEach( object => {\n\n\t\t\tif ( object.isInstancedMesh && includeInstances ) {\n\n\t\t\t\ttotal += object.count;\n\n\t\t\t} else if ( object.isBatchedMesh && includeInstances ) {\n\n\t\t\t\tif ( ! ( 'instanceCount' in object ) ) {\n\n\t\t\t\t\tthrow new Error( 'ObjectBVH: Three.js revision >= r169 is required to use BatchedMesh.' );\n\n\t\t\t\t}\n\n\t\t\t\ttotal += object.instanceCount;\n\n\t\t\t} else {\n\n\t\t\t\ttotal ++;\n\n\t\t\t}\n\n\t\t} );\n\n\t\treturn total;\n\n\t}\n\n\t_fillPrimitiveBuffer( objects, idBits, target ) {\n\n\t\tconst { includeInstances } = this;\n\t\tlet index = 0;\n\t\tobjects.forEach( ( object, i ) => {\n\n\t\t\tif ( object.isInstancedMesh && includeInstances ) {\n\n\t\t\t\tconst count = object.count;\n\t\t\t\tfor ( let c = 0; c < count; c ++ ) {\n\n\t\t\t\t\ttarget[ index ] = ( c << idBits ) | i;\n\t\t\t\t\tindex ++;\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isBatchedMesh && includeInstances ) {\n\n\t\t\t\tconst { instanceCount, maxInstanceCount } = object;\n\t\t\t\tlet foundInstances = 0;\n\t\t\t\tlet iter = 0;\n\n\t\t\t\twhile ( foundInstances < instanceCount && iter < maxInstanceCount ) {\n\n\t\t\t\t\t// TODO: it would be better to have a consistent way of querying whether an\n\t\t\t\t\t// instance were active\n\t\t\t\t\ttry {\n\n\t\t\t\t\t\tobject.getVisibleAt( iter );\n\n\t\t\t\t\t\ttarget[ index ] = ( iter << idBits ) | i;\n\t\t\t\t\t\tfoundInstances ++;\n\t\t\t\t\t\tindex ++;\n\n\t\t\t\t\t} catch {\n\n\t\t\t\t\t\t//\n\n\t\t\t\t\t}\n\n\t\t\t\t\titer ++;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\ttarget[ index ] = i;\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n}\n\n// id functions\n// extract the primary object id given the provided mask\nfunction getObjectId( id, idMask ) {\n\n\treturn id & idMask;\n\n}\n\n// extract the instance id given the mask and number of bits to shift\nfunction getInstanceId( id, idBits, idMask ) {\n\n\treturn ( id & ( ~ idMask ) ) >>> idBits;\n\n}\n\n// traverse the full scene and collect all leaves\nfunction collectObjects( root, objectSet = new Set() ) {\n\n\tif ( Array.isArray( root ) ) {\n\n\t\troot.forEach( object => collectObjects( object, objectSet ) );\n\n\t} else {\n\n\t\troot.traverse( child => {\n\n\t\t\tif ( child.isMesh || child.isLine || child.isPoints ) {\n\n\t\t\t\tobjectSet.add( child );\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n}\n\n// calculate precise box bounds of the given geometry in the given frame\nfunction getPreciseBounds( geometry, matrix, target ) {\n\n\ttarget.makeEmpty();\n\n\tconst drawRange = geometry.drawRange;\n\tconst indexAttr = geometry.index;\n\tconst posAttr = geometry.attributes.position;\n\tconst start = drawRange.start;\n\tconst vertCount = indexAttr ? indexAttr.count : posAttr.count;\n\tconst count = Math.min( vertCount - start, drawRange.count );\n\tfor ( let i = start, l = start + count; i < l; i ++ ) {\n\n\t\tlet vi = i;\n\t\tif ( indexAttr ) {\n\n\t\t\tvi = indexAttr.getX( vi );\n\n\t\t}\n\n\t\t_vec.fromBufferAttribute( posAttr, vi ).applyMatrix4( matrix );\n\t\ttarget.expandByPoint( _vec );\n\n\t}\n\n\treturn target;\n\n}\n\n// iterator helper for raycasting\nfunction iterateOverObjects( offset, count, bvh, callback, contained, depth, /* scratch */ ) {\n\n\tconst { primitiveBuffer, objects, idMask, idBits } = bvh;\n\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\tconst compositeId = primitiveBuffer[ i ];\n\t\tconst id = getObjectId( compositeId, idMask );\n\t\tconst instanceId = getInstanceId( compositeId, idBits, idMask );\n\t\tconst object = objects[ id ];\n\t\tif ( callback( object, instanceId, contained, depth ) ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t}\n\n\treturn false;\n\n}\n\nfunction shrinkToSphere( box, sphere ) {\n\n\t_vec.copy( sphere.center ).addScalar( - sphere.radius );\n\tbox.min.max( _vec );\n\n\t_vec.copy( sphere.center ).addScalar( sphere.radius );\n\tbox.max.min( _vec );\n\n}\n","/** @import { SkinnedMesh } from 'three' */\n/** @import { IntersectsBoundsCallback, IntersectsRangeCallback, BoundsTraverseOrderCallback } from './BVH.js' */\nimport { Vector3, Vector2, Ray, Matrix4, FrontSide, BackSide, Triangle, REVISION } from 'three';\nimport { GeometryBVH } from './GeometryBVH.js';\nimport { ExtendedTriangle } from '../math/ExtendedTriangle.js';\nimport { INTERSECTED, NOT_INTERSECTED, SKIP_GENERATION } from './Constants.js';\n\nconst _v0 = /* @__PURE__ */ new Vector3();\nconst _v1 = /* @__PURE__ */ new Vector3();\nconst _v2 = /* @__PURE__ */ new Vector3();\nconst _ray = /* @__PURE__ */ new Ray();\nconst _inverseMatrix = /* @__PURE__ */ new Matrix4();\nconst _localPoint = /* @__PURE__ */ new Vector3();\nconst _vec = /* @__PURE__ */ new Vector3();\nconst _axes = [ 'x', 'y', 'z' ];\n\nconst IS_GT_REVISION_169 = parseInt( REVISION ) >= 169;\nconst IS_LT_REVISION_161 = parseInt( REVISION ) <= 161;\n\nconst _uvA = /* @__PURE__ */ new Vector2();\nconst _uvB = /* @__PURE__ */ new Vector2();\nconst _uvC = /* @__PURE__ */ new Vector2();\nconst _normalA = /* @__PURE__ */ new Vector3();\nconst _normalB = /* @__PURE__ */ new Vector3();\nconst _normalC = /* @__PURE__ */ new Vector3();\n\n/**\n * @callback IntersectsTriangleCallback\n * @param {ExtendedTriangle} triangle - The triangle primitive in local space.\n * @param {number} index - The primitive index within the BVH buffer.\n * @param {boolean} contained - Whether the node bounds are fully contained by the query shape.\n * @param {number} depth - The depth of the node in the tree.\n * @returns {boolean} Return `true` to stop traversal.\n */\n\n/**\n * BVH for `SkinnedMesh` objects. Computes primitive bounds using\n * `SkinnedMesh.getVertexPosition` so the tree reflects the current posed state\n * of the mesh. Call `refit()` after updating the skeleton to keep bounds accurate.\n *\n * @param {SkinnedMesh} mesh\n * @param {Object} [options] - Same options as {@link GeometryBVH}.\n * @extends GeometryBVH\n */\nexport class SkinnedMeshBVH extends GeometryBVH {\n\n\tget primitiveStride() {\n\n\t\treturn 3;\n\n\t}\n\n\tconstructor( mesh, options = {} ) {\n\n\t\tif ( ! mesh.isMesh ) {\n\n\t\t\tthrow new Error( 'SkinnedMeshBVH: First argument must be a Mesh.' );\n\n\t\t}\n\n\t\t// skip generation initially so we can add our local fields\n\t\t// TODO: is there a more clean way to handle this? Update all subclasses to be\n\t\t// responsible for calling \"init\" themselves?\n\t\tsuper( mesh.geometry, {\n\t\t\t...options,\n\t\t\t[ SKIP_GENERATION ]: true,\n\t\t} );\n\t\tthis.mesh = mesh;\n\n\t\tif ( ! options[ SKIP_GENERATION ] ) {\n\n\t\t\tthis.init( options );\n\n\t\t}\n\n\t}\n\n\twritePrimitiveBounds( i, targetBuffer, baseIndex ) {\n\n\t\tconst { mesh, geometry } = this;\n\t\tconst indirectBuffer = this._indirectBuffer;\n\t\tconst index = geometry.index ? geometry.index.array : null;\n\n\t\tconst tri = indirectBuffer ? indirectBuffer[ i ] : i;\n\t\tconst tri3 = tri * 3;\n\n\t\tlet ai = tri3 + 0;\n\t\tlet bi = tri3 + 1;\n\t\tlet ci = tri3 + 2;\n\n\t\tif ( index ) {\n\n\t\t\tai = index[ ai ];\n\t\t\tbi = index[ bi ];\n\t\t\tci = index[ ci ];\n\n\t\t}\n\n\t\t// Get skinned vertex positions\n\t\tmesh.getVertexPosition( ai, _v0 );\n\t\tmesh.getVertexPosition( bi, _v1 );\n\t\tmesh.getVertexPosition( ci, _v2 );\n\n\t\t// Compute bounds for each axis\n\t\tfor ( let el = 0; el < 3; el ++ ) {\n\n\t\t\tconst axis = _axes[ el ];\n\t\t\tconst a = _v0[ axis ];\n\t\t\tconst b = _v1[ axis ];\n\t\t\tconst c = _v2[ axis ];\n\n\t\t\tlet min = a;\n\t\t\tif ( b < min ) min = b;\n\t\t\tif ( c < min ) min = c;\n\n\t\t\tlet max = a;\n\t\t\tif ( b > max ) max = b;\n\t\t\tif ( c > max ) max = c;\n\n\t\t\t// Write in min/max format [minx, miny, minz, maxx, maxy, maxz]\n\t\t\ttargetBuffer[ baseIndex + el ] = min;\n\t\t\ttargetBuffer[ baseIndex + el + 3 ] = max;\n\n\t\t}\n\n\t\treturn targetBuffer;\n\n\t}\n\n\t/**\n\t * Performs a spatial query against the BVH. Extends the base `shapecast` with an\n\t * `intersectsTriangle` callback that is called once per triangle primitive in leaf nodes.\n\t *\n\t * @param {Object} callbacks\n\t * @param {IntersectsBoundsCallback} callbacks.intersectsBounds\n\t * @param {IntersectsTriangleCallback} [callbacks.intersectsTriangle]\n\t * @param {IntersectsRangeCallback} [callbacks.intersectsRange]\n\t * @param {BoundsTraverseOrderCallback} [callbacks.boundsTraverseOrder]\n\t * @returns {boolean}\n\t */\n\tshapecast( callbacks ) {\n\n\t\tconst triangle = new ExtendedTriangle();\n\t\treturn super.shapecast(\n\t\t\t{\n\t\t\t\t...callbacks,\n\t\t\t\tintersectsPrimitive: callbacks.intersectsTriangle,\n\t\t\t\tscratchPrimitive: triangle,\n\t\t\t\titerate: iterateOverTriangles,\n\t\t\t},\n\t\t);\n\n\t}\n\n\traycastObject3D( object, raycaster, intersects = [] ) {\n\n\t\tconst { material } = object;\n\t\tif ( material === undefined ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst { matrixWorld } = object;\n\t\tconst { firstHitOnly } = raycaster;\n\n\t\t_inverseMatrix.copy( matrixWorld ).invert();\n\t\t_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );\n\n\t\tlet closestHit = null;\n\t\tlet closestDistance = Infinity;\n\n\t\tthis.shapecast( {\n\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\treturn box.distanceToPoint( _ray.origin );\n\n\t\t\t},\n\t\t\tintersectsBounds: box => {\n\n\t\t\t\tif ( firstHitOnly ) {\n\n\t\t\t\t\tif ( ! _ray.intersectBox( box, _vec ) ) {\n\n\t\t\t\t\t\treturn NOT_INTERSECTED;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tlet dist;\n\t\t\t\t\tif ( box.containsPoint( _ray.origin ) ) {\n\n\t\t\t\t\t\tdist = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_vec.applyMatrix4( matrixWorld );\n\t\t\t\t\t\tdist = raycaster.ray.origin.distanceTo( _vec );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// early out if the box is further than the closest raycast\n\t\t\t\t\treturn dist < closestDistance ? INTERSECTED : NOT_INTERSECTED;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn _ray.intersectsBox( box ) ? INTERSECTED : NOT_INTERSECTED;\n\n\t\t\t\t}\n\n\t\t\t},\n\t\t\tintersectsTriangle: ( tri, triIndex ) => {\n\n\t\t\t\t// get the intersection\n\t\t\t\tlet point = null;\n\t\t\t\tif ( material.side === FrontSide ) {\n\n\t\t\t\t\tpoint = _ray.intersectTriangle( tri.a, tri.b, tri.c, true, _localPoint );\n\n\t\t\t\t} else if ( material.side === BackSide ) {\n\n\t\t\t\t\tpoint = _ray.intersectTriangle( tri.c, tri.b, tri.a, true, _localPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tpoint = _ray.intersectTriangle( tri.a, tri.b, tri.c, false, _localPoint );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! point ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\t// transform it into world space\n\t\t\t\tpoint = point.clone().applyMatrix4( matrixWorld );\n\n\t\t\t\t// check distance to ray\n\t\t\t\tconst dist = raycaster.ray.origin.distanceTo( point );\n\t\t\t\tif ( dist >= raycaster.near && dist <= raycaster.far ) {\n\n\t\t\t\t\tif ( firstHitOnly && dist >= closestDistance ) {\n\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// get the vertex indices\n\t\t\t\t\tconst { geometry } = this;\n\t\t\t\t\tconst { index } = geometry;\n\t\t\t\t\tconst actualTri = this.resolvePrimitiveIndex( triIndex );\n\t\t\t\t\tconst triOffset = actualTri * 3;\n\n\t\t\t\t\tlet ai = triOffset + 0;\n\t\t\t\t\tlet bi = triOffset + 1;\n\t\t\t\t\tlet ci = triOffset + 2;\n\n\t\t\t\t\tif ( index ) {\n\n\t\t\t\t\t\tai = index.array[ ai ];\n\t\t\t\t\t\tbi = index.array[ bi ];\n\t\t\t\t\t\tci = index.array[ ci ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// build the intersection result\n\t\t\t\t\tconst hit = {\n\t\t\t\t\t\tdistance: dist,\n\t\t\t\t\t\tpoint: point.clone(),\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tuv: null,\n\t\t\t\t\t\tuv1: null,\n\t\t\t\t\t\tnormal: null,\n\t\t\t\t\t\tface: {\n\t\t\t\t\t\t\ta: ai,\n\t\t\t\t\t\t\tb: bi,\n\t\t\t\t\t\t\tc: ci,\n\t\t\t\t\t\t\tnormal: Triangle.getNormal( tri.a, tri.b, tri.c, new Vector3() ),\n\t\t\t\t\t\t\tmaterialIndex: 0\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfaceIndex: actualTri,\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( IS_GT_REVISION_169 ) {\n\n\t\t\t\t\t\tconst barycoord = new Vector3();\n\t\t\t\t\t\tTriangle.getBarycoord( _localPoint, tri.a, tri.b, tri.c, barycoord );\n\t\t\t\t\t\thit.barycoord = barycoord;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// add attribute fields if available\n\t\t\t\t\tconst uv = geometry.attributes.uv;\n\t\t\t\t\tconst uv1 = geometry.attributes.uv1;\n\t\t\t\t\tconst normal = geometry.attributes.normal;\n\n\t\t\t\t\tif ( uv ) {\n\n\t\t\t\t\t\t_uvA.fromBufferAttribute( uv, ai );\n\t\t\t\t\t\t_uvB.fromBufferAttribute( uv, bi );\n\t\t\t\t\t\t_uvC.fromBufferAttribute( uv, ci );\n\n\t\t\t\t\t\thit.uv = new Vector2();\n\t\t\t\t\t\tconst resUv = Triangle.getInterpolation( _localPoint, tri.a, tri.b, tri.c, _uvA, _uvB, _uvC, hit.uv );\n\t\t\t\t\t\tif ( ! IS_GT_REVISION_169 ) hit.uv = resUv;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( uv1 ) {\n\n\t\t\t\t\t\t_uvA.fromBufferAttribute( uv1, ai );\n\t\t\t\t\t\t_uvB.fromBufferAttribute( uv1, bi );\n\t\t\t\t\t\t_uvC.fromBufferAttribute( uv1, ci );\n\n\t\t\t\t\t\thit.uv1 = new Vector2();\n\t\t\t\t\t\tconst resUv1 = Triangle.getInterpolation( _localPoint, tri.a, tri.b, tri.c, _uvA, _uvB, _uvC, hit.uv1 );\n\t\t\t\t\t\tif ( ! IS_GT_REVISION_169 ) hit.uv1 = resUv1;\n\t\t\t\t\t\tif ( IS_LT_REVISION_161 ) hit.uv2 = hit.uv1;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( normal ) {\n\n\t\t\t\t\t\t_normalA.fromBufferAttribute( normal, ai );\n\t\t\t\t\t\t_normalB.fromBufferAttribute( normal, bi );\n\t\t\t\t\t\t_normalC.fromBufferAttribute( normal, ci );\n\n\t\t\t\t\t\thit.normal = new Vector3();\n\t\t\t\t\t\tconst resNormal = Triangle.getInterpolation( _localPoint, tri.a, tri.b, tri.c, _normalA, _normalB, _normalC, hit.normal );\n\t\t\t\t\t\tif ( hit.normal.dot( _ray.direction ) > 0 ) {\n\n\t\t\t\t\t\t\thit.normal.multiplyScalar( - 1 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! IS_GT_REVISION_169 ) hit.normal = resNormal;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// first hit only settings\n\t\t\t\t\tclosestDistance = hit.distance;\n\t\t\t\t\tclosestHit = hit;\n\n\t\t\t\t\tif ( ! firstHitOnly ) {\n\n\t\t\t\t\t\tintersects.push( hit );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t} );\n\n\t\tif ( firstHitOnly && closestHit ) {\n\n\t\t\tintersects.push( closestHit );\n\n\t\t}\n\n\t\treturn intersects;\n\n\t}\n\n}\n\nfunction iterateOverTriangles(\n\toffset,\n\tcount,\n\tbvh,\n\tintersectsTriangleFunc,\n\tcontained,\n\tdepth,\n\ttriangle\n) {\n\n\tconst { mesh, geometry } = bvh;\n\tconst index = geometry.index ? geometry.index.array : null;\n\n\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\tconst tri = bvh.resolvePrimitiveIndex( i );\n\n\t\tlet i0 = 3 * tri + 0;\n\t\tlet i1 = 3 * tri + 1;\n\t\tlet i2 = 3 * tri + 2;\n\n\t\tif ( index ) {\n\n\t\t\ti0 = index[ i0 ];\n\t\t\ti1 = index[ i1 ];\n\t\t\ti2 = index[ i2 ];\n\n\t\t}\n\n\t\tmesh.getVertexPosition( i0, triangle.a );\n\t\tmesh.getVertexPosition( i1, triangle.b );\n\t\tmesh.getVertexPosition( i2, triangle.c );\n\t\ttriangle.needsUpdate = true;\n\n\t\tif ( intersectsTriangleFunc( triangle, i, contained, depth ) ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t}\n\n\treturn false;\n\n}\n","import { StructTypeNode } from 'three/webgpu';\n\n// temporary shim so StructTypeNodes can be passed to storage functions until\n// this is fixed in three.js\nObject.defineProperty( StructTypeNode.prototype, 'layout', {\n\n\tget() {\n\n\t\treturn this;\n\n\t}\n\n} );\nStructTypeNode.prototype.isStruct = true;\n\n//\n\nexport const bvhNodeBoundsStruct = new StructTypeNode( {\n\tmin: 'array<f32, 3>',\n\tmax: 'array<f32, 3>',\n}, 'BVHBoundingBox' );\nbvhNodeBoundsStruct.getLength = () => 6;\n\nexport const bvhNodeStruct = new StructTypeNode( {\n\tbounds: 'BVHBoundingBox',\n\trightChildOrTriangleOffset: 'uint',\n\tsplitAxisOrTriangleCount: 'uint',\n}, 'BVHNode' );\nbvhNodeStruct.getLength = () => bvhNodeBoundsStruct.getLength() + 2;\n\nexport const transformStruct = new StructTypeNode( {\n\tmatrixWorld: 'mat4x4f',\n\tinverseMatrixWorld: 'mat4x4f',\n\tnodeOffset: 'uint',\n\tvisible: 'uint',\n\t_alignment0: 'uint',\n\t_alignment1: 'uint',\n}, 'TransformStruct' );\n\n\n/**\n * WGSL struct node representing a ray with an origin and direction.\n * Used as the input to BVH traversal and intersection functions.\n * @type {StructTypeNode}\n * @section TSL Structs\n */\nexport const rayStruct = new StructTypeNode( {\n\torigin: 'vec3f',\n\tdirection: 'vec3f',\n}, 'Ray' );\n\n/**\n * WGSL struct node describing a ray–triangle intersection result, including barycentric\n * coordinates, world-space normal, hit distance, face side, triangle indices, and the\n * object index within the TLAS.\n * @type {StructTypeNode}\n * @section TSL Structs\n */\nexport const rayIntersectionResultStruct = new StructTypeNode( {\n\tindices: 'vec4u',\n\tnormal: 'vec3f',\n\tdidHit: 'bool',\n\tbarycoord: 'vec3f',\n\tobjectIndex: 'uint',\n\tside: 'float',\n\tdist: 'float',\n}, 'IntersectionResult' );\n\n/**\n * WGSL struct node describing a closest-point query result, including the world-space\n * closest point, squared distance, barycentric coordinates, face normal, side, triangle\n * indices, and the object index within the TLAS.\n *\n * Barycoord convention matches {@link rayIntersectionResultStruct}: `(bary_a, bary_b, bary_c)`\n * where each component is the weight for the corresponding vertex in `faceIndices.xyz`.\n * @type {StructTypeNode}\n * @section TSL Structs\n */\nexport const pointQueryResultStruct = new StructTypeNode( {\n\tfaceIndices: 'vec4u',\n\tclosestPoint: 'vec3f',\n\tfound: 'bool',\n\tbarycoord: 'vec3f',\n\tobjectIndex: 'uint',\n\tfaceNormal: 'vec3f',\n\tside: 'float',\n\tdistanceSq: 'float',\n}, 'PointQueryResult' );\n","import { Node, TSL } from 'three/webgpu';\n\n// three r184 compat: TSL.nodeProxyConstructor only exists from three r185.\n// Recovered from the known-good Jul 21 SDK bundle (webgpu-V2WQRg97.mjs): fall\n// back to a Proxy that forwards to the wrapped node and exposes it via\n// `functionNode` so callable node functions keep working on r184.\nconst nodeProxyConstructor = TSL.nodeProxyConstructor ?? ( ( fn, target ) => new Proxy( fn, {\n\n\tget( obj, prop, receiver ) {\n\n\t\tconst value = Reflect.get( target, prop, receiver );\n\t\treturn value === undefined && prop === 'functionNode' ? target : value;\n\n\t},\n\tset( obj, prop, value ) {\n\n\t\treturn Reflect.set( target, prop, value );\n\n\t},\n\n} ) );\n\n\nclass ProxyCallNode extends Node {\n\n\tstatic get type() {\n\n\t\treturn 'ProxyCallNode';\n\n\t}\n\n\tconstructor( proxyNode, params ) {\n\n\t\tsuper();\n\t\tthis.proxyNode = proxyNode;\n\t\tthis.params = params;\n\n\t}\n\n\tsetup() {\n\n\t\treturn this.proxyNode.proxyNode.call( ...this.params );\n\n\t}\n\n}\n\nexport class NodeProxy {\n\n\tget isNode() {\n\n\t\treturn true;\n\n\t}\n\n\t// getter for the node being proxied to\n\tget proxyNode() {\n\n\t\tconst { proxyObject, proxyProperty } = this;\n\t\tconst properties = proxyProperty.split( '.' );\n\t\tlet value = proxyObject;\n\t\tfor ( let i = 0, l = properties.length; i < l; i ++ ) {\n\n\t\t\tvalue = value[ properties[ i ] ];\n\n\t\t}\n\n\t\tif ( value && 'functionNode' in value ) {\n\n\t\t\treturn value.functionNode;\n\n\t\t} else {\n\n\t\t\treturn value;\n\n\t\t}\n\n\t}\n\n\tconstructor( property, object = null ) {\n\n\t\t// store the proxy property and objects so they can be changed later\n\t\tthis.proxyObject = object;\n\t\tthis.proxyProperty = property;\n\n\t\t// set up a proxy to redirect all calls to the proxied node in order to avoid replicating\n\t\t// expected members for all node types.\n\t\treturn new Proxy( this, {\n\n\t\t\tget( target, property ) {\n\n\t\t\t\tif ( property in target ) {\n\n\t\t\t\t\treturn Reflect.get( target, property );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst node = target.proxyNode;\n\t\t\t\t\tif ( ! node ) {\n\n\t\t\t\t\t\treturn undefined;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = Reflect.get( node, property );\n\t\t\t\t\tif ( typeof value === 'function' ) {\n\n\t\t\t\t\t\treturn value.bind( node );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn value;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tset( target, property, value ) {\n\n\t\t\t\tif ( property in target ) {\n\n\t\t\t\t\treturn Reflect.set( target, property, value );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow new Error( 'NodeProxy: Cannot set members of proxied nodes.' );\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t} );\n\n\t}\n\n}\n\nexport const proxy = ( ...args ) => {\n\n\treturn new NodeProxy( ...args );\n\n};\n\nexport const proxyFn = ( ...args ) => {\n\n\tconst nodeProxy = new NodeProxy( ...args );\n\tconst fn = ( ...params ) => new ProxyCallNode( nodeProxy, params );\n\treturn nodeProxyConstructor( fn, nodeProxy );\n\n};\n","/** @import { Object3D, BufferGeometry } from 'three' */\nimport { Mesh } from 'three/webgpu';\nimport { GeometryBVH } from 'three-mesh-bvh/src/core/GeometryBVH.js';\nimport { ObjectBVH } from 'three-mesh-bvh/src/core/ObjectBVH.js';\nimport { SAH } from 'three-mesh-bvh/src/core/Constants.js';\n\n/**\n * Normalizes the various accepted `bvh` arguments into an {@link ObjectBVH}. A pre-built ObjectBVH\n * is returned as-is; otherwise an Object3D, BufferGeometry, GeometryBVH, or array of those is\n * wrapped into a new ObjectBVH.\n *\n * @private\n * @param {ObjectBVH | Object3D | BufferGeometry | GeometryBVH | Array} bvh\n * @returns {ObjectBVH}\n */\nexport function toObjectBVH( bvh ) {\n\n\tif ( bvh instanceof ObjectBVH ) {\n\n\t\treturn bvh;\n\n\t}\n\n\tif ( ! Array.isArray( bvh ) ) {\n\n\t\tbvh = [ bvh ];\n\n\t}\n\n\tconst objects = bvh.map( item => {\n\n\t\tif ( item.isObject3D ) {\n\n\t\t\treturn item;\n\n\t\t} else if ( item.isBufferGeometry ) {\n\n\t\t\treturn new Mesh( item );\n\n\t\t} else if ( item instanceof GeometryBVH ) {\n\n\t\t\tconst dummy = new Mesh();\n\t\t\tdummy.geometry.boundsTree = item;\n\t\t\treturn dummy;\n\n\t\t}\n\n\t} );\n\n\treturn new ObjectBVH( objects, { strategy: SAH, targetLeafSize: 1 } );\n\n}\n","/** @import { StructTypeNode } from 'three/webgpu' */\n/** @import { BVHComputeData } from '../BVHComputeData.js' */\nimport { Vector4 } from 'three';\nimport { BYTES_PER_NODE, UINT32_PER_NODE, IS_LEAFNODE_FLAG } from 'three-mesh-bvh/src/core/Constants.js';\n\n// scratch\nconst _def = /* @__PURE__ */ new Vector4();\nconst _vec = /* @__PURE__ */ new Vector4();\n\n// resolve an indirect buffer into a flat triangle index array\nfunction dereferenceIndex( indexAttr, indirectBuffer ) {\n\n\tconst indexArray = indexAttr ? indexAttr.array : null;\n\tconst result = new Uint32Array( indirectBuffer.length * 3 );\n\tfor ( let i = 0, l = indirectBuffer.length; i < l; i ++ ) {\n\n\t\tconst i3 = 3 * i;\n\t\tconst v3 = 3 * indirectBuffer[ i ];\n\t\tfor ( let c = 0; c < 3; c ++ ) {\n\n\t\t\tresult[ i3 + c ] = indexArray ? indexArray[ v3 + c ] : v3 + c;\n\n\t\t}\n\n\t}\n\n\treturn result;\n\n}\n\n/**\n * Copies the packed nodes of a BVH into the shared node buffer, rewriting leaf offsets / counts and\n * tagging leaves as mesh (`0xFFFF`) or TLAS (`0xFF00`) leaves. Returns the write offset of each root.\n *\n * @private\n * @param {Object} bvh\n * @param {number} geometryOffset\n * @param {Array} transformInfo\n * @param {number} nodeWriteOffset\n * @param {ArrayBuffer} target\n * @param {boolean} [tlas=false]\n * @returns {Array<number>}\n */\nexport function appendBVHData( bvh, geometryOffset, transformInfo, nodeWriteOffset, target, tlas = false ) {\n\n\tconst targetU16 = new Uint16Array( target );\n\tconst targetU32 = new Uint32Array( target );\n\tconst targetF32 = new Float32Array( target );\n\n\tconst result = [];\n\tlet tlasOffset = 0;\n\tbvh._roots.forEach( root => {\n\n\t\tconst rootBuffer16 = new Uint16Array( root );\n\t\tconst rootBuffer32 = new Uint32Array( root );\n\t\tresult.push( nodeWriteOffset );\n\t\tfor ( let i = 0, l = root.byteLength / BYTES_PER_NODE; i < l; i ++ ) {\n\n\t\t\tconst r32 = i * UINT32_PER_NODE;\n\t\t\tconst r16 = r32 * 2;\n\t\t\tconst n32 = nodeWriteOffset * UINT32_PER_NODE;\n\t\t\tconst n16 = n32 * 2;\n\n\t\t\t// write bounds\n\t\t\tconst view = new Float32Array( root, i * BYTES_PER_NODE, 6 );\n\t\t\tif ( i === 0 ) {\n\n\t\t\t\t// if we're copying the root then check for cases where there are no primitives and therefore\n\t\t\t\t// be a bounds of [ Infinity, - Infinity ]. Convert this to [ 1, - 1 ] for reliable GPU behavior.\n\t\t\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\tconst vMin = view[ i + 0 ];\n\t\t\t\t\tconst vMax = view[ i + 3 ];\n\t\t\t\t\tif ( vMin > vMax ) {\n\n\t\t\t\t\t\ttargetF32[ n32 + i + 0 ] = 1;\n\t\t\t\t\t\ttargetF32[ n32 + i + 3 ] = - 1;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttargetF32[ n32 + i + 0 ] = vMin;\n\t\t\t\t\t\ttargetF32[ n32 + i + 3 ] = vMax;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\ttargetF32.set( view, n32 );\n\n\t\t\t}\n\n\t\t\tconst isLeaf = IS_LEAFNODE_FLAG === rootBuffer16[ r16 + 15 ];\n\t\t\tif ( isLeaf ) {\n\n\t\t\t\tif ( tlas ) {\n\n\t\t\t\t\t// 0xFFFF == mesh leaf, 0xFF00 == TLAS leaf\n\t\t\t\t\ttargetU32[ n32 + 6 ] = tlasOffset;\n\t\t\t\t\ttargetU16[ n16 + 15 ] = 0xFF00;\n\n\t\t\t\t\tconst count = rootBuffer16[ r16 + 14 ];\n\t\t\t\t\t// const offset = rootBuffer32[ r32 + 6 ];\n\n\t\t\t\t\t// each root is expanded into a separate transform so we need to expand\n\t\t\t\t\t// the embedded offsets and counts.\n\t\t\t\t\tlet rootsCount = 0;\n\t\t\t\t\tfor ( let o = 0; o < count; o ++ ) {\n\n\t\t\t\t\t\tconst roots = transformInfo[ tlasOffset ].data.bvh._roots.length;\n\t\t\t\t\t\ttlasOffset += roots;\n\t\t\t\t\t\trootsCount += roots;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetU16[ n16 + 14 ] = rootsCount;\n\n\t\t\t\t} else {\n\n\t\t\t\t\ttargetU32[ n32 + 6 ] = rootBuffer32[ r32 + 6 ] + geometryOffset;\n\t\t\t\t\ttargetU16[ n16 + 14 ] = rootBuffer16[ r16 + 14 ];\n\t\t\t\t\ttargetU16[ n16 + 15 ] = IS_LEAFNODE_FLAG;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\ttargetU32[ n32 + 6 ] = rootBuffer32[ r32 + 6 ];\n\t\t\t\ttargetU32[ n32 + 7 ] = rootBuffer32[ r32 + 7 ];\n\n\t\t\t}\n\n\t\t\tnodeWriteOffset ++;\n\n\t\t}\n\n\t} );\n\n\treturn result;\n\n}\n\n/**\n * Writes the triangle index data for a BVH's geometry into the shared index buffer, rebasing the\n * indices into the packed attribute buffer.\n *\n * @private\n * @param {Object} bvh\n * @param {{start:number,count:number,vertexStart:number}} range\n * @param {number} valueOffset\n * @param {number} writeOffset\n * @param {Uint32Array} target\n */\nexport function appendIndexData( bvh, range, valueOffset, writeOffset, target ) {\n\n\tconst { geometry } = bvh;\n\tconst { start, count, vertexStart } = range;\n\tif ( bvh.indirect ) {\n\n\t\tconst dereferencedIndex = dereferenceIndex( geometry.index, bvh._indirectBuffer );\n\t\tfor ( let i = 0; i < dereferencedIndex.length; i ++ ) {\n\n\t\t\ttarget[ i + writeOffset ] = dereferencedIndex[ i ] - vertexStart + valueOffset;\n\n\t\t}\n\n\t} else if ( geometry.index ) {\n\n\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\ttarget[ i + writeOffset ] = geometry.index.getX( i + start ) - vertexStart + valueOffset;\n\n\t\t}\n\n\t} else {\n\n\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\ttarget[ i + writeOffset ] = i + start + valueOffset;\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * Writes a BVH's interleaved per-vertex attributes into the shared attribute buffer, filling missing\n * attributes with their defaults and applying bone transforms for skinned meshes.\n *\n * @private\n * @param {Object} bvh\n * @param {{vertexStart:number,vertexCount:number}} range\n * @param {number} writeOffset\n * @param {ArrayBuffer} target\n * @param {StructTypeNode} attributeStruct\n * @param {BVHComputeData} bvhData - Provides per-attribute defaults via `getDefaultAttributeValue`.\n */\nexport function appendGeometryData( bvh, range, writeOffset, target, attributeStruct, bvhData ) {\n\n\t// if \"mesh\" is present then it is assumed to be a SkinnedMeshBVH\n\tconst { geometry, mesh = null } = bvh;\n\tconst { vertexStart, vertexCount } = range;\n\tconst attributesBufferF32 = new Float32Array( target );\n\tconst attrStructLength = attributeStruct.getLength();\n\tattributeStruct.membersLayout.forEach( ( { name }, interleavedOffset ) => {\n\n\t\t// TODO: we should be able to have access to memory layout offsets here via the struct\n\t\t// API but it's not currently available.\n\t\tconst attr = geometry.attributes[ name ];\n\t\tbvhData.getDefaultAttributeValue( name, _def );\n\n\t\tfor ( let i = 0; i < vertexCount; i ++ ) {\n\n\t\t\tif ( attr ) {\n\n\t\t\t\t_vec.fromBufferAttribute( attr, i + vertexStart );\n\n\t\t\t\tswitch ( attr.itemSize ) {\n\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t_vec.y = _def.y;\n\t\t\t\t\t\t_vec.z = _def.z;\n\t\t\t\t\t\t_vec.w = _def.w;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\t_vec.z = _def.z;\n\t\t\t\t\t\t_vec.w = _def.w;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\t_vec.w = _def.w;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif ( mesh && ( name === 'position' || name === 'normal' || name === 'tangent' ) ) {\n\n\t\t\t\t\tmesh.applyBoneTransform( i + vertexStart, _vec );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_vec.copy( _def );\n\n\t\t\t}\n\n\t\t\t_vec.toArray( attributesBufferF32, ( writeOffset + i ) * attrStructLength + interleavedOffset * 4 );\n\n\t\t}\n\n\t} );\n\n}\n","import { CodeNode, FunctionNode, Node, TSL } from 'three/webgpu';\n\n// three r184 compat: TSL.nodeProxyConstructor only exists from three r185.\n// Recovered from the known-good Jul 21 SDK bundle (webgpu-V2WQRg97.mjs): fall\n// back to a Proxy that forwards to the wrapped node and exposes it via\n// `functionNode` so callable node functions keep working on r184.\nconst nodeProxyConstructor = TSL.nodeProxyConstructor ?? ( ( fn, target ) => new Proxy( fn, {\n\n\tget( obj, prop, receiver ) {\n\n\t\tconst value = Reflect.get( target, prop, receiver );\n\t\treturn value === undefined && prop === 'functionNode' ? target : value;\n\n\t},\n\tset( obj, prop, value ) {\n\n\t\treturn Reflect.set( target, prop, value );\n\n\t},\n\n} ) );\n\n\n// minimal node that outputs a raw WGSL expression verbatim when built\nclass LiteralExpression extends Node {\n\n\tconstructor( literal ) {\n\n\t\tsuper();\n\t\tthis.literal = literal;\n\n\t}\n\n\tbuild() {\n\n\t\treturn this.literal;\n\n\t}\n\n}\n\n// wraps a FunctionNode so that build() returns just the function name\nclass PropertyRefNode extends Node {\n\n\tconstructor( node, output = 'property' ) {\n\n\t\tsuper();\n\t\tthis.node = node;\n\t\tthis.output = output;\n\n\t}\n\n\tbuild( builder ) {\n\n\t\treturn this.node.build( builder, this.output );\n\n\t}\n\n}\n\n// returns the node that should be registered as an include for the given arg\n// three r184 compat (roomle patch, recovered from the known-good Jul 21\n// bundle): with the nodeProxyConstructor Proxy fallback, proxied callables are\n// plain functions carrying the wrapped node on `.functionNode` — unwrap them\n// before treating template args as nodes.\nfunction unwrapFunctionNode( arg ) {\n\n\treturn typeof arg === 'function' && arg.functionNode && ! arg.isNode ? arg.functionNode : arg;\n\n}\n\nfunction getIncludeNode( arg ) {\n\n\targ = unwrapFunctionNode( arg );\n\tif ( arg.isNode ) return new PropertyRefNode( arg );\n\treturn null;\n\n}\n\n// extract dependency nodes from template args for include registration\nfunction extractIncludes( args ) {\n\n\tconst includes = [];\n\tfor ( const arg of args ) {\n\n\t\tif ( Array.isArray( arg ) ) {\n\n\t\t\tfor ( const element of arg ) {\n\n\t\t\t\tconst node = getIncludeNode( element );\n\t\t\t\tif ( node ) includes.push( node );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn includes;\n\n}\n\n// normalize args so generate can resolve them uniformly with build():\n// - callable wrappers > PropertyRefNode (emits just the function name)\nfunction normalizeArgs( args ) {\n\n\treturn args.map( arg => {\n\n\t\targ = unwrapFunctionNode( arg );\n\t\tif ( arg && arg.isNode ) {\n\n\t\t\tif ( arg instanceof WGSLTagCodeNode ) {\n\n\t\t\t\t// use a custom flag for this node to inline the output\n\t\t\t\treturn new PropertyRefNode( arg, 'inline' );\n\n\t\t\t} else {\n\n\t\t\t\treturn new PropertyRefNode( arg );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn arg;\n\n\t} );\n\n}\n\n// interleave static tokens with resolved arg values\nfunction assembleTemplate( tokens, args, builder ) {\n\n\tlet code = '';\n\tfor ( let i = 0, l = tokens.length; i < l; i ++ ) {\n\n\t\tcode += tokens[ i ];\n\t\tif ( i < args.length ) {\n\n\t\t\tconst arg = unwrapFunctionNode( args[ i ] );\n\t\t\tif ( Array.isArray( arg ) ) {\n\n\t\t\t\t// include array — no text output\n\n\t\t\t} else if ( typeof arg === 'string' || typeof arg === 'number' ) {\n\n\t\t\t\tcode += String( arg );\n\n\t\t\t} else {\n\n\t\t\t\tcode += arg.build( builder );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn code;\n\n}\n\nexport class WGSLTagFnNode extends FunctionNode {\n\n\tstatic get type() {\n\n\t\treturn 'WGSLTagFnNode';\n\n\t}\n\n\tconstructor( tokens, args, lang = 'wgsl' ) {\n\n\t\tsuper( '', extractIncludes( args ), lang );\n\n\t\tthis.tokens = tokens;\n\t\tthis.args = args;\n\n\t}\n\n\t// assemble the signature from tokens and arg names then parse\n\tgetNodeFunction( builder ) {\n\n\t\tconst { tokens } = this;\n\t\tconst args = normalizeArgs( this.args );\n\n\t\tconst nodeData = builder.getDataFromNode( this );\n\t\tlet nodeFunction = nodeData.nodeFunction;\n\t\tif ( nodeFunction === undefined ) {\n\n\t\t\t// reconstruct the full code with known names for struct args\n\t\t\t// and dummy identifiers for everything else\n\t\t\tlet fullCode = '';\n\t\t\tfor ( let i = 0, l = tokens.length; i < l; i ++ ) {\n\n\t\t\t\tfullCode += tokens[ i ];\n\n\t\t\t\tif ( i < args.length ) {\n\n\t\t\t\t\tconst arg = args[ i ];\n\t\t\t\t\tif ( Array.isArray( arg ) ) {\n\n\t\t\t\t\t\t// include array — no text output\n\n\t\t\t\t\t} else if ( typeof arg === 'string' || typeof arg === 'number' ) {\n\n\t\t\t\t\t\t// literals\n\t\t\t\t\t\tfullCode += String( arg );\n\n\t\t\t\t\t} else if ( arg.isStructLayoutNode ) {\n\n\t\t\t\t\t\t// struct type node\n\t\t\t\t\t\tfullCode += arg.getNodeType( builder );\n\n\t\t\t\t\t} else if ( arg.isStruct ) {\n\n\t\t\t\t\t\t// struct\n\t\t\t\t\t\tfullCode += arg.layout.getNodeType( builder );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfullCode += '_arg' + i;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// remove comments\n\t\t\tfullCode = fullCode.replace( /\\/\\/.+[\\n\\r]/g, '' );\n\n\t\t\t// parse it so we have the signature defined - we will define the body content after\n\t\t\tnodeFunction = builder.parser.parseFunction( fullCode );\n\t\t\tnodeData.nodeFunction = nodeFunction;\n\n\t\t}\n\n\t\treturn nodeFunction;\n\n\t}\n\n\t// get the code for the function\n\tgenerate( builder, output ) {\n\n\t\tconst result = super.generate( builder, output );\n\t\tconst fullCode = assembleTemplate( this.tokens, normalizeArgs( this.args ), builder );\n\n\t\tconst { type } = this.getNodeFunction( builder );\n\t\tconst nodeCode = builder.getCodeFromNode( this, type );\n\n\t\tnodeCode.code = fullCode.replace( /\\/\\/.+[\\n\\r]/g, '' ).replace( /->\\s*void/, '' ).trim();\n\t\treturn result;\n\n\t}\n\n}\n\nexport class WGSLTagCodeNode extends CodeNode {\n\n\tstatic get type() {\n\n\t\treturn 'WGSLTagCodeNode';\n\n\t}\n\n\tconstructor( tokens, args, lang = 'wgsl' ) {\n\n\t\tsuper( '', extractIncludes( args ), lang );\n\n\t\tthis.tokens = tokens;\n\t\tthis.args = args;\n\n\t}\n\n\tbuild( builder, output ) {\n\n\t\tif ( output === 'inline' ) {\n\n\t\t\treturn assembleTemplate( this.tokens, normalizeArgs( this.args ), builder );\n\n\t\t} else {\n\n\t\t\treturn super.build( builder, output );\n\n\t\t}\n\n\t}\n\n\tgenerate( builder ) {\n\n\t\tsuper.generate( builder );\n\n\t\tconst nodeCode = builder.getCodeFromNode( this, this.getNodeType( builder ) );\n\t\tnodeCode.code = assembleTemplate( this.tokens, normalizeArgs( this.args ), builder );\n\t\treturn nodeCode.code;\n\n\t}\n\n}\n\nconst getFn = functionNode => {\n\n\tconst fn = ( ...params ) => {\n\n\t\t// wrap string parameter values as raw WGSL expressions so they\n\t\t// output verbatim as identifiers like local variable names\n\t\tif ( params.length === 1 && params[ 0 ] && typeof params[ 0 ] === 'object' && ! params[ 0 ].isNode ) {\n\n\t\t\tconst obj = params[ 0 ];\n\t\t\tfor ( const key in obj ) {\n\n\t\t\t\tif ( typeof obj[ key ] === 'string' ) {\n\n\t\t\t\t\tobj[ key ] = new LiteralExpression( obj[ key ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn functionNode.call( ...params );\n\n\t};\n\n\treturn nodeProxyConstructor( fn, functionNode );\n\n};\n\n// template tag literal function version of \"wgslFn\" & \"wgsl\" to generate\n// functions & code snippets respectively\nexport const wgslTagFn = ( tokens, ...args ) => getFn( new WGSLTagFnNode( tokens, args ) );\nexport const wgslTagCode = ( tokens, ...args ) => new WGSLTagCodeNode( tokens, args );\n\n// glsl versions\nexport const glslTagFn = ( tokens, ...args ) => getFn( new WGSLTagFnNode( tokens, args, 'glsl' ) );\nexport const glslTagCode = ( tokens, ...args ) => new WGSLTagCodeNode( tokens, args, 'glsl' );\n","import { uint } from 'three/tsl';\n\nexport const BVH_STACK_DEPTH = uint( 60 );\n","/** @import { StructTypeNode } from 'three/webgpu' */\n/** @import { BVHComputeData } from '../BVHComputeData.js' */\nimport { wgslTagCode, wgslTagFn } from '../nodes/WGSLTagFnNode.js';\nimport { BVH_STACK_DEPTH } from '../tsl/constants.js';\n\n/**\n * Builds a pair of WGSL shapecast functions (BLAS + TLAS traversal) for a custom shape\n * type. The returned TLAS function signature is:\n * `fn name( shape: ShapeStruct[, result: ptr<function, ResultStruct>] ) -> bool`\n *\n * @private\n * @param {BVHComputeData} bvhData - The compute data whose storage buffers are referenced.\n * @param {Object} options\n * @param {string} [options.name] - Function name. Defaults to a random identifier.\n * @param {StructTypeNode} options.shapeStruct - TSL struct or definition describing the query shape.\n * @param {StructTypeNode|null} [options.resultStruct] - TSL struct for the accumulated result, or null.\n * @param {Function|null} [options.boundsOrderFn] - function node controlling left/right child traversal order.\n * @param {Function} options.intersectsBoundsFn - function node testing the shape against a BVH node's bounds.\n * @param {Function} options.intersectRangeFn - function node testing the shape against a leaf triangle range.\n * @param {Function|null} [options.transformShapeFn] - function node that transforms the shape into object local space.\n * @param {Function|null} [options.transformResultFn] - function node that transforms a hit result back to world space.\n * @param {Function|null} [options.resetShapeFn] - function node called after each BLAS traversal to reset any per-object state set by `transformShapeFn`.\n * @returns {Function} TSL function node for the TLAS traversal.\n */\nexport function getShapecastFn( bvhData, options ) {\n\n\t// TODO: test with and verify use with TSL Fn - both passing them as arguments,\n\t// calling the function from a TSL Fn.\n\t// TODO: revisit the semantics and mental model of \"transformShapeFn\" and \"transformResultFn\".\n\t// Are they \"before\" and \"after\" hooks? Should they include words implying a direction of transform?\n\t// eg \"toLocal\" / \"toWorld\"?\n\tconst {\n\t\tname = `bvh_shapecast_fn_${ Math.random().toString( 36 ).substring( 2, 7 ) }`,\n\t\tshapeStruct,\n\t\tresultStruct = null,\n\n\t\tboundsOrderFn = null,\n\t\tintersectsBoundsFn,\n\t\tintersectRangeFn,\n\t\ttransformShapeFn = null,\n\t\ttransformResultFn = null,\n\t\tresetShapeFn = null,\n\t} = options;\n\n\t// these are proxy nodes, so they can be referenced before the storage buffers exist\n\tconst { nodes, transforms } = bvhData.storage;\n\n\t// handle optional functions\n\tlet transformResultSnippet = '';\n\tif ( transformResultFn ) {\n\n\t\ttransformResultSnippet = wgslTagCode/* wgsl */`${ transformResultFn }( result, i );`;\n\n\t}\n\n\tlet transformShapeSnippet = '';\n\tif ( transformShapeFn ) {\n\n\t\ttransformShapeSnippet = wgslTagCode/* wgsl */`${ transformShapeFn }( &localShape, i );`;\n\n\t}\n\n\tlet resetShapeSnippet = '';\n\tif ( resetShapeFn ) {\n\n\t\tresetShapeSnippet = wgslTagCode/* wgsl */`${ resetShapeFn }( i );`;\n\n\t}\n\n\tlet leftToRightSnippet = '';\n\tif ( boundsOrderFn ) {\n\n\t\tleftToRightSnippet = wgslTagCode/* wgsl */`\n\t\t\tlet leftToRight = ${ boundsOrderFn }( shape, splitAxis, node );\n\t\t\tc1 = select( rightIndex, leftIndex, leftToRight );\n\t\t\tc2 = select( leftIndex, rightIndex, leftToRight );\n\t\t`;\n\n\t}\n\n\tconst resultPtrSnippet = resultStruct ? wgslTagCode/* wgsl */`result: ptr<function, ${ resultStruct }>` : '';\n\tconst resultArg = resultStruct ? 'result' : '';\n\n\tconst getFnBody = leafSnippet => {\n\n\t\t// returns a function with a snippet inserted for the leaf intersection test\n\t\treturn wgslTagCode/* wgsl */`\n\n\t\t\tvar pointer: i32 = 0;\n\t\t\tvar stack: array<u32, ${ BVH_STACK_DEPTH }>;\n\t\t\tstack[ 0 ] = rootNodeIndex;\n\n\t\t\tloop {\n\n\t\t\t\tif ( pointer < 0 || pointer >= i32( ${ BVH_STACK_DEPTH } ) ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlet nodeIndex = stack[ pointer ];\n\t\t\t\tlet node = ${ nodes }[ nodeIndex ];\n\t\t\t\tpointer = pointer - 1;\n\n\t\t\t\tif ( ${ intersectsBoundsFn }( shape, node.bounds, ${ resultArg } ) == 0u ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tlet infoX = node.splitAxisOrTriangleCount;\n\t\t\t\tlet infoY = node.rightChildOrTriangleOffset;\n\t\t\t\tlet isLeaf = ( infoX & 0xffff0000u ) != 0u;\n\n\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\tlet count = infoX & 0x0000ffffu;\n\t\t\t\t\tlet offset = infoY;\n\t\t\t\t\t${ leafSnippet }\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlet leftIndex = nodeIndex + 1u;\n\t\t\t\t\tlet splitAxis = infoX & 0x0000ffffu;\n\t\t\t\t\tlet rightIndex = nodeIndex + infoY;\n\n\t\t\t\t\tvar c1 = rightIndex;\n\t\t\t\t\tvar c2 = leftIndex;\n\t\t\t\t\t${ leftToRightSnippet }\n\n\t\t\t\t\tpointer = pointer + 1;\n\t\t\t\t\tstack[ pointer ] = c2;\n\n\t\t\t\t\tpointer = pointer + 1;\n\t\t\t\t\tstack[ pointer ] = c1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t`;\n\n\t};\n\n\tconst blasFn = wgslTagFn/* wgsl */`\n\t\t// fn\n\t\tfn ${ name }_blas( shape: ${ shapeStruct }, rootNodeIndex: u32, ${ resultPtrSnippet } ) -> bool {\n\n\t\t\tvar didHit = false;\n\t\t\t${ getFnBody( wgslTagCode/* wgsl */`\n\n\t\t\t\tdidHit = ${ intersectRangeFn }( shape, offset, count, ${ resultArg } ) || didHit;\n\n\t\t\t` ) }\n\n\t\t\treturn didHit;\n\n\t\t}\n\t`;\n\n\tconst tlasFn = wgslTagFn/* wgsl */`\n\t\t// fn\n\t\tfn ${ name }( shape: ${ shapeStruct }, ${ resultPtrSnippet } ) -> bool {\n\n\t\t\tconst rootNodeIndex = 0u;\n\t\t\tvar didHit = false;\n\t\t\t${ getFnBody( wgslTagCode/* wgsl */`\n\n\t\t\t\tfor ( var i = offset; i < offset + count; i ++ ) {\n\n\t\t\t\t\tlet transform = ${ transforms }[ i ];\n\t\t\t\t\tif ( transform.visible == 0u ) {\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Transform shape into object local space\n\t\t\t\t\tvar localShape = shape;\n\t\t\t\t\t${ transformShapeSnippet }\n\n\t\t\t\t\tif ( ${ blasFn }( localShape, transform.nodeOffset, ${ resultArg } ) ) {\n\n\t\t\t\t\t\t${ transformResultSnippet }\n\t\t\t\t\t\tdidHit = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t${ resetShapeSnippet }\n\n\t\t\t\t}\n\n\t\t\t` ) }\n\n\t\t\treturn didHit;\n\n\t\t}\n\t`;\n\n\ttlasFn.outputType = resultStruct;\n\ttlasFn.functionName = name;\n\n\treturn tlasFn;\n\n}\n","/** @import { FunctionNode } from 'three/tsl'; */\nimport { wgslTagFn } from '../nodes/WGSLTagFnNode.js';\nimport { rayIntersectionResultStruct, rayStruct } from './structs.js';\n\n/**\n * WGSL function node that finds the closest point on a triangle to `p` and returns the barycoord.\n * @type {FunctionNode}\n * @section TSL Functions\n */\nexport const closestPointToTriangle = wgslTagFn/* wgsl */`\n\t// fn\n\tfn closestPointToTriangle(\n\t\tp: vec3f,\n\t\tv0: vec3f,\n\t\tv1: vec3f,\n\t\tv2: vec3f\n\t) -> vec3f {\n\n\t\tlet v10 = v1 - v0;\n\t\tlet v21 = v2 - v1;\n\t\tlet v02 = v0 - v2;\n\t\tlet p0 = p - v0;\n\t\tlet p1 = p - v1;\n\t\tlet p2 = p - v2;\n\n\t\tlet nor = cross( v10, v02 );\n\t\tlet q = cross( nor, p0 );\n\t\tlet d = 1.0 / dot( nor, nor );\n\t\tvar u = d * dot( q, v02 );\n\t\tvar v = d * dot( q, v10 );\n\t\tvar w = 1.0 - u - v;\n\n\t\tif ( u < 0.0 ) {\n\n\t\t\tw = clamp( dot( p2, v02 ) / dot( v02, v02 ), 0.0, 1.0 );\n\t\t\tu = 0.0;\n\t\t\tv = 1.0 - w;\n\n\t\t} else if ( v < 0.0 ) {\n\n\t\t\tu = clamp( dot( p0, v10 ) / dot( v10, v10 ), 0.0, 1.0 );\n\t\t\tv = 0.0;\n\t\t\tw = 1.0 - u;\n\n\t\t} else if ( w < 0.0 ) {\n\n\t\t\tv = clamp( dot( p1, v21 ) / dot( v21, v21 ), 0.0, 1.0 );\n\t\t\tw = 0.0;\n\t\t\tu = 1.0 - v;\n\n\t\t}\n\n\t\treturn vec3f( w, u, v );\n\n\t}\n`;\n\n/**\n * WGSL function node that tests a ray against a single triangle and returns an\n * {@link rayIntersectionResultStruct} result. Useful when writing a custom `intersectRangeFn`\n * for {@link BVHComputeData#getShapecastFn}.\n * @type {FunctionNode}\n * @section TSL Functions\n */\nexport const intersectRayTriangle = wgslTagFn/* wgsl */ `\n\t// fn\n\tfn intersectRayTriangle( ray: ${ rayStruct }, a: vec3f, b: vec3f, c: vec3f, threshold: f32 ) -> ${ rayIntersectionResultStruct } {\n\n\t\tconst DET_EPSILON = 1e-15;\n\n\t\tvar result: ${ rayIntersectionResultStruct };\n\t\tresult.didHit = false;\n\n\t\tlet edge1 = b - a;\n\t\tlet edge2 = c - a;\n\t\tlet n = cross( edge1, edge2 );\n\n\t\tlet det = - dot( ray.direction, n );\n\t\tif ( abs( det ) < DET_EPSILON ) {\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tlet invdet = 1.0 / det;\n\n\t\tlet AO = ray.origin - a;\n\t\tlet DAO = cross( AO, ray.direction );\n\n\t\tlet u = dot( edge2, DAO ) * invdet;\n\t\tif ( u < 0.0 || u > 1.0 ) {\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tlet v = - dot( edge1, DAO ) * invdet;\n\t\tif ( v < 0.0 || u + v > 1.0 ) {\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tlet t = dot( AO, n ) * invdet;\n\t\tlet w = 1.0 - u - v;\n\t\tif ( t < threshold ) {\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tresult.didHit = true;\n\t\tresult.barycoord = vec3f( w, u, v );\n\t\tresult.dist = t;\n\t\tresult.side = sign( det );\n\t\tresult.normal = result.side * normalize( n );\n\n\t\treturn result;\n\n\t}\n`;\n\n/**\n * WGSL function node that builds a camera ray (origin + far-plane direction) from an NDC\n * coordinate and an inverse model-view-projection matrix. Works for both perspective and\n * orthographic projections. The returned direction is not normalized and extends to the\n * camera far plane.\n * @type {FunctionNode}\n * @section TSL Functions\n */\nexport const ndcToCameraRay = wgslTagFn/* wgsl */`\n\t// fn\n\tfn ndcToCameraRay( ndc: vec2f, inverseModelViewProjection: mat4x4f ) -> ${ rayStruct } {\n\n\t\tvar homogeneous = vec4f();\n\t\tvar ray: ${ rayStruct };\n\n\t\thomogeneous = inverseModelViewProjection * vec4f( ndc, 0.0, 1.0 );\n\t\tray.origin = homogeneous.xyz / homogeneous.w;\n\n\t\thomogeneous = inverseModelViewProjection * vec4f( ndc, 1.0, 1.0 );\n\t\tray.direction = ( homogeneous.xyz / homogeneous.w ) - ray.origin;\n\n\t\treturn ray;\n\n\t}\n`;\n","/** @import { BVHComputeData } from '../BVHComputeData.js' */\nimport { float } from 'three/tsl';\nimport { wgslTagFn } from '../nodes/WGSLTagFnNode.js';\nimport { rayStruct, rayIntersectionResultStruct, bvhNodeStruct, bvhNodeBoundsStruct } from '../tsl/structs.js';\nimport { intersectRayTriangle } from '../tsl/fns.js';\n\n/**\n * Builds the `raycastFirstHit` shapecast function: traverses the BVH front to back and returns the\n * closest ray / triangle intersection.\n *\n * @private\n * @param {BVHComputeData} bvhData\n * @returns {Function} TSL function node for the TLAS traversal.\n */\nexport function getRaycastFirstHitFn( bvhData ) {\n\n\t// these are proxy nodes, so they can be referenced before the storage buffers exist\n\tconst { index, attributes, transforms } = bvhData.storage;\n\n\tconst scratchRayScalar = float( 1.0 ).toVar( `bvh_rayScalar_${ Math.random().toString( 36 ).substring( 2, 7 ) }` );\n\n\treturn bvhData.getShapecastFn( {\n\t\tname: 'bvh_RaycastFirstHit',\n\t\tshapeStruct: rayStruct,\n\t\tresultStruct: rayIntersectionResultStruct,\n\n\t\tboundsOrderFn: wgslTagFn/* wgsl */`\n\t\t\tfn getBoundsOrder( ray: ${ rayStruct }, splitAxis: u32, node: ${ bvhNodeStruct } ) -> bool {\n\n\t\t\t\treturn ray.direction[ splitAxis ] >= 0.0;\n\n\t\t\t}\n\t\t`,\n\t\tintersectsBoundsFn: wgslTagFn/* wgsl */`\n\t\t\tfn rayIntersectsBounds( ray: ${ rayStruct }, bounds: ${ bvhNodeBoundsStruct }, result: ptr<function, ${ rayIntersectionResultStruct }> ) -> u32 {\n\n\t\t\t\tlet boundsMin = vec3( bounds.min[0], bounds.min[1], bounds.min[2] );\n\t\t\t\tlet boundsMax = vec3( bounds.max[0], bounds.max[1], bounds.max[2] );\n\n\t\t\t\tlet invDir = 1.0 / ray.direction;\n\t\t\t\tlet tMinPlane = ( boundsMin - ray.origin ) * invDir;\n\t\t\t\tlet tMaxPlane = ( boundsMax - ray.origin ) * invDir;\n\n\t\t\t\tlet tMinHit = vec3f(\n\t\t\t\t\tmin( tMinPlane.x, tMaxPlane.x ),\n\t\t\t\t\tmin( tMinPlane.y, tMaxPlane.y ),\n\t\t\t\t\tmin( tMinPlane.z, tMaxPlane.z )\n\t\t\t\t);\n\n\t\t\t\tlet tMaxHit = vec3f(\n\t\t\t\t\tmax( tMinPlane.x, tMaxPlane.x ),\n\t\t\t\t\tmax( tMinPlane.y, tMaxPlane.y ),\n\t\t\t\t\tmax( tMinPlane.z, tMaxPlane.z )\n\t\t\t\t);\n\n\t\t\t\tlet t0 = max( max( tMinHit.x, tMinHit.y ), tMinHit.z );\n\t\t\t\tlet t1 = min( min( tMaxHit.x, tMaxHit.y ), tMaxHit.z );\n\n\t\t\t\tlet dist = max( t0, 0.0 );\n\t\t\t\tif ( t1 < dist ) {\n\n\t\t\t\t\treturn 0u;\n\n\t\t\t\t} else if ( result.didHit && dist * ${ scratchRayScalar } >= result.dist ) {\n\n\t\t\t\t\treturn 0u;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn 1u;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t`,\n\t\tintersectRangeFn: wgslTagFn/* wgsl */`\n\t\t\tfn intersectRange( ray: ${ rayStruct }, offset: u32, count: u32, result: ptr<function, ${ rayIntersectionResultStruct }> ) -> bool {\n\n\t\t\t\tvar didHit = false;\n\t\t\t\tfor ( var ti = offset; ti < offset + count; ti = ti + 1u ) {\n\n\t\t\t\t\tlet i0 = ${ index }[ ti * 3u ];\n\t\t\t\t\tlet i1 = ${ index }[ ti * 3u + 1u ];\n\t\t\t\t\tlet i2 = ${ index }[ ti * 3u + 2u ];\n\n\t\t\t\t\tlet a = ${ attributes }[ i0 ].position.xyz;\n\t\t\t\t\tlet b = ${ attributes }[ i1 ].position.xyz;\n\t\t\t\t\tlet c = ${ attributes }[ i2 ].position.xyz;\n\n\t\t\t\t\tvar triResult = ${ intersectRayTriangle }( ray, a, b, c, 0.0 );\n\t\t\t\t\ttriResult.dist *= ${ scratchRayScalar };\n\t\t\t\t\tif ( triResult.didHit && ( ! result.didHit || triResult.dist < result.dist ) ) {\n\n\t\t\t\t\t\tresult.didHit = true;\n\t\t\t\t\t\tresult.dist = triResult.dist;\n\t\t\t\t\t\tresult.normal = triResult.normal;\n\t\t\t\t\t\tresult.side = triResult.side;\n\t\t\t\t\t\tresult.barycoord = triResult.barycoord;\n\t\t\t\t\t\tresult.indices = vec4u( i0, i1, i2, ti );\n\n\t\t\t\t\t\tdidHit = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn didHit;\n\n\t\t\t}\n\t\t`,\n\t\ttransformShapeFn: wgslTagFn/* wgsl */`\n\t\t\tfn transformRay( ray: ptr<function, ${ rayStruct }>, objectIndex: u32 ) -> void {\n\n\t\t\t\tlet toLocal = ${ transforms }[ objectIndex ].inverseMatrixWorld;\n\t\t\t\tray.origin = ( toLocal * vec4f( ray.origin, 1.0 ) ).xyz;\n\t\t\t\tray.direction = ( toLocal * vec4f( ray.direction, 0.0 ) ).xyz;\n\n\t\t\t\tlet len = length( ray.direction );\n\t\t\t\tray.direction /= len;\n\t\t\t\t${ scratchRayScalar } = 1.0 / len;\n\n\t\t\t}\n\t\t`,\n\t\ttransformResultFn: wgslTagFn/* wgsl */`\n\t\t\tfn transformResult( hit: ptr<function, ${ rayIntersectionResultStruct }>, objectIndex: u32 ) -> void {\n\n\t\t\t\tlet toLocal = ${ transforms }[ objectIndex ].inverseMatrixWorld;\n\t\t\t\thit.normal = normalize( ( transpose( toLocal ) * vec4f( hit.normal, 0.0 ) ).xyz );\n\t\t\t\thit.objectIndex = objectIndex;\n\n\t\t\t}\n\t\t`,\n\t\tresetShapeFn: wgslTagFn/* wgsl */`\n\t\t\tfn resetRayScalar( objectIndex: u32 ) -> void {\n\n\t\t\t\t${ scratchRayScalar } = 1.0;\n\n\t\t\t}\n\t\t`,\n\t} );\n\n}\n","/** @import { BVHComputeData } from '../BVHComputeData.js' */\nimport { wgslTagFn } from '../nodes/WGSLTagFnNode.js';\n\n/**\n * Builds the `sampleTrianglePoint` function: interpolates the per-vertex attributes of a triangle\n * at the given barycentric coordinate. The body emits one line per attribute, so this must be built\n * after `update` has resolved the attribute struct.\n *\n * @private\n * @param {BVHComputeData} bvhData\n * @returns {Function} TSL function node.\n */\nexport function getSampleTrianglePointFn( bvhData ) {\n\n\tconst { storage, structs } = bvhData;\n\n\tconst interpolateBody = structs\n\t\t.attributes\n\t\t.membersLayout\n\t\t.map( ( { name } ) => {\n\n\t\t\treturn `result.${ name } = a0.${ name } * barycoord.x + a1.${ name } * barycoord.y + a2.${ name } * barycoord.z;`;\n\n\t\t} ).join( '\\n' );\n\n\treturn wgslTagFn/* wgsl */`\n\t\t// fn\n\t\tfn bvh_sampleTrianglePoint( barycoord: vec3f, indices: vec3u ) -> ${ structs.attributes } {\n\n\t\t\tvar result: ${ structs.attributes };\n\t\t\tvar a0 = ${ storage.attributes }[ indices.x ];\n\t\t\tvar a1 = ${ storage.attributes }[ indices.y ];\n\t\t\tvar a2 = ${ storage.attributes }[ indices.z ];\n\t\t\t${ interpolateBody }\n\t\t\treturn result;\n\n\t\t}\n\t`;\n\n}\n","/** @import { BVHComputeData } from '../BVHComputeData.js' */\nimport { mat4 } from 'three/tsl';\nimport { wgslTagFn } from '../nodes/WGSLTagFnNode.js';\nimport { bvhNodeStruct, bvhNodeBoundsStruct, pointQueryResultStruct } from '../tsl/structs.js';\nimport { closestPointToTriangle } from '../tsl/fns.js';\n\n/**\n * Builds the `closestPointToPoint` shapecast function: finds the closest point on any triangle in\n * the BVH to the given query point.\n *\n * @private\n * @param {BVHComputeData} bvhData\n * @returns {Function} TSL function node for the TLAS traversal.\n */\nexport function getClosestPointToPointFn( bvhData ) {\n\n\t// these are proxy nodes, so they can be referenced before the storage buffers exist\n\tconst { index, attributes, transforms } = bvhData.storage;\n\n\tconst scratchToWorldMat = mat4().toVar( 'bvh_toWorldMat' );\n\n\treturn bvhData.getShapecastFn( {\n\t\tname: 'bvh_ClosestPointToPoint',\n\t\tshapeStruct: 'vec3f',\n\t\tresultStruct: pointQueryResultStruct,\n\n\t\tboundsOrderFn: wgslTagFn/* wgsl */`\n\t\t\tfn cppBoundsOrder( shape: vec3f, splitAxis: u32, node: ${ bvhNodeStruct } ) -> bool {\n\n\t\t\t\tlet toWorld = ${ scratchToWorldMat };\n\n\t\t\t\t// get center\n\t\t\t\tlet bMin = vec3f( node.bounds.min[ 0 ], node.bounds.min[ 1 ], node.bounds.min[ 2 ] );\n\t\t\t\tlet bMax = vec3f( node.bounds.max[ 0 ], node.bounds.max[ 1 ], node.bounds.max[ 2 ] );\n\t\t\t\tlet center = bMin * 0.5 + bMax * 0.5;\n\n\t\t\t\t// determine the order in world space\n\t\t\t\tlet worldCenter = ( toWorld * vec4f( center, 1.0 ) ).xyz;\n\t\t\t\tlet worldAxis = normalize( toWorld[ splitAxis ].xyz );\n\t\t\t\treturn dot( shape - worldCenter, worldAxis ) <= 0.0;\n\n\t\t\t}\n\t\t`,\n\n\t\tintersectsBoundsFn: wgslTagFn/* wgsl */`\n\t\t\tfn cppIntersectsBounds( shape: vec3f, bounds: ${ bvhNodeBoundsStruct }, result: ptr<function, ${ pointQueryResultStruct }> ) -> u32 {\n\n\t\t\t\t// return 1u;\n\t\t\t\t// we need to check this no matter what if the result has not been found yet\n\t\t\t\tif ( ! result.found ) {\n\n\t\t\t\t\treturn 1u;\n\n\t\t\t\t}\n\n\t\t\t\tlet toWorld = ${ scratchToWorldMat };\n\n\t\t\t\t// transform to world space\n\t\t\t\tlet bMin = vec3f( bounds.min[ 0 ], bounds.min[ 1 ], bounds.min[ 2 ] );\n\t\t\t\tlet bMax = vec3f( bounds.max[ 0 ], bounds.max[ 1 ], bounds.max[ 2 ] );\n\t\t\t\tlet center = ( bMin + bMax ) * 0.5;\n\t\t\t\tlet halfExtent = ( bMax - bMin ) * 0.5;\n\t\t\t\tlet worldCenter = ( toWorld * vec4f( center, 1.0 ) ).xyz;\n\t\t\t\tlet worldHalfExtent =\n\t\t\t\t\tabs( toWorld[ 0 ].xyz ) * halfExtent.x +\n\t\t\t\t abs( toWorld[ 1 ].xyz ) * halfExtent.y +\n\t\t\t\t abs( toWorld[ 2 ].xyz ) * halfExtent.z;\n\t\t\t\tlet worldMin = worldCenter - worldHalfExtent;\n\t\t\t\tlet worldMax = worldCenter + worldHalfExtent;\n\n\t\t\t\t// intersect if the distance to the bounds is not bigger than the already found\n\t\t\t\tlet d = shape - clamp( shape, worldMin, worldMax );\n\t\t\t\treturn select( 0u, 1u, dot( d, d ) < result.distanceSq );\n\n\t\t\t}\n\t\t`,\n\n\t\tintersectRangeFn: wgslTagFn /* wgsl */`\n\t\t\tfn cppIntersectsRange( shape: vec3f, offset: u32, count: u32, result: ptr<function, ${ pointQueryResultStruct }> ) -> bool {\n\n\t\t\t\tvar didHit = false;\n\t\t\t\tlet toWorld = ${ scratchToWorldMat };\n\n\t\t\t\tfor ( var i = offset; i < offset + count; i ++ ) {\n\n\t\t\t\t\t// transform the triangle to world space\n\t\t\t\t\tlet i0 = ${ index }[ i * 3u + 0u ];\n\t\t\t\t\tlet i1 = ${ index }[ i * 3u + 1u ];\n\t\t\t\t\tlet i2 = ${ index }[ i * 3u + 2u ];\n\t\t\t\t\tlet a = ( toWorld * vec4f( ${ attributes }[ i0 ].position.xyz, 1.0 ) ).xyz;\n\t\t\t\t\tlet b = ( toWorld * vec4f( ${ attributes }[ i1 ].position.xyz, 1.0 ) ).xyz;\n\t\t\t\t\tlet c = ( toWorld * vec4f( ${ attributes }[ i2 ].position.xyz, 1.0 ) ).xyz;\n\n\t\t\t\t\tlet barycoord = ${ closestPointToTriangle }( shape, a, b, c );\n\t\t\t\t\tlet closestPoint = barycoord.x * a + barycoord.y * b + barycoord.z * c;\n\t\t\t\t\tlet delta = shape - closestPoint;\n\t\t\t\t\tlet distSq = dot( delta, delta );\n\n\t\t\t\t\t// copy the content over\n\t\t\t\t\tif ( ! result.found || distSq < result.distanceSq ) {\n\n\t\t\t\t\t\tlet normal = normalize( cross( a - b, b - c ) );\n\n\t\t\t\t\t\tresult.closestPoint = closestPoint;\n\t\t\t\t\t\tresult.barycoord = barycoord;\n\t\t\t\t\t\tresult.distanceSq = distSq;\n\t\t\t\t\t\tresult.faceNormal = normal;\n\t\t\t\t\t\tresult.side = sign( dot( normal, delta ) );\n\t\t\t\t\t\tresult.faceIndices = vec4u( i0, i1, i2, i );\n\t\t\t\t\t\tresult.found = true;\n\t\t\t\t\t\tdidHit = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn didHit;\n\n\t\t\t}\n\t\t`,\n\n\t\ttransformShapeFn: wgslTagFn/* wgsl */`\n\t\t\tfn cppTransformShape( shape: ptr<function, vec3f>, objectIndex: u32 ) -> void {\n\n\t\t\t\t${ scratchToWorldMat } = ${ transforms }[ objectIndex ].matrixWorld;\n\n\t\t\t}\n\t\t`,\n\n\t\ttransformResultFn: wgslTagFn/* wgsl */`\n\t\t\tfn cppTransformResult( result: ptr<function, ${ pointQueryResultStruct }>, objectIndex: u32 ) -> void {\n\n\t\t\t\tresult.objectIndex = objectIndex;\n\n\t\t\t}\n\t\t`,\n\t} );\n\n}\n","/** @import { Object3D, BufferGeometry, Vector4 } from 'three' */\nimport { Matrix4 } from 'three';\nimport { StorageBufferAttribute, StructTypeNode } from 'three/webgpu';\nimport { storage } from 'three/tsl';\nimport { MeshBVH } from 'three-mesh-bvh/src/core/MeshBVH.js';\nimport { SkinnedMeshBVH } from 'three-mesh-bvh/src/core/SkinnedMeshBVH.js';\nimport { GeometryBVH } from 'three-mesh-bvh/src/core/GeometryBVH.js';\nimport { ObjectBVH } from 'three-mesh-bvh/src/core/ObjectBVH.js';\nimport { BYTES_PER_NODE } from 'three-mesh-bvh/src/core/Constants.js';\nimport { proxy, proxyFn } from './nodes/NodeProxy.js';\nimport {\n\tbvhNodeStruct,\n\ttransformStruct,\n} from './tsl/structs.js';\nimport { toObjectBVH } from './utils/toObjectBVH.js';\nimport { appendBVHData, appendIndexData, appendGeometryData } from './utils/packBVHBufferUtils.js';\nimport { getShapecastFn } from './shapecastFns/getShapecastFn.js';\nimport { getRaycastFirstHitFn } from './shapecastFns/getRaycastFirstHitFn.js';\nimport { getSampleTrianglePointFn } from './shapecastFns/getSampleTrianglePointFn.js';\nimport { getClosestPointToPointFn } from './shapecastFns/getClosestPointToPointFn.js';\n\n// TODO: add ability to easily update a single matrix / scene rearrangement (partial update)\n// TODO: add material support w/ function to easily update material\n// \t\t- add a callback for writing a property for a geometry to a range\n// TODO: Add support for other geometry types (tris, lines, custom BVHs etc)\n\n// scratch\nconst _matrix = /* @__PURE__ */ new Matrix4();\nconst _inverseMatrix = /* @__PURE__ */ new Matrix4();\n\n// functions\nfunction isObjectVisible( object ) {\n\n\tlet curr = object;\n\twhile ( curr ) {\n\n\t\tif ( curr.visible === false ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tcurr = curr.parent;\n\n\t}\n\n\treturn true;\n\n}\n\nfunction getTotalBVHByteLength( bvh ) {\n\n\treturn bvh._roots.reduce( ( v, root ) => v + root.byteLength, 0 );\n\n}\n\n/**\n * Packs one or more scene objects into GPU-accessible BVH buffers (TLAS + BLAS) for use\n * in WebGPU compute shaders via the Three.js TSL node system. After construction, call\n * {@link BVHComputeData#update} to populate the storage buffers, then reference\n * `this.storage` and `this.fns` in your compute shader nodes.\n *\n * @note This API is unstable and subject to change in future releases.\n *\n * @note This class requires three.js r185 or higher.\n */\nexport class BVHComputeData {\n\n\t/**\n\t * @param {ObjectBVH|Object3D|BufferGeometry|GeometryBVH|Array} bvh\n\t * Scene objects to include, or a pre-built {@link ObjectBVH}. A single item or array of\n\t * Object3D, BufferGeometry, or GeometryBVH instances are all accepted and wrapped\n\t * automatically in an ObjectBVH.\n\t * @param {Object} [options]\n\t * @param {Record<string,string>} [options.attributes={ position: 'vec4f' }]\n\t * WGSL type map for the interleaved per-vertex attribute buffer. Keys are geometry\n\t * attribute names; values are WGSL type strings (e.g. `'vec3f'`, `'vec4f'`).\n\t * @param {boolean} [options.autogenerateBvh=true]\n\t * When true, a {@link MeshBVH} is automatically built for any object that does not\n\t * already have `geometry.boundsTree` set.\n\t */\n\tconstructor( bvh, options = {} ) {\n\n\t\t// convert the bvh argument to an ObjectBVH. Supports an Object3D, BufferGeometry,\n\t\t// GeometryBVH, an array of the above, or a pre-built ObjectBVH.\n\t\tbvh = toObjectBVH( bvh );\n\n\t\tconst {\n\t\t\tattributes = { position: 'vec4f' },\n\t\t\tautogenerateBvh = true,\n\t\t} = options;\n\n\t\tthis._bvhCache = new Map();\n\n\t\tthis.autogenerateBvh = autogenerateBvh;\n\t\tthis.attributes = attributes;\n\t\tthis.bvh = bvh;\n\n\t\t// storage buffers and structs are populated in \"update\"; their members are accessed through\n\t\t// proxy nodes so the functions below can reference them up front and keep working across rebuilds\n\t\tthis.storage = new NodeProxyObject();\n\t\tthis.structs = new NodeProxyObject( { transform: transformStruct } );\n\t\tthis.fns = new NodeProxyObject( {\n\t\t\traycastFirstHit: getRaycastFirstHitFn( this ),\n\t\t\tclosestPointToPoint: getClosestPointToPointFn( this ),\n\t\t\tsampleTrianglePoint: null,\n\t\t}, proxyFn );\n\n\t}\n\n\t/**\n\t * Builds a pair of WGSL shapecast functions (BLAS + TLAS traversal) for a custom shape\n\t * type. The returned TLAS function signature is:\n\t * `fn name( shape: ShapeStruct[, result: ptr<function, ResultStruct>] ) -> bool`\n\t *\n\t * @param {Object} options\n\t * @param {string} [options.name] - Function name. Defaults to a random identifier.\n\t * @param {StructTypeNode} options.shapeStruct - TSL struct or definition describing the query shape.\n\t * @param {StructTypeNode|null} [options.resultStruct] - TSL struct for the accumulated result, or null.\n\t * @param {Function|null} [options.boundsOrderFn] - function node controlling left/right child traversal order.\n\t * @param {Function} options.intersectsBoundsFn - function node testing the shape against a BVH node's bounds.\n\t * @param {Function} options.intersectRangeFn - function node testing the shape against a leaf triangle range.\n\t * @param {Function|null} [options.transformShapeFn] - function node that transforms the shape into object local space.\n\t * @param {Function|null} [options.transformResultFn] - function node that transforms a hit result back to world space.\n\t * @param {Function|null} [options.resetShapeFn] - function node called after each BLAS traversal to reset any per-object state set by `transformShapeFn`.\n\t * @returns {Function} TSL function node for the TLAS traversal.\n\t */\n\tgetShapecastFn( options ) {\n\n\t\treturn getShapecastFn( this, options );\n\n\t}\n\n\t/**\n\t * Rebuilds all GPU storage buffers from the current scene state. Must be called at least\n\t * once before using `this.storage` or `this.fns` in a shader, and again whenever the\n\t * scene topology changes (objects added/removed, geometry modified).\n\t */\n\tupdate() {\n\n\t\t// free any buffers from a previous update before swapping in the new ones\n\t\tthis.dispose();\n\n\t\tconst { attributes, structs, bvh } = this;\n\n\t\t// collect the BVHs\n\t\tconst bvhInfo = [];\n\t\tconst transformInfo = [];\n\n\t\t// accumulate the sizes of the bvh nodes buffer, number of objects, and geometry buffers\n\t\tlet bvhNodesBufferLength = getTotalBVHByteLength( bvh );\n\t\tlet indexBufferLength = 0;\n\t\tlet attributesBufferLength = 0;\n\t\tbvh.primitiveBuffer.forEach( compositeId => {\n\n\t\t\tconst object = bvh.getObjectFromId( compositeId );\n\t\t\tconst instanceId = bvh.getInstanceFromId( compositeId );\n\t\t\tconst range = { start: 0, count: 0, vertexStart: 0, vertexCount: 0 };\n\t\t\tconst primBvh = this.getBVH( object, instanceId, range );\n\n\t\t\tif ( ! primBvh ) {\n\n\t\t\t\tthrow new Error( 'BVHComputeData: BVH not found.' );\n\n\t\t\t}\n\n\t\t\t// if we haven't added this bvh, yet\n\t\t\tif ( ! bvhInfo.find( info => info.bvh === primBvh ) ) {\n\n\t\t\t\t// save the geometry info to write later and increment the buffer sizes\n\t\t\t\tconst info = {\n\t\t\t\t\tindex: bvhInfo.length,\n\t\t\t\t\tbvh: primBvh,\n\t\t\t\t\trange: range,\n\n\t\t\t\t\tbvhNodeOffsets: null,\n\t\t\t\t\tindexBufferOffset: null,\n\n\t\t\t\t};\n\n\t\t\t\t// increase the buffer sizes for bvh and geometry\n\t\t\t\tbvhNodesBufferLength += getTotalBVHByteLength( primBvh );\n\t\t\t\tindexBufferLength += info.range.count;\n\t\t\t\tattributesBufferLength += info.range.vertexCount;\n\t\t\t\tbvhInfo.push( info );\n\n\t\t\t}\n\n\t\t\t// save the index of the bvh associated with this transform\n\t\t\tconst data = bvhInfo.find( info => primBvh === info.bvh );\n\t\t\tprimBvh._roots.forEach( ( root, i ) => {\n\n\t\t\t\ttransformInfo.push( {\n\t\t\t\t\tdata,\n\t\t\t\t\troot: i,\n\t\t\t\t\tobject,\n\t\t\t\t\tinstanceId,\n\t\t\t\t\tcompositeId,\n\t\t\t\t} );\n\n\t\t\t} );\n\n\t\t} );\n\n\t\t//\n\n\t\t// @note These buffer lengths are increased to a minimum size of 2 to avoid TSL converting storage buffers\n\t\t// with length 1 being converted to a scalar value.\n\t\t// TODO: remove this when fixed in three\n\t\tconst transformBufferLength = Math.max( transformInfo.length, 2 );\n\t\tindexBufferLength = Math.max( indexBufferLength, 2 );\n\t\tattributesBufferLength = Math.max( attributesBufferLength, 2 );\n\n\t\t// construct the attribute struct\n\t\tconst attributeStruct = new StructTypeNode( attributes, 'bvh_GeometryStruct' );\n\n\t\t// write the geometry buffer attributes & bvh data\n\t\tlet attributesOffset = 0;\n\t\tlet indexOffset = 0;\n\t\tlet nodeWriteOffset = 0;\n\t\tconst indexBuffer = new Uint32Array( indexBufferLength );\n\t\tconst attributesBuffer = new ArrayBuffer( attributesBufferLength * attributeStruct.getLength() * 4 );\n\t\tconst bvhNodesBuffer = new ArrayBuffer( bvhNodesBufferLength );\n\n\t\t// append TLAS data\n\t\tappendBVHData( bvh, 0, transformInfo, 0, bvhNodesBuffer, true );\n\t\tnodeWriteOffset += getTotalBVHByteLength( bvh ) / BYTES_PER_NODE;\n\t\tbvhInfo.forEach( info => {\n\n\t\t\t// append bvh data\n\t\t\tconst bvhNodeOffsets = appendBVHData( info.bvh, indexOffset / 3, transformInfo, nodeWriteOffset, bvhNodesBuffer, false );\n\t\t\tinfo.bvhNodeOffsets = bvhNodeOffsets;\n\n\t\t\t// append geometry data\n\t\t\tappendIndexData( info.bvh, info.range, attributesOffset, indexOffset, indexBuffer );\n\t\t\tappendGeometryData( info.bvh, info.range, attributesOffset, attributesBuffer, attributeStruct, this );\n\t\t\tinfo.indexBufferOffset = indexOffset;\n\n\t\t\t// step the write offsets forward\n\t\t\tindexOffset += info.range.count;\n\t\t\tattributesOffset += info.range.vertexCount;\n\t\t\tnodeWriteOffset += getTotalBVHByteLength( info.bvh ) / BYTES_PER_NODE;\n\n\t\t} );\n\n\t\t//\n\n\t\t// write the transforms\n\t\tconst transformArrayBuffer = new ArrayBuffer( structs.transform.getLength() * transformBufferLength * 4 );\n\t\ttransformInfo.forEach( ( info, i ) => {\n\n\t\t\t_inverseMatrix.copy( bvh.matrixWorld ).invert();\n\t\t\tthis.writeTransformData( info, _inverseMatrix, i, transformArrayBuffer );\n\n\t\t} );\n\n\t\t//\n\n\t\t// set up the storage buffers\n\t\t// if itemSize for StorageBufferAttribute == arraySize,\n\t\t// then buffer is treated not as array of structs, but as a single struct\n\t\t// And that breaks code. For now itemSize = 1 does not seem to break anything\n\t\tconst bvhNodesStorage = storage( new StorageBufferAttribute( new Uint32Array( bvhNodesBuffer ), 1 ), bvhNodeStruct ).toReadOnly().setName( 'bvh_nodes' );\n\t\tconst transformsBuffer = new StorageBufferAttribute( new Uint32Array( transformArrayBuffer ), 1 );\n\t\tconst transformsStorage = storage( transformsBuffer, structs.transform ).toReadOnly().setName( 'bvh_transforms' );\n\t\tconst indexStorage = storage( new StorageBufferAttribute( indexBuffer, 1 ), 'uint' ).toReadOnly().setName( 'bvh_index' );\n\t\tconst attributesStorage = storage( new StorageBufferAttribute( new Uint32Array( attributesBuffer ), attributeStruct.getLength() ), attributeStruct ).toReadOnly().setName( 'bvh_attributes' );\n\n\t\tthis.storage.transforms = transformsStorage;\n\t\tthis.storage.nodes = bvhNodesStorage;\n\t\tthis.storage.index = indexStorage;\n\t\tthis.storage.attributes = attributesStorage;\n\t\tthis.structs.attributes = attributeStruct;\n\n\t\t// depends on the resolved attribute struct, so it must be built here rather than up front\n\t\tthis.fns.sampleTrianglePoint = getSampleTrianglePointFn( this );\n\n\t\tthis._bvhCache.clear();\n\n\t}\n\n\t/**\n\t * Writes the world/inverse-world matrices, node offset, and visibility flag for one\n\t * transform entry into a raw ArrayBuffer. Override this in a subclass to inject\n\t * additional per-object data (e.g. material index).\n\t *\n\t * @private\n\t * @param {Object3D} info - Transform entry from the internal transform info array.\n\t * @param {Matrix4} premultiplyMatrix - Matrix pre-multiplied onto the object's world matrix (usually the inverse TLAS root matrix).\n\t * @param {number} writeOffset - Index of the transform slot to write into.\n\t * @param {ArrayBuffer} targetBuffer - Destination buffer.\n\t */\n\twriteTransformData( info, premultiplyMatrix, writeOffset, targetBuffer ) {\n\n\t\tconst { structs } = this;\n\t\tconst transformBufferF32 = new Float32Array( targetBuffer );\n\t\tconst transformBufferU32 = new Uint32Array( targetBuffer );\n\n\t\tconst { object, instanceId, root, data } = info;\n\t\tconst { bvhNodeOffsets } = data;\n\t\tif ( object.isInstancedMesh || object.isBatchedMesh ) {\n\n\t\t\tobject.getMatrixAt( instanceId, _matrix );\n\t\t\t_matrix.premultiply( object.matrixWorld );\n\n\t\t} else {\n\n\t\t\t_matrix.copy( object.matrixWorld );\n\n\t\t}\n\n\t\t// write transform\n\t\t_matrix.premultiply( premultiplyMatrix );\n\t\t_matrix.toArray( transformBufferF32, writeOffset * structs.transform.getLength() );\n\n\t\t// write inverse transform\n\t\t_matrix.invert();\n\t\t_matrix.toArray( transformBufferF32, writeOffset * structs.transform.getLength() + 16 );\n\n\t\t// write node offset\n\t\ttransformBufferU32[ writeOffset * structs.transform.getLength() + 32 ] = bvhNodeOffsets[ root ];\n\n\t\tlet visible = isObjectVisible( object );\n\t\tif ( object.isBatchedMesh ) {\n\n\t\t\tvisible = visible && object.getVisibleAt( instanceId );\n\n\t\t}\n\n\t\ttransformBufferU32[ writeOffset * structs.transform.getLength() + 33 ] = visible ? 1 : 0;\n\n\t}\n\n\t/**\n\t * Returns the BVH for a given object/instance, populating `rangeTarget` with the\n\t * corresponding index and vertex ranges within the packed geometry buffers. Override\n\t * to support custom BVH types or caching strategies.\n\t *\n\t * @private\n\t * @param {Object3D} object - The object to generate a BVH for.\n\t * @param {number} instanceId - Instance index (relevant for InstancedMesh / BatchedMesh).\n\t * @param {{start:number,count:number,vertexStart:number,vertexCount:number}} rangeTarget - Populated with the object's geometry range.\n\t * @returns {MeshBVH|SkinnedMeshBVH|null}\n\t */\n\tgetBVH( object, instanceId, rangeTarget ) {\n\n\t\tconst { autogenerateBvh, _bvhCache } = this;\n\n\t\tlet bvh = null;\n\t\tif ( object.boundsTree || object.isSkinnedMesh ) {\n\n\t\t\t// this is a case where a mesh has morph targets and skinned meshes\n\t\t\tconst geometry = object.geometry;\n\t\t\trangeTarget.count = geometry.index ? geometry.index.count : geometry.attributes.position.count;\n\t\t\trangeTarget.vertexCount = geometry.attributes.position.count;\n\t\t\tbvh = object.boundsTree || null;\n\n\t\t\tif ( bvh === null && autogenerateBvh ) {\n\n\t\t\t\tconst id = object.uuid;\n\t\t\t\tbvh = _bvhCache.get( id ) || new SkinnedMeshBVH( object );\n\t\t\t\t_bvhCache.set( id, bvh );\n\n\t\t\t}\n\n\t\t} else if ( object.isBatchedMesh ) {\n\n\t\t\tconst geometryId = object.getGeometryIdAt( instanceId );\n\t\t\tconst range = object.getGeometryRangeAt( geometryId );\n\t\t\tObject.assign( rangeTarget, range );\n\t\t\tbvh = object.boundsTrees[ geometryId ] || null;\n\n\t\t\tif ( bvh === null && autogenerateBvh ) {\n\n\t\t\t\tconst id = `batched_${ object.geometry.uuid }_${ range.start }_${ range.count }`;\n\t\t\t\tbvh = _bvhCache.get( id ) || new MeshBVH( object.geometry, { range: { ...rangeTarget } } );\n\t\t\t\t_bvhCache.set( id, bvh );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst geometry = object.geometry;\n\t\t\trangeTarget.count = geometry.index ? geometry.index.count : geometry.attributes.position.count;\n\t\t\trangeTarget.vertexCount = geometry.attributes.position.count;\n\t\t\tbvh = object.geometry.boundsTree || null;\n\n\t\t\tif ( bvh === null && autogenerateBvh ) {\n\n\t\t\t\tconst id = geometry.uuid;\n\t\t\t\tbvh = _bvhCache.get( id ) || new MeshBVH( geometry );\n\t\t\t\t_bvhCache.set( id, bvh );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn bvh;\n\n\t}\n\n\t/**\n\t * Returns the default vec4 value written to the attribute buffer for vertices that lack\n\t * a given attribute. Override to change per-attribute defaults.\n\t *\n\t * @private\n\t * @param {string} key - Attribute name (e.g. `'position'`, `'normal'`).\n\t * @param {Vector4} target - Receives the default value.\n\t * @returns {Vector4}\n\t */\n\tgetDefaultAttributeValue( key, target ) {\n\n\t\tswitch ( key ) {\n\n\t\t\tcase 'position':\n\t\t\tcase 'color':\n\t\t\t\ttarget.set( 1, 1, 1, 1 );\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\ttarget.set( 0, 0, 0, 0 );\n\n\t\t}\n\n\t\treturn target;\n\n\t}\n\n\t/**\n\t * Releases GPU resources held by this instance.\n\t */\n\tdispose() {\n\n\t\tconst { storage } = this;\n\t\tfor ( const key in storage ) {\n\n\t\t\tstorage[ key ].value?.dispose();\n\t\t\tdelete storage[ key ];\n\n\t\t}\n\n\t}\n\n}\n\n\n// A container whose string members are returned as stable proxy nodes. Assigning a member stores\n// the underlying node.\n// TODO: we should automatically infer a proxy node vs fn. Perhaps in r185 we won't need the difference?\nclass NodeProxyObject {\n\n\tconstructor( initialization = {}, createProxy = proxy ) {\n\n\t\tconst proxies = {};\n\n\t\t// the raw backing object holds the underlying nodes and is the proxy target. \"createProxy\"\n\t\t// selects the proxy variant - \"proxy\" for plain nodes, \"proxyFn\" for callable function nodes.\n\t\treturn new Proxy( { ...initialization }, {\n\n\t\t\tget( target, property ) {\n\n\t\t\t\tif ( ! proxies[ property ] ) {\n\n\t\t\t\t\tproxies[ property ] = createProxy( property, target );\n\n\t\t\t\t}\n\n\t\t\t\treturn proxies[ property ];\n\n\t\t\t},\n\n\t\t\tset( target, property, value ) {\n\n\t\t\t\ttarget[ property ] = value;\n\t\t\t\treturn true;\n\n\t\t\t},\n\n\t\t} );\n\n\t}\n\n}\n","import { MeshBasicNodeMaterial, NoToneMapping, StorageTexture } from 'three/webgpu';\nimport { uv, varying, texture, vec4, toneMapping, uniform, wgslFn } from 'three/tsl';\nimport { wgslTagFn } from '../lib/three-mesh-bvh/index.js';\n\n// TODO: we could fall back to hardware-based filtering if available but it has to be specifically\n// requested and available on the renderer which we don't have access to immediately. It's possible this\n// can be detected during build time via a custom node to adjust the sample approach used?\nconst sampleTexelFn = wgslFn( /* wgsl */`\n\tfn sampleTexel( tex: texture_2d<f32>, coord: vec2f ) -> vec4f {\n\n\t\t// Manual bilinear filtering using textureLoad to support filterable float32 textures\n\t\t// on all devices\n\t\tlet size = vec2f( textureDimensions( tex, 0 ) );\n\t\tlet pxCoord = coord * size - 0.5;\n\t\tlet px = vec2i( floor( pxCoord ) );\n\t\tlet fr = fract( pxCoord );\n\n\t\t// get the four sibling samples\n\t\tlet s00 = textureLoad( tex, clamp( px, vec2i( 0 ), vec2i( size ) - 1 ), 0 );\n\t\tlet s10 = textureLoad( tex, clamp( px + vec2i( 1, 0 ), vec2i( 0 ), vec2i( size ) - 1 ), 0 );\n\t\tlet s01 = textureLoad( tex, clamp( px + vec2i( 0, 1 ), vec2i( 0 ), vec2i( size ) - 1 ), 0 );\n\t\tlet s11 = textureLoad( tex, clamp( px + vec2i( 1, 1 ), vec2i( 0 ), vec2i( size ) - 1 ), 0 );\n\n\t\t// interpolate on the x axis\n\t\tlet y0 = mix( s00, s10, fr.x );\n\t\tlet y1 = mix( s01, s11, fr.x );\n\n\t\t// then y\n\t\treturn mix( y0, y1, fr.y );\n\n\t}\n` );\n\n// Material to apply tone mapping _before_ applying alpha blending\nexport class RenderToScreenNodeMaterial extends MeshBasicNodeMaterial {\n\n\tget texture() {\n\n\t\treturn this._texNode.value;\n\n\t}\n\n\tset texture( v ) {\n\n\t\tthis._texNode.value = v;\n\n\t}\n\n\tget fromTexture() {\n\n\t\treturn this._fromTexNode.value;\n\n\t}\n\n\tset fromTexture( v ) {\n\n\t\tthis._fromTexNode.value = v;\n\n\t}\n\n\tget toneMapping() {\n\n\t\treturn this._toneMapping.toneMapping;\n\n\t}\n\n\tset toneMapping( v ) {\n\n\t\tthis._toneMapping.setToneMapping( v );\n\n\t}\n\n\tget transition() {\n\n\t\treturn this._transitionUniform.value;\n\n\t}\n\n\tset transition( v ) {\n\n\t\tthis._transitionUniform.value = v;\n\n\t}\n\n\tget exposure() {\n\n\t\treturn this._toneMapping.exposureNode.value;\n\n\t}\n\n\tset exposure( v ) {\n\n\t\tthis._toneMapping.exposureNode.value = v;\n\n\t}\n\n\tconstructor( params ) {\n\n\t\tsuper();\n\n\t\tconst texNode = texture( new StorageTexture() );\n\t\tthis._texNode = texNode;\n\n\t\tconst fromTexNode = texture( new StorageTexture() );\n\t\tthis._fromTexNode = fromTexNode;\n\n\t\tconst texUV = varying( uv() );\n\n\t\tconst transitionUniform = uniform( 1.0 );\n\t\tthis._transitionUniform = transitionUniform;\n\n\t\t// NOTE: varyings cannot be referenced directly and must be passed as arguments\n\t\tconst getFadedColorFn = wgslTagFn/* wgsl */`\n\t\t\tfn fade( uv: vec2f ) -> vec4f {\n\n\t\t\t\tif ( ${ transitionUniform } <= 0.0 ) {\n\n\t\t\t\t\treturn ${ sampleTexelFn }( ${ fromTexNode }, uv );\n\n\t\t\t\t} else if ( ${ transitionUniform } >= 1.0 ) {\n\n\t\t\t\t\treturn ${ sampleTexelFn }( ${ texNode }, uv );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlet col0 = ${ sampleTexelFn }( ${ fromTexNode }, uv );\n\t\t\t\t\tlet col1 = ${ sampleTexelFn }( ${ texNode }, uv );\n\t\t\t\t\treturn mix( col0, col1, ${ transitionUniform } );\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t`;\n\n\t\tconst toneMappingNode = toneMapping( NoToneMapping, 1.0, getFadedColorFn( texUV ) );\n\t\tthis._toneMapping = toneMappingNode;\n\n\t\t// apply alpha _after_ applying tone mapping\n\t\t// NOTE: alpha is being multiplied twice here to accommodate some odd blending in three.js\n\t\t// See mrdoob/three.js#33104. It's possible this should be removed or rethought once fixed.\n\t\tthis.transparent = true;\n\t\tthis.colorNode = vec4( toneMappingNode.rgb, toneMappingNode.a );\n\n\t\tthis.setValues( params );\n\n\t}\n\n}\n","export class ComputeKernel {\n\n\tget computeNode() {\n\n\t\treturn this.kernel.computeNode;\n\n\t}\n\n\tget workgroupSize() {\n\n\t\treturn this.kernel.workgroupSize;\n\n\t}\n\n\tset needsUpdate( v ) {\n\n\t\t// TODO: hack to force the kernel to rebuild since \"needsUpdate\" is not respected\n\t\tthis.setWorkgroupSize( ...this.workgroupSize );\n\n\t}\n\n\tconstructor( fn, options = {} ) {\n\n\t\tconst {\n\t\t\tworkgroupSize = [ 64 ],\n\t\t} = options;\n\n\t\t// this.workgroupSize = [ ...workgroupSize ];\n\t\tthis._fn = fn;\n\t\tthis.kernel = null;\n\n\t\tthis.setWorkgroupSize( ...workgroupSize );\n\n\t}\n\n\tdefineUniformAccessors( parameters ) {\n\n\t\tfor ( const key in parameters ) {\n\n\t\t\tif ( key in this ) {\n\n\t\t\t\tthrow new Error( `ComputeNode: Uniform name ${ key } is already defined.` );\n\n\t\t\t}\n\n\t\t\tconst node = parameters[ key ];\n\t\t\tif ( 'value' in node ) {\n\n\t\t\t\tObject.defineProperty( this, key, {\n\t\t\t\t\tget() {\n\n\t\t\t\t\t\treturn parameters[ key ].value;\n\n\t\t\t\t\t},\n\t\t\t\t\tset( v ) {\n\n\t\t\t\t\t\tparameters[ key ].value = v;\n\n\t\t\t\t\t},\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tsetWorkgroupSize( x = 64, y = 1, z = 1 ) {\n\n\t\tthis.kernel = this._fn.computeKernel( [ x, y, z ] );\n\t\treturn this;\n\n\t}\n\n\tgetDispatchSize( tx = 1, ty = 1, tz = 1, target = [] ) {\n\n\t\tconst [ wgx, wgy, wgz ] = this.workgroupSize;\n\t\ttarget.length = 3;\n\t\ttarget[ 0 ] = Math.ceil( tx / wgx );\n\t\ttarget[ 1 ] = Math.ceil( ty / wgy );\n\t\ttarget[ 2 ] = Math.ceil( tz / wgz );\n\t\treturn target;\n\n\t}\n\n}\n","import { uint, float, wgsl, wgslFn } from 'three/tsl';\nimport { wgslTagFn } from '../lib/three-mesh-bvh/index.js';\n\n// Alpha test should be the last index as it is summed with triangle index\nexport const RNG_INDEX_RAY_JITTER = 0;\nexport const RNG_INDEX_ENVIRONMENT_SAMPLE = 1;\nexport const RNG_INDEX_SCATTER_TYPE = 2;\nexport const RNG_INDEX_SCATTER_DIRECTION = 3;\nexport const RNG_INDEX_ALPHA_TEST = 4;\n\nexport const pcgStateStruct = wgsl( /* wgsl */`\n\n\tstruct PcgState {\n\t\ts0: vec4u,\n\t\ts1: vec4u,\n\t};\n\n\tvar<private> g_state: PcgState;\n` );\n\nexport const pcgInitFunc = wgslFn( /* wgsl */`\n\tfn pcgInitialize( pixelIndex: u32, pathIndex: u32, bounceIndex: u32 ) -> void {\n\t\tlet pixel = vec2( ( pixelIndex >> 16 ) & 0xFF, pixelIndex & 0xFF );\n\n\t\t//white noise seed\n\t\tg_state.s0 = vec4u( pixel | vec2( bounceIndex << 16 ), pathIndex, pixel.x + pixel.y);\n\n\t\t//blue noise seed\n\t\tg_state.s1 = vec4u(pathIndex, pathIndex*15843, pathIndex*31 + 4566, pathIndex*2345 + 58585);\n\n\t}\n`, [ pcgStateStruct ] );\n\nconst pcg4d = wgslFn( /* wgsl */ `\n\tfn pcg4d(v: ptr<private, vec4u>) -> void {\n\t\t*v = *v * 1664525u + 1013904223u;\n\t\t*v = *v + v.yzxy * v.wxyz;\n\t\t*v = *v ^ (*v >> vec4u(16u));\n\t\t*v = *v + v.yzxy * v.wxyz;\n\t}\n` );\n\nexport const pcgRandFunc = wgslFn( /*wgsl*/`\n\tfn pcgRand( _id: u32 ) -> f32 {\n\t\tpcg4d(&g_state.s0);\n\t\treturn abs( f32( g_state.s0.x ) / f32(0xffffffffu) );\n\t}\n`, [ pcg4d, pcgStateStruct ] );\n\nexport const pcgRand2Func = wgslFn( /*wgsl*/`\n\tfn pcgRand2( _id: u32 ) -> vec2f {\n\t\tpcg4d(&g_state.s0);\n\t\treturn abs( vec2f( g_state.s0.xy ) / f32(0xffffffffu) );\n\t}\n`, [ pcg4d, pcgStateStruct ] );\n\nexport const pcgRand3Func = wgslFn( /*wgsl*/`\n\tfn pcgRand3( _id: u32 ) -> vec3f {\n\t\tpcg4d(&g_state.s0);\n\t\treturn abs( vec3f( g_state.s0.xyz ) / f32(0xffffffffu) );\n\t}\n`, [ pcg4d, pcgStateStruct ] );\n\nexport const pcgRand4Func = wgslFn( /*wgsl*/`\n\tfn pcgRand4( _id: u32 ) -> vec4f {\n\t\tpcg4d(&g_state.s0);\n\t\treturn abs( vec4f( g_state.s0 ) / f32(0xffffffffu) );\n\t}\n`, [ pcg4d, pcgStateStruct ] );\n\nexport const pcgNextBounceFunc = wgslFn( /* wgsl */ 'fn noop() -> void {}' );\n\n// References\n// - https://jcgt.org/published/0009/04/01/\n// - Code from https://www.shadertoy.com/view/WtGyDm\n// Ported from WebGL version at sobol.glsl.js\n\nconst SOBOL_MAX_POINTS = uint( 256 * 256 );\nconst SOBOL_FACTOR = float( 1.0 / 16777216.0 );\n\nconst sobolConstants = wgsl( /* wgsl */ `\n\n\tconst SOBOL_DIRECTIONS_1 = array<u32, 32>(\n\t\t0x80000000u, 0xc0000000u, 0xa0000000u, 0xf0000000u,\n\t\t0x88000000u, 0xcc000000u, 0xaa000000u, 0xff000000u,\n\t\t0x80800000u, 0xc0c00000u, 0xa0a00000u, 0xf0f00000u,\n\t\t0x88880000u, 0xcccc0000u, 0xaaaa0000u, 0xffff0000u,\n\t\t0x80008000u, 0xc000c000u, 0xa000a000u, 0xf000f000u,\n\t\t0x88008800u, 0xcc00cc00u, 0xaa00aa00u, 0xff00ff00u,\n\t\t0x80808080u, 0xc0c0c0c0u, 0xa0a0a0a0u, 0xf0f0f0f0u,\n\t\t0x88888888u, 0xccccccccu, 0xaaaaaaaau, 0xffffffffu\n\t);\n\n\tconst SOBOL_DIRECTIONS_2 = array<u32, 32>(\n\t\t0x80000000u, 0xc0000000u, 0x60000000u, 0x90000000u,\n\t\t0xe8000000u, 0x5c000000u, 0x8e000000u, 0xc5000000u,\n\t\t0x68800000u, 0x9cc00000u, 0xee600000u, 0x55900000u,\n\t\t0x80680000u, 0xc09c0000u, 0x60ee0000u, 0x90550000u,\n\t\t0xe8808000u, 0x5cc0c000u, 0x8e606000u, 0xc5909000u,\n\t\t0x6868e800u, 0x9c9c5c00u, 0xeeee8e00u, 0x5555c500u,\n\t\t0x8000e880u, 0xc0005cc0u, 0x60008e60u, 0x9000c590u,\n\t\t0xe8006868u, 0x5c009c9cu, 0x8e00eeeeu, 0xc5005555u\n\t);\n\n\tconst SOBOL_DIRECTIONS_3 = array<u32, 32>(\n\t\t0x80000000u, 0xc0000000u, 0x20000000u, 0x50000000u,\n\t\t0xf8000000u, 0x74000000u, 0xa2000000u, 0x93000000u,\n\t\t0xd8800000u, 0x25400000u, 0x59e00000u, 0xe6d00000u,\n\t\t0x78080000u, 0xb40c0000u, 0x82020000u, 0xc3050000u,\n\t\t0x208f8000u, 0x51474000u, 0xfbea2000u, 0x75d93000u,\n\t\t0xa0858800u, 0x914e5400u, 0xdbe79e00u, 0x25db6d00u,\n\t\t0x58800080u, 0xe54000c0u, 0x79e00020u, 0xb6d00050u,\n\t\t0x800800f8u, 0xc00c0074u, 0x200200a2u, 0x50050093u\n\t);\n\n\tconst SOBOL_DIRECTIONS_4 = array<u32, 32>(\n\t\t0x80000000u, 0x40000000u, 0x20000000u, 0xb0000000u,\n\t\t0xf8000000u, 0xdc000000u, 0x7a000000u, 0x9d000000u,\n\t\t0x5a800000u, 0x2fc00000u, 0xa1600000u, 0xf0b00000u,\n\t\t0xda880000u, 0x6fc40000u, 0x81620000u, 0x40bb0000u,\n\t\t0x22878000u, 0xb3c9c000u, 0xfb65a000u, 0xddb2d000u,\n\t\t0x78022800u, 0x9c0b3c00u, 0x5a0fb600u, 0x2d0ddb00u,\n\t\t0xa2878080u, 0xf3c9c040u, 0xdb65a020u, 0x6db2d0b0u,\n\t\t0x800228f8u, 0x400b3cdcu, 0x200fb67au, 0xb00ddb9du\n\t);\n\n` );\n\nconst sobolPixelIndex = uint( 0 ).toVar( 'sobolPixelIndex' );\nconst sobolPathIndex = uint( 0 ).toVar( 'sobolPathIndex' );\nconst sobolBounceIndex = uint( 0 ).toVar( 'sobolBounceIndex' );\n\nconst getMaskedSobolFunc = wgslFn( /* wgsl */ `\n\n\tfn getMaskedSobol( index: u32, directions: array<u32, 32> ) -> u32 {\n\n\t\tvar X = 0u;\n\t\tfor ( var bit = 0u; bit < 32u; bit ++ ) {\n\n\t\t\tlet mask = ( index >> bit ) & 1u;\n\t\t\tX ^= mask * directions[ bit ];\n\n\t\t}\n\t\treturn X;\n\n\t}\n\n` );\n\n// functions to generate multi-dimensions variables of the same functions\n// to support 1, 2, 3, and 4 dimensional sobol sampling.\nconst sobolScrambleNodesGenerator = ( dim = 1 ) => {\n\n\tif ( dim <= 0 ) {\n\n\t\treturn;\n\n\t}\n\n\tconst type = dim > 1 ? `vec${dim}u` : 'u32';\n\n\tconst sobolReverseBitsFunc = wgslFn( /* wgsl */ `\n\n\t\t\tfn sobolReverseBits_${type}( in: ${type} ) -> ${type} {\n\n\t\t\t\tvar x = in;\n\t\t\t\tx = ( ( ( x & ${type}( 0xaaaaaaaau ) ) >> ${type}( 1 ) ) | ( ( x & ${type}( 0x55555555u ) ) << ${type}( 1 ) ) );\n\t\t\t\tx = ( ( ( x & ${type}( 0xccccccccu ) ) >> ${type}( 2 ) ) | ( ( x & ${type}( 0x33333333u ) ) << ${type}( 2 ) ) );\n\t\t\t\tx = ( ( ( x & ${type}( 0xf0f0f0f0u ) ) >> ${type}( 4 ) ) | ( ( x & ${type}( 0x0f0f0f0fu ) ) << ${type}( 4 ) ) );\n\t\t\t\tx = ( ( ( x & ${type}( 0xff00ff00u ) ) >> ${type}( 8 ) ) | ( ( x & ${type}( 0x00ff00ffu ) ) << ${type}( 8 ) ) );\n\t\t\t\treturn ( ( x >> ${type}( 16 ) ) | ( x << ${type}( 16 ) ) );\n\n\t\t\t}\n\n\t` );\n\n\tconst sobolHashCombineFunc = wgslFn( /* wgsl */ `\n\n\t\tfn sobolHashCombine_${type}( seed: u32, v: ${type} ) -> ${type} {\n\n\t\t\treturn ${type}( seed ) ^ ( v + ${ type }( ( seed << 6 ) + ( seed >> 2 ) ) );\n\n\t\t}\n\n\t` );\n\n\tconst sobolLaineKarrasPermutationFunc = wgslFn( /* wgsl */ `\n\n\t\tfn sobolLaineKarrasPermutation_${type}( in: ${type}, seed: ${type} ) -> ${type} {\n\n\t\t\tvar x = in;\n\t\t\tx += seed;\n\t\t\tx ^= x * 0x6c50b47cu;\n\t\t\tx ^= x * 0xb82f1e52u;\n\t\t\tx ^= x * 0xc7afe638u;\n\t\t\tx ^= x * 0x8d22f6e6u;\n\t\t\treturn x;\n\n\t\t}\n\n\t` );\n\n\tconst nestedUniformScrambleBase2Func = wgslTagFn/* wgsl */ `\n\n\t\tfn nestedUniformScrambleBase2_${type}( x: ${type}, seed: ${type} ) -> ${type} {\n\n\t\t\tvar res = ${ sobolLaineKarrasPermutationFunc }( x, seed );\n\t\t\tres = ${ sobolReverseBitsFunc }( res );\n\t\t\treturn res;\n\n\t\t}\n\n\t`;\n\n\treturn {\n\t\treverseBits: sobolReverseBitsFunc,\n\t\thashCombine: sobolHashCombineFunc,\n\t\tlkPermutation: sobolLaineKarrasPermutationFunc,\n\t\tscramble: nestedUniformScrambleBase2Func,\n\t};\n\n};\n\n// 0th node is intentionally empty to make access pattern more intuitive:\n// sobolNodes[ i ] are nodes that are needed to sample i-dimensional vectors\n// 1-dimensional vector = f32\nconst sobolNodes = Array.from( { length: 5 }, ( _, i ) => sobolScrambleNodesGenerator( i ) );\n\nexport const generateSobolPointFunc = wgslTagFn`\n ${ [ sobolConstants ] }\n\n\tfn generateSobolPoint( id: u32 ) -> vec4f {\n\n\t\tvar index = id;\n\t\tif ( index >= ${ SOBOL_MAX_POINTS } ) {\n\n\t\t\tindex = index % ${ SOBOL_MAX_POINTS };\n\t\t\t// return vec4( 0.0 );\n\n\t\t}\n\n\t\t// NOTE: this sobol \"direction\" is also available but we can't write out 5 components\n\t\t// uint x = index & 0x00ffffffu;\n\t\tlet x = ${ sobolNodes[ 1 ].reverseBits }( ${ getMaskedSobolFunc }( index, SOBOL_DIRECTIONS_1 ) ) & 0x00ffffffu;\n\t\tlet y = ${ sobolNodes[ 1 ].reverseBits }( ${ getMaskedSobolFunc }( index, SOBOL_DIRECTIONS_2 ) ) & 0x00ffffffu;\n\t\tlet z = ${ sobolNodes[ 1 ].reverseBits }( ${ getMaskedSobolFunc }( index, SOBOL_DIRECTIONS_3 ) ) & 0x00ffffffu;\n\t\tlet w = ${ sobolNodes[ 1 ].reverseBits }( ${ getMaskedSobolFunc }( index, SOBOL_DIRECTIONS_4 ) ) & 0x00ffffffu;\n\n\t\treturn vec4( f32( x ), f32( y ), f32( z ), f32( w ) ) * ${ SOBOL_FACTOR };\n\n\t}\n\n`;\n\nconst sobolHashFunc = wgslFn( /* wgsl */ `\n\n\tfn sobolHash( in: u32 ) -> u32 {\n\n\t\tvar x = in;\n\t\t// finalizer from murmurhash3\n\t\tx ^= x >> 16;\n\t\tx *= 0x85ebca6bu;\n\t\tx ^= x >> 13;\n\t\tx *= 0xc2b2ae35u;\n\t\tx ^= x >> 16;\n\t\treturn x;\n\n\t}\n\n` );\n\nconst sobolGetSeedFunc = wgslTagFn`\n\n\tfn sobolGetSeed( effect: u32 ) -> u32 {\n\n\t\treturn ${ sobolHashFunc }(\n\t\t\t${ sobolNodes[ 1 ].hashCombine }(\n\t\t\t\t${ sobolNodes[ 1 ].hashCombine }(\n\t\t\t\t\t${ sobolHashFunc }( ${ sobolBounceIndex } ),\n\t\t\t\t\t${ sobolPixelIndex }\n\t\t\t\t),\n\t\t\t\teffect\n\t\t\t)\n\t\t);\n\n\t}\n\n`;\n\nconst sobolGenerator = ( dim = 1, sobolPointFunc = generateSobolPointFunc ) => {\n\n\tif ( dim <= 0 ) {\n\n\t\treturn;\n\n\t}\n\n\tconst utype = dim > 1 ? `vec${dim}u` : 'u32';\n\tconst ftype = dim > 1 ? `vec${dim}f` : 'f32';\n\n\tlet components = '.r';\n\tlet combineValues = '1u';\n\tif ( dim === 2 ) {\n\n\t\tcomponents = '.rg';\n\t\tcombineValues = 'vec2( 1u, 2u )';\n\n\t} else if ( dim === 3 ) {\n\n\t\tcomponents = '.rgb';\n\t\tcombineValues = 'vec3( 1u, 2u, 3u )';\n\n\t} else if ( dim === 4 ) {\n\n\t\tcomponents = '';\n\t\tcombineValues = 'vec4( 1u, 2u, 3u, 4u )';\n\n\t}\n\n\treturn wgslTagFn`\n\n\t\tfn sobol${dim}( effect: u32 ) -> ${ftype} {\n\n\t\t\tlet seed = ${sobolGetSeedFunc}( effect );\n\t\t\tlet index = ${sobolPathIndex};\n\n\t\t\tlet shuffle_seed = ${ sobolNodes[ 1 ].hashCombine }( seed, 0u );\n\t\t\tlet shuffled_index = ${ sobolNodes[ 1 ].scramble }( ${ sobolNodes[ 1 ].reverseBits }( index ), shuffle_seed );\n\t\t\tlet sobol_pt = ${ sobolPointFunc }( shuffled_index )${ components };\n\t\t\tvar result = ${ utype }( sobol_pt * 16777216.0 );\n\n\t\t\tlet seed2 = ${ sobolNodes[ dim ].hashCombine }( seed, ${ combineValues } );\n\t\t\tresult = ${ sobolNodes[ dim ].scramble }( result, seed2 );\n\n\t\t\treturn ${ SOBOL_FACTOR } * ${ ftype }( result >> ${utype}( 8 ) );\n\n\t\t}\n\n\t`;\n\n};\n\nexport const sobolRand1Func = sobolGenerator( 1 );\nexport const sobolRand2Func = sobolGenerator( 2 );\nexport const sobolRand3Func = sobolGenerator( 3 );\nexport const sobolRand4Func = sobolGenerator( 4 );\n\nexport const sobolInitFunc = wgslTagFn`\n\n\tfn sobolInit( pixelIndex: u32, pathIndex: u32, bounceIndex: u32 ) -> void {\n\n\t\t${ sobolPixelIndex } = pixelIndex;\n\t\t${ sobolPathIndex } = pathIndex;\n\t\t${ sobolBounceIndex } = bounceIndex;\n\n\t}\n\n`;\n\nexport const sobolNextBounceFunc = wgslTagFn`\n\n\tfn sobolNextBounce() -> void {\n\n\t\t${ sobolBounceIndex }++;\n\n\t}\n\n`;\n\n// PCG definitions\n// export {\n// \tpcgInitFunc as rngInit,\n// \tpcgNextBounceFunc as rngNextBounce,\n// \tpcgRandFunc as rand1,\n// \tpcgRand2Func as rand2,\n// \tpcgRand3Func as rand3,\n// \tpcgRand4Func as rand4,\n// };\n\n// Sobol definitions\nexport {\n\tsobolInitFunc as rngInit,\n\tsobolNextBounceFunc as rngNextBounce,\n\tsobolRand1Func as rand1,\n\tsobolRand2Func as rand2,\n\tsobolRand3Func as rand3,\n\tsobolRand4Func as rand4,\n};\n","import { wgsl } from 'three/tsl';\nimport { StructTypeNode } from 'three/webgpu';\n\n// TODO: Move to node-based constants that are embedded with wgslTagFn\nexport const constants = wgsl( /* wgsl */ `\n\n\tconst PI: f32 = 3.141592653589793;\n\tconst EPSILON: f32 = 1e-5;\n\tconst MIN_ROUGHNESS: f32 = 1e-3;\n\n` );\n\nexport const scatterRecordStruct = new StructTypeNode( {\n\tcolor: 'vec3f',\n\tspecularPdf: 'float',\n\tdirection: 'vec3f',\n\tpdf: 'float',\n}, 'ScatterRecord' );\n\n// NOTE: all \"*Map\" fields are bit-packed integers of texture index & settings:\n// bits 0-23: texture index\n// bits 24-25: wrapS setting\n// bits 26-27: wrapT setting\n// bit 28: filter setting\n// bits 29-30: unused\n// bit 31: negative bit used for indicating unused texture\nexport const materialStruct = new StructTypeNode( {\n\t// offset 0\n\tcolor: 'vec3',\n\tmap: 'int',\n\n\t// offset 4 floats\n\tmetalness: 'float',\n\tmetalnessMap: 'int',\n\n\troughness: 'float',\n\troughnessMap: 'int',\n\n\t// offset 8 floats\n\tior: 'float',\n\ttransmission: 'float',\n\ttransmissionMap: 'int',\n\n\temissiveIntensity: 'float',\n\t// offset 12 floats\n\temissive: 'vec3',\n\temissiveMap: 'int',\n\n\t// offset 16 floats\n\tnormalMap: 'int',\n\tnormalScale: 'vec2',\n\n\t// offset 20 floats\n\tclearcoat: 'float',\n\tclearcoatMap: 'int',\n\tclearcoatNormalMap: 'int',\n\t// offset 24 floats\n\tclearcoatNormalScale: 'vec2',\n\tclearcoatRoughness: 'float',\n\tclearcoatRoughnessMap: 'int',\n\n\t// offset 28 floats\n\tiridescenceMap: 'int',\n\tiridescenceThicknessMap: 'int',\n\tiridescence: 'float',\n\tiridescenceIor: 'float',\n\t// offset 32 floats\n\tiridescenceThicknessMinimum: 'float',\n\tiridescenceThicknessMaximum: 'float',\n\n\t// offset 36 floats\n\tspecularColor: 'vec3',\n\tspecularColorMap: 'int',\n\n\t// offset 40 floats\n\tspecularIntensity: 'float',\n\tspecularIntensityMap: 'int',\n\tthinFilm: 'int', // actually a boolean\n\n\t// offset 44 floats\n\tattenuationColor: 'vec3',\n\tattenuationDistance: 'float',\n\n\t// offset 48 floats\n\talphaMap: 'int',\n\n\tcastShadow: 'int', // actually a boolean\n\topacity: 'float',\n\talphaTest: 'float',\n\n\t// offset 52 floats\n\tside: 'float',\n\tmatte: 'int', // actually a boolean\n\n\tsheen: 'float',\n\t// offset 56 floats\n\tsheenColor: 'vec3',\n\tsheenColorMap: 'int',\n\t// offset 60 floats\n\tsheenRoughness: 'float',\n\tsheenRoughnessMap: 'int',\n\n\t// All those are booleans\n\tvertexColors: 'int',\n\tflatShading: 'int',\n\t// offset 64 floats\n\ttransparent: 'int',\n\tfogVolume: 'int',\n\n\t// offset 68 floats\n\tmapTransform: 'mat3',\n\t// offset 80 floats\n\tmetalnessMapTransform: 'mat3',\n\t// offset 92 floats\n\troughnessMapTransform: 'mat3',\n\t// offset 104 floats\n\ttransmissionMapTransform: 'mat3',\n\t// offset 116 floats\n\temissiveMapTransform: 'mat3',\n\t// offset 128 floats\n\tnormalMapTransform: 'mat3',\n\t// offset 140 floats\n\tclearcoatMapTransform: 'mat3',\n\t// offset 152 floats\n\tclearcoatNormalMapTransform: 'mat3',\n\t// offset 164 floats\n\tclearcoatRoughnessMapTransform: 'mat3',\n\t// offset 176 floats\n\tsheenColorMapTransform: 'mat3',\n\t// offset 188 floats\n\tsheenRoughnessMapTransform: 'mat3',\n\t// offset 200 floats\n\tiridescenceMapTransform: 'mat3',\n\t// offset 212 floats\n\tiridescenceThicknessMapTransform: 'mat3',\n\t// offset 224 floats\n\tspecularColorMapTransform: 'mat3',\n\t// offset 236 floats\n\tspecularIntensityMapTransform: 'mat3',\n\t// offset 248 floats\n\talphaMapTransform: 'mat3',\n\t// total size = 260\n}, 'Material' );\n\nexport const surfaceRecordStruct = new StructTypeNode( {\n\t// surface type\n\tvolumeParticle: 'bool',\n\n\t// geometry\n\tfaceNormal: 'vec3f',\n\tfrontFace: 'bool',\n\tnormal: 'vec3f',\n\tnormalBasis: 'mat3x3f',\n\tnormalInvBasis: 'mat3x3f',\n\n\t// cached properties\n\teta: 'f32',\n\tf0: 'f32',\n\n\t// material\n\troughness: 'f32',\n\tmetalness: 'f32',\n\tcolor: 'vec3f',\n\temission: 'vec3f',\n\n\t// transmission\n\tior: 'f32',\n\ttransmission: 'f32',\n\tthinFilm: 'bool',\n\tattenuationColor: 'vec3f',\n\tattenuationDistance: ' f32',\n\n\t// clearcoat\n\tclearcoatNormal: 'vec3f',\n\tclearcoatBasis: 'mat3x3f',\n\tclearcoatInvBasis: 'mat3x3f',\n\tclearcoat: 'f32',\n\tclearcoatRoughness: 'f32',\n\n\t// sheen\n\tsheen: 'f32',\n\tsheenColor: 'vec3f',\n\tsheenRoughness: 'f32',\n\n\t// iridescence\n\tiridescence: 'f32',\n\tiridescenceIor: 'f32',\n\tiridescenceThickness: 'f32',\n\n\t// specular\n\tspecularColor: 'vec3f',\n\tspecularIntensity: 'f32',\n}, 'SurfaceRecord' );\n\nexport const environmentInfoStruct = new StructTypeNode( {\n\trotation: 'mat3x3f',\n\tintensity: 'float',\n\tblur: 'float',\n}, 'EnvironmentInfo' );\n\nexport const lobeWeightsStruct = new StructTypeNode( {\n\tdiffuse: 'float',\n\tspecular: 'float',\n\ttransmission: 'float',\n\tclearcoat: 'float',\n}, 'LobeWeights' );\n\nexport const bxdfContextStruct = new StructTypeNode( {\n\tNdotV: 'float',\n\tNdotL: 'float',\n\tNdotH: 'float',\n\tVdotH: 'float',\n\n\tVdotNc: 'float',\n\tLdotNc: 'float',\n\tHdotNc: 'float',\n\n}, 'BxDFContext' );\n","import { wgslFn } from 'three/tsl';\nimport { scatterRecordStruct } from './structs.wgsl.js';\nimport { wgslTagFn } from '../lib/three-mesh-bvh/index.js';\n\nexport const inverseMat3x3Func = wgslFn( /* wgsl */ `\n\n\tfn inverse(m: mat3x3f) -> mat3x3f {\n\t\tvar adj: mat3x3f;\n\t\tadj[0][0] = (m[1][1] * m[2][2] - m[2][1] * m[1][2]);\n\t\tadj[1][0] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]);\n\t\tadj[2][0] = (m[1][0] * m[2][1] - m[2][0] * m[1][1]);\n\t\tadj[0][1] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]);\n\t\tadj[1][1] = (m[0][0] * m[2][2] - m[2][0] * m[0][2]);\n\t\tadj[2][1] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]);\n\t\tadj[0][2] = (m[0][1] * m[1][2] - m[1][1] * m[0][2]);\n\t\tadj[1][2] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]);\n\t\tadj[2][2] = (m[0][0] * m[1][1] - m[1][0] * m[0][1]);\n\n\t\tlet det = ( m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1])\n\t\t\t- m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0])\n\t\t\t+ m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]));\n\n\t\treturn adj * ( 1.0 / det );\n\t}\n\n` );\n\nexport const getBasisFromNormalFunc = wgslFn( /* wgsl */ `\n\n\tfn getBasisFromNormal( normal: vec3f ) -> mat3x3f {\n\n\t\tvar other: vec3f;\n\t\tif ( abs( normal.x ) > 0.5 ) {\n\n\t\t\tother = vec3f( 0.0, 1.0, 0.0 );\n\n\t\t} else {\n\n\t\t\tother = vec3f( 1.0, 0.0, 0.0 );\n\n\t\t}\n\n\t\tlet ortho = normalize( cross( normal, other ) );\n\t\tlet ortho2 = normalize( cross( normal, ortho ) );\n\t\treturn mat3x3f( ortho2, ortho, normal );\n\n\t}\n\n` );\n\nexport const iorToF0Func = wgslFn( /* wgsl */ `\n\n\tfn iorToF0( ior: f32 ) -> f32 {\n\t\treturn pow( ( 1 - ior ) / ( 1 + ior ), 2 );\n\t}\n\n` );\n\nexport const iorToF0GeneralFunc = wgslFn( /* wgsl */ `\n\n\tfn iorToF0General( transmittedIor: f32, incidentIor: f32 ) -> f32 {\n\n\t\treturn pow( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ), 2 );\n\n\t}\n\n` );\n\nexport const iorToF0GeneralVecFunc = wgslFn( /* wgsl */ `\n\n\tfn iorToF0GeneralVec( transmittedIor: vec3f, incidentIor: vec3f ) -> vec3f {\n\n\t\tlet v = ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor );\n\t\treturn v * v;\n\n\t}\n\n` );\n\nexport const fresnel0ToIorFunc = wgslFn( /* wgsl */ `\n\n\tfn fresnel0ToIor( f0: vec3f ) -> vec3f {\n\n\t\tlet sqrtF0 = sqrt( f0 );\n\t\treturn ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n\n\t}\n\n` );\n\nexport const schlickFresnelFunc = wgslFn( /* wgsl */ `\n\n\tfn schlickFresnel( cosine: f32, f0: f32 ) -> f32 {\n\n\t\treturn f0 + ( 1.0 - f0 ) * pow( 1.0 - cosine, 5.0 );\n\n\t}\n\n` );\n\nexport const schlickFresnelVecFunc = wgslFn( /* wgsl */ `\n\n\tfn schlickFresnelVec( cosine: f32, f0: vec3f, f90: vec3f ) -> vec3f {\n\n\t\treturn f0 + ( f90 - f0 ) * pow( 1.0 - cosine, 5.0 );\n\n\t}\n\n` );\n\nexport const totalInternalReflectionFunc = wgslFn( /* wgsl */ `\n\n\tfn totalInternalReflection( cosTheta: f32, eta: f32 ) -> bool {\n\n\t\tlet sinTheta = sqrt( 1.0 - cosTheta * cosTheta );\n\t\treturn eta * sinTheta > 1.0;\n\n\t}\n\n` );\n\nexport const evaluateFresnelFunc = wgslFn( /* wgsl */ `\n\n\tfn evaluateFresnel( cosine: f32, eta: f32, f0: vec3f, f90: vec3f ) -> vec3f {\n\n\t\tif ( totalInternalReflection( cosine, eta ) ) {\n\n\t\t\treturn f90;\n\n\t\t}\n\n\t\treturn f0 + ( f90 - f0 ) * pow( 1.0 - cosine, 5.0 );\n\t}\n\n`, [ totalInternalReflectionFunc ] );\n\nexport const isTerminatingScatterFunc = wgslFn( /* wgsl */ `\n\n\tfn isTerminatingScatter( scatterRec: ScatterRecord ) -> bool {\n\t\treturn scatterRec.pdf <= 0;\n\t}\n\n`, [ scatterRecordStruct ] );\n\nexport const applyWrapFunc = wgslFn( /* wgsl */ `\n\n\tfn applyWrap( v: f32, wrapMode: i32 ) -> f32 {\n\n\t\tvar res = v;\n\t\tif ( wrapMode == 1 ) {\n\n\t\t\t// ClampToEdge\n\t\t\tres = clamp( res, 0.0, 1.0 );\n\n\t\t} else if ( wrapMode == 2 ) {\n\n\t\t\t// MirroredRepeat\n\t\t\tres = 1.0 - abs( 2.0 * fract( res * 0.5 ) - 1.0 );\n\n\t\t} else {\n\n\t\t\t// Repeat\n\t\t\tres = fract( res );\n\n\t\t}\n\n\t\treturn res;\n\n\t}\n\n` );\n\n// Factory: builds sampleTexel bound to the given per-instance textureInfo uniform\n// array node ( must be named \"textureInfo\" ). Called once per scene so a single\n// sampleTexel / textureInfo binding is shared by every caller in a pipeline.\nexport const sampleTexelFunc = ( textureInfoUniform, atlas, atlasSampler ) => wgslTagFn/* wgsl */ `\n\n\tfn sampleTexel( uv: vec2f, packed: i32, lod: f32 ) -> vec4f {\n\n\t\tlet wrapS = ( packed >> 24 ) & 0x3;\n\t\tlet wrapT = ( packed >> 26 ) & 0x3;\n\t\tlet nearest = ( packed >> 28 ) & 0x1;\n\t\tlet texIndex = packed & 0xFFFFFF;\n\n\t\t// look up the texture's rect and page within the atlas. three wraps a\n\t\t// uniformArray in a struct ( textureInfoStruct ) with a \"value\" array member.\n\t\tlet info = ${ textureInfoUniform }[ u32( texIndex ) ];\n\t\tlet offset = vec2f( vec2u( info.x & 0xFFFFu, info.x >> 16u ) );\n\t\tlet size = vec2f( vec2u( info.y & 0xFFFFu, info.y >> 16u ) );\n\t\tlet page = i32( info.z & 0xFFFFu );\n\n\t\t// wrap is applied on the logical uv first, then remapped into the tile\n\t\tlet wrappedUv = vec2f(\n\t\t\t${ applyWrapFunc }( uv.x, wrapS ),\n\t\t\t${ applyWrapFunc }( uv.y, wrapT ),\n\t\t);\n\n\t\tlet pageDim = vec2f( textureDimensions( ${ atlas }, 0 ).xy );\n\n\t\tif ( nearest == 1 ) {\n\n\t\t\tlet tileTexel = clamp( vec2i( wrappedUv * size ), vec2i( 0 ), vec2i( size ) - vec2i( 1 ) );\n\t\t\treturn textureLoad( ${ atlas }, vec2i( offset ) + tileTexel, page, 0 );\n\n\t\t} else {\n\n\t\t\tvar atlasUv = ( offset + wrappedUv * size ) / pageDim;\n\n\t\t\t// clamp to half a texel inside the tile so bilinear taps never bleed into\n\t\t\t// neighboring atlas tiles\n\t\t\tlet minUv = ( offset + vec2f( 0.5 ) ) / pageDim;\n\t\t\tlet maxUv = ( offset + size - vec2f( 0.5 ) ) / pageDim;\n\t\t\tatlasUv = clamp( atlasUv, minUv, maxUv );\n\n\t\t\treturn textureSampleLevel( ${ atlas }, ${ atlasSampler }, atlasUv, page, lod );\n\n\t\t}\n\n\t}\n`;\n\n","import { wgslFn } from 'three/tsl';\nimport { environmentInfoStruct, constants, lobeWeightsStruct } from './structs.wgsl.js';\nimport { evaluateFresnelFunc, iorToF0Func, schlickFresnelFunc } from './utils.wgsl.js';\n\n/*\nwi : incident vector or light vector (pointing toward the light)\nwo : outgoing vector or view vector (pointing towards the camera)\nwh : computed half vector from wo and wi\nVectors above are assumed to be in tangent space. i.e. +z is along macronormal of the surface\neta : Greek character used to denote the \"ratio of ior\"\n*/\n\nexport const sampleSphereFunc = wgslFn( /* wgsl */ `\n\n\tfn sampleSphere( uv: vec2f ) -> vec3f {\n\n\t\tlet u = ( uv.x - 0.5 ) * 2.0;\n\t\tlet t = uv.y * PI * 2.0;\n\t\tlet f = sqrt( 1.0 - u * u );\n\n\t\treturn vec3f( f * cos( t ), f * sin( t ), u );\n\n\t}\n\n`, [ constants ] );\n\n// TODO: Investigate sampling directly in tagent space?\n// See 16.6.1 in https://www.realtimerendering.com/raytracinggems/unofficial_RayTracingGems_v1.9.pdf\nexport const diffuseDirectionFunc = wgslFn( /* wgsl */ `\n\n\tfn diffuseDirection( wo: vec3f, uv: vec2f ) -> vec3f {\n\n\t\tvar lightDirection = sampleSphere( uv );\n\t\tlightDirection.z += 1.0;\n\t\tlightDirection = normalize( lightDirection );\n\n\t\treturn lightDirection;\n\n\t}\n\n`, [ sampleSphereFunc ] );\n\nexport const getLobeWeightsFunc = wgslFn( /* wgsl */ `\n\n\tfn getLobeWeights(wo: vec3f, woClearcoat: vec3f, wh: vec3f, clearcoatIor: f32, surf: SurfaceRecord) -> LobeWeights {\n\n\t\t// TODO: experiment with this; I don't see any usage of normal?\n\t\tlet metalness = surf.metalness;\n\t\tlet transmission = surf.transmission;\n\t\tlet HdotL = dot( wh, wo );\n\t\tlet fEstimate = evaluateFresnel( HdotL, surf.eta, vec3f( surf.f0 ), vec3f( 1.0 ) ).x;\n\n\t\tlet transSpecularProb = mix( max( 0.25, fEstimate ), 1.0, metalness );\n\t\tlet diffSpecularProb = 0.5 + 0.5 * metalness;\n\n\t\tvar weights: LobeWeights;\n\t\tweights.diffuse = ( 1.0 - transmission ) * ( 1.0 - diffSpecularProb );\n\t\tweights.specular = transmission * transSpecularProb + ( 1.0 - transmission ) * diffSpecularProb;\n\n\t\tlet clearcoatF0 = iorToF0( clearcoatIor );\n\t\tlet clearcoatFresnel = schlickFresnel( saturate( woClearcoat.z ), clearcoatF0 );\n\t\tweights.clearcoat = surf.clearcoat * clearcoatFresnel;\n\n\t\tweights.transmission = transmission * ( 1.0 - transSpecularProb );\n\n\t\tlet totalWeight = weights.diffuse + weights.specular;\n\t\tif ( totalWeight > 0 ) {\n\t\t\tweights.diffuse = ( weights.diffuse / totalWeight ) * ( 1 - weights.clearcoat );\n\t\t\tweights.specular = ( weights.specular / totalWeight ) * ( 1 - weights.clearcoat );\n\t\t}\n\t\t// weights.transmission /= totalWeight;\n\n\t\treturn weights;\n\n\t}\n\n`, [ schlickFresnelFunc, iorToF0Func, evaluateFresnelFunc, lobeWeightsStruct, constants ] );\n\nconst equirectDirectionToUvFn = wgslFn( /* wgsl */`\n\n\tfn equirectDirectionToUv(direction: vec3f) -> vec2f {\n\n\t\t// from Spherical.setFromCartesianCoords\n\t\tvar uv = vec2f( atan2( direction.z, direction.x ), acos( direction.y ) );\n\t\tuv /= vec2f( 2.0 * PI, PI );\n\n\t\t// apply adjustments to get values in range [0, 1] and y right side up\n\t\tuv.x += 0.5;\n\t\tuv.y = 1.0 - uv.y;\n\t\treturn uv;\n\n\t}\n\n` );\n\nconst sampleEquirectColorFn = wgslFn( /* wgsl */ `\n\n\tfn sampleEquirectColor( envMap: texture_2d<f32>, envMapSampler: sampler, direction: vec3f ) -> vec4f {\n\n\t\treturn textureSampleLevel( envMap, envMapSampler, equirectDirectionToUv( direction ), 0 );\n\n\t}\n\n`, [ equirectDirectionToUvFn ] );\n\nconst sampleHemisphereFn = wgslFn( /* wgsl */ `\n\n\tfn sampleHemisphere( n: vec3f, uv: vec2f ) -> vec3f {\n\n\t\t// https://www.rorydriscoll.com/2009/01/07/better-sampling/\n\t\t// https://graphics.pixar.com/library/OrthonormalB/paper.pdf\n\t\tlet sign = select( sign( n.z ), 1.0, n.z == 0.0 );\n\t\tlet a = - 1.0 / ( sign + n.z );\n\t\tlet b = n.x * n.y * a;\n\t\tlet b1 = vec3( 1.0 + sign * n.x * n.x * a, sign * b, - sign * n.x );\n\t\tlet b2 = vec3( b, sign + n.y * n.y * a, - n.y );\n\n\t\tlet r = sqrt( uv.x );\n\t\tlet theta = 2.0 * PI * uv.y;\n\t\tlet x = r * cos( theta );\n\t\tlet y = r * sin( theta );\n\t\treturn x * b1 + y * b2 + sqrt( 1.0 - uv.x ) * n;\n\n\t}\n\n`, [ constants ] );\n\nexport const sampleEnvironmentFn = wgslFn( /* wgsl */ `\n\n\tfn sampleEnvironment(\n\t\tenvMap: texture_2d<f32>,\n\t\tenvMapSampler: sampler,\n\t\tenv: EnvironmentInfo,\n\t\tdirection: vec3f,\n\t\tuv: vec2f,\n\t) -> vec4f {\n\n\t\tlet offsetDir = sampleHemisphere( direction, uv ) * 0.5 * env.blur;\n\t\tlet sampleDir = normalize( env.rotation * direction + offsetDir );\n\t\tlet col = sampleEquirectColor( envMap, envMapSampler, sampleDir );\n\n\t\treturn vec4f( env.intensity * col.rgb, col.a );\n\n\t}\n\n`, [ sampleEquirectColorFn, sampleHemisphereFn, environmentInfoStruct ] );\n\nexport const weightedAlphaBlendFn = wgslFn( /* wgsl */`\n\n\tfn weightedAlphaBlend( prevColor: vec4f, newColor: vec4f, weight: f32 ) -> vec4f {\n\n\t\tlet invWeight = 1.0 - weight;\n\t\tlet totalAlpha = prevColor.a * invWeight + newColor.a * weight;\n\t\tvar blendedColor = vec4f( 0 );\n\t\tif ( totalAlpha != 0.0 ) {\n\n\t\t\tlet prevContrib = prevColor.rgb * invWeight * prevColor.a / totalAlpha;\n\t\t\tlet resContrib = newColor.rgb * weight * newColor.a / totalAlpha;\n\t\t\tblendedColor = vec4f( prevContrib + resContrib, totalAlpha );\n\n\t\t}\n\n\t\treturn blendedColor;\n\n\t}\n\n` );\n","import { DataTexture, Matrix3, Matrix4, Vector2, StorageTexture } from 'three/webgpu';\nimport { ComputeKernel } from './ComputeKernel.js';\nimport { texture, sampler, uniform, globalId, textureStore } from 'three/tsl';\nimport { rngInit, rngNextBounce, rand2, RNG_INDEX_RAY_JITTER, RNG_INDEX_ENVIRONMENT_SAMPLE } from '../nodes/random.wgsl.js';\nimport { sampleEnvironmentFn, weightedAlphaBlendFn } from '../nodes/sampling.wgsl.js';\nimport { ndcToCameraRay, proxy, proxyFn, wgslTagFn } from '../lib/three-mesh-bvh/index.js';\nimport { isTerminatingScatterFunc } from '../nodes/utils.wgsl.js';\n\nexport class PathTracerMegaKernel extends ComputeKernel {\n\n\tconstructor( ) {\n\n\t\tconst params = {\n\t\t\tbvhData: { value: null },\n\t\t\tmaterial: { value: null },\n\n\t\t\tprevOutputTarget: textureStore( new StorageTexture( 1, 1 ) ).toReadOnly(),\n\t\t\toutputTarget: textureStore( new StorageTexture( 1, 1 ) ).toWriteOnly(),\n\t\t\tsampleCountTarget: textureStore( new StorageTexture( 1, 1 ) ).toReadWrite(),\n\n\t\t\toffset: uniform( new Vector2() ),\n\t\t\ttileSize: uniform( new Vector2() ),\n\t\t\tseed: uniform( 0 ),\n\t\t\tbounces: uniform( 5 ),\n\n\t\t\t// transforms\n\t\t\tinverseProjectionMatrix: uniform( new Matrix4() ),\n\t\t\tcameraToModelMatrix: uniform( new Matrix4() ),\n\n\t\t\t// environment\n\t\t\tenvMap: texture( new DataTexture() ),\n\t\t\tenvMapSampler: sampler( new DataTexture() ),\n\t\t\tenvMapRotation: uniform( new Matrix3() ),\n\t\t\tenvMapIntensity: uniform( 1 ),\n\n\t\t\tbackground: texture( new DataTexture() ),\n\t\t\tbackgroundSampler: sampler( new DataTexture() ),\n\t\t\tbackgroundRotation: uniform( new Matrix3() ),\n\t\t\tbackgroundIntensity: uniform( 1 ),\n\t\t\tbackgroundBlurriness: uniform( 0 ),\n\n\t\t\ttextures: texture( new DataTexture() ),\n\t\t\ttextureSampler: sampler( new DataTexture() ),\n\n\t\t\t// compute variables\n\t\t\tglobalId: globalId,\n\t\t};\n\n\t\tconst raycastOutput = proxy( 'bvhData.value.fns.raycastFirstHit.outputType', params );\n\t\tconst raycastFirstHitFn = proxyFn( 'bvhData.value.fns.raycastFirstHit', params );\n\t\tconst sampleTrianglePointFn = proxyFn( 'bvhData.value.fns.sampleTrianglePoint', params );\n\t\tconst getSurfaceRecordFn = proxyFn( 'bvhData.value.fns.getSurfaceRecord', params );\n\t\tconst bsdfSampleFn = proxyFn( 'material.value.bsdfSample', params );\n\n\t\tconst shader = wgslTagFn/* wgsl */`\n\n\t\t\tfn compute(\n\n\t\t\t\t// indices and target\n\t\t\t\tglobalId: vec3u,\n\n\t\t\t\t// tiles\n\t\t\t\toffset: vec2u,\n\t\t\t\ttileSize: vec2u,\n\n\t\t\t\t// settings\n\t\t\t\tinverseProjectionMatrix: mat4x4f,\n\t\t\t\tcameraToModelMatrix: mat4x4f,\n\t\t\t\tseed: u32,\n\t\t\t\tbounces: u32,\n\n\t\t\t\t// environment\n\t\t\t\tenvMap: texture_2d<f32>,\n\t\t\t\tenvMapSampler: sampler,\n\t\t\t\tenvMapRotation: mat3x3f,\n\t\t\t\tenvMapIntensity: f32,\n\n\t\t\t\tbackground: texture_2d<f32>,\n\t\t\t\tbackgroundSampler: sampler,\n\t\t\t\tbackgroundRotation: mat3x3f,\n\t\t\t\tbackgroundIntensity: f32,\n\t\t\t\tbackgroundBlurriness: f32,\n\n\t\t\t) -> void {\n\n\t\t\t\tlet transforms = &${ proxy( 'bvhData.value.storage.transforms', params ) };\n\t\t\t\tlet materials = &${ proxy( 'bvhData.value.storage.materials', params ) };\n\n\t\t\t\tlet envInfo = EnvironmentInfo(\n\t\t\t\t\tenvMapRotation,\n\t\t\t\t\tenvMapIntensity,\n\t\t\t\t\t0.0 // blur,\n\t\t\t\t);\n\n\t\t\t\tlet backgroundInfo = EnvironmentInfo(\n\t\t\t\t\tbackgroundRotation,\n\t\t\t\t\tbackgroundIntensity,\n\t\t\t\t\tbackgroundBlurriness,\n\t\t\t\t);\n\n\t\t\t\t// make sure we don't bleed over the edge of our tile\n\t\t\t\tif ( globalId.x >= tileSize.x || globalId.y >= tileSize.y ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\t// to screen coordinates\n\t\t\t\tlet indexUV = offset + globalId.xy;\n\t\t\t\tlet targetDimensions = textureDimensions( ${ params.outputTarget } );\n\t\t\t\tif ( indexUV.x >= targetDimensions.x || indexUV.y >= targetDimensions.y ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tlet uv = vec2f( indexUV ) / vec2f( targetDimensions );\n\t\t\t\tlet ndc = uv * 2.0 - vec2f( 1.0 );\n\n\t\t\t\tlet pixelIndex = ( indexUV.x << 16 ) | indexUV.y;\n\t\t\t\t${ rngInit }( pixelIndex, seed, 0 );\n\n\t\t\t\t// scene ray\n\t\t\t\tvar jitter = 2.0 * ${ rand2 }( ${ RNG_INDEX_RAY_JITTER } ) / vec2f( targetDimensions.xy );\n\t\t\t\tvar ray = ${ ndcToCameraRay }( ndc + jitter, cameraToModelMatrix * inverseProjectionMatrix );\n\t\t\t\tray.direction = normalize( ray.direction );\n\n\t\t\t\tvar resultColor = vec4f( 0, 0, 0, 1 );\n\t\t\t\tvar throughputColor = vec3f( 1.0 );\n\n\t\t\t\tfor ( var bounce = 0u; bounce < bounces; bounce ++ ) {\n\n\t\t\t\t\tvar hitResult: ${ raycastOutput };\n\t\t\t\t\tif ( ${ raycastFirstHitFn }( ray, &hitResult ) ) {\n\n\t\t\t\t\t\tlet object = transforms[ hitResult.objectIndex ];\n\t\t\t\t\t\tvar material = materials[ object.materialIndex ];\n\n\t\t\t\t\t\t// apply per-object colors\n\t\t\t\t\t\tmaterial.color *= object.color.rgb;\n\t\t\t\t\t\tmaterial.opacity *= object.color.a;\n\n\t\t\t\t\t\tvar vertexData = ${ sampleTrianglePointFn }( hitResult.barycoord, hitResult.indices.xyz );\n\t\t\t\t\t\tvertexData.normal = normalize( transpose( object.inverseMatrixWorld ) * vertexData.normal );\n\t\t\t\t\t\tvertexData.position = object.matrixWorld * vertexData.position;\n\n\t\t\t\t\t\tlet surface = ${ getSurfaceRecordFn }( material, vertexData, hitResult.side, hitResult.normal );\n\n\t\t\t\t\t\tresultColor += vec4f( throughputColor * surface.emission, 0.0 );\n\n\t\t\t\t\t\tlet scatterRec = ${ bsdfSampleFn }( - ray.direction, surface );\n\n\t\t\t\t\t\tif ( ${ isTerminatingScatterFunc }( scatterRec ) ) {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthroughputColor *= scatterRec.color;\n\t\t\t\t\t\tthroughputColor /= scatterRec.pdf;\n\n\t\t\t\t\t\t// TODO: Investigate offsetting this position to not self-intersect multiple times\n\t\t\t\t\t\t// Adding + scatterRec.direction * 1e-1 seems to fix almost all the fireflies\n\t\t\t\t\t\t// However that seems like a very large distance to offset\n\t\t\t\t\t\tray.origin = vertexData.position.xyz;\n\t\t\t\t\t\tray.direction = scatterRec.direction;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tlet rng = ${ rand2 }( ${ RNG_INDEX_ENVIRONMENT_SAMPLE } );\n\t\t\t\t\t\tif ( bounce > 0u ) {\n\n\t\t\t\t\t\t\tresultColor += ${ sampleEnvironmentFn }( envMap, envMapSampler, envInfo, ray.direction, rng ) * vec4f( throughputColor, 0.0 );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tresultColor = ${ sampleEnvironmentFn }( background, backgroundSampler, backgroundInfo, ray.direction, rng );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t${ rngNextBounce }();\n\n\t\t\t\t}\n\n\t\t\t\tlet sampleCount = textureLoad( ${ params.sampleCountTarget }, indexUV ).r + 1;\n\t\t\t\tlet prevColor = textureLoad( ${ params.prevOutputTarget }, indexUV );\n\t\t\t\tlet blendedColor = ${ weightedAlphaBlendFn }( prevColor, resultColor, 1.0 / f32( sampleCount ) );\n\t\t\t\ttextureStore( ${ params.sampleCountTarget }, indexUV, vec4( sampleCount ) );\n\t\t\t\ttextureStore( ${ params.outputTarget }, indexUV, blendedColor );\n\n\t\t\t}`;\n\n\t\tsuper( shader( params ) );\n\n\t\tthis.defineUniformAccessors( params );\n\n\t}\n\n}\n","import { DataUtils } from 'three';\n\n\nexport function toHalfFloatArray( f32Array ) {\n\n\tconst f16Array = new Uint16Array( f32Array.length );\n\tfor ( let i = 0, n = f32Array.length; i < n; ++ i ) {\n\n\t\tf16Array[ i ] = DataUtils.toHalfFloat( f32Array[ i ] );\n\n\t}\n\n\treturn f16Array;\n\n}\n","import { DataTexture, RedFormat, LinearFilter, DataUtils, HalfFloatType, Source, RepeatWrapping, RGBAFormat, FloatType, ClampToEdgeWrapping } from 'three';\nimport { toHalfFloatArray } from '../utils/TextureUtils.js';\n\nfunction binarySearchFindClosestIndexOf( array, targetValue, offset = 0, count = array.length ) {\n\n\tlet lower = offset;\n\tlet upper = offset + count - 1;\n\n\twhile ( lower < upper ) {\n\n\t\t// calculate the midpoint for this iteration using a bitwise shift right operator to save 1 floating point multiplication\n\t\t// and 1 truncation from the double tilde operator to improve performance\n\t\t// this results in much better performance over using standard \"~ ~ ( (lower + upper) ) / 2\" to calculate the midpoint\n\t\tconst mid = ( lower + upper ) >> 1;\n\n\t\t// check if the middle array value is above or below the target and shift\n\t\t// which half of the array we're looking at\n\t\tif ( array[ mid ] < targetValue ) {\n\n\t\t\tlower = mid + 1;\n\n\t\t} else {\n\n\t\t\tupper = mid;\n\n\t\t}\n\n\t}\n\n\treturn lower - offset;\n\n}\n\nfunction colorToLuminance( r, g, b ) {\n\n\t// https://en.wikipedia.org/wiki/Relative_luminance\n\treturn 0.2126 * r + 0.7152 * g + 0.0722 * b;\n\n}\n\n// ensures the data is all floating point values and flipY is false\nfunction preprocessEnvMap( envMap, targetType = HalfFloatType ) {\n\n\tconst map = envMap.clone();\n\tmap.source = new Source( { ...map.image } );\n\tconst { width, height, data } = map.image;\n\n\t// TODO: is there a simple way to avoid cloning and adjusting the env map data here?\n\t// convert the data from half float uint 16 arrays to float arrays for cdf computation\n\tlet newData = data;\n\tif ( map.type !== targetType ) {\n\n\t\tif ( targetType === HalfFloatType ) {\n\n\t\t\tnewData = new Uint16Array( data.length );\n\n\t\t} else {\n\n\t\t\tnewData = new Float32Array( data.length );\n\n\t\t}\n\n\t\tlet maxIntValue;\n\t\tif ( data instanceof Int8Array || data instanceof Int16Array || data instanceof Int32Array ) {\n\n\t\t\tmaxIntValue = 2 ** ( 8 * data.BYTES_PER_ELEMENT - 1 ) - 1;\n\n\t\t} else {\n\n\t\t\tmaxIntValue = 2 ** ( 8 * data.BYTES_PER_ELEMENT ) - 1;\n\n\t\t}\n\n\t\tfor ( let i = 0, l = data.length; i < l; i ++ ) {\n\n\t\t\tlet v = data[ i ];\n\t\t\tif ( map.type === HalfFloatType ) {\n\n\t\t\t\tv = DataUtils.fromHalfFloat( data[ i ] );\n\n\t\t\t}\n\n\t\t\tif ( map.type !== FloatType && map.type !== HalfFloatType ) {\n\n\t\t\t\tv /= maxIntValue;\n\n\t\t\t}\n\n\t\t\tif ( targetType === HalfFloatType ) {\n\n\t\t\t\tnewData[ i ] = DataUtils.toHalfFloat( v );\n\n\t\t\t}\n\n\t\t}\n\n\t\tmap.image.data = newData;\n\t\tmap.type = targetType;\n\n\t}\n\n\t// remove any y flipping for cdf computation\n\tif ( map.flipY ) {\n\n\t\tconst ogData = newData;\n\t\tnewData = newData.slice();\n\t\tfor ( let y = 0; y < height; y ++ ) {\n\n\t\t\tfor ( let x = 0; x < width; x ++ ) {\n\n\t\t\t\tconst newY = height - y - 1;\n\t\t\t\tconst ogIndex = 4 * ( y * width + x );\n\t\t\t\tconst newIndex = 4 * ( newY * width + x );\n\n\t\t\t\tnewData[ newIndex + 0 ] = ogData[ ogIndex + 0 ];\n\t\t\t\tnewData[ newIndex + 1 ] = ogData[ ogIndex + 1 ];\n\t\t\t\tnewData[ newIndex + 2 ] = ogData[ ogIndex + 2 ];\n\t\t\t\tnewData[ newIndex + 3 ] = ogData[ ogIndex + 3 ];\n\n\t\t\t}\n\n\t\t}\n\n\t\tmap.flipY = false;\n\t\tmap.image.data = newData;\n\n\t}\n\n\treturn map;\n\n}\n\nexport class EquirectHdrInfoUniform {\n\n\tconstructor() {\n\n\t\t// Default to a white texture and associated weights so we don't\n\t\t// just render black initially.\n\t\tconst blackTex = new DataTexture( toHalfFloatArray( new Float32Array( [ 0, 0, 0, 0 ] ) ), 1, 1 );\n\t\tblackTex.type = HalfFloatType;\n\t\tblackTex.format = RGBAFormat;\n\t\tblackTex.minFilter = LinearFilter;\n\t\tblackTex.magFilter = LinearFilter;\n\t\tblackTex.wrapS = RepeatWrapping;\n\t\tblackTex.wrapT = RepeatWrapping;\n\t\tblackTex.generateMipmaps = false;\n\t\tblackTex.needsUpdate = true;\n\n\t\t// Stores a map of [0, 1] value -> cumulative importance row & pdf\n\t\t// used to sampling a random value to a relevant row to sample from\n\t\tconst marginalWeights = new DataTexture( toHalfFloatArray( new Float32Array( [ 0, 1 ] ) ), 1, 2 );\n\t\tmarginalWeights.type = HalfFloatType;\n\t\tmarginalWeights.format = RedFormat;\n\t\tmarginalWeights.minFilter = LinearFilter;\n\t\tmarginalWeights.magFilter = LinearFilter;\n\t\tmarginalWeights.generateMipmaps = false;\n\t\tmarginalWeights.needsUpdate = true;\n\n\t\t// Stores a map of [0, 1] value -> cumulative importance column & pdf\n\t\t// used to sampling a random value to a relevant pixel to sample from\n\t\tconst conditionalWeights = new DataTexture( toHalfFloatArray( new Float32Array( [ 0, 0, 1, 1 ] ) ), 2, 2 );\n\t\tconditionalWeights.type = HalfFloatType;\n\t\tconditionalWeights.format = RedFormat;\n\t\tconditionalWeights.minFilter = LinearFilter;\n\t\tconditionalWeights.magFilter = LinearFilter;\n\t\tconditionalWeights.generateMipmaps = false;\n\t\tconditionalWeights.needsUpdate = true;\n\n\t\tthis.map = blackTex;\n\t\tthis.marginalWeights = marginalWeights;\n\t\tthis.conditionalWeights = conditionalWeights;\n\t\tthis.totalSum = 0;\n\n\t\t// TODO: Add support for float or half float types here. We need to pass this into\n\t\t// the preprocess function and ensure our CDF and MDF textures are appropriately sized\n\t\t// Ideally we wouldn't upscale a bit depth if we didn't need to.\n\t\t// this.type = HalfFloatType;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.marginalWeights.dispose();\n\t\tthis.conditionalWeights.dispose();\n\t\tthis.map.dispose();\n\n\t}\n\n\tupdateFrom( hdr ) {\n\n\t\t// https://github.com/knightcrawler25/GLSL-PathTracer/blob/3c6fd9b6b3da47cd50c527eeb45845eef06c55c3/src/loaders/hdrloader.cpp\n\t\t// https://pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Sampling_Light_Sources#InfiniteAreaLights\n\t\tconst map = preprocessEnvMap( hdr );\n\t\tmap.wrapS = RepeatWrapping;\n\t\tmap.wrapT = ClampToEdgeWrapping;\n\n\t\tconst { width, height, data } = map.image;\n\n\t\t// \"conditional\" = \"pixel relative to row pixels sum\"\n\t\t// \"marginal\" = \"row relative to row sum\"\n\n\t\t// track the importance of any given pixel in the image by tracking its weight relative to other pixels in the image\n\t\tconst pdfConditional = new Float32Array( width * height );\n\t\tconst cdfConditional = new Float32Array( width * height );\n\n\t\tconst pdfMarginal = new Float32Array( height );\n\t\tconst cdfMarginal = new Float32Array( height );\n\n\t\tlet totalSumValue = 0.0;\n\t\tlet cumulativeWeightMarginal = 0.0;\n\t\tfor ( let y = 0; y < height; y ++ ) {\n\n\t\t\tlet cumulativeRowWeight = 0.0;\n\t\t\tfor ( let x = 0; x < width; x ++ ) {\n\n\t\t\t\tconst i = y * width + x;\n\t\t\t\tconst r = DataUtils.fromHalfFloat( data[ 4 * i + 0 ] );\n\t\t\t\tconst g = DataUtils.fromHalfFloat( data[ 4 * i + 1 ] );\n\t\t\t\tconst b = DataUtils.fromHalfFloat( data[ 4 * i + 2 ] );\n\n\t\t\t\t// the probability of the pixel being selected in this row is the\n\t\t\t\t// scale of the luminance relative to the rest of the pixels.\n\t\t\t\t// TODO: this should also account for the solid angle of the pixel when sampling\n\t\t\t\tconst weight = colorToLuminance( r, g, b );\n\t\t\t\tcumulativeRowWeight += weight;\n\t\t\t\ttotalSumValue += weight;\n\n\t\t\t\tpdfConditional[ i ] = weight;\n\t\t\t\tcdfConditional[ i ] = cumulativeRowWeight;\n\n\t\t\t}\n\n\t\t\t// can happen if the row is all black\n\t\t\tif ( cumulativeRowWeight !== 0 ) {\n\n\t\t\t\t// scale the pdf and cdf to [0.0, 1.0]\n\t\t\t\tfor ( let i = y * width, l = y * width + width; i < l; i ++ ) {\n\n\t\t\t\t\tpdfConditional[ i ] /= cumulativeRowWeight;\n\t\t\t\t\tcdfConditional[ i ] /= cumulativeRowWeight;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcumulativeWeightMarginal += cumulativeRowWeight;\n\n\t\t\t// compute the marginal pdf and cdf along the height of the map.\n\t\t\tpdfMarginal[ y ] = cumulativeRowWeight;\n\t\t\tcdfMarginal[ y ] = cumulativeWeightMarginal;\n\n\t\t}\n\n\t\t// can happen if the texture is all black\n\t\tif ( cumulativeWeightMarginal !== 0 ) {\n\n\t\t\t// scale the marginal pdf and cdf to [0.0, 1.0]\n\t\t\tfor ( let i = 0, l = pdfMarginal.length; i < l; i ++ ) {\n\n\t\t\t\tpdfMarginal[ i ] /= cumulativeWeightMarginal;\n\t\t\t\tcdfMarginal[ i ] /= cumulativeWeightMarginal;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// compute a sorted index of distributions and the probabilities along them for both\n\t\t// the marginal and conditional data. These will be used to sample with a random number\n\t\t// to retrieve a uv value to sample in the environment map.\n\t\t// These values continually increase so it's okay to interpolate between them.\n\t\tconst marginalDataArray = new Uint16Array( height );\n\t\tconst conditionalDataArray = new Uint16Array( width * height );\n\n\t\t// we add a half texel offset so we're sampling the center of the pixel\n\t\tfor ( let i = 0; i < height; i ++ ) {\n\n\t\t\tconst dist = ( i + 1 ) / height;\n\t\t\tconst row = binarySearchFindClosestIndexOf( cdfMarginal, dist );\n\n\t\t\tmarginalDataArray[ i ] = DataUtils.toHalfFloat( ( row + 0.5 ) / height );\n\n\t\t}\n\n\t\tfor ( let y = 0; y < height; y ++ ) {\n\n\t\t\tfor ( let x = 0; x < width; x ++ ) {\n\n\t\t\t\tconst i = y * width + x;\n\t\t\t\tconst dist = ( x + 1 ) / width;\n\t\t\t\tconst col = binarySearchFindClosestIndexOf( cdfConditional, dist, y * width, width );\n\n\t\t\t\tconditionalDataArray[ i ] = DataUtils.toHalfFloat( ( col + 0.5 ) / width );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.dispose();\n\n\t\tconst { marginalWeights, conditionalWeights } = this;\n\t\tmarginalWeights.image = { width: height, height: 1, data: marginalDataArray };\n\t\tmarginalWeights.needsUpdate = true;\n\n\t\tconditionalWeights.image = { width, height, data: conditionalDataArray };\n\t\tconditionalWeights.needsUpdate = true;\n\n\t\tthis.totalSum = totalSumValue;\n\t\tthis.map = map;\n\n\t}\n\n}\n","import { StorageTexture } from 'three/webgpu';\nimport { ComputeKernel } from './ComputeKernel.js';\nimport { textureStore, globalId } from 'three/tsl';\nimport { wgslTagFn } from '../lib/three-mesh-bvh/index.js';\n\nexport class ZeroOutKernel extends ComputeKernel {\n\n\tconstructor() {\n\n\t\tconst params = {\n\t\t\tglobalId: globalId,\n\t\t\toutputTarget: textureStore( new StorageTexture( 1, 1 ) ).toWriteOnly(),\n\t\t};\n\n\t\tconst fn = wgslTagFn/* wgsl */`\n\t\t\tfn compute( globalId: vec3u ) -> void {\n\n\t\t\t\ttextureStore( ${ params.outputTarget }, globalId.xy, vec4( 0, 0, 0, 1 ) );\n\n\t\t\t}\n\t\t`;\n\n\t\tsuper( fn( params ) );\n\n\t\tthis.defineUniformAccessors( {\n\t\t\ttarget: params.outputTarget,\n\t\t} );\n\n\t}\n\n}\n","import { ColorManagement, FloatType, RGBAFormat } from 'three';\nimport { RedIntegerFormat, StorageTexture, UnsignedIntType } from 'three/webgpu';\nimport { ZeroOutKernel } from './compute/ZeroOutKernel.js';\n\nexport class PathTracerBackend {\n\n\tconstructor( renderer ) {\n\n\t\tthis.renderer = renderer;\n\t\tthis.camera = null;\n\t\tthis.samples = 0;\n\t\tthis.bounces = 7;\n\t\tthis.lowResMode = false;\n\n\t\tthis._renderTask = null;\n\n\t\tthis.outputTarget = new StorageTexture( 1, 1, );\n\t\tthis.outputTarget.format = RGBAFormat;\n\t\tthis.outputTarget.type = FloatType;\n\t\tthis.outputTarget.colorSpace = ColorManagement.workingColorSpace;\n\t\tthis.outputTarget.name = 'Output #0';\n\t\tthis.outputTarget.generateMipmaps = false;\n\n\t\tthis.prevOutputTarget = new StorageTexture( 1, 1, );\n\t\tthis.prevOutputTarget.format = RGBAFormat;\n\t\tthis.prevOutputTarget.type = FloatType;\n\t\tthis.prevOutputTarget.colorSpace = ColorManagement.workingColorSpace;\n\t\tthis.prevOutputTarget.name = 'Output #1';\n\t\tthis.prevOutputTarget.generateMipmaps = false;\n\n\t\tthis.sampleCountTarget = new StorageTexture( 1, 1, );\n\t\tthis.sampleCountTarget.format = RedIntegerFormat;\n\t\tthis.sampleCountTarget.type = UnsignedIntType;\n\t\tthis.sampleCountTarget.name = 'Sample Count';\n\t\tthis.sampleCountTarget.generateMipmaps = false;\n\n\t\tthis.sampleCountClearKernel = new ZeroOutKernel().setWorkgroupSize( 8, 8, 1 );\n\t\tthis.outputTargetClearKernel = new ZeroOutKernel().setWorkgroupSize( 8, 8, 1 );\n\n\t}\n\n\tsetCamera( camera ) {\n\n\t\tthis.camera = camera;\n\t\tthis.reset();\n\n\t}\n\n\tsetBVHData( data ) {\n\n\t}\n\n\tsetTextures( textures ) {\n\n\t}\n\n\tsetMaterial( material ) {\n\n\t}\n\n\tsetEnvironment(\n\t\tenvMap,\n\t\tenvMapIntensity,\n\t\tenvMapRotation,\n\n\t\tbackground,\n\t\tbackgroundIntensity,\n\t\tbackgroundRotation,\n\t\tbackgroundBlurriness,\n\t) {\n\n\t}\n\n\tsetSize( w, h ) {\n\n\t\tw = Math.ceil( w );\n\t\th = Math.ceil( h );\n\n\t\tconst { width, height } = this.outputTarget;\n\t\tif ( width === w && height === h ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tthis.outputTarget.dispose();\n\t\tthis.prevOutputTarget.dispose();\n\t\tthis.sampleCountTarget.dispose();\n\n\t\tthis.outputTarget = this.outputTarget.clone();\n\t\tthis.prevOutputTarget = this.outputTarget.clone();\n\t\tthis.sampleCountTarget = this.sampleCountTarget.clone();\n\n\t\tthis.outputTarget.setSize( w, h );\n\t\tthis.prevOutputTarget.setSize( w, h );\n\t\tthis.sampleCountTarget.setSize( w, h );\n\n\t\tthis.reset();\n\t\treturn true;\n\n\t}\n\n\tgetSize( target ) {\n\n\t\tconst { width, height } = this.outputTarget;\n\t\ttarget.x = width;\n\t\ttarget.y = height;\n\n\t\treturn target;\n\n\t}\n\n\tupdate() {\n\n\t\tconst { camera, renderer } = this;\n\t\tif ( ! camera || ! renderer.initialized ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( ! this._renderTask ) {\n\n\t\t\tthis._renderTask = this.createRenderTask();\n\n\t\t}\n\n\t\tthis._renderTask.next();\n\n\t}\n\n\t*createRenderTask() {\n\n\t}\n\n\treset() {\n\n\t\tconst {\n\t\t\trenderer,\n\t\t\toutputTargetClearKernel,\n\t\t\tsampleCountClearKernel,\n\n\t\t\toutputTarget,\n\t\t\tprevOutputTarget,\n\t\t\tsampleCountTarget,\n\t\t} = this;\n\n\t\tif ( ! renderer.initialized ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst { width, height } = outputTarget;\n\t\tconst dispatchSize = outputTargetClearKernel.getDispatchSize( width, height );\n\n\t\toutputTargetClearKernel.target = outputTarget;\n\t\trenderer.compute( outputTargetClearKernel.kernel, dispatchSize );\n\n\t\toutputTargetClearKernel.target = prevOutputTarget;\n\t\trenderer.compute( outputTargetClearKernel.kernel, dispatchSize );\n\n\t\tsampleCountClearKernel.target = sampleCountTarget;\n\t\trenderer.compute( sampleCountClearKernel.kernel, dispatchSize );\n\n\t\tthis.samples = 0;\n\t\tthis._renderTask = null;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.outputTarget.dispose();\n\t\tthis.prevOutputTarget.dispose();\n\t\tthis.sampleCountTarget.dispose();\n\n\t\tthis._renderTask = null;\n\n\t}\n\n}\n","import { Matrix4, Vector2 } from 'three/webgpu';\nimport { PathTracerMegaKernel } from './compute/PathTracerMegaKernel.js';\nimport { EquirectHdrInfoUniform } from '../uniforms/EquirectHdrInfoUniform.js';\nimport { PathTracerBackend } from './PathTracerBackend.js';\n\nexport class MegaKernelPathTracer extends PathTracerBackend {\n\n\tconstructor( renderer ) {\n\n\t\tsuper( renderer );\n\n\t\t// options\n\t\tthis.tiles = new Vector2( 2, 2 );\n\t\tthis.envInfo = new EquirectHdrInfoUniform();\n\t\tthis.samples = 0;\n\n\t\t// kernels\n\t\tthis.kernel = new PathTracerMegaKernel( ).setWorkgroupSize( 8, 8, 1 );\n\n\t}\n\n\tsetBVHData( bvhData ) {\n\n\t\tthis.kernel.bvhData = bvhData;\n\t\tthis.kernel.needsUpdate = true;\n\t\tthis.reset();\n\n\t}\n\n\tsetMaterial( material ) {\n\n\t\tthis.kernel.material = material.getData();\n\t\tthis.kernel.needsUpdate = true;\n\t\tthis.reset();\n\n\t}\n\n\tsetEnvironment(\n\t\tenvMap,\n\t\tenvMapIntensity,\n\t\tenvMapRotation,\n\n\t\tbackground,\n\t\tbackgroundIntensity,\n\t\tbackgroundRotation,\n\t\tbackgroundBlurriness,\n\t) {\n\n\t\tconst { kernel } = this;\n\n\t\tif ( kernel.background.isTexture ) {\n\n\t\t\tkernel.background.dispose();\n\n\t\t}\n\n\t\tif ( envMap !== null ) {\n\n\t\t\tthis.envInfo.updateFrom( envMap );\n\t\t\tkernel.envMap = this.envInfo.map;\n\t\t\tkernel.kernel.computeNode.parameters.envMapSampler.node.value = this.envInfo.map;\n\n\t\t}\n\n\t\tconst rotationMatrix = new Matrix4().makeRotationFromEuler( envMapRotation ).invert();\n\t\tkernel.envMapRotation.setFromMatrix4( rotationMatrix );\n\t\tkernel.envMapIntensity = envMapIntensity;\n\n\t\tkernel.background = background;\n\t\tkernel.kernel.computeNode.parameters.backgroundSampler.node.value = background;\n\t\trotationMatrix.makeRotationFromEuler( backgroundRotation ).invert();\n\t\tkernel.backgroundRotation.setFromMatrix4( rotationMatrix );\n\t\tkernel.backgroundIntensity = backgroundIntensity;\n\t\tkernel.backgroundBlurriness = backgroundBlurriness;\n\n\t}\n\n\tsetTiles( tiles ) {\n\n\t\tthis.tiles.copy( tiles );\n\n\t}\n\n\t*createRenderTask() {\n\n\t\tconst {\n\t\t\trenderer,\n\t\t\tcamera,\n\t\t\tkernel,\n\t\t\tbounces,\n\n\t\t\ttiles,\n\t\t\toutputTarget,\n\t\t\tsampleCountTarget,\n\t\t\tlowResMode,\n\t\t} = this;\n\n\t\tcamera.updateMatrixWorld();\n\n\t\t// init parameters\n\t\tkernel.outputTarget = outputTarget;\n\t\tkernel.sampleCountTarget = sampleCountTarget;\n\n\t\tkernel.bounces = bounces;\n\t\tkernel.inverseProjectionMatrix.copy( camera.projectionMatrixInverse );\n\t\tkernel.cameraToModelMatrix.copy( camera.matrixWorld );\n\n\t\twhile ( true ) {\n\n\t\t\tconst tileSize = kernel.tileSize;\n\t\t\tif ( lowResMode ) {\n\n\t\t\t\tthis.getSize( tileSize );\n\n\t\t\t} else {\n\n\t\t\t\tthis.getSize( tileSize ).divide( tiles ).ceil();\n\n\t\t\t}\n\n\t\t\tconst dispatchSize = kernel.getDispatchSize( tileSize.x, tileSize.y );\n\t\t\tkernel.seed += 1;\n\n\t\t\t// Swap targets to support devices without <rgba32float, read_write> textures\n\t\t\t// Copy latest data to a new outputTarget to keep the appearance\n\t\t\trenderer.copyTextureToTexture( this.outputTarget, this.prevOutputTarget );\n\t\t\t[ this.outputTarget, this.prevOutputTarget ] = [ this.prevOutputTarget, this.outputTarget ];\n\t\t\tkernel.prevOutputTarget = this.prevOutputTarget;\n\t\t\tkernel.outputTarget = this.outputTarget;\n\n\t\t\tfor ( let x = 0; x < tiles.x; x ++ ) {\n\n\t\t\t\tfor ( let y = 0; y < tiles.y; y ++ ) {\n\n\t\t\t\t\tkernel.offset.set( x, y ).multiply( tileSize );\n\t\t\t\t\trenderer.compute( kernel.kernel, dispatchSize );\n\t\t\t\t\tyield;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.samples ++;\n\n\t\t}\n\n\t}\n\n\tdispose() {\n\n\t\tsuper.dispose();\n\n\t\t// TODO: dispose of all buffers\n\t\tthis.envInfo.dispose();\n\n\t}\n\n}\n","import { StructTypeNode } from 'three/webgpu';\n\nexport const queuedRayStruct = new StructTypeNode( {\n\n\torigin: 'vec3f',\n\tseed: 'uint',\n\n\tdirection: 'vec3f',\n\t_alignment0: 'uint',\n\n\tthroughputColor: 'vec3f',\n\tcurrentBounce: 'uint',\n\n\tpixel: 'vec2u',\n\n\tresultColor: 'vec4f',\n\n}, 'QueuedRay' );\n\nexport const queuedHitStruct = new StructTypeNode( {\n\n\tindices: 'vec3u',\n\tseed: 'uint',\n\n\tbarycoord: 'vec2f',\n\tpixel_x: 'uint',\n\tpixel_y: 'uint',\n\n\tview: 'vec3f',\n\tcurrentBounce: 'uint',\n\n\tthroughputColor: 'vec3f',\n\tobjectIndex: 'uint',\n\n\tnormal: 'vec3f',\n\tside: 'float',\n\n\tresultColor: 'vec4f',\n\n}, 'QueuedHit' );\n","import { Vector2, Vector3 } from 'three';\nimport { IndirectStorageBufferAttribute } from 'three/webgpu';\nimport { uniform, storage } from 'three/tsl';\nimport { ComputeKernel } from '../ComputeKernel.js';\nimport { queuedRayStruct } from './structs.js';\nimport { wgslTagFn } from '../../lib/three-mesh-bvh/index.js';\n\nexport class PrimeRayGenerationDispatchKernel extends ComputeKernel {\n\n\tconstructor() {\n\n\t\tconst params = {\n\t\t\trayWorkGroupSize: uniform( new Vector3() ),\n\n\t\t\ttileSize: uniform( new Vector2() ),\n\t\t\ttileCount: uniform( new Vector2() ),\n\t\t\ttileOffset: uniform( 1 ),\n\n\t\t\trayQueue: storage( new IndirectStorageBufferAttribute( 1, queuedRayStruct.getLength() ), queuedRayStruct ).toReadOnly(),\n\t\t\tqueueSizes: storage( new IndirectStorageBufferAttribute( 4, 1 ), 'u32' ),\n\n\t\t\toutputTileIndex: storage( new IndirectStorageBufferAttribute( 2, 1 ), 'u32' ).setName( 'outputTileIndex' ),\n\t\t\toutputDispatch: storage( new IndirectStorageBufferAttribute( 3, 1 ), 'u32' ).setName( 'outputDispatch' ),\n\t\t};\n\n\t\tconst fn = wgslTagFn/* wgsl */`\n\t\t\tfn compute(\n\t\t\t\trayWorkGroupSize: vec3u,\n\n\t\t\t\ttileSize: vec2u,\n\t\t\t\ttileCount: vec2u,\n\t\t\t\ttileOffset: u32,\n\t\t\t) -> void {\n\n\t\t\t\tlet rayQueue = &${ params.rayQueue };\n\t\t\t\tlet queueSizes = &${ params.queueSizes };\n\n\t\t\t\tlet outputTileIndex = &${ params.outputTileIndex };\n\t\t\t\tlet outputDispatch = &${ params.outputDispatch };\n\n\t\t\t\t// reset hit queue size from previous iteration\n\t\t\t\tqueueSizes[ 2 ] = 0u;\n\t\t\t\tqueueSizes[ 3 ] = 0u;\n\n\t\t\t\t// keep the queue index small\n\t\t\t let queueCapacity = arrayLength( rayQueue );\n\t\t\t\tif ( queueSizes[ 0 ] >= queueCapacity ) {\n\n\t\t\t\t\t// uint division results in a floored value\n\t\t\t\t\tlet offset = queueSizes[ 0 ] / queueCapacity;\n\t\t\t\t\tqueueSizes[ 0 ] = queueSizes[ 0 ] - queueCapacity * offset;\n\t\t\t\t\tqueueSizes[ 1 ] = queueSizes[ 1 ] - queueCapacity * offset;\n\n\t\t\t\t}\n\n\t\t\t\t// calculate the amount of elements in the queue\n\t\t\t var queueSize = queueSizes[ 1 ] - queueSizes[ 0 ];\n\n\t\t\t\t// calculate the overhead of space in the queue and how much space we need to run a new tile\n\t\t\t\tlet overhead = queueCapacity - queueSize;\n\t\t\t\tlet requiredSpace = tileSize.x * tileSize.y;\n\n\t\t\t\tif ( overhead >= requiredSpace ) {\n\n\t\t\t\t\t// calculate the necessary dispatch size to cover the tile\n\t\t\t\t\toutputDispatch[ 0 ] = u32( ceil( f32( tileSize.x ) / f32( rayWorkGroupSize.x ) ) );\n\t\t\t\t\toutputDispatch[ 1 ] = u32( ceil( f32( tileSize.y ) / f32( rayWorkGroupSize.y ) ) );\n\t\t\t\t\toutputDispatch[ 2 ] = 1;\n\n\t\t\t\t\t// calculate the tile index to generate rays for\n\t\t\t\t\tlet totalTiles = tileCount.x * tileCount.y;\n\t\t\t\t\tlet currentIndex = outputTileIndex[ 1 ] * tileCount.x + outputTileIndex[ 0 ];\n\t\t\t\t\tlet nextIndex = ( currentIndex + tileOffset ) % totalTiles;\n\n\t\t\t\t\toutputTileIndex[ 0 ] = nextIndex % tileCount.x;\n\t\t\t\t\toutputTileIndex[ 1 ] = nextIndex / tileCount.x;\n\n\t\t\t\t} else {\n\n\t\t\t\t\toutputDispatch[ 0 ] = 0;\n\t\t\t\t\toutputDispatch[ 1 ] = 0;\n\t\t\t\t\toutputDispatch[ 2 ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t`;\n\n\t\tsuper( fn( params ) );\n\n\t\tthis.defineUniformAccessors( params );\n\n\t}\n\n}\n","import { Vector2, Matrix4 } from 'three';\nimport { IndirectStorageBufferAttribute, StorageTexture } from 'three/webgpu';\nimport { uniform, storage, globalId, textureStore } from 'three/tsl';\nimport { ComputeKernel } from '../ComputeKernel.js';\nimport { rngInit, rand2, RNG_INDEX_RAY_JITTER } from '../../nodes/random.wgsl.js';\nimport { queuedRayStruct } from './structs.js';\nimport { ndcToCameraRay, wgslTagFn } from '../../lib/three-mesh-bvh/index.js';\n\nexport class RayGenerationKernel extends ComputeKernel {\n\n\tconstructor( ) {\n\n\t\tconst params = {\n\t\t\tcameraToModelMatrix: uniform( new Matrix4() ),\n\t\t\tinverseProjectionMatrix: uniform( new Matrix4() ),\n\n\t\t\tseed: uniform( 0 ),\n\n\t\t\ttileIndexBuffer: storage( new IndirectStorageBufferAttribute( 2, 1 ), 'u32' ),\n\t\t\ttileSize: uniform( new Vector2() ),\n\n\t\t\trayQueue: storage( new IndirectStorageBufferAttribute( 1, queuedRayStruct.getLength() ), queuedRayStruct ),\n\t\t\tqueueSizes: storage( new IndirectStorageBufferAttribute( 4, 1 ), 'u32' ).toAtomic(),\n\n\t\t\tsampleCountTarget: textureStore( new StorageTexture() ).toReadWrite(),\n\n\t\t\tglobalId: globalId,\n\t\t};\n\n\t\tconst fn = wgslTagFn /* wgsl */`\n\t\t\tfn compute(\n\t\t\t\tcameraToModelMatrix: mat4x4f,\n\t\t\t\tinverseProjectionMatrix: mat4x4f,\n\n\t\t\t\tseed: u32,\n\t\t\t\ttileSize: vec2u,\n\n\t\t\t\tglobalId: vec3u\n\t\t\t) -> void {\n\n\t\t\t\tlet rayQueue = &${ params.rayQueue };\n\t\t\t\tlet queueSizes = &${ params.queueSizes };\n\t\t\t\tlet tileIndexBuffer = &${ params.tileIndexBuffer };\n\n\t\t\t\t// don't overstep the edge of the tile\n\t\t\t\tif ( globalId.x >= tileSize.x || globalId.y >= tileSize.y ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\t// calculate the pixel index and ensure we are not generating rays outside the texture bounds\n\t\t\t\tlet offset = vec2( tileIndexBuffer[ 0 ] * tileSize.x, tileIndexBuffer[ 1 ] * tileSize.y );\n\t\t\t\tlet indexUV = offset + globalId.xy;\n\t\t\t\tlet targetDimensions = textureDimensions( ${ params.sampleCountTarget } );\n\t\t\t\tif ( indexUV.x >= targetDimensions.x || indexUV.y >= targetDimensions.y ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\t// calculate the screen uv\n\t\t\t\tlet uv = vec2f( indexUV ) / vec2f( targetDimensions );\n\t\t\t\tlet ndc = uv * 2.0 - vec2f( 1.0 );\n\n\t\t\t\t// check whether ray is already active (added on the queue) and skip it if it is\n\t\t\t\tlet ACTIVE_FLAG = 0xF0000000u;\n\t\t\t\tlet combinedField = textureLoad( ${ params.sampleCountTarget }, indexUV ).r;\n\t\t\t\tlet isActive = ( ACTIVE_FLAG & combinedField ) != 0;\n\t\t\t\tlet samples = ( ( ~ ACTIVE_FLAG ) & combinedField );\n\n\t\t\t\tif ( isActive ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\t// get the ray index\n\t\t\t\tlet queueCapacity = arrayLength( rayQueue );\n\t\t\t\tlet index = atomicAdd( &queueSizes[ 1 ], 1 ) % queueCapacity;\n\n\t\t\t\tlet pixelIndex = ( indexUV.x << 16 ) | indexUV.y;\n\t\t\t\t${ rngInit }( pixelIndex, seed, 0 );\n\n\t\t\t\t// write the ray data\n\t\t\t\tvar jitter = 2.0 * ${ rand2 }( ${ RNG_INDEX_RAY_JITTER } ) / vec2f( targetDimensions.xy );\n\t\t\t\tvar ray = ${ ndcToCameraRay }( ndc + jitter, cameraToModelMatrix * inverseProjectionMatrix );\n\t\t\t\tray.direction = normalize( ray.direction );\n\n\t\t\t\trayQueue[ index ].origin = ray.origin;\n\t\t\t\trayQueue[ index ].direction = ray.direction;\n\t\t\t\trayQueue[ index ].pixel = indexUV;\n\t\t\t\trayQueue[ index ].throughputColor = vec3f( 1.0 );\n\t\t\t\trayQueue[ index ].currentBounce = 0;\n\t\t\t\trayQueue[ index ].resultColor = vec4f( 0.0, 0.0, 0.0, 1.0 );\n\t\t\t\trayQueue[ index ].seed = seed;\n\n\t\t\t\t// write the active params\n\t\t\t\ttextureStore( ${ params.sampleCountTarget }, indexUV, vec4( ACTIVE_FLAG | samples ) );\n\n\t\t\t}\n\t\t`;\n\n\t\tsuper( fn( params ) );\n\n\t\tthis.defineUniformAccessors( params );\n\n\t}\n\n}\n","import { DataTexture, Matrix3, IndirectStorageBufferAttribute, StorageTexture } from 'three/webgpu';\nimport { ComputeKernel } from '../ComputeKernel.js';\nimport { uniform, texture, sampler, storage, textureStore, globalId } from 'three/tsl';\nimport { rngInit, rand2, RNG_INDEX_ENVIRONMENT_SAMPLE } from '../../nodes/random.wgsl.js';\nimport { queuedRayStruct, queuedHitStruct } from './structs.js';\nimport { proxy, wgslTagFn } from '../../lib/three-mesh-bvh/index.js';\nimport { sampleEnvironmentFn, weightedAlphaBlendFn } from '../../nodes/sampling.wgsl.js';\n\nexport class RayIntersectionKernel extends ComputeKernel {\n\n\tconstructor( ) {\n\n\t\tconst params = {\n\t\t\tbvhData: { value: null },\n\n\t\t\tprevOutputTarget: textureStore( new StorageTexture( 1, 1 ) ).toReadOnly(),\n\t\t\toutputTarget: textureStore( new StorageTexture( 1, 1 ) ).toWriteOnly(),\n\t\t\tsampleCountTarget: textureStore( new StorageTexture( 1, 1 ) ).toReadWrite(),\n\n\t\t\t// rays\n\t\t\trayQueue: storage( new IndirectStorageBufferAttribute( 1, queuedRayStruct.getLength() ), queuedRayStruct ).toReadOnly(),\n\t\t\thitQueue: storage( new IndirectStorageBufferAttribute( 1, queuedHitStruct.getLength() ), queuedHitStruct ),\n\t\t\tqueueSizes: storage( new IndirectStorageBufferAttribute( 4, 1 ), 'u32' ).toAtomic(),\n\n\t\t\t// environment\n\t\t\tenvMap: texture( new DataTexture() ),\n\t\t\tenvMapSampler: sampler( new DataTexture() ),\n\t\t\tenvMapRotation: uniform( new Matrix3() ),\n\t\t\tenvMapIntensity: uniform( 1 ),\n\n\t\t\tbackground: texture( new DataTexture() ),\n\t\t\tbackgroundSampler: sampler( new DataTexture() ),\n\t\t\tbackgroundRotation: uniform( new Matrix3() ),\n\t\t\tbackgroundIntensity: uniform( 1 ),\n\t\t\tbackgroundBlurriness: uniform( 0 ),\n\n\t\t\tglobalId: globalId,\n\t\t};\n\n\t\tconst raycastOutput = proxy( 'bvhData.value.fns.raycastFirstHit.outputType', params );\n\t\tconst raycastFirstHitFn = proxy( 'bvhData.value.fns.raycastFirstHit', params );\n\n\t\tconst fn = wgslTagFn /* wgsl */`\n\n\t\t\tfn compute(\n\t\t\t\t// environment\n\t\t\t\tenvMap: texture_2d<f32>,\n\t\t\t\tenvMapSampler: sampler,\n\t\t\t\tenvMapRotation: mat3x3f,\n\t\t\t\tenvMapIntensity: f32,\n\n\t\t\t\tbackground: texture_2d<f32>,\n\t\t\t\tbackgroundSampler: sampler,\n\t\t\t\tbackgroundRotation: mat3x3f,\n\t\t\t\tbackgroundIntensity: f32,\n\t\t\t\tbackgroundBlurriness: f32,\n\n\t\t\t\tglobalId: vec3u\n\t\t\t) -> void {\n\n\t\t\t\tlet rayQueue = &${ params.rayQueue };\n\t\t\t\tlet hitQueue = &${ params.hitQueue };\n\t\t\t\tlet queueSizes = &${ params.queueSizes };\n\n\t\t\t\tlet envInfo = EnvironmentInfo(\n\t\t\t\t\tenvMapRotation,\n\t\t\t\t\tenvMapIntensity,\n\t\t\t\t\t0.0 // blur,\n\t\t\t\t);\n\n\t\t\t\tlet backgroundInfo = EnvironmentInfo(\n\t\t\t\t\tbackgroundRotation,\n\t\t\t\t\tbackgroundIntensity,\n\t\t\t\t\tbackgroundBlurriness,\n\t\t\t\t);\n\n\t\t\t\t// skip any rays invocations beyond the ray count\n\t\t\t\tlet queueCapacity = arrayLength( rayQueue );\n\t\t\t\tlet rayIndex = ( globalId.x + atomicLoad( &queueSizes[ 0 ] ) );\n\t\t\t\tif ( rayIndex >= atomicLoad( &queueSizes[ 1 ] ) ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\t// get the ray info\n\t\t\t\tlet ACTIVE_FLAG = 0xF0000000u;\n\t\t\t\tlet input = rayQueue[ rayIndex % queueCapacity ];\n\t\t\t\tlet indexUV = input.pixel;\n\n\t\t\t\tlet pixelIndex = ( indexUV.x << 16 ) | indexUV.y;\n\t\t\t\t${ rngInit }( pixelIndex, input.seed, input.currentBounce );\n\n\t\t\t\t// run intersection\n\t\t\t\tlet ray = Ray( input.origin, input.direction );\n\t\t\t\tvar hitResult: ${ raycastOutput };\n\t\t\t\tif ( ${ raycastFirstHitFn }( ray, &hitResult ) ) {\n\n\t\t\t\t\t// TODO: we process all of these materials immediately to push to the ray queue\n\t\t\t\t\tlet index = atomicAdd( &queueSizes[ 3 ], 1 );\n\t\t\t\t\thitQueue[ index ].view = - input.direction;\n\t\t\t\t\thitQueue[ index ].indices = hitResult.indices.xyz;\n\t\t\t\t\thitQueue[ index ].barycoord = hitResult.barycoord.xy;\n\t\t\t\t\thitQueue[ index ].normal = hitResult.normal.xyz;\n\t\t\t\t\thitQueue[ index ].side = hitResult.side;\n\t\t\t\t\thitQueue[ index ].pixel_x = indexUV.x;\n\t\t\t\t\thitQueue[ index ].pixel_y = indexUV.y;\n\t\t\t\t\thitQueue[ index ].objectIndex = hitResult.objectIndex;\n\t\t\t\t\thitQueue[ index ].throughputColor = input.throughputColor;\n\t\t\t\t\thitQueue[ index ].currentBounce = input.currentBounce;\n\t\t\t\t\thitQueue[ index ].resultColor = input.resultColor;\n\t\t\t\t\thitQueue[ index ].seed = input.seed;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlet rng = ${ rand2 }( ${ RNG_INDEX_ENVIRONMENT_SAMPLE } );\n\t\t\t\t\tvar resultColor = input.resultColor;\n\t\t\t\t\tif ( input.currentBounce > 0u ) {\n\n\t\t\t\t\t\tresultColor += ${ sampleEnvironmentFn }( envMap, envMapSampler, envInfo, input.direction, rng ) * vec4f( input.throughputColor, 0.0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tresultColor = ${ sampleEnvironmentFn }( background, backgroundSampler, backgroundInfo, input.direction, rng );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tlet sampleCount = ( textureLoad( ${ params.sampleCountTarget }, indexUV ).r & ( ~ ACTIVE_FLAG ) ) + 1;\n\t\t\t\t\tlet prevColor = textureLoad( ${ params.prevOutputTarget }, indexUV );\n\t\t\t\t\tlet blendedColor = ${ weightedAlphaBlendFn }( prevColor, resultColor, 1.0 / f32( sampleCount ) );\n\t\t\t\t\ttextureStore( ${ params.sampleCountTarget }, indexUV, vec4( sampleCount ) );\n\t\t\t\t\ttextureStore( ${ params.outputTarget }, indexUV, blendedColor );\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t`;\n\n\t\tsuper( fn( params ) );\n\n\t\tthis.defineUniformAccessors( params );\n\n\t}\n\n}\n","import { IndirectStorageBufferAttribute } from 'three/webgpu';\nimport { uniform, storage } from 'three/tsl';\nimport { ComputeKernel } from '../ComputeKernel.js';\nimport { wgslTagFn } from '../../lib/three-mesh-bvh/index.js';\n\nexport class UpdateRayQueueParamsKernel extends ComputeKernel {\n\n\tconstructor() {\n\n\t\tconst params = {\n\t\t\tprocessed: uniform( 0 ),\n\t\t\tqueueSizes: storage( new IndirectStorageBufferAttribute( 4, 1 ), 'u32' ),\n\t\t};\n\n\t\tconst fn = wgslTagFn/* wgsl */`\n\t\t\tfn compute( processed: u32 ) -> void {\n\n\t\t\t\tlet queueSizes = &${ params.queueSizes };\n\t\t\t var queueSize = queueSizes[ 1 ] - queueSizes[ 0 ];\n\t\t\t\tif ( processed > queueSize ) {\n\n\t\t\t\t\tqueueSizes[ 0 ] = queueSizes[ 1 ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tqueueSizes[ 0 ] = queueSizes[ 0 ] + processed;\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t`;\n\n\t\tsuper( fn( params ) );\n\n\t\tthis.defineUniformAccessors( params );\n\n\t}\n\n}\n","import { IndirectStorageBufferAttribute } from 'three/webgpu';\nimport { ComputeKernel } from './ComputeKernel.js';\nimport { storage, globalId } from 'three/tsl';\nimport { wgslTagFn } from '../lib/three-mesh-bvh/index.js';\n\nexport class ZeroOutBufferKernel extends ComputeKernel {\n\n\tconstructor( options = {} ) {\n\n\t\tconst {\n\t\t\ttype = 'u32',\n\t\t} = options;\n\n\t\tconst params = {\n\t\t\tglobalId: globalId,\n\t\t\toutputTarget: storage( new IndirectStorageBufferAttribute( 1, 1 ), type ),\n\t\t};\n\n\t\tconst fn = wgslTagFn/* wgsl */`\n\t\t\tfn compute( globalId: vec3u ) -> void {\n\n\t\t\t\t${ params.outputTarget }[ globalId.x ] = 0;\n\n\t\t\t}\n\t\t`;\n\n\t\tsuper( fn( params ) );\n\n\t\tthis.defineUniformAccessors( {\n\t\t\ttarget: params.outputTarget,\n\t\t} );\n\n\t}\n\n}\n","import { IndirectStorageBufferAttribute, StorageTexture, DataTexture } from 'three/webgpu';\nimport { ComputeKernel } from '../ComputeKernel.js';\nimport { uniform, storage, textureStore, globalId, texture, sampler } from 'three/tsl';\nimport { queuedRayStruct, queuedHitStruct } from './structs.js';\nimport { proxy, proxyFn, wgslTagFn } from '../../lib/three-mesh-bvh/index.js';\nimport { weightedAlphaBlendFn } from '../../nodes/sampling.wgsl.js';\nimport { isTerminatingScatterFunc } from '../../nodes/utils.wgsl.js';\nimport { rngInit } from '../../nodes/random.wgsl.js';\n\nexport class ProcessHitsKernel extends ComputeKernel {\n\n\tconstructor( ) {\n\n\t\tconst params = {\n\t\t\tbvhData: { value: null },\n\t\t\tmaterial: { value: null },\n\n\t\t\tprevOutputTarget: textureStore( new StorageTexture( 1, 1 ) ).toReadOnly(),\n\t\t\toutputTarget: textureStore( new StorageTexture( 1, 1 ) ).toWriteOnly(),\n\t\t\tsampleCountTarget: textureStore( new StorageTexture( 1, 1 ) ).toReadWrite(),\n\n\t\t\t// settings\n\t\t\tsmoothNormals: uniform( 1 ),\n\t\t\tbounces: uniform( 1 ),\n\n\t\t\t// rays\n\t\t\trayQueue: storage( new IndirectStorageBufferAttribute( 1, queuedRayStruct.getLength() ), queuedRayStruct ),\n\t\t\thitQueue: storage( new IndirectStorageBufferAttribute( 1, queuedHitStruct.getLength() ), queuedHitStruct ),\n\t\t\tqueueSizes: storage( new IndirectStorageBufferAttribute( 4, 1 ), 'u32' ).toAtomic(),\n\n\t\t\ttextures: texture( new DataTexture() ),\n\t\t\ttextureSampler: sampler( new DataTexture() ),\n\n\t\t\tglobalId: globalId,\n\t\t};\n\n\t\tconst sampleTrianglePointFn = proxyFn( 'bvhData.value.fns.sampleTrianglePoint', params );\n\t\tconst getSurfaceRecordFn = proxyFn( 'bvhData.value.fns.getSurfaceRecord', params );\n\t\tconst bsdfSampleFn = proxyFn( 'material.value.bsdfSample', params );\n\n\t\tconst fn = wgslTagFn/* wgsl */`\n\n\t\t\tfn compute(\n\t\t\t\t// settings\n\t\t\t\tsmoothNormals: u32,\n\t\t\t\tbounces: u32,\n\n\t\t\t\tglobalId: vec3u\n\t\t\t) -> void {\n\n\t\t\t\tlet rayQueue = &${ params.rayQueue };\n\t\t\t\tlet hitQueue = &${ params.hitQueue };\n\t\t\t\tlet queueSizes = &${ params.queueSizes };\n\n\t\t\t\tlet materials = &${ proxy( 'bvhData.value.storage.materials', params ) };\n\t\t\t\tlet transforms = &${ proxy( 'bvhData.value.storage.transforms', params ) };\n\n\t\t\t\t// skip any rays invocations beyond the ray count\n\t\t\t\tlet hitQueueCapacity = arrayLength( hitQueue );\n\t\t\t\tlet hitIndex = ( globalId.x + atomicLoad( &queueSizes[ 2 ] ) );\n\t\t\t\tif ( hitIndex >= atomicLoad( &queueSizes[ 3 ] ) ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\t// get the ray info\n\t\t\t\tlet ACTIVE_FLAG = 0xF0000000u;\n\t\t\t\tlet input = hitQueue[ hitIndex ];\n\t\t\t\tlet indexUV = vec2u( input.pixel_x, input.pixel_y );\n\n\t\t\t\tlet pixelIndex = ( indexUV.x << 16 ) | indexUV.y;\n\t\t\t\t${ rngInit }( pixelIndex, input.seed, input.currentBounce );\n\n\t\t\t\tlet object = transforms[ input.objectIndex ];\n\t\t\t\tvar material = materials[ object.materialIndex ];\n\n\t\t\t\t// apply per-object colors\n\t\t\t\tmaterial.color *= object.color.rgb;\n\t\t\t\tmaterial.opacity *= object.color.a;\n\n\t\t\t\tlet barycoord = vec3( input.barycoord, 1.0 - input.barycoord.x - input.barycoord.y );\n\t\t\t\tvar vertexData = ${ sampleTrianglePointFn }( barycoord, input.indices.xyz );\n\t\t\t\tvertexData.normal = normalize( transpose( object.inverseMatrixWorld ) * vertexData.normal );\n\t\t\t\tvertexData.position = object.matrixWorld * vertexData.position;\n\n\t\t\t\tlet surface = ${ getSurfaceRecordFn }( material, vertexData, input.side, input.normal );\n\n\t\t\t\tlet scatterRec = ${ bsdfSampleFn }( input.view, surface );\n\n\t\t\t\tlet resultColor = input.resultColor + vec4f( input.throughputColor * surface.emission, 0.0 );\n\n\t\t\t\tlet isTerminated = input.currentBounce >= bounces || ${ isTerminatingScatterFunc }( scatterRec );\n\n\t\t\t\tif ( isTerminated ) {\n\n\t\t\t\t\t// terminate ray, write color\n\t\t\t\t\tlet sampleCount = ( textureLoad( ${ params.sampleCountTarget }, indexUV ).r & ( ~ ACTIVE_FLAG ) ) + 1;\n\t\t\t\t\tlet prevColor = textureLoad( ${ params.prevOutputTarget }, indexUV );\n\t\t\t\t\tlet blendedColor = ${ weightedAlphaBlendFn }( prevColor, resultColor, 1.0 / f32( sampleCount ) );\n\t\t\t\t\ttextureStore( ${ params.sampleCountTarget }, indexUV, vec4( sampleCount ) );\n\t\t\t\t\ttextureStore( ${ params.outputTarget }, indexUV, blendedColor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlet rayQueueCapacity = arrayLength( rayQueue );\n\t\t\t\t\tlet index = atomicAdd( &queueSizes[ 1 ], 1 ) % rayQueueCapacity;\n\t\t\t\t\trayQueue[ index ].origin = vertexData.position.xyz;\n\t\t\t\t\trayQueue[ index ].direction = scatterRec.direction;\n\t\t\t\t\trayQueue[ index ].pixel = indexUV;\n\t\t\t\t\trayQueue[ index ].throughputColor = input.throughputColor * scatterRec.color / scatterRec.pdf;\n\t\t\t\t\trayQueue[ index ].currentBounce = input.currentBounce + 1;\n\t\t\t\t\trayQueue[ index ].resultColor = resultColor;\n\t\t\t\t\trayQueue[ index ].seed = input.seed;\n\n\t\t\t\t}\n\n\t\t\t}`;\n\n\t\tsuper( fn( params ) );\n\n\t\tthis.defineUniformAccessors( params );\n\n\t}\n\n}\n","import { Matrix4, IndirectStorageBufferAttribute, Vector2 } from 'three/webgpu';\nimport { PrimeRayGenerationDispatchKernel } from './compute/wavefront/PrimeRayGenerationDispatchKernel.js';\nimport { RayGenerationKernel } from './compute/wavefront/RayGenerationKernel.js';\nimport { RayIntersectionKernel } from './compute/wavefront/RayIntersectionKernel.js';\nimport { UpdateRayQueueParamsKernel } from './compute/wavefront/UpdateRayQueueParamsKernel.js';\nimport { ZeroOutBufferKernel } from './compute/ZeroOutBufferKernel.js';\nimport { ProcessHitsKernel } from './compute/wavefront/ProcessHitsKernel.js';\nimport { EquirectHdrInfoUniform } from '../uniforms/EquirectHdrInfoUniform.js';\nimport { queuedHitStruct, queuedRayStruct } from './compute/wavefront/structs.js';\nimport { PathTracerBackend } from './PathTracerBackend.js';\n\n// set the buffers to the max possible size supported by default (128MB)\n// TODO: this can be increased based on platform.\nconst RAYS_TO_PROCESS = 250000;\nconst MAX_BUFFER_SIZE = 134217728;\nconst MAX_RAY_COUNT = Math.floor( MAX_BUFFER_SIZE / ( queuedRayStruct.getLength() * 4 ) );\nconst MAX_HIT_COUNT = Math.floor( MAX_BUFFER_SIZE / ( queuedHitStruct.getLength() * 4 ) );\n\nexport class WaveFrontPathTracer extends PathTracerBackend {\n\n\tconstructor( renderer ) {\n\n\t\tsuper( renderer );\n\n\t\t// options\n\t\tthis.tiles = new Vector2( 3, 3 );\n\t\tthis.envInfo = new EquirectHdrInfoUniform();\n\n\t\t// queues\n\t\tthis.rayQueue = new IndirectStorageBufferAttribute( MAX_RAY_COUNT, queuedRayStruct.getLength() );\n\t\tthis.rayQueue.name = 'Ray Queue';\n\n\t\tthis.hitQueue = new IndirectStorageBufferAttribute( MAX_HIT_COUNT, queuedHitStruct.getLength() );\n\t\tthis.hitQueue.name = 'Hit Queue';\n\n\t\t// [0] ray head, [1] ray count, [2] hit head, [3] hit count\n\t\tthis.queueSizes = new IndirectStorageBufferAttribute( 4, 1 );\n\t\tthis.queueSizes.name = 'Queue Sizes';\n\n\t\t// dispatches\n\t\tthis.tileIndexBuffer = new IndirectStorageBufferAttribute( 2, 1 );\n\t\tthis.rayGenerationDispatch = new IndirectStorageBufferAttribute( 3, 1 );\n\t\tthis.hitProcessDispatch = new IndirectStorageBufferAttribute( 3, 1 );\n\n\t\t// kernels\n\t\tthis.primeRayGenerationDispatchKernel = new PrimeRayGenerationDispatchKernel().setWorkgroupSize( 1, 1, 1 );\n\t\tthis.enqueueRaysKernel = new RayGenerationKernel( ).setWorkgroupSize( 8, 8, 1 );\n\t\tthis.rayIntersectionKernel = new RayIntersectionKernel( ).setWorkgroupSize( 64, 1, 1 );\n\t\tthis.updateRayQueueParamsKernel = new UpdateRayQueueParamsKernel().setWorkgroupSize( 1, 1, 1 );\n\t\tthis.hitProcessKernel = new ProcessHitsKernel( ).setWorkgroupSize( 64, 1, 1 );\n\n\t\t// clear kernels\n\t\tthis.zeroDispatchKernel = new ZeroOutBufferKernel().setWorkgroupSize( 1, 1, 1 );\n\n\t\t// later\n\t\tthis.volumeKernel = null;\n\t\tthis.lightConnectionKernel = null;\n\n\t}\n\n\tsetBVHData( bvhData ) {\n\n\t\tthis.rayIntersectionKernel.bvhData = bvhData;\n\t\tthis.rayIntersectionKernel.needsUpdate = true;\n\n\t\tthis.hitProcessKernel.bvhData = bvhData;\n\t\tthis.hitProcessKernel.needsUpdate = true;\n\n\t\tthis.reset();\n\n\t}\n\n\tsetMaterial( material ) {\n\n\t\tthis.hitProcessKernel.material = material.getData();\n\t\tthis.hitProcessKernel.needsUpdate = true;\n\t\tthis.reset();\n\n\t}\n\n\tsetEnvironment(\n\t\tenvMap,\n\t\tenvMapIntensity,\n\t\tenvMapRotation,\n\n\t\tbackground,\n\t\tbackgroundIntensity,\n\t\tbackgroundRotation,\n\t\tbackgroundBlurriness,\n\t) {\n\n\t\tconst kernel = this.rayIntersectionKernel;\n\n\t\tif ( kernel.background.isTexture ) {\n\n\t\t\tkernel.background.dispose();\n\n\t\t}\n\n\t\tif ( envMap !== null ) {\n\n\t\t\tthis.envInfo.updateFrom( envMap );\n\t\t\tkernel.envMap = this.envInfo.map;\n\t\t\tkernel.kernel.computeNode.parameters.envMapSampler.node.value = this.envInfo.map;\n\n\t\t}\n\n\t\tconst rotationMatrix = new Matrix4().makeRotationFromEuler( envMapRotation ).invert();\n\t\tkernel.envMapRotation.setFromMatrix4( rotationMatrix );\n\t\tkernel.envMapIntensity = envMapIntensity;\n\n\t\tkernel.background = background;\n\t\tkernel.kernel.computeNode.parameters.backgroundSampler.node.value = background;\n\t\trotationMatrix.makeRotationFromEuler( backgroundRotation ).invert();\n\t\tkernel.backgroundRotation.setFromMatrix4( rotationMatrix );\n\t\tkernel.backgroundIntensity = backgroundIntensity;\n\t\tkernel.backgroundBlurriness = backgroundBlurriness;\n\n\t}\n\n\tsetTiles( tiles ) {\n\n\t\tthis.tiles.copy( tiles );\n\n\t}\n\n\tgetTileSize( target ) {\n\n\t\tthis.getSize( target ).divide( this.tiles ).ceil();\n\n\t\treturn target;\n\n\t}\n\n\tdispose() {\n\n\t\tsuper.dispose();\n\n\t\t// TODO: dispose of all buffers\n\t\tthis.envInfo.dispose();\n\n\t}\n\n\treset() {\n\n\t\tconst {\n\t\t\trenderer,\n\n\t\t\tsampleCountClearKernel,\n\t\t\tzeroDispatchKernel,\n\n\t\t\tsampleCountTarget,\n\n\t\t\thitProcessDispatch,\n\t\t\trayGenerationDispatch,\n\t\t\tqueueSizes,\n\t\t\ttileIndexBuffer,\n\t\t} = this;\n\n\t\tif ( ! renderer.initialized ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tsuper.reset();\n\n\t\tthis.enqueueRaysKernel.seed = 0;\n\n\t\tconst { width, height } = sampleCountTarget;\n\t\tconst dispatchSize = sampleCountClearKernel.getDispatchSize( width, height );\n\n\t\t// clear buffers\n\t\tsampleCountClearKernel.target = sampleCountTarget;\n\t\trenderer.compute( sampleCountClearKernel.kernel, dispatchSize );\n\n\t\t// clear queues\n\t\t// TODO: why do we need to se the work group size here?\n\t\tzeroDispatchKernel.target = queueSizes;\n\t\trenderer.compute( zeroDispatchKernel.kernel, [ queueSizes.count ] );\n\n\t\t// clear dispatch sizes\n\t\tzeroDispatchKernel.target = hitProcessDispatch;\n\t\trenderer.compute( zeroDispatchKernel.kernel, [ hitProcessDispatch.count ] );\n\n\t\tzeroDispatchKernel.target = rayGenerationDispatch;\n\t\trenderer.compute( zeroDispatchKernel.kernel, [ rayGenerationDispatch.count ] );\n\n\t\tzeroDispatchKernel.target = tileIndexBuffer;\n\t\trenderer.compute( zeroDispatchKernel.kernel, [ tileIndexBuffer.count ] );\n\n\t}\n\n\t*createRenderTask() {\n\n\t\tconst {\n\t\t\trenderer,\n\t\t\tcamera,\n\t\t\tbounces,\n\n\t\t\ttiles,\n\t\t\tsampleCountTarget,\n\n\t\t\trayQueue,\n\t\t\thitQueue,\n\t\t\tqueueSizes,\n\t\t\trayGenerationDispatch,\n\t\t\t// hitProcessDispatch,\n\t\t\ttileIndexBuffer,\n\n\t\t\tprimeRayGenerationDispatchKernel,\n\t\t\tenqueueRaysKernel,\n\t\t\trayIntersectionKernel,\n\t\t\tupdateRayQueueParamsKernel,\n\t\t\thitProcessKernel,\n\n\t\t\tlowResMode\n\t\t} = this;\n\n\t\tcamera.updateMatrixWorld();\n\n\t\tprimeRayGenerationDispatchKernel.tileOffset = 0;\n\n\t\tconst tileSize = new Vector2();\n\t\tconst samplesPerIteration = RAYS_TO_PROCESS / ( sampleCountTarget.width * sampleCountTarget.height * bounces );\n\t\tconst iter = lowResMode ? 5 : 1;\n\t\tlet samples = 0;\n\n\t\twhile ( true ) {\n\n\t\t\tfor ( let i = 0; i < iter; i ++ ) {\n\n\t\t\t\tthis.getTileSize( tileSize );\n\n\t\t\t\t// Swap targets to support devices without <rgba32float, read_write> textures\n\t\t\t\t// Copy latest data to a new outputTarget to keep the appearance\n\t\t\t\trenderer.copyTextureToTexture( this.outputTarget, this.prevOutputTarget );\n\t\t\t\t[ this.outputTarget, this.prevOutputTarget ] = [ this.prevOutputTarget, this.outputTarget ];\n\t\t\t\trayIntersectionKernel.prevOutputTarget = this.prevOutputTarget;\n\t\t\t\trayIntersectionKernel.outputTarget = this.outputTarget;\n\t\t\t\thitProcessKernel.prevOutputTarget = this.prevOutputTarget;\n\t\t\t\thitProcessKernel.outputTarget = this.outputTarget;\n\n\t\t\t\t// Step 1: Top up the ray queue\n\t\t\t\t// set up the ray prime kernel\n\t\t\t\tprimeRayGenerationDispatchKernel.rayWorkGroupSize.set( 8, 8, 1 );\n\t\t\t\tprimeRayGenerationDispatchKernel.tileCount.copy( tiles );\n\t\t\t\tprimeRayGenerationDispatchKernel.tileSize.copy( tileSize );\n\t\t\t\tprimeRayGenerationDispatchKernel.rayQueue = rayQueue;\n\t\t\t\tprimeRayGenerationDispatchKernel.queueSizes = queueSizes;\n\t\t\t\tprimeRayGenerationDispatchKernel.outputTileIndex = tileIndexBuffer;\n\t\t\t\tprimeRayGenerationDispatchKernel.outputDispatch = rayGenerationDispatch;\n\n\t\t\t\t// set up the ray generation kernel\n\t\t\t\tenqueueRaysKernel.seed ++;\n\t\t\t\tenqueueRaysKernel.cameraToModelMatrix.copy( camera.matrixWorld );\n\t\t\t\tenqueueRaysKernel.inverseProjectionMatrix.copy( camera.projectionMatrixInverse );\n\t\t\t\tenqueueRaysKernel.tileIndexBuffer = tileIndexBuffer;\n\t\t\t\tenqueueRaysKernel.tileSize.copy( tileSize );\n\t\t\t\tenqueueRaysKernel.rayQueue = rayQueue;\n\t\t\t\tenqueueRaysKernel.queueSizes = queueSizes;\n\t\t\t\tenqueueRaysKernel.sampleCountTarget = sampleCountTarget;\n\n\t\t\t\tfor ( let i = 0; i < tiles.x * tiles.y; i ++ ) {\n\n\t\t\t\t\t// TODO: skip rays that have converged, have reach max samples\n\t\t\t\t\trenderer.compute( primeRayGenerationDispatchKernel.kernel, [ 1, 1, 1 ] );\n\t\t\t\t\trenderer.compute( enqueueRaysKernel.kernel, rayGenerationDispatch );\n\t\t\t\t\tprimeRayGenerationDispatchKernel.tileOffset = 1;\n\n\t\t\t\t}\n\n\t\t\t\t// Step 2: run intersections, add color for terminated rays, add material handling to a dedicated queue\n\t\t\t\t// TODO: setting dispatch size to 10000 is causing failures / missed rays\n\t\t\t\tconst intersectDispatch = rayIntersectionKernel.getDispatchSize( RAYS_TO_PROCESS, 1, 1 );\n\t\t\t\trayIntersectionKernel.sampleCountTarget = sampleCountTarget;\n\t\t\t\trayIntersectionKernel.rayQueue = rayQueue;\n\t\t\t\trayIntersectionKernel.queueSizes = queueSizes;\n\t\t\t\trayIntersectionKernel.hitQueue = hitQueue;\n\t\t\t\trenderer.compute( rayIntersectionKernel.kernel, intersectDispatch );\n\n\t\t\t\t// mark the rays as consumed\n\t\t\t\tconst processed = intersectDispatch[ 0 ] * rayIntersectionKernel.workgroupSize[ 0 ];\n\t\t\t\tupdateRayQueueParamsKernel.processed = processed;\n\t\t\t\tupdateRayQueueParamsKernel.queueSizes = queueSizes;\n\t\t\t\trenderer.compute( updateRayQueueParamsKernel.kernel, [ 1, 1, 1 ] );\n\n\t\t\t\t// TODO: we should use an indirect dispatch here to only kick off the number of threads\n\t\t\t\t// as needed to iterate over all the fields\n\t\t\t\t// Step 3: attenuate ray color, scatter, run russian roulette\n\t\t\t\thitProcessKernel.sampleCountTarget = sampleCountTarget;\n\t\t\t\thitProcessKernel.bounces = bounces;\n\t\t\t\thitProcessKernel.rayQueue = rayQueue;\n\t\t\t\thitProcessKernel.queueSizes = queueSizes;\n\t\t\t\thitProcessKernel.hitQueue = hitQueue;\n\t\t\t\trenderer.compute( hitProcessKernel.kernel, hitProcessKernel.getDispatchSize( processed, 1, 1 ) );\n\t\t\t\t// Note: hit queue size ([2] and [3]) is reset at the top of the next iteration by PrimeRayGenerationDispatchKernel\n\n\t\t\t\t// Step 4: connect to lights\n\t\t\t\t// TODO\n\n\t\t\t\t// Future\n\t\t\t\t// - track variance to skip rays\n\t\t\t\t// - switch to rays pushing themselves onto the queue when terminating to avoid tiles once enough pixels have completed\n\t\t\t\t// - separate \"volume\" step?\n\t\t\t\t// - allow for simultaneous writes by queue pixel writes, sorting, and blending them in a single thread\n\n\t\t\t\tsamples += samplesPerIteration;\n\t\t\t\tthis.samples = Math.floor( samples );\n\n\t\t\t}\n\n\t\t\tyield;\n\n\t\t}\n\n\t}\n\n}\n","export const util_functions = /* glsl */`\n\n\t// TODO: possibly this should be renamed something related to material or path tracing logic\n\n\t#ifndef RAY_OFFSET\n\t#define RAY_OFFSET 1e-4\n\t#endif\n\n\t// adjust the hit point by the surface normal by a factor of some offset and the\n\t// maximum component-wise value of the current point to accommodate floating point\n\t// error as values increase.\n\tvec3 stepRayOrigin( vec3 rayOrigin, vec3 rayDirection, vec3 offset, float dist ) {\n\n\t\tvec3 point = rayOrigin + rayDirection * dist;\n\t\tvec3 absPoint = abs( point );\n\t\tfloat maxPoint = max( absPoint.x, max( absPoint.y, absPoint.z ) );\n\t\treturn point + offset * ( maxPoint + 1.0 ) * RAY_OFFSET;\n\n\t}\n\n\t// https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md#attenuation\n\tvec3 transmissionAttenuation( float dist, vec3 attColor, float attDist ) {\n\n\t\tvec3 ot = - log( attColor ) / attDist;\n\t\treturn exp( - ot * dist );\n\n\t}\n\n\tvec3 getHalfVector( vec3 wi, vec3 wo, float eta ) {\n\n\t\t// get the half vector - assuming if the light incident vector is on the other side\n\t\t// of the that it's transmissive.\n\t\tvec3 h;\n\t\tif ( wi.z > 0.0 ) {\n\n\t\t\th = normalize( wi + wo );\n\n\t\t} else {\n\n\t\t\t// Scale by the ior ratio to retrieve the appropriate half vector\n\t\t\t// From Section 2.2 on computing the transmission half vector:\n\t\t\t// https://blog.selfshadow.com/publications/s2015-shading-course/burley/s2015_pbs_disney_bsdf_notes.pdf\n\t\t\th = normalize( wi + wo * eta );\n\n\t\t}\n\n\t\th *= sign( h.z );\n\t\treturn h;\n\n\t}\n\n\tvec3 getHalfVector( vec3 a, vec3 b ) {\n\n\t\treturn normalize( a + b );\n\n\t}\n\n\t// The discrepancy between interpolated surface normal and geometry normal can cause issues when a ray\n\t// is cast that is on the top side of the geometry normal plane but below the surface normal plane. If\n\t// we find a ray like that we ignore it to avoid artifacts.\n\t// This function returns if the direction is on the same side of both planes.\n\tbool isDirectionValid( vec3 direction, vec3 surfaceNormal, vec3 geometryNormal ) {\n\n\t\tbool aboveSurfaceNormal = dot( direction, surfaceNormal ) > 0.0;\n\t\tbool aboveGeometryNormal = dot( direction, geometryNormal ) > 0.0;\n\t\treturn aboveSurfaceNormal == aboveGeometryNormal;\n\n\t}\n\n\t// ray sampling x and z are swapped to align with expected background view\n\tvec2 equirectDirectionToUv( vec3 direction ) {\n\n\t\t// from Spherical.setFromCartesianCoords\n\t\tvec2 uv = vec2( atan( direction.z, direction.x ), acos( direction.y ) );\n\t\tuv /= vec2( 2.0 * PI, PI );\n\n\t\t// apply adjustments to get values in range [0, 1] and y right side up\n\t\tuv.x += 0.5;\n\t\tuv.y = 1.0 - uv.y;\n\t\treturn uv;\n\n\t}\n\n\tvec3 equirectUvToDirection( vec2 uv ) {\n\n\t\t// undo above adjustments\n\t\tuv.x -= 0.5;\n\t\tuv.y = 1.0 - uv.y;\n\n\t\t// from Vector3.setFromSphericalCoords\n\t\tfloat theta = uv.x * 2.0 * PI;\n\t\tfloat phi = uv.y * PI;\n\n\t\tfloat sinPhi = sin( phi );\n\n\t\treturn vec3( sinPhi * cos( theta ), cos( phi ), sinPhi * sin( theta ) );\n\n\t}\n\n\t// power heuristic for multiple importance sampling\n\tfloat misHeuristic( float a, float b ) {\n\n\t\tfloat aa = a * a;\n\t\tfloat bb = b * b;\n\t\treturn aa / ( aa + bb );\n\n\t}\n\n\t// tentFilter from Peter Shirley's 'Realistic Ray Tracing (2nd Edition)' book, pg. 60\n\t// erichlof/THREE.js-PathTracing-Renderer/\n\tfloat tentFilter( float x ) {\n\n\t\treturn x < 0.5 ? sqrt( 2.0 * x ) - 1.0 : 1.0 - sqrt( 2.0 - ( 2.0 * x ) );\n\n\t}\n`;\n","import {\n\tDataTexture,\n\tDataUtils,\n\tEquirectangularReflectionMapping,\n\tFloatType,\n\tHalfFloatType,\n\tLinearFilter,\n\tLinearMipMapLinearFilter,\n\tRGBAFormat,\n\tRepeatWrapping,\n\tShaderMaterial,\n\tWebGLRenderTarget,\n} from 'three';\nimport { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';\nimport * as CommonGLSL from '../shader/common/index.js';\n\nclass CubeToEquirectMaterial extends ShaderMaterial {\n\n\tconstructor() {\n\n\t\tsuper( {\n\n\t\t\tuniforms: {\n\n\t\t\t\tenvMap: { value: null },\n\t\t\t\tflipEnvMap: { value: - 1 },\n\n\t\t\t},\n\n\t\t\tvertexShader: /* glsl */`\n\t\t\t\tvarying vec2 vUv;\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvUv = uv;\n\t\t\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t\t\t\t}`,\n\n\t\t\tfragmentShader: /* glsl */`\n\t\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\n\t\t\t\tuniform samplerCube envMap;\n\t\t\t\tuniform float flipEnvMap;\n\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t#include <common>\n\t\t\t\t#include <cube_uv_reflection_fragment>\n\n\t\t\t\t${ CommonGLSL.util_functions }\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec3 rayDirection = equirectUvToDirection( vUv );\n\t\t\t\t\trayDirection.x *= flipEnvMap;\n\t\t\t\t\tgl_FragColor = textureCube( envMap, rayDirection );\n\n\t\t\t\t}`\n\t\t} );\n\n\t\tthis.depthWrite = false;\n\t\tthis.depthTest = false;\n\n\t}\n\n}\n\nexport class CubeToEquirectGenerator {\n\n\tconstructor( renderer ) {\n\n\t\tthis._renderer = renderer;\n\t\tthis._quad = new FullScreenQuad( new CubeToEquirectMaterial() );\n\n\t}\n\n\tgenerate( source, width = null, height = null ) {\n\n\t\tif ( ! source.isCubeTexture ) {\n\n\t\t\tthrow new Error( 'CubeToEquirectMaterial: Source can only be cube textures.' );\n\n\t\t}\n\n\t\tconst image = source.images[ 0 ];\n\t\tconst renderer = this._renderer;\n\t\tconst quad = this._quad;\n\n\t\t// determine the dimensions if not provided\n\t\tif ( width === null ) {\n\n\t\t\twidth = 4 * image.height;\n\n\t\t}\n\n\t\tif ( height === null ) {\n\n\t\t\theight = 2 * image.height;\n\n\t\t}\n\n\t\tconst target = new WebGLRenderTarget( width, height, {\n\t\t\ttype: FloatType,\n\t\t\tcolorSpace: image.colorSpace,\n\t\t} );\n\n\t\t// prep the cube map data\n\t\tconst imageHeight = image.height;\n\t\tconst maxMip = Math.log2( imageHeight ) - 2;\n\t\tconst texelHeight = 1.0 / imageHeight;\n\t\tconst texelWidth = 1.0 / ( 3 * Math.max( Math.pow( 2, maxMip ), 7 * 16 ) );\n\n\t\tquad.material.defines.CUBEUV_MAX_MIP = `${ maxMip }.0`;\n\t\tquad.material.defines.CUBEUV_TEXEL_WIDTH = texelWidth;\n\t\tquad.material.defines.CUBEUV_TEXEL_HEIGHT = texelHeight;\n\t\tquad.material.uniforms.envMap.value = source;\n\t\tquad.material.uniforms.flipEnvMap.value = source.isRenderTargetTexture ? 1 : - 1;\n\t\tquad.material.needsUpdate = true;\n\n\t\t// save state and render the contents\n\t\tconst currentTarget = renderer.getRenderTarget();\n\t\tconst currentAutoClear = renderer.autoClear;\n\t\trenderer.autoClear = true;\n\t\trenderer.setRenderTarget( target );\n\t\tquad.render( renderer );\n\t\trenderer.setRenderTarget( currentTarget );\n\t\trenderer.autoClear = currentAutoClear;\n\n\t\t// read the data back\n\t\tconst buffer = new Uint16Array( width * height * 4 );\n\t\tconst readBuffer = new Float32Array( width * height * 4 );\n\t\trenderer.readRenderTargetPixels( target, 0, 0, width, height, readBuffer );\n\t\ttarget.dispose();\n\n\t\tfor ( let i = 0, l = readBuffer.length; i < l; i ++ ) {\n\n\t\t\tbuffer[ i ] = DataUtils.toHalfFloat( readBuffer[ i ] );\n\n\t\t}\n\n\t\t// produce the data texture\n\t\tconst result = new DataTexture( buffer, width, height, RGBAFormat, HalfFloatType );\n\t\tresult.minFilter = LinearMipMapLinearFilter;\n\t\tresult.magFilter = LinearFilter;\n\t\tresult.wrapS = RepeatWrapping;\n\t\tresult.wrapT = RepeatWrapping;\n\t\tresult.mapping = EquirectangularReflectionMapping;\n\t\tresult.needsUpdate = true;\n\n\t\treturn result;\n\n\t}\n\n\tdispose() {\n\n\t\tthis._quad.dispose();\n\n\t}\n\n}\n","function uuidSort( a, b ) {\n\n\tif ( a.uuid < b.uuid ) return 1;\n\tif ( a.uuid > b.uuid ) return - 1;\n\treturn 0;\n\n}\n\n// we must hash the texture to determine uniqueness using the encoding, as well, because the\n// when rendering each texture to the texture array they must have a consistent color space.\nexport function getTextureHash( t ) {\n\n\treturn `${ t.source.uuid }:${ t.colorSpace }`;\n\n}\n\n// reduce the set of textures to just those with a unique source while retaining\n// the order of the textures.\nfunction reduceTexturesToUniqueSources( textures ) {\n\n\tconst sourceSet = new Set();\n\tconst result = [];\n\tfor ( let i = 0, l = textures.length; i < l; i ++ ) {\n\n\t\tconst tex = textures[ i ];\n\t\tconst hash = getTextureHash( tex );\n\t\tif ( ! sourceSet.has( hash ) ) {\n\n\t\t\tsourceSet.add( hash );\n\t\t\tresult.push( tex );\n\n\t\t}\n\n\t}\n\n\treturn result;\n\n}\n\nexport function getIesTextures( lights ) {\n\n\tconst textures = lights.map( l => l.iesMap || null ).filter( t => t );\n\tconst textureSet = new Set( textures );\n\treturn Array.from( textureSet ).sort( uuidSort );\n\n}\n\nexport function getTextures( materials ) {\n\n\tconst textureSet = new Set();\n\tfor ( let i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\tconst material = materials[ i ];\n\t\tfor ( const key in material ) {\n\n\t\t\tconst value = material[ key ];\n\t\t\tif ( value && value.isTexture ) {\n\n\t\t\t\ttextureSet.add( value );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tconst textureArray = Array.from( textureSet );\n\treturn reduceTexturesToUniqueSources( textureArray ).sort( uuidSort );\n\n}\n\nexport function getLights( scene ) {\n\n\tconst lights = [];\n\tscene.traverse( c => {\n\n\t\tif ( c.visible ) {\n\n\t\t\tif (\n\t\t\t\tc.isRectAreaLight ||\n\t\t\t\tc.isSpotLight ||\n\t\t\t\tc.isPointLight ||\n\t\t\t\tc.isDirectionalLight\n\t\t\t) {\n\n\t\t\t\tlights.push( c );\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn lights.sort( uuidSort );\n\n}\n","import { wgslFn } from 'three/tsl';\nimport { constants } from './structs.wgsl.js';\n\n// See sampling.wgsl for vector shorthand explanations\n// The GGX functions provide sampling and distribution information for normals as output so\n// in order to get probability of scatter direction the half vector must be computed and provided.\n// [0] https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf\n// [1] https://hal.archives-ouvertes.fr/hal-01509746/document\n// [2] http://jcgt.org/published/0007/04/01/\n// [4] http://jcgt.org/published/0003/02/03/\n// [5] https://seblagarde.wordpress.com/wp-content/uploads/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf\n// trowbridge-reitz === GGX === GTR\nexport const ggxDirectionFunc = wgslFn( /* wgsl */ `\n\n\tfn ggxDirection( incidentDir: vec3f, alpha: vec2f, uv: vec2f ) -> vec3f {\n\n\t\t// Implementation from reference [1]\n\t\t// stretch view\n\t\tlet V = normalize( vec3f( alpha * incidentDir.xy, incidentDir.z ) );\n\n\t\t// orthonormal basis\n\t\tvar T1: vec3f;\n\t\tif ( V.z < 0.9999 ) {\n\t\t\tT1 = normalize( cross( V, vec3( 0.0, 0.0, 1.0 ) ) );\n\t\t} else {\n\t\t\tT1 = vec3( 1.0, 0.0, 0.0 );\n\t\t}\n\n\t\tlet T2 = cross( T1, V );\n\n\t\t// sample point with polar coordinates (r, phi)\n\t\tlet a = 1.0 / ( 1.0 + V.z );\n\t\tlet r = sqrt( uv.x );\n\t\tvar phi: f32;\n\t\tif ( uv.y < a ) {\n\t\t\tphi = uv.y / a * PI;\n\t\t} else {\n\t\t\tphi = PI + ( uv.y - a ) / ( 1.0 - a ) * PI;\n\t\t}\n\t\tlet P1 = r * cos( phi );\n\t\tvar P2 = r * sin( phi );\n\t\tif ( uv.y >= a ) {\n\t\t\tP2 *= V.z;\n\t\t}\n\n\t\t// compute normal\n\t\tvar N = P1 * T1 + P2 * T2 + V * sqrt( max( 0.0, 1.0 - P1 * P1 - P2 * P2 ) );\n\n\t\t// unstretch\n\t\tN = normalize( vec3( alpha * N.xy, max( 0.0, N.z ) ) );\n\n\t\treturn N;\n\n\t}\n\n`, [ constants ] );\n\n// Below are PDF and related functions for use in a Monte Carlo path tracer\n// as specified in Appendix B of the following paper\n// See equation (34) from reference [0]\nexport const ggxLamdaFunc = wgslFn( /* wgsl */ `\n\n\tfn ggxLamda( theta: f32, alpha: f32 ) -> f32 {\n\n\t\tlet tanTheta = tan( theta );\n\t\tlet tanTheta2 = tanTheta * tanTheta;\n\t\tlet alpha2 = alpha * alpha;\n\n\t\tlet numerator = - 1.0 + sqrt( 1.0 + alpha2 * tanTheta2 );\n\t\treturn numerator / 2.0;\n\n\t}\n\n` );\n\n// Based on equation (34) from reference [0]\nexport const ggxShadowMaskG1Func = wgslFn( /* wgsl */ `\n\n\tfn ggxShadowMaskG1( cosTheta: f32, alpha: f32 ) -> f32 {\n\n\t\tlet a2 = alpha * alpha;\n\t\tlet cosTheta2 = cosTheta * cosTheta;\n\t\tlet denom = cosTheta + sqrt( cosTheta2 * ( 1 - a2 ) + a2 );\n\t\treturn 2.0 * cosTheta / denom;\n\n\t}\n\n`, [ ggxLamdaFunc ] );\n\n// See listing 2 from reference [5]\nexport const ggxSmithVisibilityFunc = wgslFn( /* wgsl */ `\n\n\tfn ggxSmithVisibility( NdotV: f32, NdotL: f32, alpha: f32 ) -> f32 {\n\n\t\t// Original formulation of G_SmithGGX Correlated\n\t\t// lambda_v = ( -1 + sqrt ( alphaG2 * (1 - NdotL2 ) / NdotL2 + 1)) * 0.5 f;\n\t\t// lambda_l = ( -1 + sqrt ( alphaG2 * (1 - NdotV2 ) / NdotV2 + 1)) * 0.5 f;\n\t\t// G_SmithGGXCorrelated = 1 / (1 + lambda_v + lambda_l );\n\t\t// V_SmithGGXCorrelated = G_SmithGGXCorrelated / (4.0 f * NdotL * NdotV );\n\n\t\t// This is an optimized version\n\t\tlet alpha2 = alpha * alpha;\n\t\t// Caution: the \"NdotL *\" and \"NdotV *\" are explicitely inversed , this is not a mistake.\n\t\tlet Lambda_GGXV = NdotL * sqrt (( - NdotV * alpha2 + NdotV ) * NdotV + alpha2 );\n\t\tlet Lambda_GGXL = NdotV * sqrt (( - NdotL * alpha2 + NdotL ) * NdotL + alpha2 );\n\n\t\treturn 0.5 / ( Lambda_GGXV + Lambda_GGXL );\n\n\t}\n\n`, [ ggxLamdaFunc ] );\n\n\n// See listing 2 from reference [5]\nexport const ggxDistributionFunc = wgslFn( /* wgsl */ `\n\tfn ggxDistribution( NdotH: f32, alpha: f32 ) -> f32 {\n\n\t\tlet a2 = max( alpha * alpha, EPSILON );\n\t\tlet denom = NdotH * NdotH * ( a2 - 1 ) + 1;\n\n\t\treturn ( a2 / ( PI * denom * denom ) );\n\n\t}\n`, );\n\n// ggxPDF, divided by the Jacobian of reflection operation\n// See equation (17) from [2]\n// Note: HdotV cancel out bc its guaranteed to be > 0\nexport const ggxReflectionAdjustedPDFFunc = wgslFn( /* wgsl */ `\n\tfn ggxReflectionAdjustedPDF( NdotV: f32, NdotH: f32, alpha: f32 ) -> f32 {\n\n\t\tlet D = ggxDistribution( NdotH, alpha );\n\t\tlet G1 = ggxShadowMaskG1( NdotV, alpha );\n\n\t\treturn D * G1 / ( 4 * NdotV );\n\n\t}\n`, [ ggxDistributionFunc, ggxShadowMaskG1Func ] );\n","import { wgslFn, mat3 } from 'three/tsl';\nimport {\n\tinverseMat3x3Func,\n\tgetBasisFromNormalFunc,\n\tiorToF0Func,\n\tschlickFresnelFunc,\n\tschlickFresnelVecFunc,\n\tiorToF0GeneralFunc,\n\tfresnel0ToIorFunc,\n\tiorToF0GeneralVecFunc,\n} from './utils.wgsl.js';\nimport {\n\tggxSmithVisibilityFunc,\n\tggxDistributionFunc,\n\tggxDirectionFunc,\n\tggxReflectionAdjustedPDFFunc,\n} from './ggx.wgsl.js';\nimport { constants, surfaceRecordStruct } from './structs.wgsl.js';\nimport { rngInit, rand2, RNG_INDEX_SCATTER_DIRECTION } from './random.wgsl.js';\nimport { wgslTagFn } from '../lib/three-mesh-bvh/index.js';\n\n// Builds getSurfaceRecord using the given per-instance sampleTexel\nexport const getSurfaceRecordFunc = sampleTexel => wgslFn( /* wgsl */ `\n\n\tfn getSurfaceRecord(\n\t\tmaterial: Material,\n\t\tvertexData: bvh_GeometryStruct,\n\t\tside: f32,\n\t\tfaceNormal: vec3f,\n\t) -> SurfaceRecord {\n\t\tlet uv = vertexData.uv.xy;\n\n\t\tvar normal = faceNormal * side;\n\t\tif ( material.flatShading == 0 ) {\n\n\t\t\tnormal = vertexData.normal.xyz;\n\n\t\t}\n\t\tnormal = normalize( normal );\n\t\tlet baseNormal = normal;\n\n\t\tif ( material.normalMap != -1 ) {\n\n\t\t\t// some provided tangents can be malformed (0, 0, 0) causing the normal to be degenerate\n\t\t\t// resulting in NaNs and slow path tracing.\n\t\t\tif ( length( vertexData.tangent.xyz ) > 0.0 && vertexData.tangent.w != 0.0 ) {\n\n\t\t\t\tlet tangent = normalize( vertexData.tangent.xyz );\n\t\t\t\tlet bitangent = normalize( cross( baseNormal, tangent ) * vertexData.tangent.w );\n\t\t\t\tlet vTBN = mat3x3f( tangent, bitangent, baseNormal );\n\n\t\t\t\tlet uvPrime = material.normalMapTransform * vec3( uv, 1.0 );\n\t\t\t\tvar texNormal = sampleTexel( uvPrime.xy, material.normalMap, 0 ).xyz;\n\t\t\t\ttexNormal = texNormal * 2.0 - 1.0;\n\t\t\t\ttexNormal = texNormal * vec3f( material.normalScale, 1.0 );\n\t\t\t\tnormal = normalize( vTBN * texNormal );\n\n\t\t\t}\n\n\t\t}\n\n\t\tnormal *= side;\n\n\t\tvar albedo = vec4( material.color, material.opacity );\n\n\t\tif ( material.vertexColors == 1 ) {\n\n\t\t\tlet vertexColor = vertexData.color.xyz;\n\t\t\talbedo *= vec4f( vertexColor, 1.0 );\n\n\t\t}\n\n\t\tif ( material.map != -1 ) {\n\n\t\t\tlet uvPrime = material.mapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.map, 0 );\n\t\t\talbedo *= vec4f( texColor.rgb, 1.0 );\n\n\t\t}\n\n\t\tvar roughness = material.roughness;\n\t\tif ( material.roughnessMap != -1 ) {\n\n\t\t\tlet uvPrime = material.roughnessMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.roughnessMap, 0 );\n\t\t\troughness *= texColor.g;\n\n\t\t}\n\n\t\tvar metalness = material.metalness;\n\t\tif ( material.metalnessMap != -1 ) {\n\n\t\t\tlet uvPrime = material.metalnessMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.metalnessMap, 0 );\n\t\t\tmetalness *= texColor.b;\n\n\t\t}\n\n\t\tvar emission = material.emissiveIntensity * material.emissive;\n\t\tif ( material.emissiveMap != -1 ) {\n\n\t\t\tlet uvPrime = material.emissiveMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.emissiveMap, 0 );\n\t\t\temission *= texColor.rgb;\n\n\t\t}\n\n\t\tvar transmission = material.transmission;\n\t\tif ( material.transmissionMap != -1 ) {\n\n\t\t\tlet uvPrime = material.transmissionMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.transmissionMap, 0 );\n\t\t\ttransmission *= texColor.r;\n\n\t\t}\n\n\t\tvar clearcoat = material.clearcoat;\n\t\tif ( material.clearcoatMap != -1 ) {\n\n\t\t\tlet uvPrime = material.clearcoatMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.clearcoatMap, 0 );\n\t\t\tclearcoat *= texColor.r;\n\n\t\t}\n\n\t\tvar clearcoatRoughness = material.clearcoatRoughness;\n\t\tif ( material.clearcoatRoughnessMap != -1 ) {\n\n\t\t\tlet uvPrime = material.clearcoatRoughnessMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.clearcoatRoughnessMap, 0 );\n\t\t\tclearcoatRoughness *= texColor.g;\n\n\t\t}\n\n\t\tvar clearcoatNormal = baseNormal;\n\t\tif ( material.clearcoatNormalMap != -1 ) {\n\n\t\t\t// some provided tangents can be malformed (0, 0, 0) causing the normal to be degenerate\n\t\t\t// resulting in NaNs and slow path tracing.\n\t\t\tif ( length( vertexData.tangent.xyz ) > 0.0 && vertexData.tangent.w != 0.0 ) {\n\n\t\t\t\tlet tangent = normalize( vertexData.tangent.xyz );\n\t\t\t\tlet bitangent = normalize( cross( baseNormal, tangent ) * vertexData.tangent.w );\n\t\t\t\tlet vTBN = mat3x3f( tangent, bitangent, baseNormal );\n\n\t\t\t\tlet uvPrime = material.clearcoatNormalMapTransform * vec3( uv, 1.0 );\n\t\t\t\tvar texNormal = sampleTexel( uvPrime.xy, material.clearcoatNormalMap, 0 ).xyz;\n\t\t\t\ttexNormal = texNormal * 2.0 - 1.0;\n\t\t\t\ttexNormal = texNormal * vec3f( material.clearcoatNormalScale, 1.0 );\n\t\t\t\tclearcoatNormal = normalize( vTBN * texNormal );\n\n\t\t\t}\n\n\t\t}\n\t\tclearcoatNormal *= side;\n\n\t\tvar sheenColor = material.sheenColor;\n\t\tif ( material.sheenColorMap != -1 ) {\n\n\t\t\tlet uvPrime = material.sheenColorMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.sheenColorMap, 0 );\n\t\t\tsheenColor *= texColor.rgb;\n\n\t\t}\n\n\t\tvar sheenRoughness = material.sheenRoughness;\n\t\tif ( material.sheenRoughnessMap != -1 ) {\n\n\t\t\tlet uvPrime = material.sheenRoughnessMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.sheenRoughnessMap, 0 );\n\t\t\tsheenRoughness *= texColor.r;\n\n\t\t}\n\n\t\tvar iridescence = material.iridescence;\n\t\tif ( material.iridescenceMap != -1 ) {\n\n\t\t\tlet uvPrime = material.iridescenceMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.iridescenceMap, 0 );\n\t\t\tiridescence *= texColor.r;\n\n\t\t}\n\n\t\tvar iridescenceThickness = material.iridescenceThicknessMaximum;\n\t\tif ( material.iridescenceThicknessMap != -1 ) {\n\n\t\t\tlet uvPrime = material.iridescenceThicknessMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.iridescenceThicknessMap, 0 );\n\n\t\t\tiridescenceThickness = mix(\n\t\t\t\tmaterial.iridescenceThicknessMinimum,\n\t\t\t\tmaterial.iridescenceThicknessMaximum,\n\t\t\t\ttexColor.g,\n\t\t\t);\n\n\t\t}\n\n\t\tvar specularColor = material.specularColor;\n\t\tif ( material.specularColorMap != -1 ) {\n\n\t\t\tlet uvPrime = material.specularColorMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.specularColorMap, 0 );\n\t\t\tspecularColor *= texColor.rgb;\n\n\t\t}\n\n\t\tvar specularIntensity = material.specularIntensity;\n\t\tif ( material.specularIntensityMap != -1 ) {\n\n\t\t\tlet uvPrime = material.specularIntensityMapTransform * vec3f( uv, 1 );\n\t\t\tlet texColor = sampleTexel( uvPrime.xy, material.specularIntensityMap, 0 );\n\t\t\tspecularIntensity *= texColor.r;\n\n\t\t}\n\n\t\tvar surf: SurfaceRecord;\n\n\t\tsurf.volumeParticle = false;\n\t\tsurf.faceNormal = faceNormal;\n\t\tsurf.normal = normal;\n\n\t\tsurf.metalness = metalness;\n\t\tsurf.color = albedo.rgb;\n\t\tsurf.emission = emission;\n\n\t\tsurf.ior = material.ior;\n\t\tsurf.transmission = transmission;\n\t\tsurf.thinFilm = material.thinFilm == 1;\n\t\tsurf.attenuationColor = material.attenuationColor;\n\t\tsurf.attenuationDistance = material.attenuationDistance;\n\n\t\tsurf.clearcoatNormal = clearcoatNormal;\n\t\tsurf.clearcoat = clearcoat;\n\n\t\tsurf.iridescence = iridescence;\n\t\tsurf.iridescenceIor = material.iridescenceIor;\n\t\tsurf.iridescenceThickness = iridescenceThickness;\n\n\t\tsurf.specularColor = specularColor;\n\t\tsurf.specularIntensity = specularIntensity;\n\n\t\tsurf.roughness = clamp( roughness, MIN_ROUGHNESS, 1.0 );\n\t\tsurf.clearcoatRoughness = clamp( clearcoatRoughness, MIN_ROUGHNESS, 1.0 );\n\t\tsurf.sheenRoughness = clamp( sheenRoughness, MIN_ROUGHNESS, 1.0 );\n\n\t\t// frontFace is used to determine transmissive properties and PDF. If no transmission is used\n\t\t// then we can just always assume this is a front face.\n\t\tsurf.frontFace = side == 1.0 || transmission == 0.0;\n\t\tif ( material.thinFilm == 1 || surf.frontFace ) {\n\t\t\tsurf.eta = 1.0 / material.ior;\n\t\t} else {\n\t\t\tsurf.eta = material.ior;\n\t\t}\n\t\tsurf.f0 = iorToF0( surf.eta );\n\n\t\t// get the normal frames\n\t\tsurf.normalBasis = getBasisFromNormal( surf.normal );\n\t\tsurf.normalInvBasis = inverse( surf.normalBasis );\n\n\t\tsurf.clearcoatBasis = getBasisFromNormal( surf.clearcoatNormal );\n\t\tsurf.clearcoatInvBasis = inverse( surf.clearcoatBasis );\n\n\t\treturn surf;\n\t}\n\n`, [\n\tinverseMat3x3Func,\n\tiorToF0Func,\n\tgetBasisFromNormalFunc,\n\tsampleTexel,\n\tsurfaceRecordStruct,\n\tconstants,\n] );\n\n/*\n *\n * N \t\t\t : Macronormal of the surface\n * V ( wo ) : View direction\n * L ( wi ) : Light direction\n * H ( wh ) : Halfvector between V and L, micronormal of the surface in ggx\n * f0 : Amount of light reflected when looking at a surface head on - \"fresnel 0\"\n * f90 : Amount of light reflected at grazing angles\n *\n */\n\n// Disney Diffuse BRDF without subsurface approximation\nexport const diffuseBrdfFunc = wgslFn( /* wgsl */ `\n\n\tfn diffuseBrdf( NdotV: f32, NdotL: f32, VdotH: f32, surf: SurfaceRecord ) -> vec3f {\n\n\t\t// https://blog.selfshadow.com/publications/s2015-shading-course/burley/s2015_pbs_disney_bsdf_notes.pdf\n\t\t// See equation (4)\n\n\t\tlet fl = schlickFresnel( NdotL, 0.0 );\n\t\tlet fv = schlickFresnel( NdotV, 0.0 );\n\n\t\tlet alpha = surf.roughness * surf.roughness;\n\t\tlet bias = mix( 0.0, 0.5, alpha ) - 1;\n\t\tlet energyFactor = mix( 1.0, 1.0 / 1.51, alpha );\n\n\t\tlet rr = 2.0 * alpha * VdotH * VdotH;\n\t\tlet retro = rr * ( fl + fv + fl * fv * ( rr + 2.0 * bias ) );\n\t\tlet fresnel = ( 1.0 + bias * fl ) * ( 1.0f + bias * fv );\n\n\t\t// TODO: subsurface approx?\n\n\t\treturn energyFactor * ( surf.color / PI ) * ( retro + fresnel );\n\n\t}\n\n`, [ constants, schlickFresnelFunc, surfaceRecordStruct ] );\n\nexport const specularBrdfFunc = wgslFn( /* wgsl */ `\n\n\tfn specularBrdf( NdotL: f32, NdotV: f32, NdotH: f32, alpha: f32 ) -> vec3f {\n\n\t\tlet Vis = ggxSmithVisibility( NdotV, NdotL, alpha );\n\t\tlet D = ggxDistribution( NdotH, alpha );\n\n\t\treturn vec3f( D * Vis );\n\n\t}\n\n`, [ ggxSmithVisibilityFunc, ggxDistributionFunc ] );\n\nexport const fresnelMixFunc = wgslFn( /* wgsl */ `\n\n\tfn fresnelMix( VdotH: f32, ior: f32, base: vec3f, layer: vec3f ) -> vec3f {\n\n\t\tlet f0 = iorToF0( ior );\n \tlet F = schlickFresnel( abs( VdotH ), f0 );\n\n \treturn base + F * layer;\n\n\t}\n\n`, [ schlickFresnelFunc, iorToF0Func ] );\n\nconst XYZ_TO_REC709 = mat3(\n\t3.2404542, - 0.9692660, 0.0556434,\n\t- 1.5371385, 1.8760108, - 0.2040259,\n\t- 0.4985314, 0.0415560, 1.0572252,\n);\n\nconst evalSensitivityFunc = wgslTagFn/* wgsl */`\n\n\tfn evalSensitivity( OPD: f32, shift: vec3f ) -> vec3f {\n\n\t\tlet phase = 2.0 * ${ Math.PI } * OPD * 1.0e-9;\n\t\tconst val = vec3(5.4856e-13, 4.4201e-13, 5.2481e-13);\n\t\tconst pos = vec3(1.6810e+06, 1.7953e+06, 2.2084e+06);\n\t\tconst _var = vec3(4.3278e+09, 9.3046e+09, 6.6121e+09);\n\n\t\tvar xyz = val * sqrt(2.0 * ${ Math.PI } * _var) * cos(pos * phase + shift) * exp(-phase * phase * _var);\n\t\txyz.x += 9.7470e-14 * sqrt(2.0 * ${ Math.PI } * 4.5282e+09) * cos(2.2399e+06 * phase + shift.x) * exp(-4.5282e+09 * phase * phase);\n\t\txyz /= 1.0685e-7;\n\n\t\tlet rgb = ${ XYZ_TO_REC709 } * xyz;\n\t\treturn rgb;\n\n\t}\n\n`;\n\n// Reference: Belcour/Barla, 2017\n// https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html\n// This is a simplified model that ignores light polarization and uses fresnel approximation\nexport const iridescentFresnelFunc = wgslFn( /* wgsl */ `\n\n\tfn iridescentFresnel(\n\t\tcosTheta1: f32, baseF0: vec3f, iridescenceIor: f32,\n\t\toutsideIor: f32, iridescenceThickness: f32,\n\t) -> vec3f {\n\n\t\tlet sinTheta2Sq = pow( outsideIor / iridescenceIor, 2.0 ) * ( 1.0 - pow( cosTheta1, 2.0 ) );\n\t\tlet cosTheta2Sq = 1.0 - sinTheta2Sq;\n\n\t\t// Handle total internal reflection\n\t\tif ( cosTheta2Sq < 0.0 ) {\n\n\t\t\treturn vec3( 1.0 );\n\n\t\t}\n\n\t\tlet cosTheta2 = sqrt( cosTheta2Sq );\n\n\t\t// First interface: air -> iridescent thin film\n\t\tlet R0 = iorToF0General( iridescenceIor, outsideIor );\n\t\tlet R12 = schlickFresnel( cosTheta1, R0 );\n\t\tlet R21 = R12;\n\t\tlet T121 = 1.0 - R12;\n\t\tlet phi12 = select( 0.0, PI, iridescenceIor < outsideIor );\n\t\tlet phi21 = PI - phi12;\n\n\t\t// Second interface: iridescent thin film -> base material\n\t\tlet baseIor = fresnel0ToIor( baseF0 + 0.0001 ); // guard against 1.0\n\t\tlet R1 = iorToF0GeneralVec( baseIor, vec3( iridescenceIor ) );\n\t\tlet R23 = schlickFresnelVec( cosTheta2, R1, vec3( 1.0 ) );\n\t\tlet phi23 = select( vec3( 0.0 ), vec3( PI ), baseIor < vec3( iridescenceIor ) );\n\n\t\t// Phase shift\n\t\tlet OPD = 2.0 * iridescenceIor * iridescenceThickness * cosTheta2;\n\t\tlet phi = vec3( phi21 ) + phi23;\n\n\t\t// Analytical integration\n\t\t// Compound terms\n\t\tlet R123 = clamp( R12 * R23, vec3( 1e-5 ), vec3( 0.9999 ) );\n\t\tlet r123 = sqrt( R123 );\n\t\tlet Rs = T121 * T121 * R23 / ( vec3( 1.0 ) - R123 );\n\n\t\t// Reflectance term for m = 0 (DC term amplitude)\n\t\tlet C0 = R12 + Rs;\n\t\tvar I = C0;\n\n\t\t// Reflectance term for m > 0 (pairs of diracs)\n\t\tvar Cm = Rs - T121;\n\t\tfor (var m = 1; m <= 2; m += 1) {\n\n\t\t\tCm *= r123;\n\t\t\tlet Sm = 2.0 * evalSensitivity( f32( m ) * OPD, f32( m ) * phi );\n\t\t\tI += Cm * Sm;\n\n\t\t}\n\n\t\treturn max( I, vec3(0.0) );\n\n\t}\n\n`, [ iorToF0GeneralFunc, iorToF0GeneralVecFunc, schlickFresnelFunc, fresnel0ToIorFunc, evalSensitivityFunc ] );\n\nconst rgbMixFunc = wgslFn( /* wgsl */ `\n\n\tfn rgbMix( base: vec3f, specular: vec3f, rgbAlpha: vec3f ) -> vec3f {\n\n\t\tlet alphaMax = max( max( rgbAlpha.x, rgbAlpha.y ), rgbAlpha.z );\n\t\treturn ( 1 - alphaMax ) * base + rgbAlpha * specular;\n\n\t}\n\n` );\n\nexport const iridescentDielectricLayerFunc = wgslFn( /* wgsl */ `\n\n\tfn iridescentDielectricLayer(\n\t\tdielectricBase: vec3f, base: vec3f, specular: vec3f, HdotL: f32,\n\t\toutsideIor: f32, baseIor: f32, iridescenceIor: f32, thickness: f32, strength: f32,\n\t) -> vec3f {\n\n\t\tlet baseF0 = vec3( iorToF0( baseIor ) );\n\n\t\tlet iridescentF = iridescentFresnel( HdotL, baseF0, iridescenceIor, outsideIor, thickness );\n\n\t\treturn mix( dielectricBase, rgbMix( base, specular, iridescentF ), strength );\n\n\t}\n\n`, [ iorToF0Func, iridescentFresnelFunc, rgbMixFunc ] );\n\nexport const iridescentConductorLayerFunc = wgslFn( /* wgsl */ `\n\n\tfn iridescentConductorLayer(\n\t\tmetalBase: vec3f, specular: vec3f, baseF0: vec3f, HdotL: f32,\n\t\toutsideIor: f32, iridescenceIor: f32, thickness: f32, strength: f32,\n\t) -> vec3f {\n\n\t\tlet iridescenceF = iridescentFresnel( HdotL, baseF0, iridescenceIor, outsideIor, thickness );\n\n\t\treturn mix( metalBase, specular * iridescenceF, strength );\n\n\t}\n\n`, [ iridescentFresnelFunc ] );\n\nexport const conductorFresnelFunc = ( turquinTexture ) => wgslFn( /* wgsl */ `\n\n\tfn conductorFresnel( NdotV: f32, VdotH: f32, f0: vec3f, bsdf: vec3f, alpha: f32 ) -> vec3f {\n\n\t let ss = bsdf * schlickFresnelVec( abs( VdotH ), f0, vec3f( 1 ) );\n\n\t\tlet uv = vec2( NdotV, sqrt( alpha ) );\n\t\tlet energySs = max( textureSampleLevel( turquinTexture, turquinTexture_sampler, uv, 0 ).r, 1e-5 );\n\n\t\treturn ss * ( 1.0 + f0 * ( 1.0 - energySs ) / energySs );\n\n\t}\n\n`, [ schlickFresnelVecFunc, turquinTexture ] );\n\nexport const fresnelCoatFunc = wgslFn( /* wgsl */ `\n\n\tfn fresnelCoat( VdotNc: f32, ior: f32, base: vec3f, layer: vec3f, weight: f32 ) -> vec3f {\n\n\t\tlet f0 = iorToF0( ior );\n\t\tlet F = schlickFresnel( abs( VdotNc ), f0 );\n\n\t\treturn mix( base, layer, weight * F );\n\n\t}\n\n`, [ iorToF0Func, schlickFresnelFunc ] );\n\n// GGX Multibounce compensation using Turquin's method\n\nexport const albedoIntegralMetallic = wgslTagFn/* wgsl */ `\n\n\tfn albedo(\n\t\ttexture: texture_storage_2d<r16float, write>,\n\n\t\tglobalId: vec3u,\n\t) -> void {\n\n\t\tconst INTEGRATION_SAMPLES = ( 1 << 20 );\n\t\tlet pixelIndex = ( globalId.x << 16 ) | globalId.y;\n\t\t${ rngInit }( pixelIndex, 0, 0 );\n\n\t\tlet dimensions = textureDimensions( texture ).xy;\n\t\tlet uv = ( vec2f( globalId.xy ) + vec2f( 0.5 ) ) / vec2f( dimensions );\n\n\t\tlet cosThetaO = uv.x;\n\t\tlet roughness = uv.y;\n\n\t\tlet alpha = roughness * roughness;\n\n\t\tlet wo = vec3( sqrt( 1 - cosThetaO * cosThetaO ), 0 , cosThetaO );\n\n\t\tvar result = 0.0;\n\t\tfor ( var i = 0; i < INTEGRATION_SAMPLES; i++ ) {\n\n\t\t\tlet wh = ${ ggxDirectionFunc }( wo, vec2( alpha ), ${ rand2 }(${ RNG_INDEX_SCATTER_DIRECTION }) );\n\t\t\tvar wi = - reflect( wo, wh );\n\n\t\t\tlet NdotV = max( wo.z, EPSILON );\n\t\t\tlet NdotL = saturate( wi.z );\n\t\t\tlet NdotH = saturate( wh.z );\n\n\t\t\tlet specular = ${ specularBrdfFunc }( NdotL, NdotV, NdotH, alpha );\n\t\t\tlet pdf = ${ ggxReflectionAdjustedPDFFunc }( NdotV, NdotH, alpha );\n\n\t\t\tvar weight = 0.0;\n\t\t\tif ( pdf != 0.0 ) {\n\t\t\t\tweight = 1 / pdf;\n\t\t\t}\n\n\t\t\tresult += specular.x * NdotL * weight;\n\n\t\t}\n\n\t\tresult /= f32( INTEGRATION_SAMPLES );\n\n\t\ttextureStore( texture, globalId.xy, vec4( result ) );\n\n\t}\n\n`;\n","import {\n\tMeshBasicMaterial,\n\tRenderTarget,\n\tNoToneMapping,\n\tQuadMesh,\n\tNoBlending,\n\tColor,\n\tVector4,\n} from 'three/webgpu';\n\nconst MAX_TEXTURE_SIZE = 4096;\nconst _prevClearColor = new Color();\n\nfunction getTextureHash( texture ) {\n\n\treturn `${ texture.source.uuid }:${ texture.source.version }`;\n\n}\n\n// TODO: consider adding a \"waste map\"\n// TODO: consider using \"best fit\"\n\n// Skyline rectangle packing (bottom-left, no waste map).\n// A \"skyline\" is an array of contiguous segments { x, y, width } that always\n// spans [ 0, pageWidth ] and describes the upper contour of placed rectangles.\n// Each rect is placed where its top edge is lowest ( leftmost on ties ).\n//\n// Reference: Jukka Jylänki, \"A Thousand Ways to Pack the Bin - A Practical\n// Approach to Two-Dimensional Rectangle Bin Packing\" (2010), the Skyline\n// Bottom-Left (SkylineBL) heuristic. See also Sean Barrett's stb_rect_pack.h:\n// https://github.com/nothings/stb/blob/master/stb_rect_pack.h\n\n// Resting y for a w-wide rect whose left edge sits at nodes[ i ].x. The rect\n// bridges every segment it spans and rests on the tallest of them. Returns -1\n// if it would run off the right edge.\nfunction skylineFit( nodes, i, w, pageWidth ) {\n\n\tconst x = nodes[ i ].x;\n\tif ( x + w > pageWidth ) {\n\n\t\treturn - 1;\n\n\t}\n\n\tlet widthLeft = w;\n\tlet y = 0;\n\tlet j = i;\n\twhile ( widthLeft > 0 ) {\n\n\t\t// defensive: the skyline should always cover the full page width\n\t\tif ( j >= nodes.length ) {\n\n\t\t\treturn - 1;\n\n\t\t}\n\n\t\ty = Math.max( y, nodes[ j ].y );\n\t\twidthLeft -= nodes[ j ].width;\n\t\tj ++;\n\n\t}\n\n\treturn y;\n\n}\n\n// Patch the skyline after placing a rect spanning [ x, x + w ] with top edge y.\n// The left edge x always aligns to an existing segment boundary, so only the\n// right edge can split a segment. Mutates nodes in place.\nfunction addSkylineNode( nodes, x, y, w ) {\n\n\tconst right = x + w;\n\tconst result = [];\n\tlet inserted = false;\n\n\tfor ( let i = 0; i < nodes.length; i ++ ) {\n\n\t\tconst node = nodes[ i ];\n\t\tconst nodeRight = node.x + node.width;\n\n\t\tif ( nodeRight <= x ) {\n\n\t\t\t// entirely left of the new node\n\t\t\tresult.push( node );\n\n\t\t} else if ( node.x >= right ) {\n\n\t\t\t// entirely right of the new node\n\t\t\tif ( ! inserted ) {\n\n\t\t\t\tresult.push( { x, y, width: w } );\n\t\t\t\tinserted = true;\n\n\t\t\t}\n\n\t\t\tresult.push( node );\n\n\t\t} else {\n\n\t\t\t// overlapped by the new node\n\t\t\tif ( ! inserted ) {\n\n\t\t\t\tresult.push( { x, y, width: w } );\n\t\t\t\tinserted = true;\n\n\t\t\t}\n\n\t\t\t// keep any right-side remainder at its original height\n\t\t\tif ( nodeRight > right ) {\n\n\t\t\t\tresult.push( { x: right, y: node.y, width: nodeRight - right } );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tif ( ! inserted ) {\n\n\t\tresult.push( { x, y, width: w } );\n\n\t}\n\n\t// merge adjacent segments of equal height and write back into nodes\n\tnodes.length = 0;\n\tfor ( let i = 0; i < result.length; i ++ ) {\n\n\t\tconst node = result[ i ];\n\t\tconst last = nodes[ nodes.length - 1 ];\n\t\tif ( last && last.y === node.y && last.x + last.width === node.x ) {\n\n\t\t\tlast.width += node.width;\n\n\t\t} else {\n\n\t\t\tnodes.push( node );\n\n\t\t}\n\n\t}\n\n}\n\n// Try to place a w x h rect into a single page's skyline. Returns the chosen\n// { x, y } or null if it does not fit.\nfunction skylineInsert( nodes, w, h, pageWidth, pageHeight ) {\n\n\tlet bestY = Infinity;\n\tlet bestX = 0;\n\tlet bestIndex = - 1;\n\n\tfor ( let i = 0; i < nodes.length; i ++ ) {\n\n\t\tconst y = skylineFit( nodes, i, w, pageWidth );\n\t\tif ( y >= 0 && y + h <= pageHeight && y < bestY ) {\n\n\t\t\tbestY = y;\n\t\t\tbestX = nodes[ i ].x;\n\t\t\tbestIndex = i;\n\n\t\t}\n\n\t}\n\n\tif ( bestIndex === - 1 ) {\n\n\t\treturn null;\n\n\t}\n\n\taddSkylineNode( nodes, bestX, bestY + h, w );\n\treturn { x: bestX, y: bestY };\n\n}\n\n// Packs a set of textures into one or more atlas pages and exposes both the\n// packed texture and a Uint32Array of per-texture info ( atlas bounds + page )\n// suitable for upload as a uniform array.\nexport class AtlasTexture {\n\n\tget width() {\n\n\t\treturn this.renderTarget.width;\n\n\t}\n\n\tget height() {\n\n\t\treturn this.renderTarget.height;\n\n\t}\n\n\tget pageCount() {\n\n\t\treturn this.renderTarget.depth;\n\n\t}\n\n\tget texture() {\n\n\t\treturn this.renderTarget.texture;\n\n\t}\n\n\tconstructor( options = {} ) {\n\n\t\t// RenderTarget already defaults to RGBA8, linear filtering, clamp wrapping\n\t\t// and no mipmaps, so we only specify the array-target-specific options here.\n\t\tthis.renderTarget = new RenderTarget( 1, 1, {\n\t\t\tdepthBuffer: false,\n\t\t\tdepth: 1,\n\t\t\t...options,\n\t\t} );\n\t\tthis.texture.isArrayTexture = true;\n\n\t\t// per-texture packed info ( one Vector4 each ): see _buildTextureInfo\n\t\tthis.textureInfo = [ new Vector4() ];\n\n\t\tthis.hashes = [];\n\t\tthis.quadMesh = new QuadMesh( new MeshBasicMaterial() );\n\t\tthis.quadMesh.material.blending = NoBlending;\n\n\t}\n\n\tsetTextures( renderer, textures ) {\n\n\t\t// nothing to do if the set of textures is unchanged\n\t\tif ( this._hashesMatch( textures ) ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\t// calculate the maximum dimension of the atlas\n\t\tlet maxDim = textures.reduce( ( v, t ) => Math.max( v, t.width, t.height ), 1 );\n\t\tmaxDim = Math.min( MAX_TEXTURE_SIZE, maxDim );\n\n\t\tconst width = maxDim;\n\t\tconst height = maxDim;\n\n\t\t// full repack of every texture\n\t\tconst { renderTarget } = this;\n\t\tconst { placements, pageCount } = this._packTextures( textures, width, height );\n\n\t\t// RenderTarget.setSize resets isArrayTexture to \"image.depth > 1\" so\n\t\t// we reset it here.\n\t\trenderTarget.setSize( width, height, pageCount );\n\t\tthis.texture.isArrayTexture = true;\n\n\t\tthis._buildTextureInfo( placements );\n\t\tthis._renderTextures( renderer, textures, placements );\n\n\t\t// rebuild hashes and the texture -> index lookup\n\t\tconst hashes = new Array( textures.length );\n\t\tfor ( let i = 0, l = textures.length; i < l; i ++ ) {\n\n\t\t\tconst hash = getTextureHash( textures[ i ] );\n\t\t\thashes[ i ] = hash;\n\n\t\t}\n\n\t\tthis.hashes = hashes;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.renderTarget.dispose();\n\t\tthis.quadMesh.material.dispose();\n\n\t}\n\n\t_hashesMatch( textures ) {\n\n\t\tconst hashes = this.hashes;\n\t\tif ( hashes.length !== textures.length ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tfor ( let i = 0, l = textures.length; i < l; i ++ ) {\n\n\t\t\tif ( hashes[ i ] !== getTextureHash( textures[ i ] ) ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\t_packTextures( textures, width, height ) {\n\n\t\t// use each texture's native size, clamped so it can physically fit a page\n\t\t// ( anything larger is downsampled into its rect during the blit )\n\t\tconst items = [];\n\t\tfor ( let i = 0, l = textures.length; i < l; i ++ ) {\n\n\t\t\tconst texture = textures[ i ];\n\t\t\titems.push( {\n\t\t\t\tindex: i,\n\t\t\t\tw: Math.min( texture.width, width ),\n\t\t\t\th: Math.min( texture.height, height ),\n\t\t\t} );\n\n\t\t}\n\n\t\t// place taller rects first for tighter skyline occupancy\n\t\tconst order = items.sort( ( a, b ) => b.h - a.h );\n\n\t\tconst placements = new Array( textures.length );\n\t\tconst pages = [];\n\n\t\tfor ( let k = 0, l = order.length; k < l; k ++ ) {\n\n\t\t\tconst item = order[ k ];\n\t\t\tlet placed = null;\n\t\t\tlet page = - 1;\n\n\t\t\t// try to fit into an existing page\n\t\t\tfor ( let p = 0; p < pages.length; p ++ ) {\n\n\t\t\t\tplaced = skylineInsert( pages[ p ], item.w, item.h, width, height );\n\t\t\t\tif ( placed ) {\n\n\t\t\t\t\tpage = p;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// otherwise open a new page\n\t\t\tif ( ! placed ) {\n\n\t\t\t\tconst skyline = [ { x: 0, y: 0, width: width } ];\n\t\t\t\tplaced = skylineInsert( skyline, item.w, item.h, width, height );\n\t\t\t\tpages.push( skyline );\n\t\t\t\tpage = pages.length - 1;\n\n\t\t\t}\n\n\t\t\tplacements[ item.index ] = { x: placed.x, y: placed.y, w: item.w, h: item.h, page };\n\n\t\t}\n\n\t\treturn { placements, pageCount: Math.max( pages.length, 1 ) };\n\n\t}\n\n\t_buildTextureInfo( placements ) {\n\n\t\tconst info = this.textureInfo;\n\t\tinfo.length = 0;\n\t\tfor ( let i = 0, l = placements.length; i < l; i ++ ) {\n\n\t\t\t// offsetX and Y in pixels (16 bits + 16 bits)\n\t\t\t// width and height in pixels (16 bit + 16 bits)\n\t\t\t// page + reserved (16 bits)\n\t\t\t// reserved\n\t\t\tconst { x, y, w, h, page } = placements[ i ];\n\t\t\tconst v = new Vector4();\n\t\t\tv.x = ( x & 0xFFFF ) | ( ( y & 0xFFFF ) << 16 );\n\t\t\tv.y = ( w & 0xFFFF ) | ( ( h & 0xFFFF ) << 16 );\n\t\t\tv.z = page & 0xFFFF;\n\t\t\tv.w = 0;\n\t\t\tinfo.push( v );\n\n\t\t}\n\n\t\tif ( info.length === 0 ) {\n\n\t\t\tinfo.push( new Vector4( 0, 0, 0, 0 ) );\n\n\t\t}\n\n\t}\n\n\t_renderTextures( renderer, textures, placements ) {\n\n\t\tconst { quadMesh, renderTarget, width, height } = this;\n\n\t\t// Save previous renderer state\n\t\tconst prevRenderTarget = renderer.getRenderTarget();\n\t\tconst prevToneMapping = renderer.toneMapping;\n\t\tconst prevAutoClear = renderer.autoClear;\n\t\tconst prevScissorTest = renderer.getScissorTest();\n\t\tconst prevClearAlpha = renderer.getClearAlpha();\n\t\trenderer.getClearColor( _prevClearColor );\n\n\t\t// blit each tile into its sub-rect without clearing the rest of the page\n\t\trenderer.toneMapping = NoToneMapping;\n\t\trenderer.autoClear = false;\n\t\trenderer.setScissorTest( true );\n\t\trenderer.setClearColor( 0, 0 );\n\n\t\t// clear the pages\n\t\tfor ( let i = 0, l = renderTarget.depth; i < l; i ++ ) {\n\n\t\t\trenderTarget.viewport.set( 0, 0, width, height );\n\t\t\trenderTarget.scissor.set( 0, 0, width, height );\n\t\t\trenderer.setRenderTarget( renderTarget, i );\n\t\t\trenderer.clear();\n\n\t\t}\n\n\t\tfor ( let i = 0, l = textures.length; i < l; i ++ ) {\n\n\t\t\tconst { x, y, w, h, page } = placements[ i ];\n\n\t\t\t// Clone the source so we get an independent texture handle\n\t\t\tconst texture = textures[ i ].clone();\n\t\t\ttexture.matrixAutoUpdate = false;\n\t\t\ttexture.matrix.identity();\n\t\t\ttexture.needsUpdate = true;\n\n\t\t\tquadMesh.material.map = texture;\n\n\t\t\t// three.js uses the render target viewport / scissor\n\t\t\trenderTarget.viewport.set( x, y, w, h );\n\t\t\trenderTarget.scissor.set( x, y, w, h );\n\t\t\trenderer.setRenderTarget( renderTarget, page );\n\t\t\tquadMesh.render( renderer );\n\n\t\t\ttexture.dispose();\n\n\t\t}\n\n\t\t// restore the render target's full-size viewport/scissor and the renderer\n\t\trenderTarget.viewport.set( 0, 0, width, height );\n\t\trenderTarget.scissor.set( 0, 0, width, height );\n\t\tquadMesh.material.map = null;\n\t\trenderer.setClearColor( _prevClearColor, prevClearAlpha );\n\t\trenderer.setScissorTest( prevScissorTest );\n\t\trenderer.autoClear = prevAutoClear;\n\t\trenderer.setRenderTarget( prevRenderTarget );\n\t\trenderer.toneMapping = prevToneMapping;\n\n\t}\n\n}\n","import { BackSide, FrontSide, DoubleSide, BufferAttribute, BufferGeometry, StorageBufferAttribute, StructTypeNode, Vector4, SkinnedMesh, StructNode, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping, NearestFilter } from 'three/webgpu';\nimport { BVHComputeData, intersectRayTriangle, bvhNodeBoundsStruct, bvhNodeStruct, rayStruct, rayIntersectionResultStruct as intersectionResultStruct, wgslTagFn } from '../lib/three-mesh-bvh/index.js';\nimport { storage, float, sampler, texture, uniformArray } from 'three/tsl';\nimport { SkinnedMeshBVH, MeshBVH, SAH } from 'three-mesh-bvh';\nimport { materialStruct } from './structs.wgsl.js';\nimport { getTextureHash } from '../../core/utils/sceneUpdateUtils.js';\nimport { rand1, RNG_INDEX_ALPHA_TEST } from './random.wgsl.js';\nimport { sampleTexelFunc } from './utils.wgsl.js';\nimport { getSurfaceRecordFunc } from './material.wgsl.js';\nimport { AtlasTexture } from '../AtlasTexture.js';\n\nconst _colorVec = new Vector4();\nconst transformStruct = new StructTypeNode( {\n\tmatrixWorld: 'mat4x4f',\n\tinverseMatrixWorld: 'mat4x4f',\n\tnodeOffset: 'uint',\n\tvisible: 'uint',\n\tmaterialIndex: 'uint',\n\t_alignment0: 'uint',\n\tcolor: 'vec4f',\n}, 'TransformStruct' );\n\n// Pathtracer-specific version of the BVHComputeData tht includes material mapping, property structs\nexport class PathtracerBVHComputeData extends BVHComputeData {\n\n\tconstructor( bvh, options = {} ) {\n\n\t\t// TODO: once supported we should use the appropriately-sized member sizes\n\t\tsuper( bvh, {\n\t\t\tattributes: {\n\t\t\t\tposition: 'vec4f',\n\t\t\t\tnormal: 'vec4f',\n\t\t\t\ttangent: 'vec4f',\n\t\t\t\tcolor: 'vec4f',\n\t\t\t\tuv: 'vec4f',\n\t\t\t},\n\t\t\t...options,\n\t\t} );\n\n\t\tthis.structs.transform = transformStruct;\n\t\tthis.structs.material = materialStruct;\n\t\tthis.storage.materials = null;\n\t\tthis.materials = [];\n\t\tthis.bvhMap = new Map();\n\t\tthis.textureAtlas = new AtlasTexture();\n\n\t}\n\n\tuseTransparencyRaycastFn() {\n\n\t\tconst { textureAtlas, storage, structs, fns } = this;\n\t\tconst textures = textureAtlas.texture;\n\t\tconst textureInfo = uniformArray( textureAtlas.textureInfo, 'uvec4' );\n\n\t\t// build the single sampleTexel bound to this instance's textureInfo node\n\t\tconst sampleTexel = sampleTexelFunc( textureInfo, texture( textures ), sampler( textures ) );\n\n\t\t// getSurfaceRecord shares the same sampleTexel, so the surface shading and\n\t\t// the transparency raycast resolve to one textureInfo binding per pipeline\n\t\tfns.getSurfaceRecord = getSurfaceRecordFunc( sampleTexel );\n\n\t\t// raycast first hit\n\t\tconst currentMaterial = new StructNode( structs.material ).toVar( 'bvh_material' );\n\t\tconst scratchRayScalar = float( 1.0 ).toVar( 'bvh_rayScalar' );\n\t\tconst baseOpacityScalar = float( 1.0 ).toVar( 'bvh_baseOpacity' );\n\n\t\tfns.raycastFirstHit = this.getShapecastFn( {\n\t\t\tname: 'raycastFirstHit',\n\t\t\tshapeStruct: rayStruct,\n\t\t\tresultStruct: intersectionResultStruct,\n\n\t\t\tboundsOrderFn: wgslTagFn/* wgsl */`\n\t\t\t\tfn getBoundsOrder( ray: ${ rayStruct }, splitAxis: u32, node: ${ bvhNodeStruct } ) -> bool {\n\n\t\t\t\t\treturn ray.direction[ splitAxis ] >= 0.0;\n\n\t\t\t\t}\n\t\t\t`,\n\t\t\tintersectsBoundsFn: wgslTagFn/* wgsl */`\n\t\t\t\tfn rayIntersectsBounds( ray: ${ rayStruct }, bounds: ${ bvhNodeBoundsStruct }, result: ptr<function, ${ intersectionResultStruct }> ) -> u32 {\n\n\t\t\t\t\t// early-out if our object is completely transparent\n\t\t\t\t\tif ( ${ baseOpacityScalar } == 0.0 ) {\n\n\t\t\t\t\t\treturn 0u;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tlet boundsMin = vec3( bounds.min[0], bounds.min[1], bounds.min[2] );\n\t\t\t\t\tlet boundsMax = vec3( bounds.max[0], bounds.max[1], bounds.max[2] );\n\n\t\t\t\t\tlet invDir = 1.0 / ray.direction;\n\t\t\t\t\tlet tMinPlane = ( boundsMin - ray.origin ) * invDir;\n\t\t\t\t\tlet tMaxPlane = ( boundsMax - ray.origin ) * invDir;\n\n\t\t\t\t\tlet tMinHit = min( tMinPlane, tMaxPlane );\n\t\t\t\t\tlet tMaxHit = max( tMinPlane, tMaxPlane );\n\n\t\t\t\t\tlet t0 = max( max( tMinHit.x, tMinHit.y ), tMinHit.z );\n\t\t\t\t\tlet t1 = min( min( tMaxHit.x, tMaxHit.y ), tMaxHit.z );\n\n\t\t\t\t\tlet dist = max( t0, 0.0 );\n\t\t\t\t\tif ( t1 < dist ) {\n\n\t\t\t\t\t\treturn 0u;\n\n\t\t\t\t\t} else if ( result.didHit && dist * ${ scratchRayScalar } >= result.dist ) {\n\n\t\t\t\t\t\treturn 0u;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn 1u;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t`,\n\t\t\tintersectRangeFn: wgslTagFn/* wgsl */`\n\t\t\t\tfn intersectRange( ray: ${ rayStruct }, offset: u32, count: u32, result: ptr<function, ${ intersectionResultStruct }> ) -> bool {\n\n\t\t\t\t\tvar didHit = false;\n\t\t\t\t\tfor ( var ti = offset; ti < offset + count; ti = ti + 1u ) {\n\n\t\t\t\t\t\tlet i0 = ${ storage.index }[ ti * 3u ];\n\t\t\t\t\t\tlet i1 = ${ storage.index }[ ti * 3u + 1u ];\n\t\t\t\t\t\tlet i2 = ${ storage.index }[ ti * 3u + 2u ];\n\n\t\t\t\t\t\tlet a = ${ storage.attributes }[ i0 ].position.xyz;\n\t\t\t\t\t\tlet b = ${ storage.attributes }[ i1 ].position.xyz;\n\t\t\t\t\t\tlet c = ${ storage.attributes }[ i2 ].position.xyz;\n\n\t\t\t\t\t\tvar triResult = ${ intersectRayTriangle }( ray, a, b, c, 1e-5 );\n\t\t\t\t\t\ttriResult.dist *= ${ scratchRayScalar };\n\t\t\t\t\t\tif ( triResult.didHit && ( ! result.didHit || triResult.dist < result.dist ) ) {\n\n\t\t\t\t\t\t\tlet material = ${ currentMaterial };\n\n\t\t\t\t\t\t\t// TODO: if material is a transmissive volume we may need to assume double-sidedness\n\t\t\t\t\t\t\tif ( material.side != 0 && triResult.side != material.side ) {\n\n\t\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( material.transparent != 0 || material.alphaTest > 0.0 ) {\n\n\t\t\t\t\t\t\t\tvar opacity = ${ baseOpacityScalar };\n\n\t\t\t\t\t\t\t\t// account for alpha component of albedo map\n\t\t\t\t\t\t\t\tif ( material.map != - 1 ) {\n\n\t\t\t\t\t\t\t\t\tlet barycoord = triResult.barycoord;\n\t\t\t\t\t\t\t\t\tlet a = ${ storage.attributes }[ i0 ].uv.xy;\n\t\t\t\t\t\t\t\t\tlet b = ${ storage.attributes }[ i1 ].uv.xy;\n\t\t\t\t\t\t\t\t\tlet c = ${ storage.attributes }[ i2 ].uv.xy;\n\t\t\t\t\t\t\t\t\tlet uv = barycoord.x * a + barycoord.y * b + barycoord.z * c;\n\t\t\t\t\t\t\t\t\tlet uvPrime = material.mapTransform * vec3f( uv, 1 );\n\n\t\t\t\t\t\t\t\t\topacity *= ${ sampleTexel }( uvPrime.xy, material.map, 0 ).a;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// account for green component of alpha map\n\t\t\t\t\t\t\t\tif ( material.alphaMap != - 1 ) {\n\n\t\t\t\t\t\t\t\t\tlet barycoord = triResult.barycoord;\n\t\t\t\t\t\t\t\t\tlet a = ${ storage.attributes }[ i0 ].uv.xy;\n\t\t\t\t\t\t\t\t\tlet b = ${ storage.attributes }[ i1 ].uv.xy;\n\t\t\t\t\t\t\t\t\tlet c = ${ storage.attributes }[ i2 ].uv.xy;\n\t\t\t\t\t\t\t\t\tlet uv = barycoord.x * a + barycoord.y * b + barycoord.z * c;\n\t\t\t\t\t\t\t\t\tlet uvPrime = material.alphaMapTransform * vec3f( uv, 1 );\n\n\t\t\t\t\t\t\t\t\topacity *= ${ sampleTexel }( uvPrime.xy, material.alphaMap, 0 ).g;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( material.transparent != 0 && opacity < ${ rand1 }( ${ RNG_INDEX_ALPHA_TEST } + ti ) ) {\n\n\t\t\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( opacity < material.alphaTest ) {\n\n\t\t\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tresult.didHit = true;\n\t\t\t\t\t\t\tresult.dist = triResult.dist;\n\t\t\t\t\t\t\tresult.normal = triResult.normal;\n\t\t\t\t\t\t\tresult.side = triResult.side;\n\t\t\t\t\t\t\tresult.barycoord = triResult.barycoord;\n\t\t\t\t\t\t\tresult.indices = vec4u( i0, i1, i2, ti );\n\n\t\t\t\t\t\t\tdidHit = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn didHit;\n\n\t\t\t\t}\n\t\t\t`,\n\t\t\ttransformShapeFn: wgslTagFn/* wgsl */`\n\t\t\t\tfn transformRay( ray: ptr<function, ${ rayStruct }>, objectIndex: u32 ) -> void {\n\n\t\t\t\t\tlet toLocal = ${ storage.transforms }[ objectIndex ].inverseMatrixWorld;\n\t\t\t\t\tray.origin = ( toLocal * vec4f( ray.origin, 1.0 ) ).xyz;\n\t\t\t\t\tray.direction = ( toLocal * vec4f( ray.direction, 0.0 ) ).xyz;\n\n\t\t\t\t\tlet len = length( ray.direction );\n\t\t\t\t\tray.direction /= len;\n\t\t\t\t\t${ scratchRayScalar } = 1.0 / len;\n\n\t\t\t\t\tlet object = ${ storage.transforms }[ objectIndex ];\n\t\t\t\t\t${ currentMaterial } = ${ storage.materials }[ object.materialIndex ];\n\t\t\t\t\tif ( ${ currentMaterial }.transparent == 1 ) {\n\n\t\t\t\t\t\t${ baseOpacityScalar } = ${ currentMaterial }.opacity * object.color.a;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t${ baseOpacityScalar } = 1.0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t`,\n\t\t\ttransformResultFn: wgslTagFn/* wgsl */`\n\t\t\t\tfn transformResult( hit: ptr<function, ${ intersectionResultStruct }>, objectIndex: u32 ) -> void {\n\n\t\t\t\t\tlet toLocal = ${ storage.transforms }[ objectIndex ].inverseMatrixWorld;\n\t\t\t\t\thit.normal = normalize( ( transpose( toLocal ) * vec4f( hit.normal, 0.0 ) ).xyz );\n\t\t\t\t\thit.objectIndex = objectIndex;\n\n\t\t\t\t}\n\t\t\t`,\n\t\t} );\n\n\t}\n\n\tupdate() {\n\n\t\tsuper.update();\n\n\t\t// build material storage\n\t\tconst { materials, structs } = this;\n\n\t\tconst { materialData, textures } = this.writeMaterialsBuffer( materials );\n\n\t\tthis.textures = textures;\n\n\t\tconst materialAttribute = new StorageBufferAttribute( materialData, structs.material.getLength() );\n\t\tconst materialStorage = storage( materialAttribute, structs.material ).toReadOnly().setName( 'bvh_materials' );\n\t\tthis.storage.materials = materialStorage;\n\n\t\tthis.bvhMap.clear();\n\t\tthis.materials.length = 0;\n\t\tthis.useTransparencyRaycastFn();\n\n\t}\n\n\twriteMaterialsBuffer( materials ) {\n\n\t\tfunction encodeTextureWrap( wrap ) {\n\n\t\t\tswitch ( wrap ) {\n\n\t\t\t\tcase RepeatWrapping:\n\t\t\t\t\treturn 0;\n\t\t\t\tcase ClampToEdgeWrapping:\n\t\t\t\t\treturn 1;\n\t\t\t\tcase MirroredRepeatWrapping:\n\t\t\t\t\treturn 2;\n\t\t\t\tdefault:\n\t\t\t\t\treturn 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTexture( material, key ) {\n\n\t\t\tif ( key in material && material[ key ] ) {\n\n\t\t\t\tconst texture = material[ key ];\n\t\t\t\tconst hash = getTextureHash( texture );\n\n\t\t\t\tif ( ! textureLookUp.has( hash ) ) {\n\n\t\t\t\t\ttextureLookUp.set( hash, textureLookUp.size );\n\t\t\t\t\ttextures.push( texture );\n\n\t\t\t\t}\n\n\t\t\t\tconst idx = textureLookUp.get( hash );\n\t\t\t\tconst wrapS = encodeTextureWrap( texture.wrapS );\n\t\t\t\tconst wrapT = encodeTextureWrap( texture.wrapT );\n\t\t\t\tconst nearest = texture.magFilter === NearestFilter ? 1 : 0;\n\t\t\t\treturn ( nearest << 28 ) | ( wrapT << 26 ) | ( wrapS << 24 ) | idx;\n\n\t\t\t} else {\n\n\t\t\t\treturn - 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getField( material, key, def ) {\n\n\t\t\treturn key in material ? material[ key ] : def;\n\n\t\t}\n\n\t\tfunction writeTextureMatrixToArray( material, textureKey, array, offset ) {\n\n\t\t\tconst texture = material[ textureKey ] && material[ textureKey ].isTexture ? material[ textureKey ] : null;\n\n\t\t\t// check if texture exists\n\t\t\tif ( texture ) {\n\n\t\t\t\tif ( texture.matrixAutoUpdate ) {\n\n\t\t\t\t\ttexture.updateMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tconst elements = texture.matrix.elements;\n\n\t\t\t\t// Both wgsl struct and elements should be in column-major format\n\t\t\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\tarray[ offset + 4 * i + 0 ] = elements[ 3 * i + 0 ];\n\t\t\t\t\tarray[ offset + 4 * i + 1 ] = elements[ 3 * i + 1 ];\n\t\t\t\t\tarray[ offset + 4 * i + 2 ] = elements[ 3 * i + 2 ];\n\t\t\t\t\tarray[ offset + 4 * i + 3 ] = 0; // padding float\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 12;\n\n\t\t}\n\n\t\tlet index = 0;\n\n\t\t// Collect and index the list of textures based on shareable source\n\t\tconst textureLookUp = new Map();\n\t\tconst textures = [];\n\n\t\t// NOTE: make the minimum material buffer length 2 in order to avoid TSL converting it to a scalar\n\t\t// TODO: remove this when fixed in three\n\t\tconst materialBufferLength = Math.max( materials.length, 2 );\n\t\tconst floatArray = new Float32Array( materialBufferLength * this.structs.material.getLength() );\n\t\tconst intArray = new Int32Array( floatArray.buffer );\n\n\t\t// TODO: make features work\n\t\t// features.reset();\n\t\tfor ( let i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\tconst m = materials[ i ];\n\n\t\t\t// if ( m.isFogVolumeMaterial ) {\n\t\t\t//\n\t\t\t// \t// features.setUsed( 'FOG' );\n\t\t\t//\n\t\t\t// \tfor ( let j = 0; j < MATERIAL_STRIDE; j ++ ) {\n\t\t\t//\n\t\t\t// \t\tfloatArray[ index + j ] = 0;\n\t\t\t//\n\t\t\t// \t}\n\t\t\t//\n\t\t\t// \t// sample 0 .rgb\n\t\t\t// \tfloatArray[ index + 0 * 4 + 0 ] = m.color.r;\n\t\t\t// \tfloatArray[ index + 0 * 4 + 1 ] = m.color.g;\n\t\t\t// \tfloatArray[ index + 0 * 4 + 2 ] = m.color.b;\n\t\t\t//\n\t\t\t// \t// sample 2 .a\n\t\t\t// \tfloatArray[ index + 2 * 4 + 3 ] = getField( m, 'emissiveIntensity', 0.0 );\n\t\t\t//\n\t\t\t// \t// sample 3 .rgb\n\t\t\t// \tfloatArray[ index + 3 * 4 + 0 ] = m.emissive.r;\n\t\t\t// \tfloatArray[ index + 3 * 4 + 1 ] = m.emissive.g;\n\t\t\t// \tfloatArray[ index + 3 * 4 + 2 ] = m.emissive.b;\n\t\t\t//\n\t\t\t// \t// sample 13 .g\n\t\t\t// \t// reusing opacity field\n\t\t\t// \tfloatArray[ index + 13 * 4 + 1 ] = m.density;\n\t\t\t//\n\t\t\t// \t// side\n\t\t\t// \tfloatArray[ index + 13 * 4 + 3 ] = 0.0;\n\t\t\t//\n\t\t\t// \t// sample 14 .b\n\t\t\t// \tfloatArray[ index + 14 * 4 + 2 ] = 1 << 2;\n\t\t\t//\n\t\t\t// \tindex += MATERIAL_STRIDE;\n\t\t\t// \tcontinue;\n\t\t\t//\n\t\t\t// }\n\n\t\t\t// color - offset 0\n\t\t\tfloatArray[ index ++ ] = m.color.r;\n\t\t\tfloatArray[ index ++ ] = m.color.g;\n\t\t\tfloatArray[ index ++ ] = m.color.b;\n\t\t\tintArray[ index ++ ] = getTexture( m, 'map' );\n\n\t\t\t// metalness & roughness - offset 4\n\t\t\tfloatArray[ index ++ ] = getField( m, 'metalness', 0.0 );\n\t\t\tintArray[ index ++ ] = getTexture( m, 'metalnessMap' );\n\t\t\tfloatArray[ index ++ ] = getField( m, 'roughness', 0.0 );\n\t\t\tintArray[ index ++ ] = getTexture( m, 'roughnessMap' );\n\n\t\t\t// transmission & emissiveIntensity - offset 8\n\t\t\t// three.js assumes a default f0 of 0.04 if no ior is provided which equates to an ior of 1.5\n\t\t\tfloatArray[ index ++ ] = getField( m, 'ior', 1.5 );\n\t\t\tfloatArray[ index ++ ] = getField( m, 'transmission', 0.0 );\n\t\t\tintArray[ index ++ ] = getTexture( m, 'transmissionMap' );\n\t\t\tfloatArray[ index ++ ] = getField( m, 'emissiveIntensity', 0.0 );\n\n\t\t\t// emission - offset 12\n\t\t\tif ( 'emissive' in m ) {\n\n\t\t\t\tfloatArray[ index ++ ] = m.emissive.r;\n\t\t\t\tfloatArray[ index ++ ] = m.emissive.g;\n\t\t\t\tfloatArray[ index ++ ] = m.emissive.b;\n\n\t\t\t} else {\n\n\t\t\t\tfloatArray[ index ++ ] = 0.0;\n\t\t\t\tfloatArray[ index ++ ] = 0.0;\n\t\t\t\tfloatArray[ index ++ ] = 0.0;\n\n\t\t\t}\n\n\t\t\tintArray[ index ++ ] = getTexture( m, 'emissiveMap' );\n\n\t\t\t// normals - offset 16\n\t\t\tintArray[ index ++ ] = getTexture( m, 'normalMap' );\n\t\t\tindex ++; // because of vec2 alignment\n\t\t\tif ( 'normalScale' in m ) {\n\n\t\t\t\tfloatArray[ index ++ ] = m.normalScale.x;\n\t\t\t\tfloatArray[ index ++ ] = m.normalScale.y;\n\n \t\t\t} else {\n\n \t\t\t\tfloatArray[ index ++ ] = 1;\n \t\t\t\tfloatArray[ index ++ ] = 1;\n\n \t\t\t}\n\n\t\t\t// clearcoat - offset 20\n\t\t\tfloatArray[ index ++ ] = getField( m, 'clearcoat', 0.0 );\n\t\t\tintArray[ index ++ ] = getTexture( m, 'clearcoatMap' );\n\t\t\tintArray[ index ++ ] = getTexture( m, 'clearcoatNormalMap' );\n\t\t\tindex ++; // because of vec2 alignment\n\n\t\t\t// offset 24\n\t\t\tif ( 'clearcoatNormalScale' in m ) {\n\n\t\t\t\tfloatArray[ index ++ ] = m.clearcoatNormalScale.x;\n\t\t\t\tfloatArray[ index ++ ] = m.clearcoatNormalScale.y;\n\n\t\t\t} else {\n\n\t\t\t\tfloatArray[ index ++ ] = 1;\n\t\t\t\tfloatArray[ index ++ ] = 1;\n\n\t\t\t}\n\n\t\t\tfloatArray[ index ++ ] = getField( m, 'clearcoatRoughness', 0.0 );\n\t\t\tintArray[ index ++ ] = getTexture( m, 'clearcoatRoughnessMap' );\n\n\t\t\t// iridescence - offset 28\n\t\t\tintArray[ index ++ ] = getTexture( m, 'iridescenceMap' );\n\t\t\tintArray[ index ++ ] = getTexture( m, 'iridescenceThicknessMap' );\n\n\t\t\tfloatArray[ index ++ ] = getField( m, 'iridescence', 0.0 );\n\t\t\tfloatArray[ index ++ ] = getField( m, 'iridescenceIOR', 1.3 );\n\n\t\t\t// offset 32\n\t\t\tconst iridescenceThicknessRange = getField( m, 'iridescenceThicknessRange', [ 100, 400 ] );\n\t\t\tfloatArray[ index ++ ] = iridescenceThicknessRange[ 0 ];\n\t\t\tfloatArray[ index ++ ] = iridescenceThicknessRange[ 1 ];\n\t\t\t// vec3f alignment requirements\n\t\t\tindex ++;\n\t\t\tindex ++;\n\n\t\t\t// specular color - offset 36\n\t\t\tif ( 'specularColor' in m ) {\n\n\t\t\t\tfloatArray[ index ++ ] = m.specularColor.r;\n\t\t\t\tfloatArray[ index ++ ] = m.specularColor.g;\n\t\t\t\tfloatArray[ index ++ ] = m.specularColor.b;\n\n\t\t\t} else {\n\n\t\t\t\tfloatArray[ index ++ ] = 1.0;\n\t\t\t\tfloatArray[ index ++ ] = 1.0;\n\t\t\t\tfloatArray[ index ++ ] = 1.0;\n\n\t\t\t}\n\n\t\t\tintArray[ index ++ ] = getTexture( m, 'specularColorMap' );\n\n\t\t\t// specular intensity - offset 40\n\t\t\tfloatArray[ index ++ ] = getField( m, 'specularIntensity', 1.0 );\n\t\t\tintArray[ index ++ ] = getTexture( m, 'specularIntensityMap' );\n\n\t\t\t// isThinFilm\n\t\t\tconst isThinFilm = getField( m, 'thickness', 0.0 ) === 0.0 && getField( m, 'attenuationDistance', Infinity ) === Infinity;\n\t\t\tintArray[ index ++ ] = Number( isThinFilm );\n\t\t\tindex ++;\n\n\t\t\t// attenuation - offset 44\n\t\t\tif ( 'attenuationColor' in m ) {\n\n\t\t\t\tfloatArray[ index ++ ] = m.attenuationColor.r;\n\t\t\t\tfloatArray[ index ++ ] = m.attenuationColor.g;\n\t\t\t\tfloatArray[ index ++ ] = m.attenuationColor.b;\n\n\t\t\t} else {\n\n\t\t\t\tfloatArray[ index ++ ] = 1.0;\n\t\t\t\tfloatArray[ index ++ ] = 1.0;\n\t\t\t\tfloatArray[ index ++ ] = 1.0;\n\n\t\t\t}\n\n\t\t\tfloatArray[ index ++ ] = getField( m, 'attenuationDistance', Infinity );\n\n\t\t\t// alphaMap - offset 48\n\t\t\tintArray[ index ++ ] = getTexture( m, 'alphaMap' );\n\t\t\tintArray[ index ++ ] = Number( getField( m, 'castShadow', true ) ); // shadow\n\t\t\tfloatArray[ index ++ ] = m.opacity;\n\t\t\tfloatArray[ index ++ ] = m.alphaTest;\n\n\t\t\t// side & matte - offset 52\n\t\t\tif ( ! isThinFilm && m.transmission > 0.0 ) {\n\n\t\t\t\tfloatArray[ index ++ ] = 0;\n\n\t\t\t} else {\n\n\t\t\t\tswitch ( m.side ) {\n\n\t\t\t\t\tcase FrontSide:\n\t\t\t\t\t\tfloatArray[ index ++ ] = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BackSide:\n\t\t\t\t\t\tfloatArray[ index ++ ] = - 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase DoubleSide:\n\t\t\t\t\t\tfloatArray[ index ++ ] = 0;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tintArray[ index ++ ] = Number( getField( m, 'matte', false ) ); // matte\n\t\t\tfloatArray[ index ++ ] = getField( m, 'sheen', 0.0 );\n\t\t\tindex ++; // vec3 alignment requirements\n\n\t\t\t// sheenColor - offset 56\n\t\t\tif ( 'sheenColor' in m ) {\n\n\t\t\t\tfloatArray[ index ++ ] = m.sheenColor.r;\n\t\t\t\tfloatArray[ index ++ ] = m.sheenColor.g;\n\t\t\t\tfloatArray[ index ++ ] = m.sheenColor.b;\n\n\t\t\t} else {\n\n\t\t\t\tfloatArray[ index ++ ] = 0.0;\n\t\t\t\tfloatArray[ index ++ ] = 0.0;\n\t\t\t\tfloatArray[ index ++ ] = 0.0;\n\n\t\t\t}\n\n\t\t\tintArray[ index ++ ] = getTexture( m, 'sheenColorMap' );\n\n\t\t\t// sheenRoughness, flags - offset 60\n\t\t\tfloatArray[ index ++ ] = getField( m, 'sheenRoughness', 0.0 );\n\t\t\tintArray[ index ++ ] = getTexture( m, 'sheenRoughnessMap' );\n\n\t\t\tintArray[ index ++ ] = Number( m.vertexColors );\n\t\t\tintArray[ index ++ ] = Number( m.flatShading );\n\n\t\t\t// transparent, fogVolume - offset 64\n\t\t\tintArray[ index ++ ] = Number( m.transparent );\n\t\t\tintArray[ index ++ ] = 0;\n\t\t\tindex ++;\n\t\t\tindex ++;\n\n\t\t\t// map transform - offset 68\n\t\t\tindex += writeTextureMatrixToArray( m, 'map', floatArray, index );\n\n\t\t\t// metalnessMap transform - offset 80\n\t\t\tindex += writeTextureMatrixToArray( m, 'metalnessMap', floatArray, index );\n\n\t\t\t// roughnessMap transform - offset 92\n\t\t\tindex += writeTextureMatrixToArray( m, 'roughnessMap', floatArray, index );\n\n\t\t\t// transmissionMap transform - offset 104\n\t\t\tindex += writeTextureMatrixToArray( m, 'transmissionMap', floatArray, index );\n\n\t\t\t// emissiveMap transform - offset 116\n\t\t\tindex += writeTextureMatrixToArray( m, 'emissiveMap', floatArray, index );\n\n\t\t\t// normalMap transform - offset 128\n\t\t\tindex += writeTextureMatrixToArray( m, 'normalMap', floatArray, index );\n\n\t\t\t// clearcoatMap transform - offset 140\n\t\t\tindex += writeTextureMatrixToArray( m, 'clearcoatMap', floatArray, index );\n\n\t\t\t// clearcoatNormalMap transform - offset 152\n\t\t\tindex += writeTextureMatrixToArray( m, 'clearcoatNormalMap', floatArray, index );\n\n\t\t\t// clearcoatRoughnessMap transform - offset 164\n\t\t\tindex += writeTextureMatrixToArray( m, 'clearcoatRoughnessMap', floatArray, index );\n\n\t\t\t// sheenColorMap transform - offset 176\n\t\t\tindex += writeTextureMatrixToArray( m, 'sheenColorMap', floatArray, index );\n\n\t\t\t// sheenRoughnessMap transform - offset 188\n\t\t\tindex += writeTextureMatrixToArray( m, 'sheenRoughnessMap', floatArray, index );\n\n\t\t\t// iridescenceMap transform - offset 200\n\t\t\tindex += writeTextureMatrixToArray( m, 'iridescenceMap', floatArray, index );\n\n\t\t\t// iridescenceThicknessMap transform - offset 212\n\t\t\tindex += writeTextureMatrixToArray( m, 'iridescenceThicknessMap', floatArray, index );\n\n\t\t\t// specularColorMap transform - offset 224\n\t\t\tindex += writeTextureMatrixToArray( m, 'specularColorMap', floatArray, index );\n\n\t\t\t// specularIntensityMap transform - offset 236\n\t\t\tindex += writeTextureMatrixToArray( m, 'specularIntensityMap', floatArray, index );\n\n\t\t\t// alphaMap transform - offset 248\n\t\t\tindex += writeTextureMatrixToArray( m, 'alphaMap', floatArray, index );\n\n\t\t}\n\n\t\treturn { materialData: floatArray, textures };\n\n\t}\n\n\twriteTransformData( info, premultiplyMatrix, writeOffset, targetBuffer ) {\n\n\t\tsuper.writeTransformData( info, premultiplyMatrix, writeOffset, targetBuffer );\n\n\t\t// write material data to the transforms\n\t\tconst { materials } = this;\n\t\tconst { object, instanceId, root } = info;\n\n\t\t// get the material associated with the bvh group\n\t\tlet material = object.material;\n\t\tif ( Array.isArray( material ) ) {\n\n\t\t\tconst { materialIndex } = object.geometry.groups[ root ];\n\t\t\tmaterial = material[ materialIndex ];\n\n\t\t}\n\n\t\t// save the index\n\t\tlet index = materials.indexOf( material );\n\t\tif ( index === - 1 ) {\n\n\t\t\tindex = materials.length;\n\t\t\tmaterials.push( material );\n\n\t\t}\n\n\t\tconst transformBufferU32 = new Uint32Array( targetBuffer );\n\t\ttransformBufferU32[ writeOffset * transformStruct.getLength() + 34 ] = index;\n\n\t\t// write color\n\t\t// TODO: note that both BatchedMesh and InstancedMesh \"getColorAt\" functions throw\n\t\t// if colors have not been defined.\n\t\tif ( object.isInstancedMesh && object.instanceColor ) {\n\n\t\t\tobject.getColorAt( instanceId, _colorVec );\n\t\t\t_colorVec.w = 1.0;\n\n\t\t} else if ( object.isBatchedMesh && object._colorsTexture ) {\n\n\t\t\tobject.getColorAt( instanceId, _colorVec );\n\n\t\t} else {\n\n\t\t\t_colorVec.setScalar( 1 );\n\n\t\t}\n\n\t\tconst transformBufferF32 = new Float32Array( targetBuffer );\n\t\t_colorVec.toArray( transformBufferF32, writeOffset * transformStruct.getLength() + 36 );\n\n\t}\n\n\tgetBVH( object, instanceId, rangeTarget ) {\n\n\t\tconst { bvhMap } = this;\n\t\tconst bvh = super.getBVH( object, instanceId, rangeTarget );\n\t\tif ( bvhMap.has( bvh ) ) {\n\n\t\t\tconst data = bvhMap.get( bvh );\n\t\t\tObject.assign( rangeTarget, data.range );\n\n\t\t\t// make sure the mesh and bvh are updated if it's being reused across updates\n\t\t\tif ( bvh !== data.bvh && bvh instanceof SkinnedMeshBVH ) {\n\n\t\t\t\tconst sourceMesh = bvh.mesh;\n\t\t\t\tconst clonedMesh = data.bvh.mesh;\n\t\t\t\tclonedMesh.matrixWorld\n\t\t\t\t\t.copy( sourceMesh.matrixWorld )\n\t\t\t\t\t.decompose( clonedMesh.position, clonedMesh.quaternion, clonedMesh.scale );\n\n\t\t\t\tbvh.refit();\n\n\t\t\t}\n\n\t\t\treturn data.bvh;\n\n\t\t} else if ( bvh.indirect ) {\n\n\t\t\t// \"indirect\" bvhs are not supported since they cannot be unpacked in a way tht will allow for coherent material indices\n\t\t\tconst proxyGeometry = new BufferGeometry();\n\t\t\tproxyGeometry.attributes = bvh.geometry.attributes;\n\n\t\t\tlet array;\n\t\t\tif ( bvh.geometry.index ) {\n\n\t\t\t\tarray = bvh.geometry.index.array.slice( rangeTarget.start, rangeTarget.count + rangeTarget.start );\n\n\t\t\t} else {\n\n\t\t\t\tconst { start, count } = rangeTarget;\n\t\t\t\tarray = new Uint32Array( count );\n\t\t\t\tfor ( let i = 0, l = rangeTarget.count; i < l; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = start + i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tproxyGeometry.index = new BufferAttribute( array, 1 );\n\t\t\trangeTarget.start = 0;\n\n\t\t\tlet newBVH;\n\t\t\tif ( bvh instanceof SkinnedMeshBVH ) {\n\n\t\t\t\tconst sourceMesh = bvh.mesh;\n\t\t\t\tconst clonedMesh = new SkinnedMesh( proxyGeometry );\n\t\t\t\tclonedMesh.copy( sourceMesh );\n\t\t\t\tclonedMesh.matrixWorld\n\t\t\t\t\t.copy( sourceMesh.matrixWorld )\n\t\t\t\t\t.decompose( clonedMesh.position, clonedMesh.quaternion, clonedMesh.scale );\n\n\t\t\t\tnewBVH = new SkinnedMeshBVH( clonedMesh, { strategy: SAH, maxLeafSize: 5 } );\n\n\t\t\t} else {\n\n\t\t\t\tnewBVH = new MeshBVH( proxyGeometry, { strategy: SAH, maxLeafSize: 5 } );\n\n\t\t\t}\n\n\t\t\tbvhMap.set( bvh, { bvh: newBVH, range: { ...rangeTarget } } );\n\t\t\treturn newBVH;\n\n\t\t} else {\n\n\t\t\treturn bvh;\n\n\t\t}\n\n\t}\n\n}\n","import { MeshBasicNodeMaterial, DataTexture, NoBlending } from 'three/webgpu';\nimport { uv, varying, texture, uniform, wgslFn } from 'three/tsl';\n\nexport class AtlasDebugMaterial extends MeshBasicNodeMaterial {\n\n\tset texture( v ) {\n\n\t\tthis._texNode.value = v;\n\n\t}\n\n\tset layer( v ) {\n\n\t\tthis._layerUniform.value = v;\n\n\t}\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.blending = NoBlending;\n\n\t\tthis._texNode = texture( new DataTexture() );\n\t\tthis._layerUniform = uniform( 0 );\n\n\t\t// Shows one layer of the atlas array texture.\n\t\tthis.colorNode = wgslFn( /* wgsl */ `\n\t\t\tfn atlasDebug( tex: texture_2d_array<f32>, coord: vec2f, layer: f32 ) -> vec4f {\n\n\t\t\t\t// flip y so texel origin shows at the top-left\n\t\t\t\tlet dims = vec2f( textureDimensions( tex, 0 ).xy );\n\t\t\t\tlet texel = vec2i( vec2f( coord.x, 1.0 - coord.y ) * dims );\n\t\t\t\treturn textureLoad( tex, texel, i32( layer ), 0 );\n\n\t\t\t}\n\t\t` )( this._texNode, varying( uv() ), this._layerUniform );\n\n\t}\n\n}\n","import { BufferAttribute } from 'three';\n\nexport function updateMaterialIndexAttribute( geometry, materials, allMaterials ) {\n\n\tconst indexAttr = geometry.index;\n\tconst posAttr = geometry.attributes.position;\n\tconst vertCount = posAttr.count;\n\tconst totalCount = indexAttr ? indexAttr.count : vertCount;\n\tlet groups = geometry.groups;\n\tif ( groups.length === 0 ) {\n\n\t\tgroups = [ { count: totalCount, start: 0, materialIndex: 0 } ];\n\n\t}\n\n\tlet materialIndexAttribute = geometry.getAttribute( 'materialIndex' );\n\tif ( ! materialIndexAttribute || materialIndexAttribute.count !== vertCount ) {\n\n\t\t// use an array with the minimum precision required to store all material id references.\n\t\tlet array;\n\t\tif ( allMaterials.length <= 255 ) {\n\n\t\t\tarray = new Uint8Array( vertCount );\n\n\t\t} else {\n\n\t\t\tarray = new Uint16Array( vertCount );\n\n\t\t}\n\n\t\tmaterialIndexAttribute = new BufferAttribute( array, 1, false );\n\t\tgeometry.deleteAttribute( 'materialIndex' );\n\t\tgeometry.setAttribute( 'materialIndex', materialIndexAttribute );\n\n\t}\n\n\tconst materialArray = materialIndexAttribute.array;\n\tfor ( let i = 0; i < groups.length; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\t\tconst start = group.start;\n\t\tconst count = group.count;\n\t\tconst endCount = Math.min( count, totalCount - start );\n\n\t\tconst mat = Array.isArray( materials ) ? materials[ group.materialIndex ] : materials;\n\t\tconst materialIndex = allMaterials.indexOf( mat );\n\n\t\tfor ( let j = 0; j < endCount; j ++ ) {\n\n\t\t\tlet index = start + j;\n\t\t\tif ( indexAttr ) {\n\n\t\t\t\tindex = indexAttr.getX( index );\n\n\t\t\t}\n\n\t\t\tmaterialArray[ index ] = materialIndex;\n\n\t\t}\n\n\t}\n\n}\n\nexport function setCommonAttributes( geometry, attributes ) {\n\n\tif ( ! geometry.index ) {\n\n\t\t// TODO: compute a typed array\n\t\tconst indexCount = geometry.attributes.position.count;\n\t\tconst array = new Array( indexCount );\n\t\tfor ( let i = 0; i < indexCount; i ++ ) {\n\n\t\t\tarray[ i ] = i;\n\n\t\t}\n\n\t\tgeometry.setIndex( array );\n\n\t}\n\n\tif ( ! geometry.attributes.normal && ( attributes && attributes.includes( 'normal' ) ) ) {\n\n\t\tgeometry.computeVertexNormals();\n\n\t}\n\n\tif ( ! geometry.attributes.uv && ( attributes && attributes.includes( 'uv' ) ) ) {\n\n\t\tconst vertCount = geometry.attributes.position.count;\n\t\tgeometry.setAttribute( 'uv', new BufferAttribute( new Float32Array( vertCount * 2 ), 2, false ) );\n\n\t}\n\n\tif ( ! geometry.attributes.uv2 && ( attributes && attributes.includes( 'uv2' ) ) ) {\n\n\t\tconst vertCount = geometry.attributes.position.count;\n\t\tgeometry.setAttribute( 'uv2', new BufferAttribute( new Float32Array( vertCount * 2 ), 2, false ) );\n\n\t}\n\n\tif ( ! geometry.attributes.tangent && ( attributes && attributes.includes( 'tangent' ) ) ) {\n\n\t\t// compute tangents requires a uv and normal buffer\n\t\tif ( geometry.attributes.uv && geometry.attributes.normal ) {\n\n\t\t\tgeometry.computeTangents();\n\n\t\t} else {\n\n\t\t\tconst vertCount = geometry.attributes.position.count;\n\t\t\tgeometry.setAttribute( 'tangent', new BufferAttribute( new Float32Array( vertCount * 4 ), 4, false ) );\n\n\t\t}\n\n\t}\n\n\tif ( ! geometry.attributes.color && ( attributes && attributes.includes( 'color' ) ) ) {\n\n\t\tconst vertCount = geometry.attributes.position.count;\n\t\tconst array = new Float32Array( vertCount * 4 );\n\t\tarray.fill( 1.0 );\n\t\tgeometry.setAttribute( 'color', new BufferAttribute( array, 4 ) );\n\n\t}\n\n}\n","import { wgslTagFn } from '../lib/three-mesh-bvh/index.js';\nimport { rand2, RNG_INDEX_SCATTER_DIRECTION } from '../nodes/random.wgsl.js';\nimport { diffuseDirectionFunc } from '../nodes/sampling.wgsl.js';\n\n/**\n * Defines a material sampled by the pathtracer\n */\nexport class PathtracingMaterial {\n\n\t/**\n\t *\n\t * Called once per material\n\t * Adds ability to initialize state\n\t *\n\t */\n\tinit( /* renderer */ ) {\n\n\t}\n\n\t/**\n\t *\n\t * Must return a bsdf sampling function node with signature\n\t * ( worldView: vec3f, surface: Surface ) -> ScatterRecord\n\t *\n\t */\n\tgetBsdfNode() {\n\n\t\treturn wgslTagFn`\n\n\t\t\tfn bsdfSample( worldWo: vec3f, surf: SurfaceRecord ) -> ScatterRecord {\n\n\t\t\t\tvar record: ScatterRecord;\n\n\t\t\t\tlet wo = normalize( surf.normalInvBasis * worldWo );\n\t\t\t\tlet wi = ${ diffuseDirectionFunc }( wo, ${ rand2 }( ${ RNG_INDEX_SCATTER_DIRECTION } ) );\n\t\t\t\trecord.color = surf.color * max( wi.z, 0.0 );\n\t\t\t\trecord.pdf = max( wi.z, 0.0 ) / PI;\n\t\t\t\trecord.direction = normalize( surf.normalBasis * wi );\n\n\t\t\t\treturn record;\n\n\t\t\t}\n\n\t\t`;\n\n\t}\n\n\tgetData() {\n\n\t\treturn {\n\n\t\t\tbsdfSample: this.getBsdfNode(),\n\n\t\t};\n\n\t}\n\n}\n","import { texture, textureStore, globalId, float } from 'three/tsl';\nimport { StorageTexture, RedFormat, LinearFilter, TextureLoader, HalfFloatType } from 'three/webgpu';\nimport { wgslTagFn } from '../lib/three-mesh-bvh/index.js';\nimport { PathtracingMaterial } from './PathtracingMaterial';\nimport { specularBrdfFunc, diffuseBrdfFunc, fresnelMixFunc, conductorFresnelFunc, albedoIntegralMetallic, fresnelCoatFunc, iridescentDielectricLayerFunc, iridescentConductorLayerFunc } from '../nodes/material.wgsl.js';\nimport { diffuseDirectionFunc, getLobeWeightsFunc } from '../nodes/sampling.wgsl.js';\nimport { ggxDirectionFunc, ggxReflectionAdjustedPDFFunc } from '../nodes/ggx.wgsl.js';\nimport { bxdfContextStruct, scatterRecordStruct, surfaceRecordStruct } from '../nodes/structs.wgsl.js';\nimport { rand1, rand2, RNG_INDEX_SCATTER_DIRECTION, RNG_INDEX_SCATTER_TYPE } from '../nodes/random.wgsl.js';\nimport { ComputeKernel } from '../compute/ComputeKernel';\n\nconst TURQUIN_METAL_URL = new URL( '../../textures/turquinMetal.png', import.meta.url ).toString();\nconst TURQUIN_METAL_TEXTURE = await new TextureLoader().loadAsync( TURQUIN_METAL_URL );\n\nconst CLEARCOAT_IOR = float( 1.5 );\nconst MIN_INCIDENT_COS = float( 1e-3 );\n\nexport class GltfCompliantMaterial extends PathtracingMaterial {\n\n\tconstructor( options = {} ) {\n\n\t\tsuper();\n\n\t\tconst {\n\t\t\tspecularBrdf = specularBrdfFunc,\n\t\t\tdiffuseBrdf = diffuseBrdfFunc,\n\t\t\tfresnelMix = fresnelMixFunc,\n\t\t\tconductorFresnel = conductorFresnelFunc,\n\t\t\tfresnelCoat = fresnelCoatFunc,\n\t\t\tiridescentDielectricLayer = iridescentDielectricLayerFunc,\n\t\t\tiridescentConductorLayer = iridescentConductorLayerFunc,\n\t\t\tcalculateTurquinTexture = false,\n\t\t} = options;\n\n\t\tif ( calculateTurquinTexture ) {\n\n\t\t\tthis.turquinTexture = new StorageTexture( 32, 32 );\n\t\t\tthis.turquinTexture.type = HalfFloatType;\n\n\t\t} else {\n\n\t\t\tthis.turquinTexture = TURQUIN_METAL_TEXTURE;\n\t\t\tthis.turquinTexture.flipY = false;\n\n\t\t}\n\n\t\tthis.turquinTexture.format = RedFormat;\n\t\tthis.turquinTexture.minFilter = LinearFilter;\n\t\tthis.turquinTexture.magFilter = LinearFilter;\n\n\t\tconst turquinNode = texture( this.turquinTexture ).setName( 'turquinTexture' );\n\n\t\tthis.specularBrdf = specularBrdf;\n\t\tthis.diffuseBrdf = diffuseBrdf;\n\t\tthis.fresnelMix = fresnelMix;\n\t\tthis.conductorFresnel = conductorFresnel( turquinNode );\n\t\tthis.fresnelCoat = fresnelCoat;\n\t\tthis.iridescentDielectricLayer = iridescentDielectricLayer;\n\t\tthis.iridescentConductorLayer = iridescentConductorLayer;\n\t\tthis.calculateTurquinTexture = calculateTurquinTexture;\n\n\t}\n\n\tinit( renderer ) {\n\n\t\tif ( ! this.calculateTurquinTexture ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst turquinParams = {\n\t\t\ttexture: textureStore( this.turquinTexture ).toWriteOnly(),\n\t\t\tglobalId,\n\t\t};\n\t\tconst turquinKernel = new ComputeKernel( albedoIntegralMetallic( turquinParams ), { workgroupSize: [ 16, 16, 1 ] } );\n\n\t\trenderer.compute( turquinKernel.kernel, [ 2, 2, 1 ] );\n\n\t}\n\n\tgetBsdfNode() {\n\n\t\tconst bsdfEvalFunc = wgslTagFn/* wgsl */`\n\n\t\t\tfn bsdfEval( ctx: ${ bxdfContextStruct }, surf: ${ surfaceRecordStruct } ) -> vec3f {\n\n\t\t\t\tlet alpha = surf.roughness * surf.roughness;\n\n\t\t\t\tlet specular = ${ this.specularBrdf }( ctx.NdotL, ctx.NdotV, ctx.NdotH, alpha );\n\t\t\t\tlet diffuse = ${ this.diffuseBrdf }( ctx.NdotV, ctx.NdotL, ctx.VdotH, surf );\n\t\t\t\tlet dielectricBase = ${ this.fresnelMix }( ctx.VdotH, surf.ior, diffuse, specular );\n\n\t\t\t\tlet dielectric = ${ this.iridescentDielectricLayer }(\n\t\t\t\t\tdielectricBase, diffuse, specular, ctx.VdotH, /* outsideIor */ 1.0,\n\t\t\t\t\tsurf.ior, surf.iridescenceIor, surf.iridescenceThickness, surf.iridescence\n\t\t\t\t);\n\n\t\t\t\tlet metallicBase = ${ this.conductorFresnel }( ctx.NdotV, ctx.VdotH, surf.color, specular, alpha );\n\n\t\t\t\tlet metallic = ${ this.iridescentConductorLayer }(\n\t\t\t\t\tmetallicBase, specular, surf.color, ctx.VdotH, /* outsideIor */ 1.0,\n\t\t\t\t\tsurf.iridescenceIor, surf.iridescenceThickness, surf.iridescence\n\t\t\t\t);\n\n\t\t\t\tlet material = mix( dielectric, metallic, surf.metalness );\n\n\t\t\t\tlet clearcoatAlpha = surf.clearcoatRoughness * surf.clearcoatRoughness;\n\t\t\t\tlet clearcoat = ${ this.specularBrdf }( ctx.LdotNc, ctx.VdotNc, ctx.HdotNc, clearcoatAlpha );\n\n\t\t\t\tlet coatedMaterial = ${ this.fresnelCoat }( ctx.VdotNc, ${ CLEARCOAT_IOR }, material, clearcoat, surf.clearcoat );\n\n\t\t\t\treturn coatedMaterial;\n\n\t\t\t}\n\n\t\t`;\n\n\t\treturn wgslTagFn/* wgsl */`\n\n\t\t\tfn bsdfSample( worldWo: vec3f, surf: ${ surfaceRecordStruct } ) -> ${ scatterRecordStruct } {\n\n\t\t\t\tvar result: ${ scatterRecordStruct };\n\t\t\t\tresult.pdf = 0.0;\n\n\t\t\t\tlet alpha = surf.roughness * surf.roughness;\n\t\t\t\tlet clearcoatAlpha = surf.clearcoatRoughness * surf.clearcoatRoughness;\n\n\t\t\t\tlet normalBasis = surf.normalBasis;\n\t\t\t\tlet invBasis = surf.normalInvBasis;\n\t\t\t\tlet clearcoatBasis = surf.clearcoatBasis;\n\t\t\t\tlet invClearcoatBasis = surf.clearcoatInvBasis;\n\n\t\t\t\tlet wo = normalize( invBasis * worldWo );\n\t\t\t\tlet woClearcoat = normalize( invClearcoatBasis * worldWo );\n\n\t\t\t\t// TODO: handle such intersections better;\n\t\t\t\t// Sometimes .z < 0.0 on a pretty round surface e.g. sphere\n\t\t\t\t// Disabling this condition leads to more fireflies on ClearCoatCarPaint example\n\t\t\t\t// This could also be fixed by offsetting rays by 1e-1\n\t\t\t\t// Also, this will be an invalid condition when transmission is implemented\n\t\t\t\tif ( wo.z < 0.0 || woClearcoat.z < 0.0 ) {\n\n\t\t\t\t\treturn result;\n\n\t\t\t\t}\n\n\t\t\t\tlet weights = ${ getLobeWeightsFunc }( wo, woClearcoat, vec3( 0, 0, 1 ), ${ CLEARCOAT_IOR }, surf );\n\n\t\t\t\tvar cdf: vec4f;\n\t\t\t\tcdf.x = weights.diffuse;\n\t\t\t\tcdf.y = weights.specular + cdf.x;\n\t\t\t\tcdf.z = weights.clearcoat + cdf.y;\n\t\t\t\tcdf.w = 0; // weights.transmission + cdf.z;\n\n\t\t\t\tlet r = ${ rand1 }( ${ RNG_INDEX_SCATTER_TYPE } ) * cdf.z;\n\n\t\t\t\tlet directionUV = ${ rand2 }( ${ RNG_INDEX_SCATTER_DIRECTION } );\n\t\t\t\tvar wi: vec3f;\n\t\t\t\tvar wiClearcoat: vec3f;\n\t\t\t\tvar wh: vec3f;\n\t\t\t\tvar whClearcoat: vec3f;\n\n\t\t\t\tif ( r <= cdf.x ) { // diffuse\n\n\t\t\t\t\twi = ${ diffuseDirectionFunc }( wo, directionUV );\n\t\t\t\t\twh = normalize( wi + wo );\n\n\t\t\t\t\twiClearcoat = normalize( invClearcoatBasis * normalBasis * wi );\n\t\t\t\t\twhClearcoat = normalize( invClearcoatBasis * normalBasis * wh );\n\n\t\t\t\t} else if ( r <= cdf.y ) { // specular\n\n\t\t\t\t\twh = ${ ggxDirectionFunc }( wo, vec2( alpha ), directionUV );\n\t\t\t\t\twi = - normalize( reflect( wo, wh ) );\n\n\t\t\t\t\twiClearcoat = normalize( invClearcoatBasis * normalBasis * wi );\n\t\t\t\t\twhClearcoat = normalize( invClearcoatBasis * normalBasis * wh );\n\n\t\t\t\t} else if ( r <= cdf.z ) { // clearcoat\n\n\t\t\t\t\twhClearcoat = ${ ggxDirectionFunc }( woClearcoat, vec2( clearcoatAlpha ), directionUV );\n\t\t\t\t\twiClearcoat = - normalize( reflect( woClearcoat, whClearcoat ) );\n\n\t\t\t\t\twi = normalize( invBasis * clearcoatBasis * wiClearcoat );\n\t\t\t\t\twh = normalize( invBasis * clearcoatBasis * whClearcoat );\n\n\t\t\t\t} else if ( r <= cdf.w ) { // transmission / refraction\n\n\t\t\t\t\t// NOT IMPLEMENTED\n\n\t\t\t\t}\n\n\t\t\t\tvar ctx: ${ bxdfContextStruct };\n\t\t\t\tctx.NdotV = max( wo.z, ${ MIN_INCIDENT_COS } );\n\t\t\t\tctx.NdotL = max( wi.z, ${ MIN_INCIDENT_COS } );\n\t\t\t\tctx.NdotH = saturate( wh.z );\n\t\t\t\tctx.VdotH = saturate( dot( wo, wh ) );\n\n\t\t\t\tctx.VdotNc = max( woClearcoat.z, ${ MIN_INCIDENT_COS } );\n\t\t\t\tctx.LdotNc = max( wiClearcoat.z, ${ MIN_INCIDENT_COS } );\n\t\t\t\tctx.HdotNc = saturate( whClearcoat.z );\n\n\t\t\t\tif ( weights.diffuse > 0.0 ) {\n\n\t\t\t\t\tresult.pdf += weights.diffuse * max( wi.z, 0.0 ) / PI;\n\n\t\t\t\t}\n\n\t\t\t\tif ( weights.specular > 0.0 && wi.z > 0.0 ) {\n\n\t\t\t\t\tresult.pdf += weights.specular * ${ ggxReflectionAdjustedPDFFunc }( ctx.NdotV, ctx.NdotH, alpha );\n\n\t\t\t\t}\n\n\t\t\t\tif ( weights.clearcoat > 0.0 && wiClearcoat.z > 0.0 ) {\n\n\t\t\t\t\tresult.pdf += weights.clearcoat * ${ ggxReflectionAdjustedPDFFunc }( ctx.VdotNc, ctx.HdotNc, clearcoatAlpha );\n\n\t\t\t\t}\n\n\t\t\t\tresult.color = ${ bsdfEvalFunc }( ctx, surf );\n\t\t\t\tresult.color *= max( 0.0, wi.z );\n\t\t\t\tresult.direction = normalize( normalBasis * wi );\n\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t`;\n\n\t}\n\n}\n","import { DataTexture, LinearFilter, Vector2, Scene, PerspectiveCamera, Color, NoToneMapping, FloatType, Timer, StorageTexture } from 'three/webgpu';\nimport { SkinnedMeshBVH, MeshBVH, SAH } from 'three-mesh-bvh';\nimport { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';\nimport { RenderToScreenNodeMaterial } from './materials/RenderToScreenMaterial.js';\nimport { MegaKernelPathTracer } from './MegaKernelPathTracer.js';\nimport { WaveFrontPathTracer } from './WaveFrontPathTracer.js';\nimport { CubeToEquirectGenerator } from '../utils/CubeToEquirectGenerator.js';\nimport { PathtracerBVHComputeData } from './nodes/PathtracerBVHComputeData.js';\nimport { AtlasDebugMaterial } from './materials/debug/AtlasDebugMaterial.js';\nimport { setCommonAttributes } from '../core/utils/GeometryPreparationUtils.js';\nimport { GltfCompliantMaterial } from './materials/GltfCompliantMaterial.js';\n\nconst _resolution = new Vector2();\nconst _color = new Color();\n\nexport class WebGPUPathTracer {\n\n\tget bounces() {\n\n\t\treturn this._pathTracer.bounces;\n\n\t}\n\n\tset bounces( v ) {\n\n\t\tthis._pathTracer.bounces = v;\n\t\tthis._pathTracer.reset();\n\n\t}\n\n\tget samples() {\n\n\t\treturn this._pathTracer.samples;\n\n\t}\n\n\tget fadeState() {\n\n\t\treturn this._fadeState;\n\n\t}\n\n\tget textureAtlas() {\n\n\t\treturn this._bvhData.textureAtlas;\n\n\t}\n\n\tuseMegakernel( value ) {\n\n\t\tthis._pathTracer.dispose();\n\t\tthis._pathTracer = value ? new MegaKernelPathTracer( this._renderer ) : new WaveFrontPathTracer( this._renderer );\n\t\tthis._pathTracer.setBVHData( this._bvhData );\n\t\tthis._pathTracer.setMaterial( this.material );\n\t\tthis.setCamera( this.camera );\n\t\tthis.updateEnvironment();\n\n\t}\n\n\tconstructor( renderer ) {\n\n\t\t// members\n\t\tthis._renderer = renderer;\n\t\tthis._timer = new Timer();\n\n\t\tthis._envColorTexture = new DataTexture( );\n\t\tthis._envColorTexture.image.data = new Uint8Array( [ 255, 255, 255, 255 ] );\n\t\tthis._envColorTexture.needsUpdate = true;\n\t\tthis._envColorTexture.minFilter = LinearFilter;\n\t\tthis._envColorTexture.magFilter = LinearFilter;\n\n\t\tthis._backgroundColorTexture = new DataTexture( );\n\t\tthis._backgroundColorTexture.image.data = new Uint8Array( [ 255, 255, 255, 255 ] );\n\t\tthis._backgroundColorTexture.needsUpdate = true;\n\t\tthis._backgroundColorTexture.minFilter = LinearFilter;\n\t\tthis._backgroundColorTexture.magFilter = LinearFilter;\n\n\t\tthis._resetTime = - 1;\n\t\tthis._fadeState = 0;\n\t\tthis._size = new Vector2();\n\t\tthis._blitQuad = new FullScreenQuad( new RenderToScreenNodeMaterial() );\n\n\t\t// avoid mipmap gen on copy, not always supported with float type\n\t\tthis._lowResTarget = new StorageTexture( 1, 1 );\n\t\tthis._lowResTarget.type = FloatType;\n\t\tthis._lowResTarget.generateMipmaps = false;\n\n\t\t// options\n\t\tthis.minSamples = 1;\n\t\tthis.renderDelay = 500;\n\t\tthis.fadeDuration = 500;\n\t\tthis.dynamicLowRes = true;\n\t\tthis.lowResScale = 0.2;\n\t\tthis.renderScale = 1;\n\t\tthis.synchronizeRenderSize = true;\n\t\tthis.generateMissingAttributes = true;\n\t\tthis.commonAttributes = [ 'normal', 'uv', 'tangent', 'color' ];\n\n\t\tthis.material = new GltfCompliantMaterial();\n\t\tthis._pathTracer = new MegaKernelPathTracer( renderer );\n\n\t\t// initialize the scene so it doesn't fail\n\t\tthis.setScene( new Scene(), new PerspectiveCamera() );\n\n\t}\n\n\tsetScene( scene, camera ) {\n\n\t\tscene.updateMatrixWorld( true );\n\t\tcamera.updateMatrixWorld();\n\n\t\t// Build BVH for each mesh geometry\n\t\tscene.traverse( child => {\n\n\t\t\tif ( this.generateMissingAttributes && child.geometry?.isBufferGeometry ) {\n\n\t\t\t\tsetCommonAttributes( child.geometry, this.commonAttributes );\n\n\t\t\t}\n\n\t\t\tif ( child.isSkinnedMesh ) {\n\n\t\t\t\tif ( ! child.boundsTree ) {\n\n\t\t\t\t\tchild.boundsTree = new SkinnedMeshBVH( child, { strategy: SAH, maxLeafSize: 5, indirect: true } );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tchild.boundsTree.refit();\n\n\t\t\t\t}\n\n\t\t\t} else if ( child.isMesh ) {\n\n\t\t\t\tif ( ! child.geometry.boundsTree ) {\n\n\t\t\t\t\tchild.geometry.boundsTree = new MeshBVH( child.geometry, { strategy: SAH, maxLeafSize: 5 } );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} );\n\n\t\t// Build TLAS and compute functions\n\t\tconst bvhData = new PathtracerBVHComputeData( scene );\n\t\tbvhData.update();\n\t\tbvhData.textureAtlas.setTextures( this._renderer, bvhData.textures );\n\n\t\tthis.scene = scene;\n\t\tthis._bvhData = bvhData;\n\t\tthis._pathTracer.setBVHData( bvhData );\n\t\tthis.setCamera( camera );\n\t\tthis.updateEnvironment();\n\n\t}\n\n\tgetMaterial() {\n\n\t\treturn this.material;\n\n\t}\n\n\tsetMaterial( material ) {\n\n\t\tthis.material = material;\n\t\tthis._pathTracer.setMaterial( material );\n\n\t}\n\n\t// TODO: support async generation of ObjectBVH\n\tsetSceneAsync( ...args ) {\n\n\t\tthis.setScene( ...args );\n\n\t}\n\n\tsetCamera( camera ) {\n\n\t\tthis.camera = camera;\n\t\tthis.updateCamera();\n\n\t}\n\n\tupdateCamera() {\n\n\t\tconst camera = this.camera;\n\t\tcamera.updateMatrixWorld();\n\n\t\tthis._pathTracer.setCamera( camera );\n\t\tthis.reset();\n\n\t}\n\n\tupdateEnvironment() {\n\n\t\tconst {\n\t\t\t_renderer,\n\t\t\t_pathTracer,\n\t\t\tscene,\n\t\t\t_envColorTexture,\n\t\t\t_backgroundColorTexture,\n\t\t} = this;\n\n\t\tconst environment = convertToTexture( _renderer, scene.environment || _color.set( 0 ), _envColorTexture );\n\t\tconst background = convertToTexture( _renderer, scene.background, _backgroundColorTexture );\n\n\t\t_pathTracer.setEnvironment(\n\t\t\tenvironment,\n\t\t\tscene.environmentIntensity,\n\t\t\tscene.environmentRotation,\n\n\t\t\tbackground,\n\t\t\tscene.backgroundIntensity,\n\t\t\tscene.backgroundRotation,\n\t\t\tscene.backgroundBlurriness,\n\t\t);\n\n\t}\n\n\tsetSize( x, y ) {\n\n\t\tif ( this._size.x !== x || this._size.y !== y ) {\n\n\t\t\tthis._size.set( x, y );\n\t\t\tthis.reset();\n\n\t\t}\n\n\t}\n\n\treset() {\n\n\t\tthis._pathTracer.reset();\n\t\tthis._resetTime = 0;\n\t\tthis._fadeState = 0;\n\n\t}\n\n\trenderSample() {\n\n\t\tconst renderer = this._renderer;\n\t\tconst size = this._size;\n\t\tconst blitQuad = this._blitQuad;\n\t\tconst pathTracer = this._pathTracer;\n\t\tconst lowResTarget = this._lowResTarget;\n\t\tconst timer = this._timer;\n\t\tconst {\n\t\t\trenderDelay,\n\t\t\tdynamicLowRes,\n\t\t\tsynchronizeRenderSize,\n\t\t\trenderScale,\n\t\t\tlowResScale,\n\t\t\tminSamples,\n\t\t} = this;\n\n\t\ttimer.update();\n\n\t\tif ( ! this._renderer._initialized ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( ! this.material.initialized ) {\n\n\t\t\tthis.material.init( renderer );\n\t\t\tthis.material.initialized = true;\n\n\t\t}\n\n\t\tconst delta = 1000 * timer.getDelta();\n\t\tthis._resetTime += delta;\n\n\t\tconst originalToneMapping = renderer.toneMapping;\n\t\tconst originalExposure = renderer.toneMappingExposure;\n\t\tconst originalTarget = renderer.getRenderTarget();\n\t\tconst originalAutoClear = renderer.autoClear;\n\t\trenderer.toneMapping = NoToneMapping;\n\t\trenderer.toneMappingExposure = 1.0;\n\n\t\t// handle canvas-size auto synchronization\n\t\tif ( synchronizeRenderSize ) {\n\n\t\t\trenderer.getDrawingBufferSize( _resolution );\n\t\t\tconst w = Math.floor( renderScale * _resolution.x );\n\t\t\tconst h = Math.floor( renderScale * _resolution.y );\n\t\t\tthis.setSize( w, h );\n\n\t\t}\n\n\t\t// check if we should be in low res mode and calculate the target size\n\t\tlet { width, height } = size;\n\t\tconst lowResMode = this._resetTime < renderDelay;\n\t\tif ( lowResMode ) {\n\n\t\t\twidth = Math.ceil( lowResScale * width );\n\t\t\theight = Math.ceil( lowResScale * height );\n\n\t\t}\n\n\t\t// set the size if necessary\n\t\tpathTracer.getSize( _resolution );\n\n\t\tconst resized = _resolution.x !== width || _resolution.y !== height;\n\t\tif ( resized ) {\n\n\t\t\tif ( ! lowResMode && dynamicLowRes ) {\n\n\t\t\t\t// copy the low reset content if we're transitioning to the full\n\t\t\t\t// resolution view so we can fade to it\n\t\t\t\tlowResTarget.setSize( Math.ceil( lowResScale * width ), Math.ceil( lowResScale * height ) );\n\t\t\t\trenderer.copyTextureToTexture( pathTracer.outputTarget, lowResTarget );\n\n\t\t\t}\n\n\t\t\tpathTracer.setSize( width, height );\n\n\t\t}\n\n\t\tif ( ! lowResMode && pathTracer.samples >= minSamples ) {\n\n\t\t\tthis._fadeState += delta / this.fadeDuration;\n\t\t\tthis._fadeState = Math.min( 1.0, this._fadeState );\n\n\t\t}\n\n\n\t\t// update the samples\n\t\tif ( ! lowResMode || ( lowResMode && dynamicLowRes ) ) {\n\n\t\t\tpathTracer.lowResMode = lowResMode;\n\t\t\tpathTracer.update();\n\n\t\t}\n\n\n\t\t// render the content to the canvas\n\t\tconst opacity = ( lowResMode && dynamicLowRes ? 1.0 : this._fadeState );\n\n\t\trenderer.autoClear = dynamicLowRes ? true : opacity === 1.0;\n\t\tblitQuad.material.transition = dynamicLowRes ? opacity : 1.0;\n\t\tblitQuad.material.opacity = dynamicLowRes ? 1.0 : opacity;\n\t\tblitQuad.material.fromTexture = lowResTarget;\n\t\tblitQuad.material.texture = pathTracer.outputTarget;\n\t\tblitQuad.material.toneMapping = originalToneMapping;\n\t\tblitQuad.material.toneMappingExposure = originalExposure;\n\t\tblitQuad.render( renderer );\n\n\t\t// reset the renderer\n\t\trenderer.autoClear = originalAutoClear;\n\t\trenderer.toneMapping = originalToneMapping;\n\t\trenderer.toneMappingExposure = originalExposure;\n\t\trenderer.setRenderTarget( originalTarget );\n\n\t}\n\n\trenderTextureAtlas( layer = 0 ) {\n\n\t\tconst renderer = this._renderer;\n\t\tif ( ! renderer._initialized ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( ! this._atlasDebugQuad ) {\n\n\t\t\tthis._atlasDebugQuad = new FullScreenQuad( new AtlasDebugMaterial() );\n\n\t\t}\n\n\t\tconst quad = this._atlasDebugQuad;\n\t\tquad.material.texture = this.textureAtlas.texture;\n\t\tquad.material.layer = layer;\n\t\trenderer.setRenderTarget( null );\n\t\tquad.render( renderer );\n\n\t}\n\n\tdispose() {\n\n\t\tthis._pathTracer.dispose();\n\t\tthis._blitQuad.dispose();\n\t\tthis._lowResTarget.dispose();\n\t\tthis._envColorTexture.dispose();\n\t\tthis._backgroundColorTexture.dispose();\n\t\tthis._atlasDebugQuad?.dispose();\n\n\t}\n\n\tasync getDetailedSampleCount() {\n\n\t\tconst sampleCountTarget = this._pathTracer.sampleCountTarget;\n\t\tconst { width, height } = sampleCountTarget;\n\t\tconst renderer = this._renderer;\n\n\t\t// Create a stub \"render target\" with just textures field to read from the storage texture\n\t\tconst targetStub = { textures: [ sampleCountTarget ] };\n\n\t\tconst buffer = await renderer.readRenderTargetPixelsAsync( targetStub, 0, 0, width, height );\n\t\tconst uintBuffer = new Uint32Array( buffer.buffer );\n\n\t\t// copyTexture requires a multiple of 256 bytes for texelsPerRow\n\t\t// Hence a multiple of 64 u32 per row\n\t\tconst texelsPerRow = Math.ceil( width / 64 ) * 64;\n\n\t\t// Sum up all sample counts and divide by pixel count to get average samples per pixel\n\t\tlet totalSamples = 0;\n\t\tlet minSamples = Number.MAX_VALUE;\n\t\tlet maxSamples = - Number.MAX_VALUE;\n\t\tfor ( let i = 0, l = uintBuffer.length; i < l; i ++ ) {\n\n\t\t\t// Skip padding\n\t\t\tif ( i % texelsPerRow >= width ) {\n\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\t// Each entry contains sample count in lower bits and active flag in high bit\n\t\t\t// Mask out the active flag (0xF0000000) to get just the sample count\n\t\t\tconst samples = uintBuffer[ i ] & 0x0FFFFFFF;\n\n\t\t\ttotalSamples += samples;\n\t\t\tminSamples = Math.min( minSamples, samples );\n\t\t\tmaxSamples = Math.max( maxSamples, samples );\n\n\t\t}\n\n\t\treturn {\n\t\t\tmin: minSamples,\n\t\t\tmax: maxSamples,\n\t\t\tavg: Math.floor( totalSamples / ( width * height ) ),\n\t\t};\n\n\n\t}\n\n\t// Returns time since last reset in ms\n\tgetRenderTime() {\n\n\t\treturn this._resetTime;\n\n\t}\n\n}\n\nfunction convertToTexture( renderer, value, colorTexture ) {\n\n\tif ( ! value ) {\n\n\t\tconst clearAlpha = renderer.getClearAlpha();\n\t\trenderer.getClearColor( _color );\n\n\t\tcolorTexture.image.data[ 0 ] = _color.r * 255;\n\t\tcolorTexture.image.data[ 1 ] = _color.g * 255;\n\t\tcolorTexture.image.data[ 2 ] = _color.b * 255;\n\t\tcolorTexture.image.data[ 3 ] = clearAlpha * 255;\n\n\t\tcolorTexture.needsUpdate = true;\n\t\tvalue = colorTexture;\n\n\t} else if ( value.isColor ) {\n\n\t\tcolorTexture.image.data[ 0 ] = value.r * 255;\n\t\tcolorTexture.image.data[ 1 ] = value.g * 255;\n\t\tcolorTexture.image.data[ 2 ] = value.b * 255;\n\t\tcolorTexture.image.data[ 3 ] = 255;\n\t\tcolorTexture.needsUpdate = true;\n\t\tvalue = colorTexture;\n\n\t} else if ( value?.isCubeTexture ) {\n\n\t\tvalue = new CubeToEquirectGenerator( renderer ).generate( value );\n\n\t}\n\n\treturn value;\n\n}\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86],"mappings":"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"}