@zephyr3d/scene 0.9.26 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. package/README.md +60 -27
  2. package/dist/animation/animation_bank.js +634 -0
  3. package/dist/animation/animation_bank.js.map +1 -0
  4. package/dist/animation/animation_bank_gpu.js +256 -0
  5. package/dist/animation/animation_bank_gpu.js.map +1 -0
  6. package/dist/animation/animationset.js +146 -30
  7. package/dist/animation/animationset.js.map +1 -1
  8. package/dist/animation/cloth/gpu_cloth_component.js +406 -0
  9. package/dist/animation/cloth/gpu_cloth_component.js.map +1 -0
  10. package/dist/animation/cloth/gpu_cloth_system.js +332 -202
  11. package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
  12. package/dist/animation/gpu_animation_driver.js +289 -0
  13. package/dist/animation/gpu_animation_driver.js.map +1 -0
  14. package/dist/animation/joint_dynamics/collision.js +112 -1
  15. package/dist/animation/joint_dynamics/collision.js.map +1 -1
  16. package/dist/animation/joint_dynamics/controller.js +6 -0
  17. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  18. package/dist/animation/joint_dynamics/joint_dynamics_system.js +11 -0
  19. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  20. package/dist/animation/joint_dynamics/solver.js +50 -12
  21. package/dist/animation/joint_dynamics/solver.js.map +1 -1
  22. package/dist/animation/joint_dynamics/types.js.map +1 -1
  23. package/dist/animation/skeleton.js +300 -56
  24. package/dist/animation/skeleton.js.map +1 -1
  25. package/dist/animation/skin_palette_atlas.js +252 -0
  26. package/dist/animation/skin_palette_atlas.js.map +1 -0
  27. package/dist/animation/spring/multi_chain_spring_system.js +298 -38
  28. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  29. package/dist/animation/spring/spring_chain.js +2 -0
  30. package/dist/animation/spring/spring_chain.js.map +1 -1
  31. package/dist/animation/spring/spring_collider.js +159 -21
  32. package/dist/animation/spring/spring_collider.js.map +1 -1
  33. package/dist/animation/spring/spring_particle.js +1 -0
  34. package/dist/animation/spring/spring_particle.js.map +1 -1
  35. package/dist/animation/spring/spring_solver.js +173 -0
  36. package/dist/animation/spring/spring_solver.js.map +1 -0
  37. package/dist/animation/spring/spring_system.js +249 -24
  38. package/dist/animation/spring/spring_system.js.map +1 -1
  39. package/dist/animation/spring_modifier.js +32 -1
  40. package/dist/animation/spring_modifier.js.map +1 -1
  41. package/dist/app/app.js +26 -0
  42. package/dist/app/app.js.map +1 -1
  43. package/dist/app/engine.js +86 -15
  44. package/dist/app/engine.js.map +1 -1
  45. package/dist/app/gamepad.js +191 -0
  46. package/dist/app/gamepad.js.map +1 -0
  47. package/dist/app/inputactions.js +271 -0
  48. package/dist/app/inputactions.js.map +1 -0
  49. package/dist/app/inputmgr.js +331 -22
  50. package/dist/app/inputmgr.js.map +1 -1
  51. package/dist/app/loading.js +138 -0
  52. package/dist/app/loading.js.map +1 -0
  53. package/dist/app/pipelinecache.js +209 -0
  54. package/dist/app/pipelinecache.js.map +1 -0
  55. package/dist/app/runtimescript.js +25 -0
  56. package/dist/app/runtimescript.js.map +1 -1
  57. package/dist/app/scriptingsystem.js +54 -0
  58. package/dist/app/scriptingsystem.js.map +1 -1
  59. package/dist/app/scriptregistry.js +7 -2
  60. package/dist/app/scriptregistry.js.map +1 -1
  61. package/dist/asset/asset_manifest.js +59 -0
  62. package/dist/asset/asset_manifest.js.map +1 -0
  63. package/dist/asset/asset_preload.js +258 -0
  64. package/dist/asset/asset_preload.js.map +1 -0
  65. package/dist/asset/assetmanager.js +117 -65
  66. package/dist/asset/assetmanager.js.map +1 -1
  67. package/dist/asset/loaders/ktx2/basis/LICENSE +201 -0
  68. package/dist/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
  69. package/dist/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
  70. package/dist/asset/loaders/ktx2/basis_location.js +17 -0
  71. package/dist/asset/loaders/ktx2/basis_location.js.map +1 -0
  72. package/dist/asset/loaders/ktx2/ktx2_loader.js +88 -0
  73. package/dist/asset/loaders/ktx2/ktx2_loader.js.map +1 -0
  74. package/dist/asset/loaders/ktx2/ktx2_targets.js +118 -0
  75. package/dist/asset/loaders/ktx2/ktx2_targets.js.map +1 -0
  76. package/dist/asset/loaders/ktx2/transcoder_pool.js +259 -0
  77. package/dist/asset/loaders/ktx2/transcoder_pool.js.map +1 -0
  78. package/dist/asset/mesh_lod_builder.js +104 -0
  79. package/dist/asset/mesh_lod_builder.js.map +1 -0
  80. package/dist/asset/mesh_settings.js +111 -0
  81. package/dist/asset/mesh_settings.js.map +1 -0
  82. package/dist/asset/meshopt_decoder.js +18 -0
  83. package/dist/asset/meshopt_decoder.js.map +1 -0
  84. package/dist/asset/meshopt_simplifier.js +26 -0
  85. package/dist/asset/meshopt_simplifier.js.map +1 -0
  86. package/dist/asset/model.js +177 -3
  87. package/dist/asset/model.js.map +1 -1
  88. package/dist/asset/texture_settings.js +231 -0
  89. package/dist/asset/texture_settings.js.map +1 -0
  90. package/dist/asset/zmsh_binary.js +131 -0
  91. package/dist/asset/zmsh_binary.js.map +1 -0
  92. package/dist/asset/zsdf_binary.js +111 -0
  93. package/dist/asset/zsdf_binary.js.map +1 -0
  94. package/dist/blitter/bilateralblur.js +1 -2
  95. package/dist/blitter/bilateralblur.js.map +1 -1
  96. package/dist/blitter/gaussianblur.js +1 -6
  97. package/dist/blitter/gaussianblur.js.map +1 -1
  98. package/dist/camera/base.js +31 -10
  99. package/dist/camera/base.js.map +1 -1
  100. package/dist/camera/camera.js +178 -200
  101. package/dist/camera/camera.js.map +1 -1
  102. package/dist/camera/follow.js +342 -0
  103. package/dist/camera/follow.js.map +1 -0
  104. package/dist/camera/fps.js +9 -7
  105. package/dist/camera/fps.js.map +1 -1
  106. package/dist/camera/orbit.js +46 -19
  107. package/dist/camera/orbit.js.map +1 -1
  108. package/dist/index.d.ts +30475 -19865
  109. package/dist/index.js +67 -12
  110. package/dist/index.js.map +1 -1
  111. package/dist/material/blinn.js +3 -0
  112. package/dist/material/blinn.js.map +1 -1
  113. package/dist/material/eye.js +1 -1
  114. package/dist/material/eye.js.map +1 -1
  115. package/dist/material/hair.js +2 -3
  116. package/dist/material/hair.js.map +1 -1
  117. package/dist/material/hairstrand.js +235 -235
  118. package/dist/material/hairstrand.js.map +1 -1
  119. package/dist/material/lambert.js +4 -1
  120. package/dist/material/lambert.js.map +1 -1
  121. package/dist/material/material.js +362 -300
  122. package/dist/material/material.js.map +1 -1
  123. package/dist/material/meshmaterial.js +118 -45
  124. package/dist/material/meshmaterial.js.map +1 -1
  125. package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
  126. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  127. package/dist/material/mixins/lightmodel/lambert.js +1 -1
  128. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  129. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +34 -61
  130. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  131. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -2
  132. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  133. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +2 -1
  134. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  135. package/dist/material/mixins/lit.js +223 -83
  136. package/dist/material/mixins/lit.js.map +1 -1
  137. package/dist/material/mixins/pbr/common.js +31 -206
  138. package/dist/material/mixins/pbr/common.js.map +1 -1
  139. package/dist/material/mtoon.js +1 -1
  140. package/dist/material/mtoon.js.map +1 -1
  141. package/dist/material/pbrmr.js +3 -0
  142. package/dist/material/pbrmr.js.map +1 -1
  143. package/dist/material/pbrsg.js +3 -0
  144. package/dist/material/pbrsg.js.map +1 -1
  145. package/dist/material/sdf_debug.js +78 -0
  146. package/dist/material/sdf_debug.js.map +1 -0
  147. package/dist/material/shader/helper.js +733 -190
  148. package/dist/material/shader/helper.js.map +1 -1
  149. package/dist/material/shader/terrain_blend.js +204 -43
  150. package/dist/material/shader/terrain_blend.js.map +1 -1
  151. package/dist/material/skin.js +331 -297
  152. package/dist/material/skin.js.map +1 -1
  153. package/dist/material/skinprofile.js +1058 -0
  154. package/dist/material/skinprofile.js.map +1 -0
  155. package/dist/material/sss.js +353 -0
  156. package/dist/material/sss.js.map +1 -0
  157. package/dist/material/sss_kernel.js +265 -0
  158. package/dist/material/sss_kernel.js.map +1 -0
  159. package/dist/material/sssprofile.js +879 -0
  160. package/dist/material/sssprofile.js.map +1 -0
  161. package/dist/material/subsurfaceprofile.js +4 -8
  162. package/dist/material/subsurfaceprofile.js.map +1 -1
  163. package/dist/material/terrain-cm.js +464 -188
  164. package/dist/material/terrain-cm.js.map +1 -1
  165. package/dist/material/unlit.js +3 -0
  166. package/dist/material/unlit.js.map +1 -1
  167. package/dist/material/water.js +2009 -201
  168. package/dist/material/water.js.map +1 -1
  169. package/dist/node_modules/meshoptimizer/LICENSE +21 -0
  170. package/dist/node_modules/meshoptimizer/meshopt_decoder.js +197 -0
  171. package/dist/node_modules/meshoptimizer/meshopt_decoder.js.map +1 -0
  172. package/dist/node_modules/meshoptimizer/meshopt_simplifier.js +677 -0
  173. package/dist/node_modules/meshoptimizer/meshopt_simplifier.js.map +1 -0
  174. package/dist/physics/character.js +226 -0
  175. package/dist/physics/character.js.map +1 -0
  176. package/dist/physics/collider.js +209 -0
  177. package/dist/physics/collider.js.map +1 -0
  178. package/dist/physics/events.js +79 -0
  179. package/dist/physics/events.js.map +1 -0
  180. package/dist/physics/joint.js +272 -0
  181. package/dist/physics/joint.js.map +1 -0
  182. package/dist/physics/node_physics.js +234 -0
  183. package/dist/physics/node_physics.js.map +1 -0
  184. package/dist/physics/part.js +91 -0
  185. package/dist/physics/part.js.map +1 -0
  186. package/dist/physics/rigid_body.js +379 -0
  187. package/dist/physics/rigid_body.js.map +1 -0
  188. package/dist/physics/vehicle.js +335 -0
  189. package/dist/physics/vehicle.js.map +1 -0
  190. package/dist/physics/world.js +25 -0
  191. package/dist/physics/world.js.map +1 -0
  192. package/dist/posteffect/bloom.js +49 -14
  193. package/dist/posteffect/bloom.js.map +1 -1
  194. package/dist/posteffect/motionblur.js +668 -63
  195. package/dist/posteffect/motionblur.js.map +1 -1
  196. package/dist/posteffect/posteffect.js +12 -1
  197. package/dist/posteffect/posteffect.js.map +1 -1
  198. package/dist/posteffect/postsss.js +572 -0
  199. package/dist/posteffect/postsss.js.map +1 -0
  200. package/dist/posteffect/sao.js +48 -50
  201. package/dist/posteffect/sao.js.map +1 -1
  202. package/dist/posteffect/skinsss.js +605 -355
  203. package/dist/posteffect/skinsss.js.map +1 -1
  204. package/dist/posteffect/ssgi.js +91 -162
  205. package/dist/posteffect/ssgi.js.map +1 -1
  206. package/dist/posteffect/ssr.js +3 -11
  207. package/dist/posteffect/ssr.js.map +1 -1
  208. package/dist/posteffect/sss.js +34 -15
  209. package/dist/posteffect/sss.js.map +1 -1
  210. package/dist/posteffect/taa.js +1 -0
  211. package/dist/posteffect/taa.js.map +1 -1
  212. package/dist/render/abuffer_oit.js +40 -39
  213. package/dist/render/abuffer_oit.js.map +1 -1
  214. package/dist/render/clipmap.js +328 -62
  215. package/dist/render/clipmap.js.map +1 -1
  216. package/dist/render/cluster_light.js +958 -224
  217. package/dist/render/cluster_light.js.map +1 -1
  218. package/dist/render/cull_visitor.js +26 -5
  219. package/dist/render/cull_visitor.js.map +1 -1
  220. package/dist/render/debug_views.js +37 -0
  221. package/dist/render/debug_views.js.map +1 -0
  222. package/dist/render/depthpass.js +5 -1
  223. package/dist/render/depthpass.js.map +1 -1
  224. package/dist/render/drawable_mixin.js +53 -6
  225. package/dist/render/drawable_mixin.js.map +1 -1
  226. package/dist/render/dualdepthpeeling_oit.js +53 -53
  227. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  228. package/dist/render/envlight.js +196 -113
  229. package/dist/render/envlight.js.map +1 -1
  230. package/dist/render/fbm_wavegenerator.js +8 -13
  231. package/dist/render/fbm_wavegenerator.js.map +1 -1
  232. package/dist/render/fft_wavegenerator.js +268 -136
  233. package/dist/render/fft_wavegenerator.js.map +1 -1
  234. package/dist/render/gerstner_wavegenerator.js +113 -28
  235. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  236. package/dist/render/gi/probe_volume.js +1334 -0
  237. package/dist/render/gi/probe_volume.js.map +1 -0
  238. package/dist/render/gi/scene_gi.js +282 -0
  239. package/dist/render/gi/scene_gi.js.map +1 -0
  240. package/dist/render/gi/voxel_atlas.js +198 -0
  241. package/dist/render/gi/voxel_atlas.js.map +1 -0
  242. package/dist/render/gi/voxel_lighting.js +652 -0
  243. package/dist/render/gi/voxel_lighting.js.map +1 -0
  244. package/dist/render/gi/voxel_scene.js +642 -0
  245. package/dist/render/gi/voxel_scene.js.map +1 -0
  246. package/dist/render/gi/voxelize_pass.js +223 -0
  247. package/dist/render/gi/voxelize_pass.js.map +1 -0
  248. package/dist/render/globalbindgroup_allocator.js +3 -2
  249. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  250. package/dist/render/gpu_picking.js +9 -36
  251. package/dist/render/gpu_picking.js.map +1 -1
  252. package/dist/render/hzb.js +80 -22
  253. package/dist/render/hzb.js.map +1 -1
  254. package/dist/render/instance_culling.js +499 -0
  255. package/dist/render/instance_culling.js.map +1 -0
  256. package/dist/render/lightpass.js +23 -9
  257. package/dist/render/lightpass.js.map +1 -1
  258. package/dist/render/lod.js +46 -0
  259. package/dist/render/lod.js.map +1 -0
  260. package/dist/render/oit.js +11 -11
  261. package/dist/render/oit.js.map +1 -1
  262. package/dist/render/primitive.js +301 -9
  263. package/dist/render/primitive.js.map +1 -1
  264. package/dist/render/primitive_readback.js +209 -0
  265. package/dist/render/primitive_readback.js.map +1 -0
  266. package/dist/render/render_queue.js +198 -11
  267. package/dist/render/render_queue.js.map +1 -1
  268. package/dist/render/renderer.js +14 -7
  269. package/dist/render/renderer.js.map +1 -1
  270. package/dist/render/rendergraph/blackboard.js +15 -1
  271. package/dist/render/rendergraph/blackboard.js.map +1 -1
  272. package/dist/render/rendergraph/executor.js +136 -0
  273. package/dist/render/rendergraph/executor.js.map +1 -1
  274. package/dist/render/rendergraph/forward_plus_builder.js +585 -59
  275. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  276. package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
  277. package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
  278. package/dist/render/rendergraph/history_resources.js +8 -1
  279. package/dist/render/rendergraph/history_resources.js.map +1 -1
  280. package/dist/render/rendergraph/scene_render_context.js +31 -2
  281. package/dist/render/rendergraph/scene_render_context.js.map +1 -1
  282. package/dist/render/rendergraph/types.js.map +1 -1
  283. package/dist/render/renderpass.js +28 -5
  284. package/dist/render/renderpass.js.map +1 -1
  285. package/dist/render/sdf/box_allocator.js +98 -0
  286. package/dist/render/sdf/box_allocator.js.map +1 -0
  287. package/dist/render/sdf/global_sdf.js +865 -0
  288. package/dist/render/sdf/global_sdf.js.map +1 -0
  289. package/dist/render/sdf/scene_sdf.js +562 -0
  290. package/dist/render/sdf/scene_sdf.js.map +1 -0
  291. package/dist/render/sdf/sdf_atlas.js +227 -0
  292. package/dist/render/sdf/sdf_atlas.js.map +1 -0
  293. package/dist/render/sdf/sdf_programs.js +42 -0
  294. package/dist/render/sdf/sdf_programs.js.map +1 -0
  295. package/dist/render/sdf/sdf_view.js +199 -0
  296. package/dist/render/sdf/sdf_view.js.map +1 -0
  297. package/dist/render/sdf/waterline.js +610 -0
  298. package/dist/render/sdf/waterline.js.map +1 -0
  299. package/dist/render/shadow_mask_pass.js +142 -25
  300. package/dist/render/shadow_mask_pass.js.map +1 -1
  301. package/dist/render/shore_wave_generator.js +1193 -0
  302. package/dist/render/shore_wave_generator.js.map +1 -0
  303. package/dist/render/sky.js +516 -86
  304. package/dist/render/sky.js.map +1 -1
  305. package/dist/render/transmission_thickness_pass.js +477 -0
  306. package/dist/render/transmission_thickness_pass.js.map +1 -0
  307. package/dist/render/underwater.js +524 -0
  308. package/dist/render/underwater.js.map +1 -0
  309. package/dist/render/virtualtexture/virtual_texture.js +1214 -0
  310. package/dist/render/virtualtexture/virtual_texture.js.map +1 -0
  311. package/dist/render/volumetric_cloud/cloud_common.js +472 -0
  312. package/dist/render/volumetric_cloud/cloud_common.js.map +1 -0
  313. package/dist/render/volumetric_cloud/cloud_noise.js +189 -0
  314. package/dist/render/volumetric_cloud/cloud_noise.js.map +1 -0
  315. package/dist/render/volumetric_cloud/debug_view.js +131 -0
  316. package/dist/render/volumetric_cloud/debug_view.js.map +1 -0
  317. package/dist/render/volumetric_cloud/resources.js +380 -0
  318. package/dist/render/volumetric_cloud/resources.js.map +1 -0
  319. package/dist/render/volumetric_cloud/sky_cache.js +380 -0
  320. package/dist/render/volumetric_cloud/sky_cache.js.map +1 -0
  321. package/dist/render/volumetric_cloud/volumetric_cloud.js +318 -0
  322. package/dist/render/volumetric_cloud/volumetric_cloud.js.map +1 -0
  323. package/dist/render/water_caustics.js +1195 -0
  324. package/dist/render/water_caustics.js.map +1 -0
  325. package/dist/render/water_foam.js +627 -0
  326. package/dist/render/water_foam.js.map +1 -0
  327. package/dist/render/water_interaction.js +1795 -0
  328. package/dist/render/water_interaction.js.map +1 -0
  329. package/dist/render/weightedblended_oit.js +36 -36
  330. package/dist/render/weightedblended_oit.js.map +1 -1
  331. package/dist/scene/basesprite.js +9 -4
  332. package/dist/scene/basesprite.js.map +1 -1
  333. package/dist/scene/batchgroup.js +108 -12
  334. package/dist/scene/batchgroup.js.map +1 -1
  335. package/dist/scene/environment.js +28 -7
  336. package/dist/scene/environment.js.map +1 -1
  337. package/dist/scene/foliage.js +1020 -0
  338. package/dist/scene/foliage.js.map +1 -0
  339. package/dist/scene/foliage_buckets.js +147 -0
  340. package/dist/scene/foliage_buckets.js.map +1 -0
  341. package/dist/scene/foliage_mask.js +358 -0
  342. package/dist/scene/foliage_mask.js.map +1 -0
  343. package/dist/scene/hair.js +15 -4
  344. package/dist/scene/hair.js.map +1 -1
  345. package/dist/scene/light.js +179 -13
  346. package/dist/scene/light.js.map +1 -1
  347. package/dist/scene/mesh.js +327 -45
  348. package/dist/scene/mesh.js.map +1 -1
  349. package/dist/scene/meshdrawable.js +6 -0
  350. package/dist/scene/meshdrawable.js.map +1 -1
  351. package/dist/scene/msdftext.js +9 -3
  352. package/dist/scene/msdftext.js.map +1 -1
  353. package/dist/scene/msdftextsprite.js +9 -3
  354. package/dist/scene/msdftextsprite.js.map +1 -1
  355. package/dist/scene/particlesys.js +8 -2
  356. package/dist/scene/particlesys.js.map +1 -1
  357. package/dist/scene/physics_settings.js +157 -0
  358. package/dist/scene/physics_settings.js.map +1 -0
  359. package/dist/scene/scene.js +190 -44
  360. package/dist/scene/scene.js.map +1 -1
  361. package/dist/scene/scene_node.js +147 -6
  362. package/dist/scene/scene_node.js.map +1 -1
  363. package/dist/scene/terrain-cm/bladegrassmaterial.js +735 -0
  364. package/dist/scene/terrain-cm/bladegrassmaterial.js.map +1 -0
  365. package/dist/scene/terrain-cm/grass.js +881 -42
  366. package/dist/scene/terrain-cm/grass.js.map +1 -1
  367. package/dist/scene/terrain-cm/grass_gpu.js +929 -0
  368. package/dist/scene/terrain-cm/grass_gpu.js.map +1 -0
  369. package/dist/scene/terrain-cm/grassmaterial.js +180 -9
  370. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  371. package/dist/scene/terrain-cm/terrain-cm.js +465 -36
  372. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  373. package/dist/scene/terrain-cm/terrain_gi_albedo.js +257 -0
  374. package/dist/scene/terrain-cm/terrain_gi_albedo.js.map +1 -0
  375. package/dist/scene/terrain-cm/terrain_rvt.js +395 -0
  376. package/dist/scene/terrain-cm/terrain_rvt.js.map +1 -0
  377. package/dist/scene/update_queue.js +54 -0
  378. package/dist/scene/update_queue.js.map +1 -0
  379. package/dist/scene/water.js +997 -96
  380. package/dist/scene/water.js.map +1 -1
  381. package/dist/scene/water_surface_sampler.js +324 -0
  382. package/dist/scene/water_surface_sampler.js.map +1 -0
  383. package/dist/scene/wind.js +317 -0
  384. package/dist/scene/wind.js.map +1 -0
  385. package/dist/shaders/atmosphere.js +388 -166
  386. package/dist/shaders/atmosphere.js.map +1 -1
  387. package/dist/shaders/fog.js +100 -32
  388. package/dist/shaders/fog.js.map +1 -1
  389. package/dist/shaders/gi.js +365 -0
  390. package/dist/shaders/gi.js.map +1 -0
  391. package/dist/shaders/ltc_rect.js +202 -0
  392. package/dist/shaders/ltc_rect.js.map +1 -0
  393. package/dist/shaders/misc.js +1 -10
  394. package/dist/shaders/misc.js.map +1 -1
  395. package/dist/shaders/noise.js +5 -1
  396. package/dist/shaders/noise.js.map +1 -1
  397. package/dist/shaders/probes.js +309 -0
  398. package/dist/shaders/probes.js.map +1 -0
  399. package/dist/shaders/sdf.js +537 -0
  400. package/dist/shaders/sdf.js.map +1 -0
  401. package/dist/shaders/shadow.js +104 -70
  402. package/dist/shaders/shadow.js.map +1 -1
  403. package/dist/shaders/skin_brdf.js +243 -0
  404. package/dist/shaders/skin_brdf.js.map +1 -0
  405. package/dist/shaders/ssr.js +6 -159
  406. package/dist/shaders/ssr.js.map +1 -1
  407. package/dist/shaders/temporal.js +38 -27
  408. package/dist/shaders/temporal.js.map +1 -1
  409. package/dist/shaders/water.js +40 -87
  410. package/dist/shaders/water.js.map +1 -1
  411. package/dist/shaders/water_medium.js +42 -0
  412. package/dist/shaders/water_medium.js.map +1 -0
  413. package/dist/shadow/dom.js +110 -19
  414. package/dist/shadow/dom.js.map +1 -1
  415. package/dist/shadow/esm.js +3 -3
  416. package/dist/shadow/esm.js.map +1 -1
  417. package/dist/shadow/pcf_opt.js +15 -48
  418. package/dist/shadow/pcf_opt.js.map +1 -1
  419. package/dist/shadow/pcf_pd.js +15 -53
  420. package/dist/shadow/pcf_pd.js.map +1 -1
  421. package/dist/shadow/pcss.js +34 -9
  422. package/dist/shadow/pcss.js.map +1 -1
  423. package/dist/shadow/shadow_impl.js +3 -8
  424. package/dist/shadow/shadow_impl.js.map +1 -1
  425. package/dist/shadow/shadow_region.js +87 -49
  426. package/dist/shadow/shadow_region.js.map +1 -1
  427. package/dist/shadow/shadowmapper.js +93 -53
  428. package/dist/shadow/shadowmapper.js.map +1 -1
  429. package/dist/shadow/ssm.js +18 -72
  430. package/dist/shadow/ssm.js.map +1 -1
  431. package/dist/shadow/vsm.js +3 -3
  432. package/dist/shadow/vsm.js.map +1 -1
  433. package/dist/shapes/shape.js +44 -1
  434. package/dist/shapes/shape.js.map +1 -1
  435. package/dist/utility/buoyancy.js +287 -0
  436. package/dist/utility/buoyancy.js.map +1 -0
  437. package/dist/utility/physical.js +10 -1
  438. package/dist/utility/physical.js.map +1 -1
  439. package/dist/utility/pmrem.js +17 -43
  440. package/dist/utility/pmrem.js.map +1 -1
  441. package/dist/utility/sdf/bake.js +435 -0
  442. package/dist/utility/sdf/bake.js.map +1 -0
  443. package/dist/utility/sdf/bvh.js +576 -0
  444. package/dist/utility/sdf/bvh.js.map +1 -0
  445. package/dist/utility/serialization/manager.js +36 -6
  446. package/dist/utility/serialization/manager.js.map +1 -1
  447. package/dist/utility/serialization/scene/animation.js +77 -7
  448. package/dist/utility/serialization/scene/animation.js.map +1 -1
  449. package/dist/utility/serialization/scene/batch.js +11 -4
  450. package/dist/utility/serialization/scene/batch.js.map +1 -1
  451. package/dist/utility/serialization/scene/camera.js +140 -279
  452. package/dist/utility/serialization/scene/camera.js.map +1 -1
  453. package/dist/utility/serialization/scene/cloth.js +25 -0
  454. package/dist/utility/serialization/scene/cloth.js.map +1 -0
  455. package/dist/utility/serialization/scene/common.js +14 -6
  456. package/dist/utility/serialization/scene/common.js.map +1 -1
  457. package/dist/utility/serialization/scene/foliage.js +821 -0
  458. package/dist/utility/serialization/scene/foliage.js.map +1 -0
  459. package/dist/utility/serialization/scene/hair.js +11 -4
  460. package/dist/utility/serialization/scene/hair.js.map +1 -1
  461. package/dist/utility/serialization/scene/light.js +115 -7
  462. package/dist/utility/serialization/scene/light.js.map +1 -1
  463. package/dist/utility/serialization/scene/material.js +388 -220
  464. package/dist/utility/serialization/scene/material.js.map +1 -1
  465. package/dist/utility/serialization/scene/mesh.js +69 -4
  466. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  467. package/dist/utility/serialization/scene/node.js +140 -5
  468. package/dist/utility/serialization/scene/node.js.map +1 -1
  469. package/dist/utility/serialization/scene/node_physics.js +1318 -0
  470. package/dist/utility/serialization/scene/node_physics.js.map +1 -0
  471. package/dist/utility/serialization/scene/particle.js +11 -4
  472. package/dist/utility/serialization/scene/particle.js.map +1 -1
  473. package/dist/utility/serialization/scene/physics.js +120 -0
  474. package/dist/utility/serialization/scene/physics.js.map +1 -0
  475. package/dist/utility/serialization/scene/primitive.js +124 -10
  476. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  477. package/dist/utility/serialization/scene/scene.js +1687 -51
  478. package/dist/utility/serialization/scene/scene.js.map +1 -1
  479. package/dist/utility/serialization/scene/sprite.js +11 -4
  480. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  481. package/dist/utility/serialization/scene/terrain.js +163 -33
  482. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  483. package/dist/utility/serialization/scene/text.js +11 -4
  484. package/dist/utility/serialization/scene/text.js.map +1 -1
  485. package/dist/utility/serialization/scene/water.js +2473 -114
  486. package/dist/utility/serialization/scene/water.js.map +1 -1
  487. package/dist/utility/serialization/types.js.map +1 -1
  488. package/dist/utility/shprojector.js +97 -109
  489. package/dist/utility/shprojector.js.map +1 -1
  490. package/dist/utility/textures/foam.js +170 -0
  491. package/dist/utility/textures/foam.js.map +1 -0
  492. package/dist/utility/textures/ggxlut.js +17 -43
  493. package/dist/utility/textures/ggxlut.js.map +1 -1
  494. package/dist/utility/textures/ltcdata.js +4 -4
  495. package/dist/utility/textures/ltcdata.js.map +1 -1
  496. package/dist/utility/textures/ltclut.js +16 -6
  497. package/dist/utility/textures/ltclut.js.map +1 -1
  498. package/dist/utility/unsupported.js +24 -0
  499. package/dist/utility/unsupported.js.map +1 -0
  500. package/dist/values.js +13 -1
  501. package/dist/values.js.map +1 -1
  502. package/package.json +25 -12
  503. package/src/asset/loaders/ktx2/basis/LICENSE +201 -0
  504. package/src/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
  505. package/src/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
  506. package/src/asset/meshoptimizer/LICENSE +21 -0
@@ -0,0 +1,562 @@
1
+ import { makeObservable, Disposable, Vector3, AABB } from '@zephyr3d/base';
2
+ import { getEngine } from '../../app/api.js';
3
+ import { readZsdf, writeZsdf, getMeshSDFPath } from '../../asset/zsdf_binary.js';
4
+ import { SDF_ATLAS_BLOCK, MeshSDFAtlas } from './sdf_atlas.js';
5
+ import { GlobalSDF } from './global_sdf.js';
6
+ import { readPrimitiveTriangles } from '../primitive_readback.js';
7
+ import { bakeMeshSDF } from '../../utility/sdf/bake.js';
8
+
9
+ /** Fields given at run time, by the key their primitive takes part under; shared by every scene. */ const runtimeFields = new Map();
10
+ /** The key of each primitive given a field at run time. */ const runtimeKeys = new WeakMap();
11
+ let runtimeKeyCounter = 0;
12
+ /**
13
+ * A baked mesh field as loaded, shared by every instance of the mesh.
14
+ * @public
15
+ */ class MeshSDFAsset {
16
+ /**
17
+ * Asset path of the mesh; for a field given at run time (see
18
+ * {@link SceneSDF.setField}), a key of its own starting with `runtime:`.
19
+ */ meshPath;
20
+ /** `loading`, then `ready` with data, `missing` when nothing is baked, `failed` on a bad file. */ state;
21
+ header;
22
+ voxels;
23
+ /** Instances using it. */ refs;
24
+ /** Seconds of scene time it was last wanted, for eviction. */ lastWanted;
25
+ /** True once its file read has started. */ requested;
26
+ /** {@link MeshSDFAtlas.version} when it last did not fit, or -1; retried only after the atlas changes. */ failedVersion;
27
+ constructor(meshPath){
28
+ this.meshPath = meshPath;
29
+ this.requested = false;
30
+ this.failedVersion = -1;
31
+ this.state = 'loading';
32
+ this.header = null;
33
+ this.voxels = null;
34
+ this.refs = 0;
35
+ this.lastWanted = 0;
36
+ }
37
+ /** Bytes of voxel data. */ get byteSize() {
38
+ return this.voxels?.byteLength ?? 0;
39
+ }
40
+ }
41
+ /**
42
+ * Signed distance field data of a scene: tracks meshes whose effective {@link Mesh.sdfMode} is not
43
+ * `none` and streams their baked fields (from {@link getMeshSDFPath}, or given at run time via
44
+ * {@link SceneSDF.setField} / {@link SceneSDF.bakeField}) into a shared {@link MeshSDFAtlas},
45
+ * nearest the camera first, evicting least recently wanted. Changes are reported as dirty world
46
+ * boxes. Off by default.
47
+ *
48
+ * @public
49
+ */ class SceneSDF extends makeObservable(Disposable)() {
50
+ /** Distance from the camera within which fields are kept loaded, in world units. */ streamRadius;
51
+ /** Field files read at once. */ maxConcurrentLoads;
52
+ _atlasSize;
53
+ _atlasFullWarned;
54
+ /** Bytes uploaded to the atlas per frame. */ uploadBudget;
55
+ _scene;
56
+ _enabled;
57
+ _atlas;
58
+ _global;
59
+ _globalFailed;
60
+ _terrain;
61
+ /** Nodes attached since the last update, tracked then. */ _pendingAttach;
62
+ /** Meshes listened to, whether or not they take part. */ _tracked;
63
+ _instances;
64
+ _assets;
65
+ _loading;
66
+ _time;
67
+ _atlasFull;
68
+ _updates;
69
+ _camera;
70
+ constructor(scene){
71
+ super();
72
+ this._scene = scene;
73
+ this._enabled = false;
74
+ this._atlas = null;
75
+ this._global = null;
76
+ this._globalFailed = false;
77
+ this._terrain = null;
78
+ this._pendingAttach = new Set();
79
+ this._tracked = new Set();
80
+ this._instances = new Map();
81
+ this._assets = new Map();
82
+ this._loading = 0;
83
+ this._time = 0;
84
+ this._atlasFull = 0;
85
+ this._atlasFullWarned = false;
86
+ this._atlasSize = [
87
+ 512,
88
+ 256,
89
+ 256
90
+ ];
91
+ this._updates = 0;
92
+ this._camera = new Vector3();
93
+ this.streamRadius = 256;
94
+ this.maxConcurrentLoads = 4;
95
+ this.uploadBudget = 4 * 1024 * 1024;
96
+ }
97
+ get enabled() {
98
+ return this._enabled;
99
+ }
100
+ set enabled(val) {
101
+ val = !!val;
102
+ if (val === this._enabled) {
103
+ return;
104
+ }
105
+ this._enabled = val;
106
+ const root = this._scene.rootNode;
107
+ if (val) {
108
+ root.on('nodeattached', this.onNodeAttached, this);
109
+ root.on('noderemoved', this.onNodeRemoved, this);
110
+ root.on('visiblechanged', this.onVisibleChanged, this);
111
+ this.collect(root);
112
+ } else {
113
+ root.off('nodeattached', this.onNodeAttached, this);
114
+ root.off('noderemoved', this.onNodeRemoved, this);
115
+ root.off('visiblechanged', this.onVisibleChanged, this);
116
+ this._pendingAttach.clear();
117
+ for (const mesh of [
118
+ ...this._tracked
119
+ ]){
120
+ this.untrack(mesh);
121
+ }
122
+ this._assets.clear();
123
+ this._atlas?.dispose();
124
+ this._atlas = null;
125
+ this._global?.dispose();
126
+ this._global = null;
127
+ this._globalFailed = false;
128
+ this._terrain = null;
129
+ }
130
+ }
131
+ /**
132
+ * Voxels per axis of the shared half-float atlas; 512×256×256 (64 MB) by default. Fields that
133
+ * do not fit are left out with a warning. Changing it empties the atlas.
134
+ */ get atlasSize() {
135
+ return [
136
+ ...this._atlasSize
137
+ ];
138
+ }
139
+ set atlasSize(val) {
140
+ const size = val.map((v)=>Math.max(SDF_ATLAS_BLOCK, Math.floor(v)));
141
+ if (size.some((v, i)=>v !== this._atlasSize[i])) {
142
+ this._atlasSize = size;
143
+ if (this._atlas) {
144
+ for (const asset of this._assets.values()){
145
+ if (this._atlas.getSlot(asset)) {
146
+ this.dirtyAsset(asset);
147
+ }
148
+ }
149
+ this._atlas.dispose();
150
+ this._atlas = null;
151
+ }
152
+ this._atlasFull = 0;
153
+ this._atlasFullWarned = false;
154
+ }
155
+ }
156
+ /** The atlas of resident fields, created when first needed. */ get atlas() {
157
+ if (!this._atlas) {
158
+ this._atlas = new MeshSDFAtlas(this._atlasSize);
159
+ }
160
+ return this._atlas;
161
+ }
162
+ /**
163
+ * The clipmap field built from the static instances and the terrain, or null
164
+ * where it cannot be built (WebGL2) or while disabled.
165
+ */ get global() {
166
+ if (this._globalFailed) {
167
+ return null;
168
+ }
169
+ if (!this._global && this._enabled && GlobalSDF.isSupported()) {
170
+ this._global = new GlobalSDF(this);
171
+ }
172
+ return this._global;
173
+ }
174
+ /** Instances taking part, static and dynamic. */ get instances() {
175
+ return this._instances.values();
176
+ }
177
+ /** True when the instance's field is in the atlas and on the GPU. */ isReady(instance) {
178
+ return !!instance.asset && instance.asset.state === 'ready' && !!this._atlas?.isReady(instance.asset);
179
+ }
180
+ getStats() {
181
+ const stats = {
182
+ instances: this._instances.size,
183
+ staticInstances: 0,
184
+ dynamicInstances: 0,
185
+ readyInstances: 0,
186
+ assets: this._assets.size,
187
+ assetsLoading: 0,
188
+ assetsMissing: 0,
189
+ assetsFailed: 0,
190
+ assetsResident: this._atlas?.count ?? 0,
191
+ atlasSize: this._atlas ? [
192
+ ...this._atlas.size
193
+ ] : [
194
+ 0,
195
+ 0,
196
+ 0
197
+ ],
198
+ atlasOccupancy: this._atlas?.occupancy ?? 0,
199
+ pendingUploads: this._atlas?.pendingUploads ?? 0,
200
+ atlasFull: this._atlasFull,
201
+ updates: this._updates,
202
+ loadsInFlight: this._loading,
203
+ camera: [
204
+ this._camera.x,
205
+ this._camera.y,
206
+ this._camera.z
207
+ ]
208
+ };
209
+ for (const inst of this._instances.values()){
210
+ stats[inst.mode === 'static' ? 'staticInstances' : 'dynamicInstances']++;
211
+ stats.readyInstances += this.isReady(inst) ? 1 : 0;
212
+ }
213
+ for (const asset of this._assets.values()){
214
+ stats.assetsLoading += asset.state === 'loading' ? 1 : 0;
215
+ stats.assetsMissing += asset.state === 'missing' ? 1 : 0;
216
+ stats.assetsFailed += asset.state === 'failed' ? 1 : 0;
217
+ }
218
+ return stats;
219
+ }
220
+ /**
221
+ * Gives a primitive without a baked field asset (e.g. a code-built shape) a field at run time,
222
+ * in the primitive's local space as {@link bakeMeshSDF} makes it. Replaces any earlier one and
223
+ * is shared by every scene.
224
+ */ setField(primitive, sdf) {
225
+ let key = runtimeKeys.get(primitive);
226
+ if (!key) {
227
+ key = `runtime:${++runtimeKeyCounter}`;
228
+ runtimeKeys.set(primitive, key);
229
+ }
230
+ const { header, voxels } = readZsdf(writeZsdf(sdf));
231
+ runtimeFields.set(key, {
232
+ header,
233
+ voxels
234
+ });
235
+ this.invalidate(key);
236
+ for (const mesh of this._tracked){
237
+ if (mesh.primitive === primitive) {
238
+ this.retrack(mesh);
239
+ }
240
+ }
241
+ }
242
+ /**
243
+ * Bakes a primitive's field on the CPU from its GPU-read-back triangles and applies it with
244
+ * {@link SceneSDF.setField}. For code-built primitives; may take a moment for large meshes.
245
+ */ async bakeField(primitive, options) {
246
+ const { positions, indices } = await readPrimitiveTriangles(primitive, 0);
247
+ this.setField(primitive, bakeMeshSDF(positions, indices, options));
248
+ }
249
+ /**
250
+ * Drops the loaded field of a mesh so it is read again, e.g. after it was
251
+ * rebaked. Without a path, every field that was missing or failed is retried.
252
+ */ invalidate(meshPath) {
253
+ for (const asset of this._assets.values()){
254
+ if (meshPath ? asset.meshPath === meshPath : asset.state === 'missing' || asset.state === 'failed') {
255
+ if (this._atlas?.getSlot(asset)) {
256
+ this._atlas.remove(asset);
257
+ this.dirtyAsset(asset);
258
+ }
259
+ asset.state = 'loading';
260
+ asset.requested = false;
261
+ asset.header = null;
262
+ asset.voxels = null;
263
+ }
264
+ }
265
+ }
266
+ /**
267
+ * Streams fields for a camera position: loads the nearest wanted, places loaded ones in the
268
+ * atlas (evicting when full) and uploads within the byte budget. Called once a frame.
269
+ */ update(cameraPos, deltaSeconds) {
270
+ if (!this._enabled) {
271
+ return;
272
+ }
273
+ this._time += deltaSeconds;
274
+ for (const node of this._pendingAttach){
275
+ if (node.attached && !node.disposed) {
276
+ this.collect(node);
277
+ }
278
+ }
279
+ this._pendingAttach.clear();
280
+ this._updates++;
281
+ this._camera.set(cameraPos);
282
+ // Wanted assets, nearest instance first
283
+ const wanted = new Map();
284
+ for (const inst of this._instances.values()){
285
+ this.refreshBounds(inst);
286
+ const asset = inst.asset;
287
+ if (!asset || asset.state === 'missing' || asset.state === 'failed') {
288
+ continue;
289
+ }
290
+ const d = distanceToBox(cameraPos, inst.bounds);
291
+ if (d <= this.streamRadius) {
292
+ const prev = wanted.get(asset);
293
+ wanted.set(asset, prev === undefined ? d : Math.min(prev, d));
294
+ }
295
+ }
296
+ const order = [
297
+ ...wanted.entries()
298
+ ].sort((a, b)=>a[1] - b[1]).map((e)=>e[0]);
299
+ const atlas = this.atlas;
300
+ for (const asset of order){
301
+ asset.lastWanted = this._time;
302
+ if (asset.state === 'loading') {
303
+ if (!asset.requested && this._loading < this.maxConcurrentLoads) {
304
+ this.load(asset);
305
+ }
306
+ continue;
307
+ }
308
+ if (asset.state === 'ready' && !atlas.getSlot(asset) && asset.failedVersion !== atlas.version) {
309
+ this.place(asset, wanted);
310
+ }
311
+ }
312
+ for (const key of atlas.flush(this.uploadBudget)){
313
+ this.dirtyAsset(key);
314
+ }
315
+ if (this._terrain && (!this._terrain.attached || this._terrain.scene !== this._scene)) {
316
+ this._terrain = null;
317
+ }
318
+ if (!this._globalFailed) {
319
+ try {
320
+ this.global?.update(cameraPos, this._terrain);
321
+ } catch (err) {
322
+ // A failed program fails every frame: report once and disable the global field
323
+ this._globalFailed = true;
324
+ console.error('SceneSDF: the global field is disabled after an error', err);
325
+ }
326
+ }
327
+ }
328
+ onDispose() {
329
+ super.onDispose();
330
+ this.enabled = false;
331
+ }
332
+ /** @internal */ place(asset, wanted) {
333
+ const atlas = this.atlas;
334
+ const res = asset.header.resolution;
335
+ if (atlas.add(asset, res, asset.voxels)) {
336
+ return;
337
+ }
338
+ // Evict resident fields that are not wanted, least recently wanted first,
339
+ // then wanted ones farther from the camera than this one, farthest first
340
+ const resident = [
341
+ ...this._assets.values()
342
+ ].filter((a)=>a !== asset && atlas.getSlot(a));
343
+ const dist = wanted.get(asset);
344
+ const nearer = (a)=>wanted.has(a) && wanted.get(a) <= dist;
345
+ const victims = [
346
+ ...resident.filter((a)=>!wanted.has(a)).sort((a, b)=>a.lastWanted - b.lastWanted),
347
+ ...resident.filter((a)=>wanted.get(a) > dist).sort((a, b)=>wanted.get(b) - wanted.get(a))
348
+ ];
349
+ // Skip evicting when even the nearer fields leave no room, or fields would thrash each frame
350
+ const fits = atlas.fits(res, resident.filter(nearer));
351
+ for (const victim of fits ? victims : []){
352
+ atlas.remove(victim);
353
+ this.dirtyAsset(victim);
354
+ if (atlas.add(asset, res, asset.voxels)) {
355
+ return;
356
+ }
357
+ }
358
+ asset.failedVersion = atlas.version;
359
+ this._atlasFull++;
360
+ if (!this._atlasFullWarned) {
361
+ this._atlasFullWarned = true;
362
+ let demand = 0;
363
+ for (const a of wanted.keys()){
364
+ if (a.header) {
365
+ demand += a.header.resolution.reduce((n, v)=>n * Math.ceil(v / SDF_ATLAS_BLOCK) * SDF_ATLAS_BLOCK, 1);
366
+ }
367
+ }
368
+ const capacity = atlas.size[0] * atlas.size[1] * atlas.size[2];
369
+ console.warn(`SceneSDF: the field of ${asset.meshPath} (${res.join('×')} voxels) does not fit the ${this._atlasSize.join('×')} atlas, which is ${Math.round(atlas.occupancy * 100)}% full; the loaded fields within SceneSDF.streamRadius (${this.streamRadius}) need ${(demand / capacity).toFixed(1)}× the atlas. It and any other field that does not fit are left out of the scene field. Raise SceneSDF.atlasSize, lower SceneSDF.streamRadius or bake meshes at a lower resolution scale.`);
370
+ }
371
+ }
372
+ /** @internal */ load(asset) {
373
+ asset.requested = true;
374
+ const given = runtimeFields.get(asset.meshPath);
375
+ if (given) {
376
+ asset.header = given.header;
377
+ asset.voxels = given.voxels;
378
+ asset.state = 'ready';
379
+ return;
380
+ }
381
+ this._loading++;
382
+ const vfs = getEngine().VFS;
383
+ const path = getMeshSDFPath(asset.meshPath);
384
+ (async ()=>{
385
+ if (!await vfs.exists(path)) {
386
+ return 'missing';
387
+ }
388
+ const { header, voxels } = readZsdf(await vfs.readFile(path, {
389
+ encoding: 'binary'
390
+ }));
391
+ asset.header = header;
392
+ asset.voxels = voxels;
393
+ return 'ready';
394
+ })().then((state)=>{
395
+ this._loading--;
396
+ asset.state = state;
397
+ }, (err)=>{
398
+ this._loading--;
399
+ asset.state = 'failed';
400
+ console.warn(`SceneSDF: cannot read the field of ${asset.meshPath}: ${err}`);
401
+ });
402
+ }
403
+ /** @internal */ collect(root) {
404
+ root.iterate((node)=>{
405
+ if (node.isMesh()) {
406
+ this.track(node);
407
+ } else if (node.isClipmapTerrain() && !this._terrain) {
408
+ this._terrain = node;
409
+ }
410
+ return false;
411
+ });
412
+ }
413
+ /** @internal */ onNodeAttached(node) {
414
+ // Deferred to the next update: a node constructed with a parent attaches from the base
415
+ // constructor, before the derived class is set up
416
+ this._pendingAttach.add(node);
417
+ }
418
+ /** @internal */ onNodeRemoved(node) {
419
+ this._pendingAttach.delete(node);
420
+ node.iterate((child)=>{
421
+ if (child.isMesh()) {
422
+ this.untrack(child);
423
+ }
424
+ return false;
425
+ });
426
+ }
427
+ /** @internal */ track(mesh) {
428
+ if (!this._tracked.has(mesh)) {
429
+ this._tracked.add(mesh);
430
+ mesh.on('sdfmode_changed', this.onMeshChanged, this);
431
+ mesh.on('primitive_changed', this.onPrimitiveChanged, this);
432
+ }
433
+ this.retrack(mesh);
434
+ }
435
+ /** @internal */ onVisibleChanged(node) {
436
+ // Bubbles to the root from the node whose show state changed
437
+ node.iterate((child)=>{
438
+ if (child.isMesh() && this._tracked.has(child)) {
439
+ this.retrack(child);
440
+ }
441
+ return false;
442
+ });
443
+ }
444
+ /** Places a tracked mesh again after its mode, primitive, parentage or visibility changed. @internal */ retrack(mesh) {
445
+ const mode = mesh.attached && !mesh.hidden ? mesh.effectiveSDFMode : 'none';
446
+ const primitive = mesh.primitive;
447
+ const path = primitive ? getEngine().resourceManager.getAssetId(primitive) : null;
448
+ // A field given at run time wins over a baked one
449
+ const runtimeKey = primitive ? runtimeKeys.get(primitive) : undefined;
450
+ const meshPath = runtimeKey && runtimeFields.has(runtimeKey) ? runtimeKey : path && path.toLowerCase().endsWith('.zmsh') ? path : null;
451
+ const prev = this._instances.get(mesh);
452
+ if (prev && prev.mode === mode && prev.asset?.meshPath === (meshPath ?? undefined)) {
453
+ return;
454
+ }
455
+ if (prev) {
456
+ this.dropInstance(prev);
457
+ }
458
+ if (mode === 'none') {
459
+ if (prev) {
460
+ this._instances.delete(mesh);
461
+ }
462
+ return;
463
+ }
464
+ const inst = {
465
+ mesh,
466
+ mode,
467
+ asset: meshPath ? this.acquire(meshPath) : null,
468
+ bounds: emptyBox()
469
+ };
470
+ this.refreshBounds(inst);
471
+ this._instances.set(mesh, inst);
472
+ if (this.isReady(inst)) {
473
+ this.emitBounds(inst.bounds);
474
+ }
475
+ }
476
+ /** @internal */ untrack(mesh) {
477
+ if (!this._tracked.delete(mesh)) {
478
+ return;
479
+ }
480
+ mesh.off('sdfmode_changed', this.onMeshChanged, this);
481
+ mesh.off('primitive_changed', this.onPrimitiveChanged, this);
482
+ const inst = this._instances.get(mesh);
483
+ if (inst) {
484
+ this.dropInstance(inst);
485
+ this._instances.delete(mesh);
486
+ }
487
+ }
488
+ /** @internal */ dropInstance(inst) {
489
+ if (this.isReady(inst)) {
490
+ this.emitBounds(inst.bounds);
491
+ }
492
+ const asset = inst.asset;
493
+ if (asset && --asset.refs <= 0) {
494
+ this._atlas?.remove(asset);
495
+ this._assets.delete(asset.meshPath);
496
+ }
497
+ }
498
+ /** @internal */ acquire(meshPath) {
499
+ let asset = this._assets.get(meshPath);
500
+ if (!asset) {
501
+ asset = new MeshSDFAsset(meshPath);
502
+ this._assets.set(meshPath, asset);
503
+ }
504
+ asset.refs++;
505
+ return asset;
506
+ }
507
+ /** @internal */ onMeshChanged(mesh) {
508
+ this.retrack(mesh);
509
+ }
510
+ /** @internal */ onPrimitiveChanged() {
511
+ // The event carries the primitive, not the mesh: recheck all; primitives change rarely
512
+ for (const mesh of this._tracked){
513
+ this.retrack(mesh);
514
+ }
515
+ }
516
+ /** World bounds of the instance; a static one that moved dirties both boxes. @internal */ refreshBounds(inst) {
517
+ const bv = inst.mesh.getWorldBoundingVolume();
518
+ if (!bv) {
519
+ return;
520
+ }
521
+ const box = bv.toAABB();
522
+ const b = inst.bounds;
523
+ // equalsTo's tolerance scales with the values, so test emptiness (infinite box) first
524
+ const wasValid = b.minPoint.x <= b.maxPoint.x;
525
+ if (wasValid && b.minPoint.equalsTo(box.minPoint) && b.maxPoint.equalsTo(box.maxPoint)) {
526
+ return;
527
+ }
528
+ if (inst.mode === 'static' && this.isReady(inst)) {
529
+ if (wasValid) {
530
+ this.emitBounds(b);
531
+ }
532
+ this.emitBounds(box);
533
+ }
534
+ b.minPoint.set(box.minPoint);
535
+ b.maxPoint.set(box.maxPoint);
536
+ }
537
+ /** @internal */ dirtyAsset(asset) {
538
+ for (const inst of this._instances.values()){
539
+ if (inst.asset === asset) {
540
+ this.emitBounds(inst.bounds);
541
+ }
542
+ }
543
+ }
544
+ /** @internal */ emitBounds(box) {
545
+ if (box.minPoint.x <= box.maxPoint.x) {
546
+ this._global?.markDirty(box.minPoint, box.maxPoint);
547
+ this.dispatchEvent('dirty', box.minPoint, box.maxPoint);
548
+ }
549
+ }
550
+ }
551
+ function emptyBox() {
552
+ return new AABB(new Vector3(Infinity, Infinity, Infinity), new Vector3(-Infinity, -Infinity, -Infinity));
553
+ }
554
+ function distanceToBox(p, box) {
555
+ const dx = Math.max(box.minPoint.x - p.x, 0, p.x - box.maxPoint.x);
556
+ const dy = Math.max(box.minPoint.y - p.y, 0, p.y - box.maxPoint.y);
557
+ const dz = Math.max(box.minPoint.z - p.z, 0, p.z - box.maxPoint.z);
558
+ return Math.hypot(dx, dy, dz);
559
+ }
560
+
561
+ export { MeshSDFAsset, SceneSDF };
562
+ //# sourceMappingURL=scene_sdf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene_sdf.js","sources":["../../../src/render/sdf/scene_sdf.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { AABB, Disposable, makeObservable, Vector3 } from '@zephyr3d/base';\r\nimport type { Mesh } from '../../scene/mesh';\r\nimport type { Scene } from '../../scene/scene';\r\nimport type { SceneNode } from '../../scene/scene_node';\r\nimport { getEngine } from '../../app/api';\r\nimport { getMeshSDFPath, readZsdf, writeZsdf } from '../../asset/zsdf_binary';\r\nimport type { ZsdfHeader } from '../../asset/zsdf_binary';\r\nimport { MeshSDFAtlas, SDF_ATLAS_BLOCK } from './sdf_atlas';\r\nimport { GlobalSDF } from './global_sdf';\r\nimport type { ClipmapTerrain } from '../../scene/terrain-cm/terrain-cm';\r\nimport type { Primitive } from '../primitive';\r\nimport { readPrimitiveTriangles } from '../primitive_readback';\r\nimport type { MeshSDFBakeOptions, MeshSDFData } from '../../utility/sdf/bake';\r\nimport { bakeMeshSDF } from '../../utility/sdf/bake';\r\n\r\n/** A field given at run time rather than read from a baked file, see {@link SceneSDF.setField}. */\r\ninterface RuntimeField {\r\n header: ZsdfHeader;\r\n voxels: Uint16Array<ArrayBuffer>;\r\n}\r\n\r\n/** Fields given at run time, by the key their primitive takes part under; shared by every scene. */\r\nconst runtimeFields = new Map<string, RuntimeField>();\r\n/** The key of each primitive given a field at run time. */\r\nconst runtimeKeys = new WeakMap<Primitive, string>();\r\nlet runtimeKeyCounter = 0;\r\n\r\n/**\r\n * A baked mesh field as loaded, shared by every instance of the mesh.\r\n * @public\r\n */\r\nexport class MeshSDFAsset {\r\n /**\r\n * Asset path of the mesh; for a field given at run time (see\r\n * {@link SceneSDF.setField}), a key of its own starting with `runtime:`.\r\n */\r\n readonly meshPath: string;\r\n /** `loading`, then `ready` with data, `missing` when nothing is baked, `failed` on a bad file. */\r\n state: 'loading' | 'ready' | 'missing' | 'failed';\r\n header: Nullable<ZsdfHeader>;\r\n voxels: Nullable<Uint16Array<ArrayBuffer>>;\r\n /** Instances using it. */\r\n refs: number;\r\n /** Seconds of scene time it was last wanted, for eviction. */\r\n lastWanted: number;\r\n /** True once its file read has started. */\r\n requested: boolean;\r\n /** {@link MeshSDFAtlas.version} when it last did not fit, or -1; retried only after the atlas changes. */\r\n failedVersion: number;\r\n constructor(meshPath: string) {\r\n this.meshPath = meshPath;\r\n this.requested = false;\r\n this.failedVersion = -1;\r\n this.state = 'loading';\r\n this.header = null;\r\n this.voxels = null;\r\n this.refs = 0;\r\n this.lastWanted = 0;\r\n }\r\n /** Bytes of voxel data. */\r\n get byteSize() {\r\n return this.voxels?.byteLength ?? 0;\r\n }\r\n}\r\n\r\n/**\r\n * A mesh taking part in the scene field.\r\n * @public\r\n */\r\nexport interface SDFInstance {\r\n readonly mesh: Mesh;\r\n /** Resolved {@link Mesh.sdfMode}, never `none` or `auto` here. */\r\n mode: 'static' | 'dynamic';\r\n /** Shared field data; null for a mesh without a primitive asset. */\r\n asset: Nullable<MeshSDFAsset>;\r\n /** World bounds at the last update. */\r\n readonly bounds: AABB;\r\n}\r\n\r\n/**\r\n * Counters of a {@link SceneSDF}, for tools and debugging.\r\n * @public\r\n */\r\nexport interface SceneSDFStats {\r\n instances: number;\r\n staticInstances: number;\r\n dynamicInstances: number;\r\n /** Instances whose field is in the atlas and uploaded. */\r\n readyInstances: number;\r\n assets: number;\r\n assetsLoading: number;\r\n assetsMissing: number;\r\n assetsFailed: number;\r\n assetsResident: number;\r\n atlasSize: [number, number, number];\r\n atlasOccupancy: number;\r\n pendingUploads: number;\r\n /** Times a wanted field did not fit even after evicting. */\r\n atlasFull: number;\r\n /** Calls of {@link SceneSDF.update} since enabled. */\r\n updates: number;\r\n /** Field files being read now. */\r\n loadsInFlight: number;\r\n /** Camera position of the last update. */\r\n camera: [number, number, number];\r\n}\r\n\r\ntype SceneSDFEvents = {\r\n /**\r\n * The field changed inside a world box: an instance became ready, went away,\r\n * or a static one moved. A global field rebuilds the region.\r\n */\r\n dirty: [min: Vector3, max: Vector3];\r\n};\r\n\r\n/**\r\n * Signed distance field data of a scene: tracks meshes whose effective {@link Mesh.sdfMode} is not\r\n * `none` and streams their baked fields (from {@link getMeshSDFPath}, or given at run time via\r\n * {@link SceneSDF.setField} / {@link SceneSDF.bakeField}) into a shared {@link MeshSDFAtlas},\r\n * nearest the camera first, evicting least recently wanted. Changes are reported as dirty world\r\n * boxes. Off by default.\r\n *\r\n * @public\r\n */\r\nexport class SceneSDF extends makeObservable(Disposable)<SceneSDFEvents>() {\r\n /** Distance from the camera within which fields are kept loaded, in world units. */\r\n streamRadius: number;\r\n /** Field files read at once. */\r\n maxConcurrentLoads: number;\r\n private _atlasSize: [number, number, number];\r\n private _atlasFullWarned: boolean;\r\n /** Bytes uploaded to the atlas per frame. */\r\n uploadBudget: number;\r\n private readonly _scene: Scene;\r\n private _enabled: boolean;\r\n private _atlas: Nullable<MeshSDFAtlas>;\r\n private _global: Nullable<GlobalSDF>;\r\n private _globalFailed: boolean;\r\n private _terrain: Nullable<ClipmapTerrain>;\r\n /** Nodes attached since the last update, tracked then. */\r\n private readonly _pendingAttach: Set<SceneNode>;\r\n /** Meshes listened to, whether or not they take part. */\r\n private readonly _tracked: Set<Mesh>;\r\n private readonly _instances: Map<Mesh, SDFInstance>;\r\n private readonly _assets: Map<string, MeshSDFAsset>;\r\n private _loading: number;\r\n private _time: number;\r\n private _atlasFull: number;\r\n private _updates: number;\r\n private readonly _camera: Vector3;\r\n constructor(scene: Scene) {\r\n super();\r\n this._scene = scene;\r\n this._enabled = false;\r\n this._atlas = null;\r\n this._global = null;\r\n this._globalFailed = false;\r\n this._terrain = null;\r\n this._pendingAttach = new Set();\r\n this._tracked = new Set();\r\n this._instances = new Map();\r\n this._assets = new Map();\r\n this._loading = 0;\r\n this._time = 0;\r\n this._atlasFull = 0;\r\n this._atlasFullWarned = false;\r\n this._atlasSize = [512, 256, 256];\r\n this._updates = 0;\r\n this._camera = new Vector3();\r\n this.streamRadius = 256;\r\n this.maxConcurrentLoads = 4;\r\n this.uploadBudget = 4 * 1024 * 1024;\r\n }\r\n get enabled() {\r\n return this._enabled;\r\n }\r\n set enabled(val: boolean) {\r\n val = !!val;\r\n if (val === this._enabled) {\r\n return;\r\n }\r\n this._enabled = val;\r\n const root = this._scene.rootNode;\r\n if (val) {\r\n root.on('nodeattached', this.onNodeAttached, this);\r\n root.on('noderemoved', this.onNodeRemoved, this);\r\n root.on('visiblechanged', this.onVisibleChanged, this);\r\n this.collect(root);\r\n } else {\r\n root.off('nodeattached', this.onNodeAttached, this);\r\n root.off('noderemoved', this.onNodeRemoved, this);\r\n root.off('visiblechanged', this.onVisibleChanged, this);\r\n this._pendingAttach.clear();\r\n for (const mesh of [...this._tracked]) {\r\n this.untrack(mesh);\r\n }\r\n this._assets.clear();\r\n this._atlas?.dispose();\r\n this._atlas = null;\r\n this._global?.dispose();\r\n this._global = null;\r\n this._globalFailed = false;\r\n this._terrain = null;\r\n }\r\n }\r\n /**\r\n * Voxels per axis of the shared half-float atlas; 512×256×256 (64 MB) by default. Fields that\r\n * do not fit are left out with a warning. Changing it empties the atlas.\r\n */\r\n get atlasSize(): [number, number, number] {\r\n return [...this._atlasSize];\r\n }\r\n set atlasSize(val: [number, number, number]) {\r\n const size = val.map((v) => Math.max(SDF_ATLAS_BLOCK, Math.floor(v))) as [number, number, number];\r\n if (size.some((v, i) => v !== this._atlasSize[i])) {\r\n this._atlasSize = size;\r\n if (this._atlas) {\r\n for (const asset of this._assets.values()) {\r\n if (this._atlas.getSlot(asset)) {\r\n this.dirtyAsset(asset);\r\n }\r\n }\r\n this._atlas.dispose();\r\n this._atlas = null;\r\n }\r\n this._atlasFull = 0;\r\n this._atlasFullWarned = false;\r\n }\r\n }\r\n /** The atlas of resident fields, created when first needed. */\r\n get atlas() {\r\n if (!this._atlas) {\r\n this._atlas = new MeshSDFAtlas(this._atlasSize);\r\n }\r\n return this._atlas;\r\n }\r\n /**\r\n * The clipmap field built from the static instances and the terrain, or null\r\n * where it cannot be built (WebGL2) or while disabled.\r\n */\r\n get global() {\r\n if (this._globalFailed) {\r\n return null;\r\n }\r\n if (!this._global && this._enabled && GlobalSDF.isSupported()) {\r\n this._global = new GlobalSDF(this);\r\n }\r\n return this._global;\r\n }\r\n /** Instances taking part, static and dynamic. */\r\n get instances(): IterableIterator<SDFInstance> {\r\n return this._instances.values();\r\n }\r\n /** True when the instance's field is in the atlas and on the GPU. */\r\n isReady(instance: SDFInstance) {\r\n return !!instance.asset && instance.asset.state === 'ready' && !!this._atlas?.isReady(instance.asset);\r\n }\r\n getStats(): SceneSDFStats {\r\n const stats: SceneSDFStats = {\r\n instances: this._instances.size,\r\n staticInstances: 0,\r\n dynamicInstances: 0,\r\n readyInstances: 0,\r\n assets: this._assets.size,\r\n assetsLoading: 0,\r\n assetsMissing: 0,\r\n assetsFailed: 0,\r\n assetsResident: this._atlas?.count ?? 0,\r\n atlasSize: this._atlas ? [...this._atlas.size] : [0, 0, 0],\r\n atlasOccupancy: this._atlas?.occupancy ?? 0,\r\n pendingUploads: this._atlas?.pendingUploads ?? 0,\r\n atlasFull: this._atlasFull,\r\n updates: this._updates,\r\n loadsInFlight: this._loading,\r\n camera: [this._camera.x, this._camera.y, this._camera.z]\r\n };\r\n for (const inst of this._instances.values()) {\r\n stats[inst.mode === 'static' ? 'staticInstances' : 'dynamicInstances']++;\r\n stats.readyInstances += this.isReady(inst) ? 1 : 0;\r\n }\r\n for (const asset of this._assets.values()) {\r\n stats.assetsLoading += asset.state === 'loading' ? 1 : 0;\r\n stats.assetsMissing += asset.state === 'missing' ? 1 : 0;\r\n stats.assetsFailed += asset.state === 'failed' ? 1 : 0;\r\n }\r\n return stats;\r\n }\r\n /**\r\n * Gives a primitive without a baked field asset (e.g. a code-built shape) a field at run time,\r\n * in the primitive's local space as {@link bakeMeshSDF} makes it. Replaces any earlier one and\r\n * is shared by every scene.\r\n */\r\n setField(primitive: Primitive, sdf: MeshSDFData) {\r\n let key = runtimeKeys.get(primitive);\r\n if (!key) {\r\n key = `runtime:${++runtimeKeyCounter}`;\r\n runtimeKeys.set(primitive, key);\r\n }\r\n const { header, voxels } = readZsdf(writeZsdf(sdf));\r\n runtimeFields.set(key, { header, voxels });\r\n this.invalidate(key);\r\n for (const mesh of this._tracked) {\r\n if (mesh.primitive === primitive) {\r\n this.retrack(mesh);\r\n }\r\n }\r\n }\r\n /**\r\n * Bakes a primitive's field on the CPU from its GPU-read-back triangles and applies it with\r\n * {@link SceneSDF.setField}. For code-built primitives; may take a moment for large meshes.\r\n */\r\n async bakeField(primitive: Primitive, options?: MeshSDFBakeOptions) {\r\n const { positions, indices } = await readPrimitiveTriangles(primitive, 0);\r\n this.setField(primitive, bakeMeshSDF(positions, indices, options));\r\n }\r\n /**\r\n * Drops the loaded field of a mesh so it is read again, e.g. after it was\r\n * rebaked. Without a path, every field that was missing or failed is retried.\r\n */\r\n invalidate(meshPath?: string) {\r\n for (const asset of this._assets.values()) {\r\n if (meshPath ? asset.meshPath === meshPath : asset.state === 'missing' || asset.state === 'failed') {\r\n if (this._atlas?.getSlot(asset)) {\r\n this._atlas.remove(asset);\r\n this.dirtyAsset(asset);\r\n }\r\n asset.state = 'loading';\r\n asset.requested = false;\r\n asset.header = null;\r\n asset.voxels = null;\r\n }\r\n }\r\n }\r\n /**\r\n * Streams fields for a camera position: loads the nearest wanted, places loaded ones in the\r\n * atlas (evicting when full) and uploads within the byte budget. Called once a frame.\r\n */\r\n update(cameraPos: Vector3, deltaSeconds: number) {\r\n if (!this._enabled) {\r\n return;\r\n }\r\n this._time += deltaSeconds;\r\n for (const node of this._pendingAttach) {\r\n if (node.attached && !node.disposed) {\r\n this.collect(node);\r\n }\r\n }\r\n this._pendingAttach.clear();\r\n this._updates++;\r\n this._camera.set(cameraPos);\r\n // Wanted assets, nearest instance first\r\n const wanted = new Map<MeshSDFAsset, number>();\r\n for (const inst of this._instances.values()) {\r\n this.refreshBounds(inst);\r\n const asset = inst.asset;\r\n if (!asset || asset.state === 'missing' || asset.state === 'failed') {\r\n continue;\r\n }\r\n const d = distanceToBox(cameraPos, inst.bounds);\r\n if (d <= this.streamRadius) {\r\n const prev = wanted.get(asset);\r\n wanted.set(asset, prev === undefined ? d : Math.min(prev, d));\r\n }\r\n }\r\n const order = [...wanted.entries()].sort((a, b) => a[1] - b[1]).map((e) => e[0]);\r\n const atlas = this.atlas;\r\n for (const asset of order) {\r\n asset.lastWanted = this._time;\r\n if (asset.state === 'loading') {\r\n if (!asset.requested && this._loading < this.maxConcurrentLoads) {\r\n this.load(asset);\r\n }\r\n continue;\r\n }\r\n if (asset.state === 'ready' && !atlas.getSlot(asset) && asset.failedVersion !== atlas.version) {\r\n this.place(asset, wanted);\r\n }\r\n }\r\n for (const key of atlas.flush(this.uploadBudget)) {\r\n this.dirtyAsset(key as MeshSDFAsset);\r\n }\r\n if (this._terrain && (!this._terrain.attached || this._terrain.scene !== this._scene)) {\r\n this._terrain = null;\r\n }\r\n if (!this._globalFailed) {\r\n try {\r\n this.global?.update(cameraPos, this._terrain);\r\n } catch (err) {\r\n // A failed program fails every frame: report once and disable the global field\r\n this._globalFailed = true;\r\n console.error('SceneSDF: the global field is disabled after an error', err);\r\n }\r\n }\r\n }\r\n protected onDispose() {\r\n super.onDispose();\r\n this.enabled = false;\r\n }\r\n /** @internal */\r\n private place(asset: MeshSDFAsset, wanted: Map<MeshSDFAsset, number>) {\r\n const atlas = this.atlas;\r\n const res = asset.header!.resolution;\r\n if (atlas.add(asset, res, asset.voxels!)) {\r\n return;\r\n }\r\n // Evict resident fields that are not wanted, least recently wanted first,\r\n // then wanted ones farther from the camera than this one, farthest first\r\n const resident = [...this._assets.values()].filter((a) => a !== asset && atlas.getSlot(a));\r\n const dist = wanted.get(asset)!;\r\n const nearer = (a: MeshSDFAsset) => wanted.has(a) && wanted.get(a)! <= dist;\r\n const victims = [\r\n ...resident.filter((a) => !wanted.has(a)).sort((a, b) => a.lastWanted - b.lastWanted),\r\n ...resident.filter((a) => wanted.get(a)! > dist).sort((a, b) => wanted.get(b)! - wanted.get(a)!)\r\n ];\r\n // Skip evicting when even the nearer fields leave no room, or fields would thrash each frame\r\n const fits = atlas.fits(res, resident.filter(nearer));\r\n for (const victim of fits ? victims : []) {\r\n atlas.remove(victim);\r\n this.dirtyAsset(victim);\r\n if (atlas.add(asset, res, asset.voxels!)) {\r\n return;\r\n }\r\n }\r\n asset.failedVersion = atlas.version;\r\n this._atlasFull++;\r\n if (!this._atlasFullWarned) {\r\n this._atlasFullWarned = true;\r\n let demand = 0;\r\n for (const a of wanted.keys()) {\r\n if (a.header) {\r\n demand += a.header.resolution.reduce(\r\n (n, v) => n * Math.ceil(v / SDF_ATLAS_BLOCK) * SDF_ATLAS_BLOCK,\r\n 1\r\n );\r\n }\r\n }\r\n const capacity = atlas.size[0] * atlas.size[1] * atlas.size[2];\r\n console.warn(\r\n `SceneSDF: the field of ${asset.meshPath} (${res.join('×')} voxels) does not fit the ${this._atlasSize.join('×')} atlas, which is ${Math.round(atlas.occupancy * 100)}% full; the loaded fields within SceneSDF.streamRadius (${this.streamRadius}) need ${(demand / capacity).toFixed(1)}× the atlas. It and any other field that does not fit are left out of the scene field. Raise SceneSDF.atlasSize, lower SceneSDF.streamRadius or bake meshes at a lower resolution scale.`\r\n );\r\n }\r\n }\r\n /** @internal */\r\n private load(asset: MeshSDFAsset) {\r\n asset.requested = true;\r\n const given = runtimeFields.get(asset.meshPath);\r\n if (given) {\r\n asset.header = given.header;\r\n asset.voxels = given.voxels;\r\n asset.state = 'ready';\r\n return;\r\n }\r\n this._loading++;\r\n const vfs = getEngine().VFS;\r\n const path = getMeshSDFPath(asset.meshPath);\r\n (async () => {\r\n if (!(await vfs.exists(path))) {\r\n return 'missing' as const;\r\n }\r\n const { header, voxels } = readZsdf((await vfs.readFile(path, { encoding: 'binary' })) as ArrayBuffer);\r\n asset.header = header;\r\n asset.voxels = voxels;\r\n return 'ready' as const;\r\n })().then(\r\n (state) => {\r\n this._loading--;\r\n asset.state = state;\r\n },\r\n (err) => {\r\n this._loading--;\r\n asset.state = 'failed';\r\n console.warn(`SceneSDF: cannot read the field of ${asset.meshPath}: ${err}`);\r\n }\r\n );\r\n }\r\n /** @internal */\r\n private collect(root: SceneNode) {\r\n root.iterate((node) => {\r\n if (node.isMesh()) {\r\n this.track(node);\r\n } else if (node.isClipmapTerrain() && !this._terrain) {\r\n this._terrain = node;\r\n }\r\n return false;\r\n });\r\n }\r\n /** @internal */\r\n private onNodeAttached(node: SceneNode) {\r\n // Deferred to the next update: a node constructed with a parent attaches from the base\r\n // constructor, before the derived class is set up\r\n this._pendingAttach.add(node);\r\n }\r\n /** @internal */\r\n private onNodeRemoved(node: SceneNode) {\r\n this._pendingAttach.delete(node);\r\n node.iterate((child) => {\r\n if (child.isMesh()) {\r\n this.untrack(child);\r\n }\r\n return false;\r\n });\r\n }\r\n /** @internal */\r\n private track(mesh: Mesh) {\r\n if (!this._tracked.has(mesh)) {\r\n this._tracked.add(mesh);\r\n mesh.on('sdfmode_changed', this.onMeshChanged, this);\r\n mesh.on('primitive_changed', this.onPrimitiveChanged, this);\r\n }\r\n this.retrack(mesh);\r\n }\r\n /** @internal */\r\n private onVisibleChanged(node: SceneNode) {\r\n // Bubbles to the root from the node whose show state changed\r\n node.iterate((child) => {\r\n if (child.isMesh() && this._tracked.has(child)) {\r\n this.retrack(child);\r\n }\r\n return false;\r\n });\r\n }\r\n /** Places a tracked mesh again after its mode, primitive, parentage or visibility changed. @internal */\r\n private retrack(mesh: Mesh) {\r\n const mode = mesh.attached && !mesh.hidden ? mesh.effectiveSDFMode : 'none';\r\n const primitive = mesh.primitive;\r\n const path = primitive ? getEngine().resourceManager.getAssetId(primitive) : null;\r\n // A field given at run time wins over a baked one\r\n const runtimeKey = primitive ? runtimeKeys.get(primitive) : undefined;\r\n const meshPath =\r\n runtimeKey && runtimeFields.has(runtimeKey)\r\n ? runtimeKey\r\n : path && path.toLowerCase().endsWith('.zmsh')\r\n ? path\r\n : null;\r\n const prev = this._instances.get(mesh);\r\n if (prev && prev.mode === mode && prev.asset?.meshPath === (meshPath ?? undefined)) {\r\n return;\r\n }\r\n if (prev) {\r\n this.dropInstance(prev);\r\n }\r\n if (mode === 'none') {\r\n if (prev) {\r\n this._instances.delete(mesh);\r\n }\r\n return;\r\n }\r\n const inst: SDFInstance = {\r\n mesh,\r\n mode,\r\n asset: meshPath ? this.acquire(meshPath) : null,\r\n bounds: emptyBox()\r\n };\r\n this.refreshBounds(inst);\r\n this._instances.set(mesh, inst);\r\n if (this.isReady(inst)) {\r\n this.emitBounds(inst.bounds);\r\n }\r\n }\r\n /** @internal */\r\n private untrack(mesh: Mesh) {\r\n if (!this._tracked.delete(mesh)) {\r\n return;\r\n }\r\n mesh.off('sdfmode_changed', this.onMeshChanged, this);\r\n mesh.off('primitive_changed', this.onPrimitiveChanged, this);\r\n const inst = this._instances.get(mesh);\r\n if (inst) {\r\n this.dropInstance(inst);\r\n this._instances.delete(mesh);\r\n }\r\n }\r\n /** @internal */\r\n private dropInstance(inst: SDFInstance) {\r\n if (this.isReady(inst)) {\r\n this.emitBounds(inst.bounds);\r\n }\r\n const asset = inst.asset;\r\n if (asset && --asset.refs <= 0) {\r\n this._atlas?.remove(asset);\r\n this._assets.delete(asset.meshPath);\r\n }\r\n }\r\n /** @internal */\r\n private acquire(meshPath: string) {\r\n let asset = this._assets.get(meshPath);\r\n if (!asset) {\r\n asset = new MeshSDFAsset(meshPath);\r\n this._assets.set(meshPath, asset);\r\n }\r\n asset.refs++;\r\n return asset;\r\n }\r\n /** @internal */\r\n private onMeshChanged(mesh: Mesh) {\r\n this.retrack(mesh);\r\n }\r\n /** @internal */\r\n private onPrimitiveChanged() {\r\n // The event carries the primitive, not the mesh: recheck all; primitives change rarely\r\n for (const mesh of this._tracked) {\r\n this.retrack(mesh);\r\n }\r\n }\r\n /** World bounds of the instance; a static one that moved dirties both boxes. @internal */\r\n private refreshBounds(inst: SDFInstance) {\r\n const bv = inst.mesh.getWorldBoundingVolume();\r\n if (!bv) {\r\n return;\r\n }\r\n const box = bv.toAABB();\r\n const b = inst.bounds;\r\n // equalsTo's tolerance scales with the values, so test emptiness (infinite box) first\r\n const wasValid = b.minPoint.x <= b.maxPoint.x;\r\n if (wasValid && b.minPoint.equalsTo(box.minPoint) && b.maxPoint.equalsTo(box.maxPoint)) {\r\n return;\r\n }\r\n if (inst.mode === 'static' && this.isReady(inst)) {\r\n if (wasValid) {\r\n this.emitBounds(b);\r\n }\r\n this.emitBounds(box);\r\n }\r\n b.minPoint.set(box.minPoint);\r\n b.maxPoint.set(box.maxPoint);\r\n }\r\n /** @internal */\r\n private dirtyAsset(asset: MeshSDFAsset) {\r\n for (const inst of this._instances.values()) {\r\n if (inst.asset === asset) {\r\n this.emitBounds(inst.bounds);\r\n }\r\n }\r\n }\r\n /** @internal */\r\n private emitBounds(box: AABB) {\r\n if (box.minPoint.x <= box.maxPoint.x) {\r\n this._global?.markDirty(box.minPoint, box.maxPoint);\r\n this.dispatchEvent('dirty', box.minPoint, box.maxPoint);\r\n }\r\n }\r\n}\r\n\r\nfunction emptyBox() {\r\n return new AABB(new Vector3(Infinity, Infinity, Infinity), new Vector3(-Infinity, -Infinity, -Infinity));\r\n}\r\n\r\nfunction distanceToBox(p: Vector3, box: AABB) {\r\n const dx = Math.max(box.minPoint.x - p.x, 0, p.x - box.maxPoint.x);\r\n const dy = Math.max(box.minPoint.y - p.y, 0, p.y - box.maxPoint.y);\r\n const dz = Math.max(box.minPoint.z - p.z, 0, p.z - box.maxPoint.z);\r\n return Math.hypot(dx, dy, dz);\r\n}\r\n"],"names":["runtimeFields","Map","runtimeKeys","WeakMap","runtimeKeyCounter","MeshSDFAsset","state","header","voxels","refs","lastWanted","requested","failedVersion","meshPath","byteSize","byteLength","SceneSDF","makeObservable","Disposable","streamRadius","maxConcurrentLoads","_atlasSize","_atlasFullWarned","uploadBudget","_scene","_enabled","_atlas","_global","_globalFailed","_terrain","_instances","_assets","_loading","_time","_atlasFull","_updates","_camera","scene","_pendingAttach","Set","_tracked","Vector3","enabled","val","root","rootNode","on","onNodeAttached","onNodeRemoved","onVisibleChanged","collect","off","clear","mesh","untrack","dispose","atlasSize","size","map","v","Math","max","SDF_ATLAS_BLOCK","floor","some","i","asset","values","getSlot","dirtyAsset","atlas","MeshSDFAtlas","global","GlobalSDF","isSupported","instances","isReady","instance","getStats","stats","staticInstances","dynamicInstances","readyInstances","assets","assetsLoading","assetsMissing","assetsFailed","assetsResident","count","atlasOccupancy","occupancy","pendingUploads","atlasFull","updates","loadsInFlight","camera","x","y","z","inst","mode","setField","primitive","sdf","key","get","set","readZsdf","writeZsdf","invalidate","retrack","bakeField","options","positions","indices","readPrimitiveTriangles","bakeMeshSDF","remove","update","cameraPos","deltaSeconds","node","attached","disposed","wanted","refreshBounds","d","distanceToBox","bounds","prev","undefined","min","order","entries","sort","a","b","e","load","version","place","flush","err","console","error","onDispose","res","resolution","add","resident","filter","dist","nearer","has","victims","fits","victim","demand","keys","reduce","n","ceil","capacity","warn","join","round","toFixed","given","vfs","getEngine","VFS","path","getMeshSDFPath","exists","readFile","encoding","then","iterate","isMesh","track","isClipmapTerrain","delete","child","onMeshChanged","onPrimitiveChanged","hidden","effectiveSDFMode","resourceManager","getAssetId","runtimeKey","toLowerCase","endsWith","dropInstance","acquire","emptyBox","emitBounds","bv","getWorldBoundingVolume","box","toAABB","wasValid","minPoint","maxPoint","equalsTo","markDirty","dispatchEvent","AABB","Infinity","p","dx","dy","dz","hypot"],"mappings":";;;;;;;;AAsBA,qGACA,MAAMA,aAAAA,GAAgB,IAAIC,GAAAA,EAAAA;AAC1B,4DACA,MAAMC,WAAAA,GAAc,IAAIC,OAAAA,EAAAA;AACxB,IAAIC,iBAAoB,GAAA,CAAA;AAExB;;;AAGC,IACM,MAAMC,YAAAA,CAAAA;AACX;;;AAGC,MACD,QAA0B;AAC1B,uGACAC,KAAkD;IAClDC,MAA6B;IAC7BC,MAA2C;AAC3C,+BACAC,IAAa;AACb,mEACAC,UAAmB;AACnB,gDACAC,SAAmB;AACnB,+GACAC,aAAsB;AACtB,IAAA,WAAA,CAAYC,QAAgB,CAAE;QAC5B,IAAI,CAACA,QAAQ,GAAGA,QAAAA;QAChB,IAAI,CAACF,SAAS,GAAG,KAAA;QACjB,IAAI,CAACC,aAAa,GAAG,EAAC;QACtB,IAAI,CAACN,KAAK,GAAG,SAAA;QACb,IAAI,CAACC,MAAM,GAAG,IAAA;QACd,IAAI,CAACC,MAAM,GAAG,IAAA;QACd,IAAI,CAACC,IAAI,GAAG,CAAA;QACZ,IAAI,CAACC,UAAU,GAAG,CAAA;AACpB;gCAEA,IAAII,QAAW,GAAA;AACb,QAAA,OAAO,IAAI,CAACN,MAAM,EAAEO,UAAc,IAAA,CAAA;AACpC;AACF;AAoDA;;;;;;;;IASO,MAAMC,QAAAA,SAAiBC,cAAeC,CAAAA,UAAAA,CAAAA,EAAAA,CAAAA;AAC3C,yFACAC,YAAqB;AACrB,qCACAC,kBAA2B;IACnBC,UAAqC;IACrCC,gBAA0B;AAClC,kDACAC,YAAqB;IACJC,MAAc;IACvBC,QAAkB;IAClBC,MAA+B;IAC/BC,OAA6B;IAC7BC,aAAuB;IACvBC,QAAmC;+DAE3C,cAAgD;8DAEhD,QAAqC;IACpBC,UAAmC;IACnCC,OAAmC;IAC5CC,QAAiB;IACjBC,KAAc;IACdC,UAAmB;IACnBC,QAAiB;IACRC,OAAiB;AAClC,IAAA,WAAA,CAAYC,KAAY,CAAE;QACxB,KAAK,EAAA;QACL,IAAI,CAACb,MAAM,GAAGa,KAAAA;QACd,IAAI,CAACZ,QAAQ,GAAG,KAAA;QAChB,IAAI,CAACC,MAAM,GAAG,IAAA;QACd,IAAI,CAACC,OAAO,GAAG,IAAA;QACf,IAAI,CAACC,aAAa,GAAG,KAAA;QACrB,IAAI,CAACC,QAAQ,GAAG,IAAA;QAChB,IAAI,CAACS,cAAc,GAAG,IAAIC,GAAAA,EAAAA;QAC1B,IAAI,CAACC,QAAQ,GAAG,IAAID,GAAAA,EAAAA;QACpB,IAAI,CAACT,UAAU,GAAG,IAAI7B,GAAAA,EAAAA;QACtB,IAAI,CAAC8B,OAAO,GAAG,IAAI9B,GAAAA,EAAAA;QACnB,IAAI,CAAC+B,QAAQ,GAAG,CAAA;QAChB,IAAI,CAACC,KAAK,GAAG,CAAA;QACb,IAAI,CAACC,UAAU,GAAG,CAAA;QAClB,IAAI,CAACZ,gBAAgB,GAAG,KAAA;QACxB,IAAI,CAACD,UAAU,GAAG;AAAC,YAAA,GAAA;AAAK,YAAA,GAAA;AAAK,YAAA;AAAI,SAAA;QACjC,IAAI,CAACc,QAAQ,GAAG,CAAA;QAChB,IAAI,CAACC,OAAO,GAAG,IAAIK,OAAAA,EAAAA;QACnB,IAAI,CAACtB,YAAY,GAAG,GAAA;QACpB,IAAI,CAACC,kBAAkB,GAAG,CAAA;AAC1B,QAAA,IAAI,CAACG,YAAY,GAAG,CAAA,GAAI,IAAO,GAAA,IAAA;AACjC;AACA,IAAA,IAAImB,OAAU,GAAA;QACZ,OAAO,IAAI,CAACjB,QAAQ;AACtB;IACA,IAAIiB,OAAAA,CAAQC,GAAY,EAAE;AACxBA,QAAAA,GAAAA,GAAM,CAAC,CAACA,GAAAA;AACR,QAAA,IAAIA,GAAQ,KAAA,IAAI,CAAClB,QAAQ,EAAE;AACzB,YAAA;AACF;QACA,IAAI,CAACA,QAAQ,GAAGkB,GAAAA;AAChB,QAAA,MAAMC,IAAO,GAAA,IAAI,CAACpB,MAAM,CAACqB,QAAQ;AACjC,QAAA,IAAIF,GAAK,EAAA;AACPC,YAAAA,IAAAA,CAAKE,EAAE,CAAC,cAAA,EAAgB,IAAI,CAACC,cAAc,EAAE,IAAI,CAAA;AACjDH,YAAAA,IAAAA,CAAKE,EAAE,CAAC,aAAA,EAAe,IAAI,CAACE,aAAa,EAAE,IAAI,CAAA;AAC/CJ,YAAAA,IAAAA,CAAKE,EAAE,CAAC,gBAAA,EAAkB,IAAI,CAACG,gBAAgB,EAAE,IAAI,CAAA;YACrD,IAAI,CAACC,OAAO,CAACN,IAAAA,CAAAA;SACR,MAAA;AACLA,YAAAA,IAAAA,CAAKO,GAAG,CAAC,cAAA,EAAgB,IAAI,CAACJ,cAAc,EAAE,IAAI,CAAA;AAClDH,YAAAA,IAAAA,CAAKO,GAAG,CAAC,aAAA,EAAe,IAAI,CAACH,aAAa,EAAE,IAAI,CAAA;AAChDJ,YAAAA,IAAAA,CAAKO,GAAG,CAAC,gBAAA,EAAkB,IAAI,CAACF,gBAAgB,EAAE,IAAI,CAAA;YACtD,IAAI,CAACX,cAAc,CAACc,KAAK,EAAA;AACzB,YAAA,KAAK,MAAMC,IAAQ,IAAA;AAAI,gBAAA,GAAA,IAAI,CAACb;aAAS,CAAE;gBACrC,IAAI,CAACc,OAAO,CAACD,IAAAA,CAAAA;AACf;YACA,IAAI,CAACtB,OAAO,CAACqB,KAAK,EAAA;YAClB,IAAI,CAAC1B,MAAM,EAAE6B,OAAAA,EAAAA;YACb,IAAI,CAAC7B,MAAM,GAAG,IAAA;YACd,IAAI,CAACC,OAAO,EAAE4B,OAAAA,EAAAA;YACd,IAAI,CAAC5B,OAAO,GAAG,IAAA;YACf,IAAI,CAACC,aAAa,GAAG,KAAA;YACrB,IAAI,CAACC,QAAQ,GAAG,IAAA;AAClB;AACF;AACA;;;AAGC,MACD,IAAI2B,SAAsC,GAAA;QACxC,OAAO;AAAI,YAAA,GAAA,IAAI,CAACnC;AAAW,SAAA;AAC7B;IACA,IAAImC,SAAAA,CAAUb,GAA6B,EAAE;AAC3C,QAAA,MAAMc,IAAOd,GAAAA,GAAAA,CAAIe,GAAG,CAAC,CAACC,CAAAA,GAAMC,IAAKC,CAAAA,GAAG,CAACC,eAAAA,EAAiBF,IAAKG,CAAAA,KAAK,CAACJ,CAAAA,CAAAA,CAAAA,CAAAA;AACjE,QAAA,IAAIF,IAAKO,CAAAA,IAAI,CAAC,CAACL,CAAGM,EAAAA,CAAAA,GAAMN,CAAM,KAAA,IAAI,CAACtC,UAAU,CAAC4C,CAAAA,CAAE,CAAG,EAAA;YACjD,IAAI,CAAC5C,UAAU,GAAGoC,IAAAA;YAClB,IAAI,IAAI,CAAC/B,MAAM,EAAE;AACf,gBAAA,KAAK,MAAMwC,KAAS,IAAA,IAAI,CAACnC,OAAO,CAACoC,MAAM,EAAI,CAAA;AACzC,oBAAA,IAAI,IAAI,CAACzC,MAAM,CAAC0C,OAAO,CAACF,KAAQ,CAAA,EAAA;wBAC9B,IAAI,CAACG,UAAU,CAACH,KAAAA,CAAAA;AAClB;AACF;gBACA,IAAI,CAACxC,MAAM,CAAC6B,OAAO,EAAA;gBACnB,IAAI,CAAC7B,MAAM,GAAG,IAAA;AAChB;YACA,IAAI,CAACQ,UAAU,GAAG,CAAA;YAClB,IAAI,CAACZ,gBAAgB,GAAG,KAAA;AAC1B;AACF;oEAEA,IAAIgD,KAAQ,GAAA;AACV,QAAA,IAAI,CAAC,IAAI,CAAC5C,MAAM,EAAE;AAChB,YAAA,IAAI,CAACA,MAAM,GAAG,IAAI6C,YAAa,CAAA,IAAI,CAAClD,UAAU,CAAA;AAChD;QACA,OAAO,IAAI,CAACK,MAAM;AACpB;AACA;;;AAGC,MACD,IAAI8C,MAAS,GAAA;QACX,IAAI,IAAI,CAAC5C,aAAa,EAAE;YACtB,OAAO,IAAA;AACT;QACA,IAAI,CAAC,IAAI,CAACD,OAAO,IAAI,IAAI,CAACF,QAAQ,IAAIgD,SAAUC,CAAAA,WAAW,EAAI,EAAA;AAC7D,YAAA,IAAI,CAAC/C,OAAO,GAAG,IAAI8C,UAAU,IAAI,CAAA;AACnC;QACA,OAAO,IAAI,CAAC9C,OAAO;AACrB;sDAEA,IAAIgD,SAA2C,GAAA;AAC7C,QAAA,OAAO,IAAI,CAAC7C,UAAU,CAACqC,MAAM,EAAA;AAC/B;0EAEAS,OAAQC,CAAAA,QAAqB,EAAE;AAC7B,QAAA,OAAO,CAAC,CAACA,QAAAA,CAASX,KAAK,IAAIW,QAAAA,CAASX,KAAK,CAAC5D,KAAK,KAAK,OAAW,IAAA,CAAC,CAAC,IAAI,CAACoB,MAAM,EAAEkD,OAAAA,CAAQC,SAASX,KAAK,CAAA;AACtG;IACAY,QAA0B,GAAA;AACxB,QAAA,MAAMC,KAAuB,GAAA;AAC3BJ,YAAAA,SAAAA,EAAW,IAAI,CAAC7C,UAAU,CAAC2B,IAAI;YAC/BuB,eAAiB,EAAA,CAAA;YACjBC,gBAAkB,EAAA,CAAA;YAClBC,cAAgB,EAAA,CAAA;AAChBC,YAAAA,MAAAA,EAAQ,IAAI,CAACpD,OAAO,CAAC0B,IAAI;YACzB2B,aAAe,EAAA,CAAA;YACfC,aAAe,EAAA,CAAA;YACfC,YAAc,EAAA,CAAA;AACdC,YAAAA,cAAAA,EAAgB,IAAI,CAAC7D,MAAM,EAAE8D,KAAS,IAAA,CAAA;YACtChC,SAAW,EAAA,IAAI,CAAC9B,MAAM,GAAG;mBAAI,IAAI,CAACA,MAAM,CAAC+B;aAAK,GAAG;AAAC,gBAAA,CAAA;AAAG,gBAAA,CAAA;AAAG,gBAAA;AAAE,aAAA;AAC1DgC,YAAAA,cAAAA,EAAgB,IAAI,CAAC/D,MAAM,EAAEgE,SAAa,IAAA,CAAA;AAC1CC,YAAAA,cAAAA,EAAgB,IAAI,CAACjE,MAAM,EAAEiE,cAAkB,IAAA,CAAA;YAC/CC,SAAW,EAAA,IAAI,CAAC1D,UAAU;YAC1B2D,OAAS,EAAA,IAAI,CAAC1D,QAAQ;YACtB2D,aAAe,EAAA,IAAI,CAAC9D,QAAQ;YAC5B+D,MAAQ,EAAA;gBAAC,IAAI,CAAC3D,OAAO,CAAC4D,CAAC;gBAAE,IAAI,CAAC5D,OAAO,CAAC6D,CAAC;gBAAE,IAAI,CAAC7D,OAAO,CAAC8D;AAAE;AAC1D,SAAA;AACA,QAAA,KAAK,MAAMC,IAAQ,IAAA,IAAI,CAACrE,UAAU,CAACqC,MAAM,EAAI,CAAA;AAC3CY,YAAAA,KAAK,CAACoB,IAAKC,CAAAA,IAAI,KAAK,QAAA,GAAW,oBAAoB,kBAAmB,CAAA,EAAA;AACtErB,YAAAA,KAAAA,CAAMG,cAAc,IAAI,IAAI,CAACN,OAAO,CAACuB,QAAQ,CAAI,GAAA,CAAA;AACnD;AACA,QAAA,KAAK,MAAMjC,KAAS,IAAA,IAAI,CAACnC,OAAO,CAACoC,MAAM,EAAI,CAAA;AACzCY,YAAAA,KAAAA,CAAMK,aAAa,IAAIlB,KAAAA,CAAM5D,KAAK,KAAK,YAAY,CAAI,GAAA,CAAA;AACvDyE,YAAAA,KAAAA,CAAMM,aAAa,IAAInB,KAAAA,CAAM5D,KAAK,KAAK,YAAY,CAAI,GAAA,CAAA;AACvDyE,YAAAA,KAAAA,CAAMO,YAAY,IAAIpB,KAAAA,CAAM5D,KAAK,KAAK,WAAW,CAAI,GAAA,CAAA;AACvD;QACA,OAAOyE,KAAAA;AACT;AACA;;;;AAIC,MACDsB,QAASC,CAAAA,SAAoB,EAAEC,GAAgB,EAAE;QAC/C,IAAIC,GAAAA,GAAMtG,WAAYuG,CAAAA,GAAG,CAACH,SAAAA,CAAAA;AAC1B,QAAA,IAAI,CAACE,GAAK,EAAA;AACRA,YAAAA,GAAAA,GAAM,CAAC,QAAQ,EAAE,EAAEpG,iBAAmB,CAAA,CAAA;YACtCF,WAAYwG,CAAAA,GAAG,CAACJ,SAAWE,EAAAA,GAAAA,CAAAA;AAC7B;AACA,QAAA,MAAM,EAAEjG,MAAM,EAAEC,MAAM,EAAE,GAAGmG,SAASC,SAAUL,CAAAA,GAAAA,CAAAA,CAAAA;QAC9CvG,aAAc0G,CAAAA,GAAG,CAACF,GAAK,EAAA;AAAEjG,YAAAA,MAAAA;AAAQC,YAAAA;AAAO,SAAA,CAAA;QACxC,IAAI,CAACqG,UAAU,CAACL,GAAAA,CAAAA;AAChB,QAAA,KAAK,MAAMnD,IAAAA,IAAQ,IAAI,CAACb,QAAQ,CAAE;YAChC,IAAIa,IAAAA,CAAKiD,SAAS,KAAKA,SAAW,EAAA;gBAChC,IAAI,CAACQ,OAAO,CAACzD,IAAAA,CAAAA;AACf;AACF;AACF;AACA;;;AAGC,MACD,MAAM0D,SAAAA,CAAUT,SAAoB,EAAEU,OAA4B,EAAE;QAClE,MAAM,EAAEC,SAAS,EAAEC,OAAO,EAAE,GAAG,MAAMC,uBAAuBb,SAAW,EAAA,CAAA,CAAA;AACvE,QAAA,IAAI,CAACD,QAAQ,CAACC,SAAWc,EAAAA,WAAAA,CAAYH,WAAWC,OAASF,EAAAA,OAAAA,CAAAA,CAAAA;AAC3D;AACA;;;MAIAH,UAAAA,CAAWhG,QAAiB,EAAE;AAC5B,QAAA,KAAK,MAAMqD,KAAS,IAAA,IAAI,CAACnC,OAAO,CAACoC,MAAM,EAAI,CAAA;AACzC,YAAA,IAAItD,QAAWqD,GAAAA,KAAAA,CAAMrD,QAAQ,KAAKA,QAAWqD,GAAAA,KAAAA,CAAM5D,KAAK,KAAK,SAAa4D,IAAAA,KAAAA,CAAM5D,KAAK,KAAK,QAAU,EAAA;AAClG,gBAAA,IAAI,IAAI,CAACoB,MAAM,EAAE0C,QAAQF,KAAQ,CAAA,EAAA;AAC/B,oBAAA,IAAI,CAACxC,MAAM,CAAC2F,MAAM,CAACnD,KAAAA,CAAAA;oBACnB,IAAI,CAACG,UAAU,CAACH,KAAAA,CAAAA;AAClB;AACAA,gBAAAA,KAAAA,CAAM5D,KAAK,GAAG,SAAA;AACd4D,gBAAAA,KAAAA,CAAMvD,SAAS,GAAG,KAAA;AAClBuD,gBAAAA,KAAAA,CAAM3D,MAAM,GAAG,IAAA;AACf2D,gBAAAA,KAAAA,CAAM1D,MAAM,GAAG,IAAA;AACjB;AACF;AACF;AACA;;;AAGC,MACD8G,MAAOC,CAAAA,SAAkB,EAAEC,YAAoB,EAAE;AAC/C,QAAA,IAAI,CAAC,IAAI,CAAC/F,QAAQ,EAAE;AAClB,YAAA;AACF;QACA,IAAI,CAACQ,KAAK,IAAIuF,YAAAA;AACd,QAAA,KAAK,MAAMC,IAAAA,IAAQ,IAAI,CAACnF,cAAc,CAAE;AACtC,YAAA,IAAImF,KAAKC,QAAQ,IAAI,CAACD,IAAAA,CAAKE,QAAQ,EAAE;gBACnC,IAAI,CAACzE,OAAO,CAACuE,IAAAA,CAAAA;AACf;AACF;QACA,IAAI,CAACnF,cAAc,CAACc,KAAK,EAAA;AACzB,QAAA,IAAI,CAACjB,QAAQ,EAAA;AACb,QAAA,IAAI,CAACC,OAAO,CAACsE,GAAG,CAACa,SAAAA,CAAAA;;AAEjB,QAAA,MAAMK,SAAS,IAAI3H,GAAAA,EAAAA;AACnB,QAAA,KAAK,MAAMkG,IAAQ,IAAA,IAAI,CAACrE,UAAU,CAACqC,MAAM,EAAI,CAAA;YAC3C,IAAI,CAAC0D,aAAa,CAAC1B,IAAAA,CAAAA;YACnB,MAAMjC,KAAAA,GAAQiC,KAAKjC,KAAK;YACxB,IAAI,CAACA,SAASA,KAAM5D,CAAAA,KAAK,KAAK,SAAa4D,IAAAA,KAAAA,CAAM5D,KAAK,KAAK,QAAU,EAAA;AACnE,gBAAA;AACF;AACA,YAAA,MAAMwH,CAAIC,GAAAA,aAAAA,CAAcR,SAAWpB,EAAAA,IAAAA,CAAK6B,MAAM,CAAA;AAC9C,YAAA,IAAIF,CAAK,IAAA,IAAI,CAAC3G,YAAY,EAAE;gBAC1B,MAAM8G,IAAAA,GAAOL,MAAOnB,CAAAA,GAAG,CAACvC,KAAAA,CAAAA;gBACxB0D,MAAOlB,CAAAA,GAAG,CAACxC,KAAO+D,EAAAA,IAAAA,KAASC,YAAYJ,CAAIlE,GAAAA,IAAAA,CAAKuE,GAAG,CAACF,IAAMH,EAAAA,CAAAA,CAAAA,CAAAA;AAC5D;AACF;AACA,QAAA,MAAMM,KAAQ,GAAA;AAAIR,YAAAA,GAAAA,MAAAA,CAAOS,OAAO;AAAG,SAAA,CAACC,IAAI,CAAC,CAACC,GAAGC,CAAMD,GAAAA,CAAC,CAAC,CAAE,CAAA,GAAGC,CAAC,CAAC,CAAA,CAAE,EAAE9E,GAAG,CAAC,CAAC+E,CAAMA,GAAAA,CAAC,CAAC,CAAE,CAAA,CAAA;QAC/E,MAAMnE,KAAAA,GAAQ,IAAI,CAACA,KAAK;QACxB,KAAK,MAAMJ,SAASkE,KAAO,CAAA;AACzBlE,YAAAA,KAAAA,CAAMxD,UAAU,GAAG,IAAI,CAACuB,KAAK;YAC7B,IAAIiC,KAAAA,CAAM5D,KAAK,KAAK,SAAW,EAAA;gBAC7B,IAAI,CAAC4D,KAAMvD,CAAAA,SAAS,IAAI,IAAI,CAACqB,QAAQ,GAAG,IAAI,CAACZ,kBAAkB,EAAE;oBAC/D,IAAI,CAACsH,IAAI,CAACxE,KAAAA,CAAAA;AACZ;AACA,gBAAA;AACF;AACA,YAAA,IAAIA,KAAM5D,CAAAA,KAAK,KAAK,OAAA,IAAW,CAACgE,KAAMF,CAAAA,OAAO,CAACF,KAAAA,CAAAA,IAAUA,KAAMtD,CAAAA,aAAa,KAAK0D,KAAAA,CAAMqE,OAAO,EAAE;gBAC7F,IAAI,CAACC,KAAK,CAAC1E,KAAO0D,EAAAA,MAAAA,CAAAA;AACpB;AACF;QACA,KAAK,MAAMpB,OAAOlC,KAAMuE,CAAAA,KAAK,CAAC,IAAI,CAACtH,YAAY,CAAG,CAAA;YAChD,IAAI,CAAC8C,UAAU,CAACmC,GAAAA,CAAAA;AAClB;QACA,IAAI,IAAI,CAAC3E,QAAQ,KAAK,CAAC,IAAI,CAACA,QAAQ,CAAC6F,QAAQ,IAAI,IAAI,CAAC7F,QAAQ,CAACQ,KAAK,KAAK,IAAI,CAACb,MAAK,CAAI,EAAA;YACrF,IAAI,CAACK,QAAQ,GAAG,IAAA;AAClB;AACA,QAAA,IAAI,CAAC,IAAI,CAACD,aAAa,EAAE;YACvB,IAAI;AACF,gBAAA,IAAI,CAAC4C,MAAM,EAAE8C,OAAOC,SAAW,EAAA,IAAI,CAAC1F,QAAQ,CAAA;AAC9C,aAAA,CAAE,OAAOiH,GAAK,EAAA;;gBAEZ,IAAI,CAAClH,aAAa,GAAG,IAAA;gBACrBmH,OAAQC,CAAAA,KAAK,CAAC,uDAAyDF,EAAAA,GAAAA,CAAAA;AACzE;AACF;AACF;IACUG,SAAY,GAAA;AACpB,QAAA,KAAK,CAACA,SAAAA,EAAAA;QACN,IAAI,CAACvG,OAAO,GAAG,KAAA;AACjB;AACA,qBACA,KAAQkG,CAAM1E,KAAmB,EAAE0D,MAAiC,EAAE;QACpE,MAAMtD,KAAAA,GAAQ,IAAI,CAACA,KAAK;AACxB,QAAA,MAAM4E,GAAMhF,GAAAA,KAAAA,CAAM3D,MAAM,CAAE4I,UAAU;AACpC,QAAA,IAAI7E,MAAM8E,GAAG,CAAClF,OAAOgF,GAAKhF,EAAAA,KAAAA,CAAM1D,MAAM,CAAI,EAAA;AACxC,YAAA;AACF;;;AAGA,QAAA,MAAM6I,QAAW,GAAA;eAAI,IAAI,CAACtH,OAAO,CAACoC,MAAM;SAAG,CAACmF,MAAM,CAAC,CAACf,CAAAA,GAAMA,MAAMrE,KAASI,IAAAA,KAAAA,CAAMF,OAAO,CAACmE,CAAAA,CAAAA,CAAAA;QACvF,MAAMgB,IAAAA,GAAO3B,MAAOnB,CAAAA,GAAG,CAACvC,KAAAA,CAAAA;QACxB,MAAMsF,MAAAA,GAAS,CAACjB,CAAAA,GAAoBX,MAAO6B,CAAAA,GAAG,CAAClB,CAAMX,CAAAA,IAAAA,MAAAA,CAAOnB,GAAG,CAAC8B,CAAOgB,CAAAA,IAAAA,IAAAA;AACvE,QAAA,MAAMG,OAAU,GAAA;AACXL,YAAAA,GAAAA,QAAAA,CAASC,MAAM,CAAC,CAACf,IAAM,CAACX,MAAAA,CAAO6B,GAAG,CAAClB,CAAAA,CAAAA,CAAAA,CAAID,IAAI,CAAC,CAACC,CAAGC,EAAAA,CAAAA,GAAMD,EAAE7H,UAAU,GAAG8H,EAAE9H,UAAU,CAAA;eACjF2I,QAASC,CAAAA,MAAM,CAAC,CAACf,CAAAA,GAAMX,OAAOnB,GAAG,CAAC8B,KAAMgB,IAAMjB,CAAAA,CAAAA,IAAI,CAAC,CAACC,CAAAA,EAAGC,IAAMZ,MAAOnB,CAAAA,GAAG,CAAC+B,CAAMZ,CAAAA,GAAAA,MAAAA,CAAOnB,GAAG,CAAC8B,CAAAA,CAAAA;AAC7F,SAAA;;AAED,QAAA,MAAMoB,OAAOrF,KAAMqF,CAAAA,IAAI,CAACT,GAAKG,EAAAA,QAAAA,CAASC,MAAM,CAACE,MAAAA,CAAAA,CAAAA;AAC7C,QAAA,KAAK,MAAMI,MAAAA,IAAUD,IAAOD,GAAAA,OAAAA,GAAU,EAAE,CAAE;AACxCpF,YAAAA,KAAAA,CAAM+C,MAAM,CAACuC,MAAAA,CAAAA;YACb,IAAI,CAACvF,UAAU,CAACuF,MAAAA,CAAAA;AAChB,YAAA,IAAItF,MAAM8E,GAAG,CAAClF,OAAOgF,GAAKhF,EAAAA,KAAAA,CAAM1D,MAAM,CAAI,EAAA;AACxC,gBAAA;AACF;AACF;QACA0D,KAAMtD,CAAAA,aAAa,GAAG0D,KAAAA,CAAMqE,OAAO;AACnC,QAAA,IAAI,CAACzG,UAAU,EAAA;AACf,QAAA,IAAI,CAAC,IAAI,CAACZ,gBAAgB,EAAE;YAC1B,IAAI,CAACA,gBAAgB,GAAG,IAAA;AACxB,YAAA,IAAIuI,MAAS,GAAA,CAAA;AACb,YAAA,KAAK,MAAMtB,CAAAA,IAAKX,MAAOkC,CAAAA,IAAI,EAAI,CAAA;gBAC7B,IAAIvB,CAAAA,CAAEhI,MAAM,EAAE;AACZsJ,oBAAAA,MAAAA,IAAUtB,EAAEhI,MAAM,CAAC4I,UAAU,CAACY,MAAM,CAClC,CAACC,CAAGrG,EAAAA,CAAAA,GAAMqG,IAAIpG,IAAKqG,CAAAA,IAAI,CAACtG,CAAAA,GAAIG,mBAAmBA,eAC/C,EAAA,CAAA,CAAA;AAEJ;AACF;AACA,YAAA,MAAMoG,QAAW5F,GAAAA,KAAAA,CAAMb,IAAI,CAAC,EAAE,GAAGa,KAAAA,CAAMb,IAAI,CAAC,CAAE,CAAA,GAAGa,KAAMb,CAAAA,IAAI,CAAC,CAAE,CAAA;YAC9DsF,OAAQoB,CAAAA,IAAI,CACV,CAAC,uBAAuB,EAAEjG,KAAMrD,CAAAA,QAAQ,CAAC,EAAE,EAAEqI,GAAAA,CAAIkB,IAAI,CAAC,GAAA,CAAA,CAAK,0BAA0B,EAAE,IAAI,CAAC/I,UAAU,CAAC+I,IAAI,CAAC,GAAK,CAAA,CAAA,iBAAiB,EAAExG,IAAKyG,CAAAA,KAAK,CAAC/F,KAAMoB,CAAAA,SAAS,GAAG,GAAK,CAAA,CAAA,wDAAwD,EAAE,IAAI,CAACvE,YAAY,CAAC,OAAO,EAAE,CAAC0I,MAASK,GAAAA,QAAO,EAAGI,OAAO,CAAC,CAAG,CAAA,CAAA,wLAAwL,CAAC,CAAA;AAEvd;AACF;AACA,qBACQ5B,IAAKxE,CAAAA,KAAmB,EAAE;AAChCA,QAAAA,KAAAA,CAAMvD,SAAS,GAAG,IAAA;AAClB,QAAA,MAAM4J,KAAQvK,GAAAA,aAAAA,CAAcyG,GAAG,CAACvC,MAAMrD,QAAQ,CAAA;AAC9C,QAAA,IAAI0J,KAAO,EAAA;YACTrG,KAAM3D,CAAAA,MAAM,GAAGgK,KAAAA,CAAMhK,MAAM;YAC3B2D,KAAM1D,CAAAA,MAAM,GAAG+J,KAAAA,CAAM/J,MAAM;AAC3B0D,YAAAA,KAAAA,CAAM5D,KAAK,GAAG,OAAA;AACd,YAAA;AACF;AACA,QAAA,IAAI,CAAC0B,QAAQ,EAAA;QACb,MAAMwI,GAAAA,GAAMC,YAAYC,GAAG;QAC3B,MAAMC,IAAAA,GAAOC,cAAe1G,CAAAA,KAAAA,CAAMrD,QAAQ,CAAA;QACzC,CAAA,UAAA;AACC,YAAA,IAAI,CAAE,MAAM2J,GAAIK,CAAAA,MAAM,CAACF,IAAQ,CAAA,EAAA;gBAC7B,OAAO,SAAA;AACT;YACA,MAAM,EAAEpK,MAAM,EAAEC,MAAM,EAAE,GAAGmG,QAAAA,CAAU,MAAM6D,GAAAA,CAAIM,QAAQ,CAACH,IAAM,EAAA;gBAAEI,QAAU,EAAA;AAAS,aAAA,CAAA,CAAA;AACnF7G,YAAAA,KAAAA,CAAM3D,MAAM,GAAGA,MAAAA;AACf2D,YAAAA,KAAAA,CAAM1D,MAAM,GAAGA,MAAAA;YACf,OAAO,OAAA;SACT,GAAA,CAAKwK,IAAI,CACP,CAAC1K,KAAAA,GAAAA;AACC,YAAA,IAAI,CAAC0B,QAAQ,EAAA;AACbkC,YAAAA,KAAAA,CAAM5D,KAAK,GAAGA,KAAAA;AAChB,SAAA,EACA,CAACwI,GAAAA,GAAAA;AACC,YAAA,IAAI,CAAC9G,QAAQ,EAAA;AACbkC,YAAAA,KAAAA,CAAM5D,KAAK,GAAG,QAAA;YACdyI,OAAQoB,CAAAA,IAAI,CAAC,CAAC,mCAAmC,EAAEjG,MAAMrD,QAAQ,CAAC,EAAE,EAAEiI,GAAK,CAAA,CAAA,CAAA;AAC7E,SAAA,CAAA;AAEJ;AACA,qBACQ5F,OAAQN,CAAAA,IAAe,EAAE;QAC/BA,IAAKqI,CAAAA,OAAO,CAAC,CAACxD,IAAAA,GAAAA;YACZ,IAAIA,IAAAA,CAAKyD,MAAM,EAAI,EAAA;gBACjB,IAAI,CAACC,KAAK,CAAC1D,IAAAA,CAAAA;aACN,MAAA,IAAIA,KAAK2D,gBAAgB,EAAA,IAAM,CAAC,IAAI,CAACvJ,QAAQ,EAAE;gBACpD,IAAI,CAACA,QAAQ,GAAG4F,IAAAA;AAClB;YACA,OAAO,KAAA;AACT,SAAA,CAAA;AACF;AACA,qBACQ1E,cAAe0E,CAAAA,IAAe,EAAE;;;AAGtC,QAAA,IAAI,CAACnF,cAAc,CAAC8G,GAAG,CAAC3B,IAAAA,CAAAA;AAC1B;AACA,qBACQzE,aAAcyE,CAAAA,IAAe,EAAE;AACrC,QAAA,IAAI,CAACnF,cAAc,CAAC+I,MAAM,CAAC5D,IAAAA,CAAAA;QAC3BA,IAAKwD,CAAAA,OAAO,CAAC,CAACK,KAAAA,GAAAA;YACZ,IAAIA,KAAAA,CAAMJ,MAAM,EAAI,EAAA;gBAClB,IAAI,CAAC5H,OAAO,CAACgI,KAAAA,CAAAA;AACf;YACA,OAAO,KAAA;AACT,SAAA,CAAA;AACF;AACA,qBACQH,KAAM9H,CAAAA,IAAU,EAAE;AACxB,QAAA,IAAI,CAAC,IAAI,CAACb,QAAQ,CAACiH,GAAG,CAACpG,IAAO,CAAA,EAAA;AAC5B,YAAA,IAAI,CAACb,QAAQ,CAAC4G,GAAG,CAAC/F,IAAAA,CAAAA;AAClBA,YAAAA,IAAAA,CAAKP,EAAE,CAAC,iBAAA,EAAmB,IAAI,CAACyI,aAAa,EAAE,IAAI,CAAA;AACnDlI,YAAAA,IAAAA,CAAKP,EAAE,CAAC,mBAAA,EAAqB,IAAI,CAAC0I,kBAAkB,EAAE,IAAI,CAAA;AAC5D;QACA,IAAI,CAAC1E,OAAO,CAACzD,IAAAA,CAAAA;AACf;AACA,qBACQJ,gBAAiBwE,CAAAA,IAAe,EAAE;;QAExCA,IAAKwD,CAAAA,OAAO,CAAC,CAACK,KAAAA,GAAAA;YACZ,IAAIA,KAAAA,CAAMJ,MAAM,EAAM,IAAA,IAAI,CAAC1I,QAAQ,CAACiH,GAAG,CAAC6B,KAAQ,CAAA,EAAA;gBAC9C,IAAI,CAACxE,OAAO,CAACwE,KAAAA,CAAAA;AACf;YACA,OAAO,KAAA;AACT,SAAA,CAAA;AACF;AACA,6GACQxE,OAAQzD,CAAAA,IAAU,EAAE;QAC1B,MAAM+C,IAAAA,GAAO/C,IAAKqE,CAAAA,QAAQ,IAAI,CAACrE,KAAKoI,MAAM,GAAGpI,IAAKqI,CAAAA,gBAAgB,GAAG,MAAA;QACrE,MAAMpF,SAAAA,GAAYjD,KAAKiD,SAAS;AAChC,QAAA,MAAMqE,OAAOrE,SAAYmE,GAAAA,SAAAA,EAAAA,CAAYkB,eAAe,CAACC,UAAU,CAACtF,SAAa,CAAA,GAAA,IAAA;;AAE7E,QAAA,MAAMuF,UAAavF,GAAAA,SAAAA,GAAYpG,WAAYuG,CAAAA,GAAG,CAACH,SAAa4B,CAAAA,GAAAA,SAAAA;AAC5D,QAAA,MAAMrH,QACJgL,GAAAA,UAAAA,IAAc7L,aAAcyJ,CAAAA,GAAG,CAACoC,UAC5BA,CAAAA,GAAAA,UAAAA,GACAlB,IAAQA,IAAAA,IAAAA,CAAKmB,WAAW,EAAA,CAAGC,QAAQ,CAAC,WAClCpB,IACA,GAAA,IAAA;AACR,QAAA,MAAM1C,OAAO,IAAI,CAACnG,UAAU,CAAC2E,GAAG,CAACpD,IAAAA,CAAAA;AACjC,QAAA,IAAI4E,IAAQA,IAAAA,IAAAA,CAAK7B,IAAI,KAAKA,IAAQ6B,IAAAA,IAAAA,CAAK/D,KAAK,EAAErD,QAAcA,MAAAA,QAAYqH,IAAAA,SAAQ,CAAI,EAAA;AAClF,YAAA;AACF;AACA,QAAA,IAAID,IAAM,EAAA;YACR,IAAI,CAAC+D,YAAY,CAAC/D,IAAAA,CAAAA;AACpB;AACA,QAAA,IAAI7B,SAAS,MAAQ,EAAA;AACnB,YAAA,IAAI6B,IAAM,EAAA;AACR,gBAAA,IAAI,CAACnG,UAAU,CAACuJ,MAAM,CAAChI,IAAAA,CAAAA;AACzB;AACA,YAAA;AACF;AACA,QAAA,MAAM8C,IAAoB,GAAA;AACxB9C,YAAAA,IAAAA;AACA+C,YAAAA,IAAAA;AACAlC,YAAAA,KAAAA,EAAOrD,QAAW,GAAA,IAAI,CAACoL,OAAO,CAACpL,QAAY,CAAA,GAAA,IAAA;YAC3CmH,MAAQkE,EAAAA,QAAAA;AACV,SAAA;QACA,IAAI,CAACrE,aAAa,CAAC1B,IAAAA,CAAAA;AACnB,QAAA,IAAI,CAACrE,UAAU,CAAC4E,GAAG,CAACrD,IAAM8C,EAAAA,IAAAA,CAAAA;AAC1B,QAAA,IAAI,IAAI,CAACvB,OAAO,CAACuB,IAAO,CAAA,EAAA;AACtB,YAAA,IAAI,CAACgG,UAAU,CAAChG,IAAAA,CAAK6B,MAAM,CAAA;AAC7B;AACF;AACA,qBACQ1E,OAAQD,CAAAA,IAAU,EAAE;AAC1B,QAAA,IAAI,CAAC,IAAI,CAACb,QAAQ,CAAC6I,MAAM,CAAChI,IAAO,CAAA,EAAA;AAC/B,YAAA;AACF;AACAA,QAAAA,IAAAA,CAAKF,GAAG,CAAC,iBAAA,EAAmB,IAAI,CAACoI,aAAa,EAAE,IAAI,CAAA;AACpDlI,QAAAA,IAAAA,CAAKF,GAAG,CAAC,mBAAA,EAAqB,IAAI,CAACqI,kBAAkB,EAAE,IAAI,CAAA;AAC3D,QAAA,MAAMrF,OAAO,IAAI,CAACrE,UAAU,CAAC2E,GAAG,CAACpD,IAAAA,CAAAA;AACjC,QAAA,IAAI8C,IAAM,EAAA;YACR,IAAI,CAAC6F,YAAY,CAAC7F,IAAAA,CAAAA;AAClB,YAAA,IAAI,CAACrE,UAAU,CAACuJ,MAAM,CAAChI,IAAAA,CAAAA;AACzB;AACF;AACA,qBACQ2I,YAAa7F,CAAAA,IAAiB,EAAE;AACtC,QAAA,IAAI,IAAI,CAACvB,OAAO,CAACuB,IAAO,CAAA,EAAA;AACtB,YAAA,IAAI,CAACgG,UAAU,CAAChG,IAAAA,CAAK6B,MAAM,CAAA;AAC7B;QACA,MAAM9D,KAAAA,GAAQiC,KAAKjC,KAAK;AACxB,QAAA,IAAIA,KAAS,IAAA,EAAEA,KAAMzD,CAAAA,IAAI,IAAI,CAAG,EAAA;YAC9B,IAAI,CAACiB,MAAM,EAAE2F,MAAOnD,CAAAA,KAAAA,CAAAA;AACpB,YAAA,IAAI,CAACnC,OAAO,CAACsJ,MAAM,CAACnH,MAAMrD,QAAQ,CAAA;AACpC;AACF;AACA,qBACQoL,OAAQpL,CAAAA,QAAgB,EAAE;AAChC,QAAA,IAAIqD,QAAQ,IAAI,CAACnC,OAAO,CAAC0E,GAAG,CAAC5F,QAAAA,CAAAA;AAC7B,QAAA,IAAI,CAACqD,KAAO,EAAA;AACVA,YAAAA,KAAAA,GAAQ,IAAI7D,YAAaQ,CAAAA,QAAAA,CAAAA;AACzB,YAAA,IAAI,CAACkB,OAAO,CAAC2E,GAAG,CAAC7F,QAAUqD,EAAAA,KAAAA,CAAAA;AAC7B;AACAA,QAAAA,KAAAA,CAAMzD,IAAI,EAAA;QACV,OAAOyD,KAAAA;AACT;AACA,qBACQqH,aAAclI,CAAAA,IAAU,EAAE;QAChC,IAAI,CAACyD,OAAO,CAACzD,IAAAA,CAAAA;AACf;qBAEA,kBAA6B,GAAA;;AAE3B,QAAA,KAAK,MAAMA,IAAAA,IAAQ,IAAI,CAACb,QAAQ,CAAE;YAChC,IAAI,CAACsE,OAAO,CAACzD,IAAAA,CAAAA;AACf;AACF;AACA,+FACQwE,aAAc1B,CAAAA,IAAiB,EAAE;AACvC,QAAA,MAAMiG,EAAKjG,GAAAA,IAAAA,CAAK9C,IAAI,CAACgJ,sBAAsB,EAAA;AAC3C,QAAA,IAAI,CAACD,EAAI,EAAA;AACP,YAAA;AACF;QACA,MAAME,GAAAA,GAAMF,GAAGG,MAAM,EAAA;QACrB,MAAM/D,CAAAA,GAAIrC,KAAK6B,MAAM;;QAErB,MAAMwE,QAAAA,GAAWhE,EAAEiE,QAAQ,CAACzG,CAAC,IAAIwC,CAAAA,CAAEkE,QAAQ,CAAC1G,CAAC;AAC7C,QAAA,IAAIwG,YAAYhE,CAAEiE,CAAAA,QAAQ,CAACE,QAAQ,CAACL,GAAIG,CAAAA,QAAQ,CAAKjE,IAAAA,CAAAA,CAAEkE,QAAQ,CAACC,QAAQ,CAACL,GAAAA,CAAII,QAAQ,CAAG,EAAA;AACtF,YAAA;AACF;QACA,IAAIvG,IAAAA,CAAKC,IAAI,KAAK,QAAA,IAAY,IAAI,CAACxB,OAAO,CAACuB,IAAO,CAAA,EAAA;AAChD,YAAA,IAAIqG,QAAU,EAAA;gBACZ,IAAI,CAACL,UAAU,CAAC3D,CAAAA,CAAAA;AAClB;YACA,IAAI,CAAC2D,UAAU,CAACG,GAAAA,CAAAA;AAClB;AACA9D,QAAAA,CAAAA,CAAEiE,QAAQ,CAAC/F,GAAG,CAAC4F,IAAIG,QAAQ,CAAA;AAC3BjE,QAAAA,CAAAA,CAAEkE,QAAQ,CAAChG,GAAG,CAAC4F,IAAII,QAAQ,CAAA;AAC7B;AACA,qBACQrI,UAAWH,CAAAA,KAAmB,EAAE;AACtC,QAAA,KAAK,MAAMiC,IAAQ,IAAA,IAAI,CAACrE,UAAU,CAACqC,MAAM,EAAI,CAAA;YAC3C,IAAIgC,IAAAA,CAAKjC,KAAK,KAAKA,KAAO,EAAA;AACxB,gBAAA,IAAI,CAACiI,UAAU,CAAChG,IAAAA,CAAK6B,MAAM,CAAA;AAC7B;AACF;AACF;AACA,qBACQmE,UAAWG,CAAAA,GAAS,EAAE;QAC5B,IAAIA,GAAAA,CAAIG,QAAQ,CAACzG,CAAC,IAAIsG,GAAII,CAAAA,QAAQ,CAAC1G,CAAC,EAAE;YACpC,IAAI,CAACrE,OAAO,EAAEiL,SAAAA,CAAUN,IAAIG,QAAQ,EAAEH,IAAII,QAAQ,CAAA;YAClD,IAAI,CAACG,aAAa,CAAC,OAAA,EAASP,IAAIG,QAAQ,EAAEH,IAAII,QAAQ,CAAA;AACxD;AACF;AACF;AAEA,SAASR,QAAAA,GAAAA;AACP,IAAA,OAAO,IAAIY,IAAAA,CAAK,IAAIrK,OAAAA,CAAQsK,QAAUA,EAAAA,QAAAA,EAAUA,QAAW,CAAA,EAAA,IAAItK,OAAQ,CAAA,CAACsK,QAAU,EAAA,CAACA,UAAU,CAACA,QAAAA,CAAAA,CAAAA;AAChG;AAEA,SAAShF,aAAAA,CAAciF,CAAU,EAAEV,GAAS,EAAA;AAC1C,IAAA,MAAMW,KAAKrJ,IAAKC,CAAAA,GAAG,CAACyI,GAAIG,CAAAA,QAAQ,CAACzG,CAAC,GAAGgH,EAAEhH,CAAC,EAAE,GAAGgH,CAAEhH,CAAAA,CAAC,GAAGsG,GAAII,CAAAA,QAAQ,CAAC1G,CAAC,CAAA;AACjE,IAAA,MAAMkH,KAAKtJ,IAAKC,CAAAA,GAAG,CAACyI,GAAIG,CAAAA,QAAQ,CAACxG,CAAC,GAAG+G,EAAE/G,CAAC,EAAE,GAAG+G,CAAE/G,CAAAA,CAAC,GAAGqG,GAAII,CAAAA,QAAQ,CAACzG,CAAC,CAAA;AACjE,IAAA,MAAMkH,KAAKvJ,IAAKC,CAAAA,GAAG,CAACyI,GAAIG,CAAAA,QAAQ,CAACvG,CAAC,GAAG8G,EAAE9G,CAAC,EAAE,GAAG8G,CAAE9G,CAAAA,CAAC,GAAGoG,GAAII,CAAAA,QAAQ,CAACxG,CAAC,CAAA;AACjE,IAAA,OAAOtC,IAAKwJ,CAAAA,KAAK,CAACH,EAAAA,EAAIC,EAAIC,EAAAA,EAAAA,CAAAA;AAC5B;;;;"}