@zephyr3d/scene 0.9.25 → 0.9.27

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 (299) hide show
  1. package/dist/animation/animationset.js +92 -30
  2. package/dist/animation/animationset.js.map +1 -1
  3. package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
  4. package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
  5. package/dist/animation/joint_dynamics/controller.js +7 -5
  6. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  7. package/dist/animation/joint_dynamics/convex_collider.js +320 -0
  8. package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
  9. package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
  10. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  11. package/dist/animation/morphtrack.js +3 -4
  12. package/dist/animation/morphtrack.js.map +1 -1
  13. package/dist/animation/skeleton.js +79 -25
  14. package/dist/animation/skeleton.js.map +1 -1
  15. package/dist/animation/spring/multi_chain_spring_system.js +577 -179
  16. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  17. package/dist/animation/spring/spring_collider.js +4 -3
  18. package/dist/animation/spring/spring_collider.js.map +1 -1
  19. package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
  20. package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
  21. package/dist/animation/spring/spring_particle.js +2 -0
  22. package/dist/animation/spring/spring_particle.js.map +1 -1
  23. package/dist/animation/spring/spring_system.js +11 -3
  24. package/dist/animation/spring/spring_system.js.map +1 -1
  25. package/dist/animation/spring_modifier.js +10 -0
  26. package/dist/animation/spring_modifier.js.map +1 -1
  27. package/dist/app/engine.js +53 -43
  28. package/dist/app/engine.js.map +1 -1
  29. package/dist/app/scriptingsystem.js +119 -6
  30. package/dist/app/scriptingsystem.js.map +1 -1
  31. package/dist/app/scriptregistry.js +3 -2
  32. package/dist/app/scriptregistry.js.map +1 -1
  33. package/dist/asset/assetmanager.js +284 -67
  34. package/dist/asset/assetmanager.js.map +1 -1
  35. package/dist/asset/loaders/zhair/zhair_format.js +288 -0
  36. package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
  37. package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
  38. package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
  39. package/dist/asset/model.js +184 -69
  40. package/dist/asset/model.js.map +1 -1
  41. package/dist/camera/camera.js +268 -44
  42. package/dist/camera/camera.js.map +1 -1
  43. package/dist/camera/perspectivecamera.js +3 -1
  44. package/dist/camera/perspectivecamera.js.map +1 -1
  45. package/dist/index.d.ts +9044 -5139
  46. package/dist/index.js +17 -6
  47. package/dist/index.js.map +1 -1
  48. package/dist/material/eye.js +932 -0
  49. package/dist/material/eye.js.map +1 -0
  50. package/dist/material/hair.js +917 -0
  51. package/dist/material/hair.js.map +1 -0
  52. package/dist/material/hairstrand.js +842 -0
  53. package/dist/material/hairstrand.js.map +1 -0
  54. package/dist/material/hairstrand_data.js +162 -0
  55. package/dist/material/hairstrand_data.js.map +1 -0
  56. package/dist/material/lambert.js +5 -2
  57. package/dist/material/lambert.js.map +1 -1
  58. package/dist/material/material.js +48 -10
  59. package/dist/material/material.js.map +1 -1
  60. package/dist/material/meshmaterial.js +120 -19
  61. package/dist/material/meshmaterial.js.map +1 -1
  62. package/dist/material/mixins/albedocolor.js +1 -1
  63. package/dist/material/mixins/albedocolor.js.map +1 -1
  64. package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
  65. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  66. package/dist/material/mixins/lightmodel/lambert.js +5 -4
  67. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  68. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
  69. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  70. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
  71. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  72. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
  73. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  74. package/dist/material/mixins/lit.js +106 -19
  75. package/dist/material/mixins/lit.js.map +1 -1
  76. package/dist/material/mixins/pbr/common.js +4 -4
  77. package/dist/material/mixins/pbr/common.js.map +1 -1
  78. package/dist/material/mixins/texture.js +48 -11
  79. package/dist/material/mixins/texture.js.map +1 -1
  80. package/dist/material/mtoon.js +6 -5
  81. package/dist/material/mtoon.js.map +1 -1
  82. package/dist/material/pbrblueprint.js +146 -28
  83. package/dist/material/pbrblueprint.js.map +1 -1
  84. package/dist/material/pbrblueprint_instance.js +501 -0
  85. package/dist/material/pbrblueprint_instance.js.map +1 -0
  86. package/dist/material/pbrmr.js +15 -16
  87. package/dist/material/pbrmr.js.map +1 -1
  88. package/dist/material/shader/helper.js +734 -23
  89. package/dist/material/shader/helper.js.map +1 -1
  90. package/dist/material/shader/terrain_blend.js +55 -0
  91. package/dist/material/shader/terrain_blend.js.map +1 -0
  92. package/dist/material/skin.js +192 -32
  93. package/dist/material/skin.js.map +1 -1
  94. package/dist/material/spriteblueprint.js +16 -1
  95. package/dist/material/spriteblueprint.js.map +1 -1
  96. package/dist/material/subsurfaceprofile.js +86 -23
  97. package/dist/material/subsurfaceprofile.js.map +1 -1
  98. package/dist/material/water.js +2059 -72
  99. package/dist/material/water.js.map +1 -1
  100. package/dist/posteffect/bloom.js +167 -7
  101. package/dist/posteffect/bloom.js.map +1 -1
  102. package/dist/posteffect/coloradjust.js +2 -1
  103. package/dist/posteffect/coloradjust.js.map +1 -1
  104. package/dist/posteffect/compositor.js.map +1 -1
  105. package/dist/posteffect/fxaa.js +2 -1
  106. package/dist/posteffect/fxaa.js.map +1 -1
  107. package/dist/posteffect/grayscale.js +3 -1
  108. package/dist/posteffect/grayscale.js.map +1 -1
  109. package/dist/posteffect/motionblur.js +664 -56
  110. package/dist/posteffect/motionblur.js.map +1 -1
  111. package/dist/posteffect/posteffect.js +12 -1
  112. package/dist/posteffect/posteffect.js.map +1 -1
  113. package/dist/posteffect/sao.js +46 -44
  114. package/dist/posteffect/sao.js.map +1 -1
  115. package/dist/posteffect/skinsss.js +368 -69
  116. package/dist/posteffect/skinsss.js.map +1 -1
  117. package/dist/posteffect/ssgi.js +16 -9
  118. package/dist/posteffect/ssgi.js.map +1 -1
  119. package/dist/posteffect/ssr.js +3 -0
  120. package/dist/posteffect/ssr.js.map +1 -1
  121. package/dist/posteffect/sss.js +121 -36
  122. package/dist/posteffect/sss.js.map +1 -1
  123. package/dist/posteffect/taa.js.map +1 -1
  124. package/dist/posteffect/tonemap.js +44 -1
  125. package/dist/posteffect/tonemap.js.map +1 -1
  126. package/dist/render/abuffer_oit.js +8 -2
  127. package/dist/render/abuffer_oit.js.map +1 -1
  128. package/dist/render/clipmap.js +156 -5
  129. package/dist/render/clipmap.js.map +1 -1
  130. package/dist/render/cull_visitor.js +20 -0
  131. package/dist/render/cull_visitor.js.map +1 -1
  132. package/dist/render/depthpass.js +36 -2
  133. package/dist/render/depthpass.js.map +1 -1
  134. package/dist/render/drawable_mixin.js +26 -1
  135. package/dist/render/drawable_mixin.js.map +1 -1
  136. package/dist/render/dualdepthpeeling_oit.js +3 -2
  137. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  138. package/dist/render/envlight.js +1 -1
  139. package/dist/render/envlight.js.map +1 -1
  140. package/dist/render/fbm_wavegenerator.js +6 -3
  141. package/dist/render/fbm_wavegenerator.js.map +1 -1
  142. package/dist/render/fft_wavegenerator.js +57 -15
  143. package/dist/render/fft_wavegenerator.js.map +1 -1
  144. package/dist/render/gerstner_wavegenerator.js +130 -20
  145. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  146. package/dist/render/globalbindgroup_allocator.js +3 -0
  147. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  148. package/dist/render/hzb.js +80 -22
  149. package/dist/render/hzb.js.map +1 -1
  150. package/dist/render/lightpass.js +6 -3
  151. package/dist/render/lightpass.js.map +1 -1
  152. package/dist/render/oit.js +29 -0
  153. package/dist/render/oit.js.map +1 -0
  154. package/dist/render/render_queue.js +39 -0
  155. package/dist/render/render_queue.js.map +1 -1
  156. package/dist/render/renderer.js +4 -0
  157. package/dist/render/renderer.js.map +1 -1
  158. package/dist/render/rendergraph/blackboard.js +1 -0
  159. package/dist/render/rendergraph/blackboard.js.map +1 -1
  160. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  161. package/dist/render/rendergraph/executor.js +2 -0
  162. package/dist/render/rendergraph/executor.js.map +1 -1
  163. package/dist/render/rendergraph/forward_plus_builder.js +379 -10
  164. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  165. package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
  166. package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
  167. package/dist/render/rendergraph/history_resources.js +8 -1
  168. package/dist/render/rendergraph/history_resources.js.map +1 -1
  169. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  170. package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
  171. package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
  172. package/dist/render/rendergraph/types.js.map +1 -1
  173. package/dist/render/shadow_mask_pass.js +73 -8
  174. package/dist/render/shadow_mask_pass.js.map +1 -1
  175. package/dist/render/sky.js +166 -126
  176. package/dist/render/sky.js.map +1 -1
  177. package/dist/render/underwater.js +624 -0
  178. package/dist/render/underwater.js.map +1 -0
  179. package/dist/render/water_caustics.js +1380 -0
  180. package/dist/render/water_caustics.js.map +1 -0
  181. package/dist/render/weightedblended_oit.js +3 -2
  182. package/dist/render/weightedblended_oit.js.map +1 -1
  183. package/dist/scene/basesprite.js +8 -0
  184. package/dist/scene/basesprite.js.map +1 -1
  185. package/dist/scene/batchgroup.js +3 -0
  186. package/dist/scene/batchgroup.js.map +1 -1
  187. package/dist/scene/environment.js +4 -1
  188. package/dist/scene/environment.js.map +1 -1
  189. package/dist/scene/hair.js +963 -0
  190. package/dist/scene/hair.js.map +1 -0
  191. package/dist/scene/light.js +5 -1
  192. package/dist/scene/light.js.map +1 -1
  193. package/dist/scene/mesh.js +481 -47
  194. package/dist/scene/mesh.js.map +1 -1
  195. package/dist/scene/meshdrawable.js +6 -0
  196. package/dist/scene/meshdrawable.js.map +1 -1
  197. package/dist/scene/msdftext.js +3 -0
  198. package/dist/scene/msdftext.js.map +1 -1
  199. package/dist/scene/msdftextsprite.js +3 -0
  200. package/dist/scene/msdftextsprite.js.map +1 -1
  201. package/dist/scene/particlesys.js +6 -0
  202. package/dist/scene/particlesys.js.map +1 -1
  203. package/dist/scene/scene.js +3 -0
  204. package/dist/scene/scene.js.map +1 -1
  205. package/dist/scene/scene_node.js +6 -1
  206. package/dist/scene/scene_node.js.map +1 -1
  207. package/dist/scene/terrain-cm/grass.js +3 -0
  208. package/dist/scene/terrain-cm/grass.js.map +1 -1
  209. package/dist/scene/terrain-cm/grassmaterial.js +3 -0
  210. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  211. package/dist/scene/terrain-cm/terrain-cm.js +6 -0
  212. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  213. package/dist/scene/terrain-cm/texture_cache.js +309 -0
  214. package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
  215. package/dist/scene/water.js +546 -4
  216. package/dist/scene/water.js.map +1 -1
  217. package/dist/shaders/atmosphere.js.map +1 -1
  218. package/dist/shaders/diffusion.js +54 -0
  219. package/dist/shaders/diffusion.js.map +1 -0
  220. package/dist/shaders/shadow.js +33 -21
  221. package/dist/shaders/shadow.js.map +1 -1
  222. package/dist/shaders/temporal.js +71 -33
  223. package/dist/shaders/temporal.js.map +1 -1
  224. package/dist/shaders/water.js +22 -19
  225. package/dist/shaders/water.js.map +1 -1
  226. package/dist/shaders/water_medium.js +56 -0
  227. package/dist/shaders/water_medium.js.map +1 -0
  228. package/dist/shadow/dom.js +546 -0
  229. package/dist/shadow/dom.js.map +1 -0
  230. package/dist/shadow/pcf_opt.js +3 -5
  231. package/dist/shadow/pcf_opt.js.map +1 -1
  232. package/dist/shadow/pcf_pd.js +1 -1
  233. package/dist/shadow/pcf_pd.js.map +1 -1
  234. package/dist/shadow/receiver_bias.js +41 -0
  235. package/dist/shadow/receiver_bias.js.map +1 -0
  236. package/dist/shadow/shader.js +20 -60
  237. package/dist/shadow/shader.js.map +1 -1
  238. package/dist/shadow/shadow_impl.js +89 -0
  239. package/dist/shadow/shadow_impl.js.map +1 -1
  240. package/dist/shadow/shadow_region.js +1 -1
  241. package/dist/shadow/shadow_region.js.map +1 -1
  242. package/dist/shadow/shadowmapper.js +150 -37
  243. package/dist/shadow/shadowmapper.js.map +1 -1
  244. package/dist/shapes/shape.js +11 -2
  245. package/dist/shapes/shape.js.map +1 -1
  246. package/dist/shapes/sphere.js +50 -9
  247. package/dist/shapes/sphere.js.map +1 -1
  248. package/dist/utility/blueprint/common/constants.js +112 -2
  249. package/dist/utility/blueprint/common/constants.js.map +1 -1
  250. package/dist/utility/blueprint/material/func.js +142 -49
  251. package/dist/utility/blueprint/material/func.js.map +1 -1
  252. package/dist/utility/blueprint/material/ir.js +490 -25
  253. package/dist/utility/blueprint/material/ir.js.map +1 -1
  254. package/dist/utility/blueprint/material/texture.js +898 -4
  255. package/dist/utility/blueprint/material/texture.js.map +1 -1
  256. package/dist/utility/serialization/manager.js +434 -101
  257. package/dist/utility/serialization/manager.js.map +1 -1
  258. package/dist/utility/serialization/scene/animation.js +401 -5
  259. package/dist/utility/serialization/scene/animation.js.map +1 -1
  260. package/dist/utility/serialization/scene/batch.js +4 -0
  261. package/dist/utility/serialization/scene/batch.js.map +1 -1
  262. package/dist/utility/serialization/scene/camera.js +186 -26
  263. package/dist/utility/serialization/scene/camera.js.map +1 -1
  264. package/dist/utility/serialization/scene/common.js +26 -5
  265. package/dist/utility/serialization/scene/common.js.map +1 -1
  266. package/dist/utility/serialization/scene/hair.js +1141 -0
  267. package/dist/utility/serialization/scene/hair.js.map +1 -0
  268. package/dist/utility/serialization/scene/light.js +84 -4
  269. package/dist/utility/serialization/scene/light.js.map +1 -1
  270. package/dist/utility/serialization/scene/material.js +1867 -166
  271. package/dist/utility/serialization/scene/material.js.map +1 -1
  272. package/dist/utility/serialization/scene/mesh.js +231 -14
  273. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  274. package/dist/utility/serialization/scene/node.js +141 -7
  275. package/dist/utility/serialization/scene/node.js.map +1 -1
  276. package/dist/utility/serialization/scene/particle.js +4 -0
  277. package/dist/utility/serialization/scene/particle.js.map +1 -1
  278. package/dist/utility/serialization/scene/primitive.js +18 -0
  279. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  280. package/dist/utility/serialization/scene/sprite.js +4 -0
  281. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  282. package/dist/utility/serialization/scene/terrain.js +4 -0
  283. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  284. package/dist/utility/serialization/scene/text.js +4 -0
  285. package/dist/utility/serialization/scene/text.js.map +1 -1
  286. package/dist/utility/serialization/scene/water.js +1105 -21
  287. package/dist/utility/serialization/scene/water.js.map +1 -1
  288. package/dist/utility/serialization/types.js.map +1 -1
  289. package/dist/utility/shprojector.js +9 -8
  290. package/dist/utility/shprojector.js.map +1 -1
  291. package/dist/values.js +49 -2
  292. package/dist/values.js.map +1 -1
  293. package/package.json +3 -3
  294. package/dist/render/rendergraph/frame_graph_context.js +0 -41
  295. package/dist/render/rendergraph/frame_graph_context.js.map +0 -1
  296. package/dist/shaders/ssgi.js +0 -63
  297. package/dist/shaders/ssgi.js.map +0 -1
  298. package/dist/shaders/ssgi_reprojection.js +0 -118
  299. package/dist/shaders/ssgi_reprojection.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hair.js","sources":["../../src/scene/hair.ts"],"sourcesContent":["/**\r\n * A groom in the scene graph.\r\n *\r\n * @remarks\r\n * Strand hair is drawn from control points held in storage buffers and expanded\r\n * into camera-facing ribbons in the vertex shader, which needs a handful of\r\n * pieces wired together that nothing else in the engine needs: a primitive that\r\n * carries no attributes but still establishes a vertex layout, a draw range\r\n * derived from the material rather than from an index buffer, and a bounding box\r\n * computed on the CPU because the geometry does not exist until the vertex stage\r\n * has run. This node owns that assembly so a groom can be placed, transformed,\r\n * serialised and simulated like anything else.\r\n *\r\n * The material is deliberately not exposed. Strand geometry only exists inside\r\n * {@link HairStrandMaterial} - it reads control points from storage buffers that\r\n * no other material knows about - so letting one be swapped in would produce a\r\n * node that cannot draw. The shading controls are surfaced as properties of the\r\n * node instead, and they are what gets serialised.\r\n *\r\n * The geometry itself lives in a `.zhair` asset, referenced by path. That file\r\n * holds nothing but strands: the node's own settings, shading included, belong\r\n * to the scene rather than to the asset, so one groom can be shared by several\r\n * characters that each style it differently.\r\n *\r\n * WebGPU only, because the expansion reads storage buffers from the vertex\r\n * stage. On other backends the node exists and keeps its data but draws nothing.\r\n */\r\nimport type { Immutable, Nullable, Vector4 } from '@zephyr3d/base';\r\nimport { applyMixins, DRef, Vector3 } from '@zephyr3d/base';\r\nimport type { Scene } from './scene';\r\nimport { GraphNode } from './graph_node';\r\nimport { mixinDrawable } from '../render/drawable_mixin';\r\nimport type { Drawable, DrawContext, PickTarget, RenderQueue } from '../render';\r\nimport { Primitive } from '../render';\r\nimport { HairStrandMaterial } from '../material/hairstrand';\r\nimport type { HairShadingModel } from '../material/hair';\r\nimport { HairStrandData, type HairStrandSource } from '../material/hairstrand_data';\r\nimport {\r\n GPUHairSimulation,\r\n isHairSimulationSupported,\r\n type GPUHairSimulationOptions\r\n} from '../animation/hair/gpu_hair_simulation';\r\nimport type { ParsedZHair } from '../asset/loaders/zhair/zhair_format';\r\nimport { parseZHair } from '../asset/loaders/zhair/zhair_format';\r\nimport { loadZHairStrandSources, mergeHairStrandSources } from '../asset/loaders/zhair/zhair_loader';\r\nimport { BoundingBox } from '../utility/bounding_volume';\r\nimport { QUEUE_OPAQUE } from '../values';\r\nimport { getEngine } from '../app/api';\r\nimport type { BlendMode } from '../material/meshmaterial';\r\n\r\n/**\r\n * Hair scene node.\r\n *\r\n * @remarks\r\n * Point it at a `.zhair` asset with {@link HairNode.setHairAsset}, or hand it\r\n * control points directly with {@link HairNode.setStrands}. Everything the draw\r\n * call needs is derived from them.\r\n *\r\n * @public\r\n */\r\nexport class HairNode extends applyMixins(GraphNode, mixinDrawable) implements Drawable {\r\n /** @internal */\r\n private readonly _pickTarget: PickTarget;\r\n /** @internal */\r\n private readonly _material: DRef<HairStrandMaterial>;\r\n /** @internal */\r\n private readonly _primitive: DRef<Primitive>;\r\n /** @internal */\r\n private readonly _strands: DRef<HairStrandData>;\r\n /** @internal Local-space bounds of the control points, width included. */\r\n private _bounds: Nullable<BoundingBox>;\r\n /** @internal Length of the longest strand, for padding the bounds while simulating. */\r\n private _maxStrandLength: number;\r\n /** @internal */\r\n private _castShadow: boolean;\r\n /** @internal Kept so the simulation can be rebuilt from the authored pose. */\r\n private _source: Nullable<HairStrandSource>;\r\n /** @internal Path of the `.zhair` asset, empty when strands were set directly. */\r\n private _hairAsset: string;\r\n /**\r\n * @internal The opened asset, kept so decimation can be changed without\r\n * reading the file again.\r\n */\r\n private _parsedAsset: Nullable<ParsedZHair>;\r\n /** @internal */\r\n private _strandStride: number;\r\n /** @internal */\r\n private _maxStrands: number;\r\n /** @internal */\r\n private _simulation: Nullable<GPUHairSimulation>;\r\n /** @internal */\r\n private _simulationEnabled: boolean;\r\n /**\r\n * @internal Simulation tuning, owned by the node.\r\n *\r\n * Held here rather than on the simulation because the node outlives it: the\r\n * dials survive the simulation being switched off and on, and can be set\r\n * before any strands have loaded.\r\n */\r\n private readonly _simulationOptions: GPUHairSimulationOptions;\r\n /**\r\n * Creates an empty hair node.\r\n *\r\n * @param scene - Scene the node belongs to.\r\n */\r\n constructor(scene: Scene) {\r\n super(scene);\r\n this._pickTarget = { node: this };\r\n this._material = new DRef(new HairStrandMaterial());\r\n this._primitive = new DRef();\r\n this._strands = new DRef();\r\n this._bounds = null;\r\n this._maxStrandLength = 0;\r\n this._castShadow = true;\r\n this._source = null;\r\n this._hairAsset = '';\r\n this._parsedAsset = null;\r\n this._strandStride = 1;\r\n this._maxStrands = 0;\r\n this._simulation = null;\r\n this._simulationEnabled = false;\r\n this._simulationOptions = {\r\n gravity: new Vector3(0, -9.8, 0),\r\n damping: 0.08,\r\n globalStiffness: 0,\r\n globalRange: 0,\r\n localStiffness: 0.9,\r\n localIterations: 2,\r\n ftlDamping: 0.7,\r\n vspCoeff: 0.8,\r\n vspAccelThreshold: 50,\r\n substeps: 1,\r\n friction: 0.2,\r\n maxSpeedFactor: 4\r\n };\r\n }\r\n\r\n //\r\n // Geometry\r\n //\r\n\r\n /** Path of the `.zhair` asset this node draws, or an empty string. */\r\n get hairAsset() {\r\n return this._hairAsset;\r\n }\r\n /**\r\n * Loads a `.zhair` asset.\r\n *\r\n * @remarks\r\n * The opened file is kept, so changing {@link HairNode.strandStride} or\r\n * {@link HairNode.maxStrands} afterwards re-decimates what is already in\r\n * memory instead of reading it again - and never touches the source archive\r\n * the asset was converted from.\r\n *\r\n * @param path - Asset path, or an empty string to clear the node.\r\n */\r\n async setHairAsset(path: string) {\r\n const assetId = path?.trim() ?? '';\r\n if (assetId === this._hairAsset) {\r\n return;\r\n }\r\n this._hairAsset = assetId;\r\n this._parsedAsset = null;\r\n if (!assetId) {\r\n this.setStrands(null);\r\n return;\r\n }\r\n let parsed: ParsedZHair;\r\n try {\r\n const data = (await getEngine().resourceManager.assetManager.fetchBinaryData(assetId)) as ArrayBuffer;\r\n parsed = parseZHair(data);\r\n } catch (err) {\r\n console.error(`Load hair asset failed: ${assetId}: ${err}`);\r\n this.setStrands(null);\r\n return;\r\n }\r\n // A load that was superseded while it was in flight must not overwrite the\r\n // asset that replaced it.\r\n if (this._hairAsset !== assetId) {\r\n return;\r\n }\r\n this._parsedAsset = parsed;\r\n this._applyAssetDecimation();\r\n }\r\n /**\r\n * Draw one strand in every `strandStride`.\r\n *\r\n * @remarks\r\n * A stride rather than a leading slice, so the kept strands stay spread over\r\n * the whole scalp instead of leaving a bald patch. Only meaningful when the\r\n * strands came from an asset; strands set directly are used as given.\r\n */\r\n get strandStride() {\r\n return this._strandStride;\r\n }\r\n set strandStride(val: number) {\r\n const v = val < 1 ? 1 : val | 0;\r\n if (v !== this._strandStride) {\r\n this._strandStride = v;\r\n this._applyAssetDecimation();\r\n }\r\n }\r\n /**\r\n * Upper bound on the number of strands drawn, or 0 for no bound.\r\n *\r\n * @remarks\r\n * Applied on top of {@link HairNode.strandStride} by widening the stride\r\n * further, so the result stays evenly spread.\r\n */\r\n get maxStrands() {\r\n return this._maxStrands;\r\n }\r\n set maxStrands(val: number) {\r\n const v = val < 0 ? 0 : val | 0;\r\n if (v !== this._maxStrands) {\r\n this._maxStrands = v;\r\n this._applyAssetDecimation();\r\n }\r\n }\r\n /** GPU-resident strand geometry, or null when none has been assigned. */\r\n get strands(): Nullable<HairStrandData> {\r\n return this._strands.get();\r\n }\r\n /** Number of strands currently drawn. */\r\n get strandCount() {\r\n return this._strands.get()?.strandCount ?? 0;\r\n }\r\n /**\r\n * Replaces the strands this node draws.\r\n *\r\n * @remarks\r\n * The direct route, for strands built in code rather than loaded from an\r\n * asset. Uploads the control points, sizes the draw call and recomputes the\r\n * bounding box; the previous strand data is released and any running\r\n * simulation is rebuilt, since its rest pose comes from the strands.\r\n *\r\n * @param source - Control points and topology, or null to clear the node.\r\n */\r\n setStrands(source: Nullable<HairStrandSource>) {\r\n this._disposeSimulation();\r\n this._strands.dispose();\r\n this._bounds = null;\r\n this._maxStrandLength = 0;\r\n this._source = null;\r\n if (!source) {\r\n this.material.strands = null;\r\n this._primitive.dispose();\r\n this.invalidateBoundingVolume();\r\n return;\r\n }\r\n const data = new HairStrandData(source);\r\n this._strands.set(data);\r\n this._source = source;\r\n this.material.strands = data;\r\n const extents = computeStrandExtents(source);\r\n this._bounds = extents.bounds;\r\n this._maxStrandLength = extents.maxStrandLength;\r\n this._ensurePrimitive();\r\n this._syncDrawRange();\r\n this.invalidateBoundingVolume();\r\n if (this._simulationEnabled) {\r\n this._createSimulation();\r\n }\r\n }\r\n\r\n //\r\n // Shading\r\n //\r\n // The material is an implementation detail of this node - see the class\r\n // remarks - so its controls are surfaced here. Only the ones that do something\r\n // on the strand path are: the vertex shader emits no texture coordinates, so\r\n // the material's albedo, shift and occlusion maps have nothing to sample and\r\n // are deliberately left unreachable.\r\n //\r\n\r\n /** Base colour of the strands. */\r\n get albedoColor(): Immutable<Vector4> {\r\n return this.material.albedoColor;\r\n }\r\n set albedoColor(value: Vector4) {\r\n this.material.albedoColor = value;\r\n }\r\n /**\r\n * Which scattering model shades the hair.\r\n *\r\n * @remarks\r\n * `kajiya-kay` is the art-directed double lobe; `marschner` derives the lobes\r\n * from the fibre and is the one that renders back-lighting.\r\n */\r\n get shadingModel(): HairShadingModel {\r\n return this.material.shadingModel;\r\n }\r\n set shadingModel(value: HairShadingModel) {\r\n this.material.shadingModel = value;\r\n }\r\n /** Colour of the primary, near-white specular lobe. */\r\n get specular1Color(): Immutable<Vector3> {\r\n return this.material.specular1Color;\r\n }\r\n set specular1Color(value: Vector3) {\r\n this.material.specular1Color = value;\r\n }\r\n /** Exponent of the primary specular lobe. */\r\n get specular1Power() {\r\n return this.material.specular1Power;\r\n }\r\n set specular1Power(value: number) {\r\n this.material.specular1Power = value;\r\n }\r\n /** Shift of the primary specular lobe along the strand. */\r\n get specular1Shift() {\r\n return this.material.specular1Shift;\r\n }\r\n set specular1Shift(value: number) {\r\n this.material.specular1Shift = value;\r\n }\r\n /** Colour of the secondary, tinted specular lobe. */\r\n get specular2Color(): Immutable<Vector3> {\r\n return this.material.specular2Color;\r\n }\r\n set specular2Color(value: Vector3) {\r\n this.material.specular2Color = value;\r\n }\r\n /** Exponent of the secondary specular lobe. */\r\n get specular2Power() {\r\n return this.material.specular2Power;\r\n }\r\n set specular2Power(value: number) {\r\n this.material.specular2Power = value;\r\n }\r\n /** Shift of the secondary specular lobe along the strand. */\r\n get specular2Shift() {\r\n return this.material.specular2Shift;\r\n }\r\n set specular2Shift(value: number) {\r\n this.material.specular2Shift = value;\r\n }\r\n /** How far diffuse lighting wraps around the fibre. */\r\n get diffuseWrap() {\r\n return this.material.diffuseWrap;\r\n }\r\n set diffuseWrap(value: number) {\r\n this.material.diffuseWrap = value;\r\n }\r\n /** Colour of light transmitted through the fibre. */\r\n get transmissionColor(): Immutable<Vector3> {\r\n return this.material.transmissionColor;\r\n }\r\n set transmissionColor(value: Vector3) {\r\n this.material.transmissionColor = value;\r\n }\r\n /** Strength of back-lit transmission. */\r\n get transmissionIntensity() {\r\n return this.material.transmissionIntensity;\r\n }\r\n set transmissionIntensity(value: number) {\r\n this.material.transmissionIntensity = value;\r\n }\r\n /** Falloff exponent of back-lit transmission. */\r\n get transmissionPower() {\r\n return this.material.transmissionPower;\r\n }\r\n set transmissionPower(value: number) {\r\n this.material.transmissionPower = value;\r\n }\r\n /** Colour of multiple scattering within the groom. */\r\n get scatterColor(): Immutable<Vector3> {\r\n return this.material.scatterColor;\r\n }\r\n set scatterColor(value: Vector3) {\r\n this.material.scatterColor = value;\r\n }\r\n /** Strength of multiple scattering. */\r\n get scatterIntensity() {\r\n return this.material.scatterIntensity;\r\n }\r\n set scatterIntensity(value: number) {\r\n this.material.scatterIntensity = value;\r\n }\r\n /** Share of scattering taken as local rather than global. */\r\n get scatterLocal() {\r\n return this.material.scatterLocal;\r\n }\r\n set scatterLocal(value: number) {\r\n this.material.scatterLocal = value;\r\n }\r\n /** How far scattered light wraps around the fibre. */\r\n get scatterWrap() {\r\n return this.material.scatterWrap;\r\n }\r\n set scatterWrap(value: number) {\r\n this.material.scatterWrap = value;\r\n }\r\n /** Longitudinal shift of the Marschner lobes. */\r\n get marschnerShift() {\r\n return this.material.marschnerShift;\r\n }\r\n set marschnerShift(value: number) {\r\n this.material.marschnerShift = value;\r\n }\r\n /** Longitudinal roughness of the Marschner lobes. */\r\n get marschnerRoughness() {\r\n return this.material.marschnerRoughness;\r\n }\r\n set marschnerRoughness(value: number) {\r\n this.material.marschnerRoughness = value;\r\n }\r\n /** Index of refraction of the fibre. */\r\n get marschnerIOR() {\r\n return this.material.marschnerIOR;\r\n }\r\n set marschnerIOR(value: number) {\r\n this.material.marschnerIOR = value;\r\n }\r\n /**\r\n * How strongly pigmented the fibre is.\r\n *\r\n * @remarks\r\n * A multiplier on the distance transmitted light travels before leaving, so\r\n * raising it deepens the colour of the TT and TRT paths without touching the\r\n * white surface reflection.\r\n */\r\n get marschnerAbsorption() {\r\n return this.material.marschnerAbsorption;\r\n }\r\n set marschnerAbsorption(value: number) {\r\n this.material.marschnerAbsorption = value;\r\n }\r\n /** Relative weight of the R, TT and TRT lobes. */\r\n get marschnerLobes(): Immutable<Vector3> {\r\n return this.material.marschnerLobes;\r\n }\r\n set marschnerLobes(value: Immutable<Vector3>) {\r\n this.material.marschnerLobes = value;\r\n }\r\n\r\n //\r\n // Strand expansion\r\n //\r\n\r\n /**\r\n * Ribbon segments generated per strand.\r\n *\r\n * @remarks\r\n * The main quality dial, and independent of how many control points a strand\r\n * has: the shader resamples the curve, so the same 30-point strand can be\r\n * drawn with 12 segments close up and 3 far away.\r\n */\r\n get segmentsPerStrand() {\r\n return this.material.segmentsPerStrand;\r\n }\r\n set segmentsPerStrand(val: number) {\r\n if (val !== this.material.segmentsPerStrand) {\r\n this.material.segmentsPerStrand = val;\r\n this._syncDrawRange();\r\n }\r\n }\r\n /** Multiplier on the width stored in the strand data. */\r\n get strandWidthScale() {\r\n return this.material.strandWidthScale;\r\n }\r\n set strandWidthScale(value: number) {\r\n this.material.strandWidthScale = value;\r\n }\r\n /** Lower bound on ribbon width, in world units. */\r\n get minStrandWidth() {\r\n return this.material.minStrandWidth;\r\n }\r\n set minStrandWidth(value: number) {\r\n this.material.minStrandWidth = value;\r\n }\r\n /**\r\n * Lower bound on ribbon width, in pixels.\r\n *\r\n * @remarks\r\n * Real hair is thinner than a pixel and rasterises to a flickering dotted\r\n * line. Widening it to about a pixel and paying the extra coverage back in\r\n * alpha keeps distant hair fading rather than breaking up.\r\n */\r\n get minPixelWidth() {\r\n return this.material.minPixelWidth;\r\n }\r\n set minPixelWidth(value: number) {\r\n this.material.minPixelWidth = value;\r\n }\r\n /**\r\n * How far the shading normal bends across the ribbon, in [0, 1].\r\n *\r\n * @remarks\r\n * At 0 a strand shades as a flat tape, at 1 as a cylinder.\r\n */\r\n get strandRoundness() {\r\n return this.material.strandRoundness;\r\n }\r\n set strandRoundness(value: number) {\r\n this.material.strandRoundness = value;\r\n }\r\n /**\r\n * Strength of the root-depth ambient occlusion, in [0, 1].\r\n *\r\n * @remarks\r\n * Environment irradiance is not attenuated by anything - a shadow map answers\r\n * for one light, not for the sky - so without this every strand of a groom\r\n * receives the full sky and a dense hairstyle is lit as brightly in its\r\n * interior as on its surface, which reads as a flat silhouette with no volume.\r\n * Most obvious on pale hair, where there is little pigment to darken the\r\n * interior instead. Set to 0 to disable.\r\n *\r\n * Ambient light only: direct light is already attenuated by the shadow map,\r\n * and under DOM by a graded transmittance, so it is left alone.\r\n */\r\n get rootOcclusion() {\r\n return this.material.rootOcclusion;\r\n }\r\n set rootOcclusion(value: number) {\r\n this.material.rootOcclusion = value;\r\n }\r\n /**\r\n * How far along a strand the root occlusion reaches, in (0, 1].\r\n *\r\n * @remarks\r\n * Short for a groom whose strands leave the scalp quickly, longer for one\r\n * where they lie against each other most of their length.\r\n */\r\n get rootOcclusionRange() {\r\n return this.material.rootOcclusionRange;\r\n }\r\n set rootOcclusionRange(value: number) {\r\n this.material.rootOcclusionRange = value;\r\n }\r\n /** Drop strands with distance, redistributing their coverage to the survivors. */\r\n get strandLOD() {\r\n return this.material.strandLOD;\r\n }\r\n set strandLOD(value: boolean) {\r\n this.material.strandLOD = value;\r\n }\r\n /** Floor on the fraction of strands distance decimation keeps. */\r\n get minStrandLODRatio() {\r\n return this.material.minStrandLODRatio;\r\n }\r\n set minStrandLODRatio(value: number) {\r\n this.material.minStrandLODRatio = value;\r\n }\r\n\r\n //\r\n // Transparency and shadows\r\n //\r\n\r\n /**\r\n * How the strands blend with what is behind them.\r\n *\r\n * @remarks\r\n * The pixel-width floor pays its widening back in alpha, which only means\r\n * anything once blending is on; left at `none` every strand covers its pixel\r\n * fully and a dense groom reads as a solid shell.\r\n */\r\n get blendMode(): BlendMode {\r\n return this.material.blendMode;\r\n }\r\n set blendMode(value: BlendMode) {\r\n this.material.blendMode = value;\r\n }\r\n /** Alpha below which a fragment is discarded. */\r\n get alphaCutoff() {\r\n return this.material.alphaCutoff;\r\n }\r\n set alphaCutoff(value: number) {\r\n this.material.alphaCutoff = value;\r\n }\r\n /** Dither the alpha test, so a temporal filter resolves the soft edge. */\r\n get alphaDither() {\r\n return this.material.alphaDither;\r\n }\r\n set alphaDither(value: boolean) {\r\n this.material.alphaDither = value;\r\n }\r\n /**\r\n * Whether a blended groom contributes motion vectors.\r\n *\r\n * @remarks\r\n * Only meaningful with {@link HairNode.blendMode} set to something other than\r\n * `none`. Blended geometry is otherwise absent from the prepass, so a groom\r\n * carries the velocity of whatever is behind it and a temporal filter smears\r\n * it as it swings - the same ghosting the dithered path avoids by being\r\n * opaque. On by default, because a groom is dense enough to own its pixels\r\n * and there is no reason to want the ghosting.\r\n */\r\n get transparentMotionVector() {\r\n return this.material.transparentMotionVector;\r\n }\r\n set transparentMotionVector(value: boolean) {\r\n this.material.transparentMotionVector = value;\r\n }\r\n /** Whether the groom is drawn into shadow maps. */\r\n get castShadow() {\r\n return this._castShadow;\r\n }\r\n set castShadow(val: boolean) {\r\n this._castShadow = !!val;\r\n }\r\n /** Let the shadow caster pass respect strand alpha, for softer self-shadowing. */\r\n get transparentShadowCaster() {\r\n return this.material.transparentShadowCaster;\r\n }\r\n set transparentShadowCaster(value: boolean) {\r\n this.material.transparentShadowCaster = value;\r\n }\r\n /** Alpha below which a fragment casts no shadow. */\r\n get shadowAlphaCutoff() {\r\n return this.material.shadowAlphaCutoff;\r\n }\r\n set shadowAlphaCutoff(value: number) {\r\n this.material.shadowAlphaCutoff = value;\r\n }\r\n\r\n //\r\n // Simulation\r\n //\r\n\r\n /**\r\n * Whether strand dynamics run on this groom.\r\n *\r\n * @remarks\r\n * WebGPU only. Switching it on with no strands loaded is allowed - the\r\n * simulation is built when the strands arrive.\r\n */\r\n get simulationEnabled() {\r\n return this._simulationEnabled;\r\n }\r\n set simulationEnabled(val: boolean) {\r\n const enabled = !!val;\r\n if (enabled === this._simulationEnabled) {\r\n return;\r\n }\r\n this._simulationEnabled = enabled;\r\n if (enabled) {\r\n this._createSimulation();\r\n } else {\r\n this._disposeSimulation();\r\n // Without this the groom keeps whatever pose it was last simulated into,\r\n // which reads as a bug rather than as hair that stopped moving.\r\n if (this._source) {\r\n this._strands.get()?.dispose();\r\n this._strands.set(new HairStrandData(this._source));\r\n this.material.strands = this._strands.get();\r\n }\r\n // Back to the tight rest bounds.\r\n this.invalidateBoundingVolume();\r\n }\r\n }\r\n /**\r\n * The running strand dynamics, or null when they are off or unsupported.\r\n *\r\n * @remarks\r\n * Exposed so a caller can reach past the node's own dials - to set colliders,\r\n * for one, which have no serialised form here.\r\n */\r\n get simulation(): Nullable<GPUHairSimulation> {\r\n return this._simulation;\r\n }\r\n /** World-space gravity acting on the strands. */\r\n get gravity(): Immutable<Vector3> {\r\n return this._simulationOptions.gravity!;\r\n }\r\n set gravity(value: Vector3) {\r\n this._simulationOptions.gravity = new Vector3(value);\r\n if (this._simulation) {\r\n this._simulation.gravity = this._simulationOptions.gravity;\r\n }\r\n }\r\n /**\r\n * How strongly strands keep the shape they were authored with, in [0, 1].\r\n *\r\n * @remarks\r\n * The dial to reach for first. It holds the angle each segment makes with the\r\n * one before it, measured against that segment's current direction rather\r\n * than a fixed pose, so a groom keeps its curl while remaining free to hang\r\n * and swing. It is also what damps a groom: without bending resistance a\r\n * strand carries a disturbance up and down its length for seconds.\r\n */\r\n get localStiffness() {\r\n return this._simulationOptions.localStiffness!;\r\n }\r\n set localStiffness(value: number) {\r\n this._simulationOptions.localStiffness = value;\r\n if (this._simulation) {\r\n this._simulation.localStiffness = value;\r\n }\r\n }\r\n /** Local shape constraint passes per substep. */\r\n get localIterations() {\r\n return this._simulationOptions.localIterations!;\r\n }\r\n set localIterations(value: number) {\r\n this._simulationOptions.localIterations = value;\r\n if (this._simulation) {\r\n this._simulation.localIterations = value;\r\n }\r\n }\r\n /**\r\n * How strongly strands are pulled back to their authored pose, in [0, 1].\r\n *\r\n * @remarks\r\n * Off by default. It anchors a point to a fixed place rather than to its\r\n * neighbours, which is a spring, and a groom held by springs reads as one.\r\n * {@link HairNode.localStiffness} is what holds styling without that; this is\r\n * for grooms that genuinely should not move far from how they were authored,\r\n * and wants {@link HairNode.globalRange} set as well.\r\n */\r\n get globalStiffness() {\r\n return this._simulationOptions.globalStiffness!;\r\n }\r\n set globalStiffness(value: number) {\r\n this._simulationOptions.globalStiffness = value;\r\n if (this._simulation) {\r\n this._simulation.globalStiffness = value;\r\n }\r\n }\r\n /** Fraction of a strand, from the root, the pose pull acts on, in [0, 1]. */\r\n get globalRange() {\r\n return this._simulationOptions.globalRange!;\r\n }\r\n set globalRange(value: number) {\r\n this._simulationOptions.globalRange = value;\r\n if (this._simulation) {\r\n this._simulation.globalRange = value;\r\n }\r\n }\r\n /**\r\n * Share of a point's length correction fed back into its parent, in [0, 1].\r\n *\r\n * @remarks\r\n * What keeps the solver from gaining energy as the node moves. Lowering it\r\n * makes a groom livelier and, past a point, makes it whip; 0 removes the\r\n * feedback entirely.\r\n */\r\n get ftlDamping() {\r\n return this._simulationOptions.ftlDamping!;\r\n }\r\n set ftlDamping(value: number) {\r\n this._simulationOptions.ftlDamping = value;\r\n if (this._simulation) {\r\n this._simulation.ftlDamping = value;\r\n }\r\n }\r\n /** Velocity lost each step, in [0, 1]. */\r\n get damping() {\r\n return this._simulationOptions.damping!;\r\n }\r\n set damping(value: number) {\r\n this._simulationOptions.damping = value;\r\n if (this._simulation) {\r\n this._simulation.damping = value;\r\n }\r\n }\r\n /** Tangential motion removed at a contact, in [0, 1]. */\r\n get friction() {\r\n return this._simulationOptions.friction!;\r\n }\r\n set friction(value: number) {\r\n this._simulationOptions.friction = value;\r\n if (this._simulation) {\r\n this._simulation.friction = value;\r\n }\r\n }\r\n /**\r\n * How much of the node's motion strands are carried along by, in [0, 1].\r\n *\r\n * @remarks\r\n * 0 leaves a groom exactly where it was in the world and lets the pinned\r\n * roots drag it along, which is what produces lag; 1 carries it rigidly with\r\n * the node, so it never lags. Lower values give a livelier, floppier groom.\r\n */\r\n get vspCoeff() {\r\n return this._simulationOptions.vspCoeff!;\r\n }\r\n set vspCoeff(value: number) {\r\n this._simulationOptions.vspCoeff = value;\r\n if (this._simulation) {\r\n this._simulation.vspCoeff = value;\r\n }\r\n }\r\n /** Node acceleration above which strands are carried rigidly, in units/s². */\r\n get vspAccelThreshold() {\r\n return this._simulationOptions.vspAccelThreshold!;\r\n }\r\n set vspAccelThreshold(value: number) {\r\n this._simulationOptions.vspAccelThreshold = value;\r\n if (this._simulation) {\r\n this._simulation.vspAccelThreshold = value;\r\n }\r\n }\r\n /**\r\n * Per-substep ceiling on how far a point may travel, in segment lengths.\r\n *\r\n * @remarks\r\n * A backstop against a single bad substep, not a dial to shape motion with:\r\n * at the default it never engages during ordinary movement.\r\n */\r\n get maxSpeedFactor() {\r\n return this._simulationOptions.maxSpeedFactor!;\r\n }\r\n set maxSpeedFactor(value: number) {\r\n this._simulationOptions.maxSpeedFactor = value;\r\n if (this._simulation) {\r\n this._simulation.maxSpeedFactor = value;\r\n }\r\n }\r\n /** Integration substeps per fixed step. */\r\n get substeps() {\r\n return this._simulationOptions.substeps!;\r\n }\r\n set substeps(value: number) {\r\n this._simulationOptions.substeps = value;\r\n if (this._simulation) {\r\n this._simulation.substeps = value;\r\n }\r\n }\r\n\r\n //\r\n // Scene node and drawable\r\n //\r\n\r\n /**\r\n * {@inheritDoc SceneNode.update}\r\n *\r\n * @remarks\r\n * Drives the strand solver. The node re-queues itself every frame, because a\r\n * simulation only stands still when it is switched off.\r\n */\r\n update(frameId: number, elapsedInSeconds: number, deltaInSeconds: number) {\r\n super.update(frameId, elapsedInSeconds, deltaInSeconds);\r\n const simulation = this._simulation;\r\n if (simulation?.enabled) {\r\n simulation.update(deltaInSeconds, this.worldMatrix);\r\n this.scene?.queueUpdateNode(this);\r\n }\r\n }\r\n /**\r\n * {@inheritDoc SceneNode.computeBoundingVolume}\r\n *\r\n * @remarks\r\n * Derived on the CPU from the control points, because the ribbons are built in\r\n * the vertex shader and the engine never sees them. The box is in local space;\r\n * the base class applies the world matrix.\r\n *\r\n * While a simulation runs, the strands swing out of their authored pose, so\r\n * the rest bounds are padded by the longest strand: the solver keeps every\r\n * point within its strand's length of the pinned root, which bounds any pose\r\n * it can produce.\r\n */\r\n computeBoundingVolume(): Nullable<BoundingBox> {\r\n if (!this._bounds) {\r\n return null;\r\n }\r\n const box = new BoundingBox(this._bounds);\r\n if (this._simulation) {\r\n const pad = this._maxStrandLength;\r\n box.minPoint.setXYZ(box.minPoint.x - pad, box.minPoint.y - pad, box.minPoint.z - pad);\r\n box.maxPoint.setXYZ(box.maxPoint.x + pad, box.maxPoint.y + pad, box.maxPoint.z + pad);\r\n }\r\n return box;\r\n }\r\n /** {@inheritDoc SceneNode.isHair} */\r\n isHair(): this is HairNode {\r\n return true;\r\n }\r\n /** {@inheritDoc Drawable.getPickTarget} */\r\n getPickTarget() {\r\n return this._pickTarget;\r\n }\r\n /** {@inheritDoc Drawable.getMaterial} */\r\n getMaterial() {\r\n return this._material.get();\r\n }\r\n /** {@inheritDoc Drawable.getPrimitive} */\r\n getPrimitive() {\r\n return this._primitive.get();\r\n }\r\n /** {@inheritDoc Drawable.getMorphData} */\r\n getMorphData() {\r\n return null;\r\n }\r\n /** {@inheritDoc Drawable.getMorphInfo} */\r\n getMorphInfo() {\r\n return null;\r\n }\r\n /** {@inheritDoc Drawable.getSkinInfluenceData} */\r\n getSkinInfluenceData() {\r\n return null;\r\n }\r\n /** {@inheritDoc Drawable.getQueueType} */\r\n getQueueType() {\r\n return this._material.get()?.getQueueType() ?? QUEUE_OPAQUE;\r\n }\r\n /** {@inheritDoc Drawable.isUnlit} */\r\n isUnlit() {\r\n return !this._material.get()?.supportLighting();\r\n }\r\n /** {@inheritDoc Drawable.needSceneColor} */\r\n needSceneColor() {\r\n return this._material.get()?.needSceneColor() ?? false;\r\n }\r\n /** {@inheritDoc Drawable.needSceneDepth} */\r\n needSceneDepth() {\r\n return this._material.get()?.needSceneDepth() ?? false;\r\n }\r\n /** {@inheritDoc Drawable.draw} */\r\n draw(ctx: DrawContext, renderQueue: Nullable<RenderQueue>) {\r\n const material = this._material.get();\r\n const primitive = this._primitive.get();\r\n // An empty groom is a legitimate state - a node exists before its asset has\r\n // finished loading - and the draw range is zero until strands arrive.\r\n if (material && primitive && material.vertexCount > 0) {\r\n this.bind(ctx, renderQueue);\r\n material.draw(primitive, ctx);\r\n }\r\n }\r\n protected onDispose() {\r\n super.onDispose();\r\n this._disposeSimulation();\r\n this._primitive.dispose();\r\n this._strands.dispose();\r\n this._material.dispose();\r\n this._parsedAsset = null;\r\n this._source = null;\r\n this._bounds = null;\r\n }\r\n\r\n //\r\n // Internals\r\n //\r\n\r\n /**\r\n * The material, which is an implementation detail of this node.\r\n * @internal\r\n */\r\n private get material() {\r\n return this._material.get()!;\r\n }\r\n /**\r\n * Re-decimates the opened asset into the strands actually drawn.\r\n * @internal\r\n */\r\n private _applyAssetDecimation() {\r\n const parsed = this._parsedAsset;\r\n if (!parsed) {\r\n return;\r\n }\r\n // A `.zhair` holds one set per source curve object, and an XGen export\r\n // routinely carries several spline descriptions for a single hairstyle;\r\n // merging lets the whole head draw in one call.\r\n this.setStrands(\r\n mergeHairStrandSources(\r\n loadZHairStrandSources(parsed, {\r\n strandStride: this._strandStride,\r\n maxStrands: this._maxStrands\r\n })\r\n )\r\n );\r\n }\r\n /**\r\n * Starts strand dynamics over the current strands.\r\n * @internal\r\n */\r\n private _createSimulation() {\r\n this._disposeSimulation();\r\n const data = this._strands.get();\r\n if (!data || !this._source || !isHairSimulationSupported()) {\r\n return;\r\n }\r\n const simulation = new GPUHairSimulation(data, this._source, this._simulationOptions);\r\n if (simulation.enabled) {\r\n this._simulation = simulation;\r\n // Motion vectors have to follow the control points once something is\r\n // moving them, or a groom swinging under a still head reports no motion\r\n // and a temporal filter smears it.\r\n this.material.prevPoints = simulation.framePointBuffer;\r\n // The bounds widen while a simulation runs - see computeBoundingVolume.\r\n this.invalidateBoundingVolume();\r\n this.scene?.queueUpdateNode(this);\r\n } else {\r\n console.warn(simulation.disabledReason ?? 'GPU hair simulation could not start');\r\n simulation.dispose();\r\n }\r\n }\r\n /** @internal */\r\n private _disposeSimulation() {\r\n this.material.prevPoints = null;\r\n this._simulation?.dispose();\r\n this._simulation = null;\r\n }\r\n /**\r\n * Builds the primitive the draw call is issued against.\r\n *\r\n * @remarks\r\n * No vertex attribute is ever read - the vertex shader derives everything from\r\n * the vertex index and the storage buffers - but a draw still needs a vertex\r\n * layout to exist, and one float is the smallest buffer that establishes one.\r\n * @internal\r\n */\r\n private _ensurePrimitive() {\r\n if (this._primitive.get()) {\r\n return;\r\n }\r\n const primitive = new Primitive();\r\n primitive.createAndSetVertexBuffer('position_f32x3', new Float32Array(3));\r\n primitive.primitiveType = 'triangle-list';\r\n this._primitive.set(primitive);\r\n }\r\n /**\r\n * Points the draw range at however many vertices the material now needs.\r\n *\r\n * @remarks\r\n * Drawing is non-indexed, six vertices per ribbon segment, so the count moves\r\n * with both the strand count and {@link HairNode.segmentsPerStrand}.\r\n * @internal\r\n */\r\n private _syncDrawRange() {\r\n const primitive = this._primitive.get();\r\n if (primitive) {\r\n primitive.indexCount = this.material.vertexCount;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Local-space bounds of a strand source, padded by the widest strand, along\r\n * with the length of the longest strand.\r\n *\r\n * @remarks\r\n * The ribbon is built around the control point, so half a width would suffice;\r\n * a full width is used because {@link HairNode.minPixelWidth} widens sub-pixel\r\n * strands beyond their authored size and the box has to survive that.\r\n *\r\n * The strand length is measured here because the same pass already touches\r\n * every point; it pads the bounds while a simulation runs.\r\n * @internal\r\n */\r\nfunction computeStrandExtents(source: HairStrandSource): {\r\n bounds: BoundingBox;\r\n maxStrandLength: number;\r\n} {\r\n const scale = source.scale ?? 1;\r\n const positions = source.positions;\r\n const box = new BoundingBox();\r\n box.beginExtend();\r\n let maxStrandLength = 0;\r\n let first = 0;\r\n for (let s = 0; s < source.pointCounts.length; s++) {\r\n const count = source.pointCounts[s];\r\n let length = 0;\r\n for (let i = 0; i < count; i++) {\r\n const p = (first + i) * 3;\r\n const x = positions[p] * scale;\r\n const y = positions[p + 1] * scale;\r\n const z = positions[p + 2] * scale;\r\n box.extend3(x, y, z);\r\n if (i > 0) {\r\n length += Math.hypot(\r\n x - positions[p - 3] * scale,\r\n y - positions[p - 2] * scale,\r\n z - positions[p - 1] * scale\r\n );\r\n }\r\n }\r\n if (length > maxStrandLength) {\r\n maxStrandLength = length;\r\n }\r\n first += count;\r\n }\r\n let widest = source.defaultWidth ?? 0.0001;\r\n if (source.widths) {\r\n for (let i = 0; i < source.widths.length; i++) {\r\n if (source.widths[i] > widest) {\r\n widest = source.widths[i];\r\n }\r\n }\r\n }\r\n const pad = widest * scale * (source.widthScale ?? 1);\r\n box.minPoint.setXYZ(box.minPoint.x - pad, box.minPoint.y - pad, box.minPoint.z - pad);\r\n box.maxPoint.setXYZ(box.maxPoint.x + pad, box.maxPoint.y + pad, box.maxPoint.z + pad);\r\n return { bounds: box, maxStrandLength };\r\n}\r\n"],"names":["HairNode","applyMixins","GraphNode","mixinDrawable","scene","_pickTarget","node","_material","DRef","HairStrandMaterial","_primitive","_strands","_bounds","_maxStrandLength","_castShadow","_source","_hairAsset","_parsedAsset","_strandStride","_maxStrands","_simulation","_simulationEnabled","_simulationOptions","gravity","Vector3","damping","globalStiffness","globalRange","localStiffness","localIterations","ftlDamping","vspCoeff","vspAccelThreshold","substeps","friction","maxSpeedFactor","hairAsset","setHairAsset","path","assetId","trim","setStrands","parsed","data","getEngine","resourceManager","assetManager","fetchBinaryData","parseZHair","err","console","error","_applyAssetDecimation","strandStride","val","v","maxStrands","strands","get","strandCount","source","_disposeSimulation","dispose","material","invalidateBoundingVolume","HairStrandData","set","extents","computeStrandExtents","bounds","maxStrandLength","_ensurePrimitive","_syncDrawRange","_createSimulation","albedoColor","value","shadingModel","specular1Color","specular1Power","specular1Shift","specular2Color","specular2Power","specular2Shift","diffuseWrap","transmissionColor","transmissionIntensity","transmissionPower","scatterColor","scatterIntensity","scatterLocal","scatterWrap","marschnerShift","marschnerRoughness","marschnerIOR","marschnerAbsorption","marschnerLobes","segmentsPerStrand","strandWidthScale","minStrandWidth","minPixelWidth","strandRoundness","rootOcclusion","rootOcclusionRange","strandLOD","minStrandLODRatio","blendMode","alphaCutoff","alphaDither","transparentMotionVector","castShadow","transparentShadowCaster","shadowAlphaCutoff","simulationEnabled","enabled","simulation","update","frameId","elapsedInSeconds","deltaInSeconds","worldMatrix","queueUpdateNode","computeBoundingVolume","box","BoundingBox","pad","minPoint","setXYZ","x","y","z","maxPoint","isHair","getPickTarget","getMaterial","getPrimitive","getMorphData","getMorphInfo","getSkinInfluenceData","getQueueType","QUEUE_OPAQUE","isUnlit","supportLighting","needSceneColor","needSceneDepth","draw","ctx","renderQueue","primitive","vertexCount","bind","onDispose","mergeHairStrandSources","loadZHairStrandSources","isHairSimulationSupported","GPUHairSimulation","prevPoints","framePointBuffer","warn","disabledReason","Primitive","createAndSetVertexBuffer","Float32Array","primitiveType","indexCount","scale","positions","beginExtend","first","s","pointCounts","length","count","i","p","extend3","Math","hypot","widest","defaultWidth","widths","widthScale"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA;;;;;;;;;AASC,IACM,MAAMA,QAAiBC,SAAAA,WAAAA,CAAYC,SAAWC,EAAAA,aAAAA,CAAAA,CAAAA;qBAEnD,WAAyC;qBAEzC,SAAqD;qBAErD,UAA6C;qBAE7C,QAAgD;+EAEhD,OAAuC;4FAEvC,gBAAiC;qBAEjC,WAA6B;mFAE7B,OAA4C;uFAE5C,UAA2B;AAC3B;;;AAGC,MACD,YAA4C;qBAE5C,aAA8B;qBAE9B,WAA4B;qBAE5B,WAAiD;qBAEjD,kBAAoC;AACpC;;;;;;AAMC,MACD,kBAA8D;AAC9D;;;;MAKA,WAAA,CAAYC,KAAY,CAAE;AACxB,QAAA,KAAK,CAACA,KAAAA,CAAAA;QACN,IAAI,CAACC,WAAW,GAAG;AAAEC,YAAAA,IAAAA,EAAM;AAAK,SAAA;AAChC,QAAA,IAAI,CAACC,SAAS,GAAG,IAAIC,KAAK,IAAIC,kBAAAA,EAAAA,CAAAA;QAC9B,IAAI,CAACC,UAAU,GAAG,IAAIF,IAAAA,EAAAA;QACtB,IAAI,CAACG,QAAQ,GAAG,IAAIH,IAAAA,EAAAA;QACpB,IAAI,CAACI,OAAO,GAAG,IAAA;QACf,IAAI,CAACC,gBAAgB,GAAG,CAAA;QACxB,IAAI,CAACC,WAAW,GAAG,IAAA;QACnB,IAAI,CAACC,OAAO,GAAG,IAAA;QACf,IAAI,CAACC,UAAU,GAAG,EAAA;QAClB,IAAI,CAACC,YAAY,GAAG,IAAA;QACpB,IAAI,CAACC,aAAa,GAAG,CAAA;QACrB,IAAI,CAACC,WAAW,GAAG,CAAA;QACnB,IAAI,CAACC,WAAW,GAAG,IAAA;QACnB,IAAI,CAACC,kBAAkB,GAAG,KAAA;QAC1B,IAAI,CAACC,kBAAkB,GAAG;AACxBC,YAAAA,OAAAA,EAAS,IAAIC,OAAAA,CAAQ,CAAG,EAAA,IAAM,EAAA,CAAA,CAAA;YAC9BC,OAAS,EAAA,IAAA;YACTC,eAAiB,EAAA,CAAA;YACjBC,WAAa,EAAA,CAAA;YACbC,cAAgB,EAAA,GAAA;YAChBC,eAAiB,EAAA,CAAA;YACjBC,UAAY,EAAA,GAAA;YACZC,QAAU,EAAA,GAAA;YACVC,iBAAmB,EAAA,EAAA;YACnBC,QAAU,EAAA,CAAA;YACVC,QAAU,EAAA,GAAA;YACVC,cAAgB,EAAA;AAClB,SAAA;AACF;;;;2EAOA,IAAIC,SAAY,GAAA;QACd,OAAO,IAAI,CAACpB,UAAU;AACxB;AACA;;;;;;;;;;MAWA,MAAMqB,YAAaC,CAAAA,IAAY,EAAE;QAC/B,MAAMC,OAAAA,GAAUD,MAAME,IAAU,EAAA,IAAA,EAAA;AAChC,QAAA,IAAID,OAAY,KAAA,IAAI,CAACvB,UAAU,EAAE;AAC/B,YAAA;AACF;QACA,IAAI,CAACA,UAAU,GAAGuB,OAAAA;QAClB,IAAI,CAACtB,YAAY,GAAG,IAAA;AACpB,QAAA,IAAI,CAACsB,OAAS,EAAA;YACZ,IAAI,CAACE,UAAU,CAAC,IAAA,CAAA;AAChB,YAAA;AACF;QACA,IAAIC,MAAAA;QACJ,IAAI;YACF,MAAMC,IAAAA,GAAQ,MAAMC,SAAYC,EAAAA,CAAAA,eAAe,CAACC,YAAY,CAACC,eAAe,CAACR,OAAAA,CAAAA;AAC7EG,YAAAA,MAAAA,GAASM,UAAWL,CAAAA,IAAAA,CAAAA;AACtB,SAAA,CAAE,OAAOM,GAAK,EAAA;YACZC,OAAQC,CAAAA,KAAK,CAAC,CAAC,wBAAwB,EAAEZ,OAAQ,CAAA,EAAE,EAAEU,GAAK,CAAA,CAAA,CAAA;YAC1D,IAAI,CAACR,UAAU,CAAC,IAAA,CAAA;AAChB,YAAA;AACF;;;AAGA,QAAA,IAAI,IAAI,CAACzB,UAAU,KAAKuB,OAAS,EAAA;AAC/B,YAAA;AACF;QACA,IAAI,CAACtB,YAAY,GAAGyB,MAAAA;AACpB,QAAA,IAAI,CAACU,qBAAqB,EAAA;AAC5B;AACA;;;;;;;AAOC,MACD,IAAIC,YAAe,GAAA;QACjB,OAAO,IAAI,CAACnC,aAAa;AAC3B;IACA,IAAImC,YAAAA,CAAaC,GAAW,EAAE;AAC5B,QAAA,MAAMC,CAAID,GAAAA,GAAAA,GAAM,CAAI,GAAA,CAAA,GAAIA,GAAM,GAAA,CAAA;AAC9B,QAAA,IAAIC,CAAM,KAAA,IAAI,CAACrC,aAAa,EAAE;YAC5B,IAAI,CAACA,aAAa,GAAGqC,CAAAA;AACrB,YAAA,IAAI,CAACH,qBAAqB,EAAA;AAC5B;AACF;AACA;;;;;;AAMC,MACD,IAAII,UAAa,GAAA;QACf,OAAO,IAAI,CAACrC,WAAW;AACzB;IACA,IAAIqC,UAAAA,CAAWF,GAAW,EAAE;AAC1B,QAAA,MAAMC,CAAID,GAAAA,GAAAA,GAAM,CAAI,GAAA,CAAA,GAAIA,GAAM,GAAA,CAAA;AAC9B,QAAA,IAAIC,CAAM,KAAA,IAAI,CAACpC,WAAW,EAAE;YAC1B,IAAI,CAACA,WAAW,GAAGoC,CAAAA;AACnB,YAAA,IAAI,CAACH,qBAAqB,EAAA;AAC5B;AACF;8EAEA,IAAIK,OAAoC,GAAA;AACtC,QAAA,OAAO,IAAI,CAAC9C,QAAQ,CAAC+C,GAAG,EAAA;AAC1B;8CAEA,IAAIC,WAAc,GAAA;AAChB,QAAA,OAAO,IAAI,CAAChD,QAAQ,CAAC+C,GAAG,IAAIC,WAAe,IAAA,CAAA;AAC7C;AACA;;;;;;;;;;MAWAlB,UAAAA,CAAWmB,MAAkC,EAAE;AAC7C,QAAA,IAAI,CAACC,kBAAkB,EAAA;QACvB,IAAI,CAAClD,QAAQ,CAACmD,OAAO,EAAA;QACrB,IAAI,CAAClD,OAAO,GAAG,IAAA;QACf,IAAI,CAACC,gBAAgB,GAAG,CAAA;QACxB,IAAI,CAACE,OAAO,GAAG,IAAA;AACf,QAAA,IAAI,CAAC6C,MAAQ,EAAA;AACX,YAAA,IAAI,CAACG,QAAQ,CAACN,OAAO,GAAG,IAAA;YACxB,IAAI,CAAC/C,UAAU,CAACoD,OAAO,EAAA;AACvB,YAAA,IAAI,CAACE,wBAAwB,EAAA;AAC7B,YAAA;AACF;QACA,MAAMrB,IAAAA,GAAO,IAAIsB,cAAeL,CAAAA,MAAAA,CAAAA;AAChC,QAAA,IAAI,CAACjD,QAAQ,CAACuD,GAAG,CAACvB,IAAAA,CAAAA;QAClB,IAAI,CAAC5B,OAAO,GAAG6C,MAAAA;AACf,QAAA,IAAI,CAACG,QAAQ,CAACN,OAAO,GAAGd,IAAAA;AACxB,QAAA,MAAMwB,UAAUC,oBAAqBR,CAAAA,MAAAA,CAAAA;AACrC,QAAA,IAAI,CAAChD,OAAO,GAAGuD,OAAAA,CAAQE,MAAM;AAC7B,QAAA,IAAI,CAACxD,gBAAgB,GAAGsD,OAAAA,CAAQG,eAAe;AAC/C,QAAA,IAAI,CAACC,gBAAgB,EAAA;AACrB,QAAA,IAAI,CAACC,cAAc,EAAA;AACnB,QAAA,IAAI,CAACR,wBAAwB,EAAA;QAC7B,IAAI,IAAI,CAAC3C,kBAAkB,EAAE;AAC3B,YAAA,IAAI,CAACoD,iBAAiB,EAAA;AACxB;AACF;;;;;;;;;;uCAaA,IAAIC,WAAkC,GAAA;AACpC,QAAA,OAAO,IAAI,CAACX,QAAQ,CAACW,WAAW;AAClC;IACA,IAAIA,WAAAA,CAAYC,KAAc,EAAE;AAC9B,QAAA,IAAI,CAACZ,QAAQ,CAACW,WAAW,GAAGC,KAAAA;AAC9B;AACA;;;;;;AAMC,MACD,IAAIC,YAAiC,GAAA;AACnC,QAAA,OAAO,IAAI,CAACb,QAAQ,CAACa,YAAY;AACnC;IACA,IAAIA,YAAAA,CAAaD,KAAuB,EAAE;AACxC,QAAA,IAAI,CAACZ,QAAQ,CAACa,YAAY,GAAGD,KAAAA;AAC/B;4DAEA,IAAIE,cAAqC,GAAA;AACvC,QAAA,OAAO,IAAI,CAACd,QAAQ,CAACc,cAAc;AACrC;IACA,IAAIA,cAAAA,CAAeF,KAAc,EAAE;AACjC,QAAA,IAAI,CAACZ,QAAQ,CAACc,cAAc,GAAGF,KAAAA;AACjC;kDAEA,IAAIG,cAAiB,GAAA;AACnB,QAAA,OAAO,IAAI,CAACf,QAAQ,CAACe,cAAc;AACrC;IACA,IAAIA,cAAAA,CAAeH,KAAa,EAAE;AAChC,QAAA,IAAI,CAACZ,QAAQ,CAACe,cAAc,GAAGH,KAAAA;AACjC;gEAEA,IAAII,cAAiB,GAAA;AACnB,QAAA,OAAO,IAAI,CAAChB,QAAQ,CAACgB,cAAc;AACrC;IACA,IAAIA,cAAAA,CAAeJ,KAAa,EAAE;AAChC,QAAA,IAAI,CAACZ,QAAQ,CAACgB,cAAc,GAAGJ,KAAAA;AACjC;0DAEA,IAAIK,cAAqC,GAAA;AACvC,QAAA,OAAO,IAAI,CAACjB,QAAQ,CAACiB,cAAc;AACrC;IACA,IAAIA,cAAAA,CAAeL,KAAc,EAAE;AACjC,QAAA,IAAI,CAACZ,QAAQ,CAACiB,cAAc,GAAGL,KAAAA;AACjC;oDAEA,IAAIM,cAAiB,GAAA;AACnB,QAAA,OAAO,IAAI,CAAClB,QAAQ,CAACkB,cAAc;AACrC;IACA,IAAIA,cAAAA,CAAeN,KAAa,EAAE;AAChC,QAAA,IAAI,CAACZ,QAAQ,CAACkB,cAAc,GAAGN,KAAAA;AACjC;kEAEA,IAAIO,cAAiB,GAAA;AACnB,QAAA,OAAO,IAAI,CAACnB,QAAQ,CAACmB,cAAc;AACrC;IACA,IAAIA,cAAAA,CAAeP,KAAa,EAAE;AAChC,QAAA,IAAI,CAACZ,QAAQ,CAACmB,cAAc,GAAGP,KAAAA;AACjC;4DAEA,IAAIQ,WAAc,GAAA;AAChB,QAAA,OAAO,IAAI,CAACpB,QAAQ,CAACoB,WAAW;AAClC;IACA,IAAIA,WAAAA,CAAYR,KAAa,EAAE;AAC7B,QAAA,IAAI,CAACZ,QAAQ,CAACoB,WAAW,GAAGR,KAAAA;AAC9B;0DAEA,IAAIS,iBAAwC,GAAA;AAC1C,QAAA,OAAO,IAAI,CAACrB,QAAQ,CAACqB,iBAAiB;AACxC;IACA,IAAIA,iBAAAA,CAAkBT,KAAc,EAAE;AACpC,QAAA,IAAI,CAACZ,QAAQ,CAACqB,iBAAiB,GAAGT,KAAAA;AACpC;8CAEA,IAAIU,qBAAwB,GAAA;AAC1B,QAAA,OAAO,IAAI,CAACtB,QAAQ,CAACsB,qBAAqB;AAC5C;IACA,IAAIA,qBAAAA,CAAsBV,KAAa,EAAE;AACvC,QAAA,IAAI,CAACZ,QAAQ,CAACsB,qBAAqB,GAAGV,KAAAA;AACxC;sDAEA,IAAIW,iBAAoB,GAAA;AACtB,QAAA,OAAO,IAAI,CAACvB,QAAQ,CAACuB,iBAAiB;AACxC;IACA,IAAIA,iBAAAA,CAAkBX,KAAa,EAAE;AACnC,QAAA,IAAI,CAACZ,QAAQ,CAACuB,iBAAiB,GAAGX,KAAAA;AACpC;2DAEA,IAAIY,YAAmC,GAAA;AACrC,QAAA,OAAO,IAAI,CAACxB,QAAQ,CAACwB,YAAY;AACnC;IACA,IAAIA,YAAAA,CAAaZ,KAAc,EAAE;AAC/B,QAAA,IAAI,CAACZ,QAAQ,CAACwB,YAAY,GAAGZ,KAAAA;AAC/B;4CAEA,IAAIa,gBAAmB,GAAA;AACrB,QAAA,OAAO,IAAI,CAACzB,QAAQ,CAACyB,gBAAgB;AACvC;IACA,IAAIA,gBAAAA,CAAiBb,KAAa,EAAE;AAClC,QAAA,IAAI,CAACZ,QAAQ,CAACyB,gBAAgB,GAAGb,KAAAA;AACnC;kEAEA,IAAIc,YAAe,GAAA;AACjB,QAAA,OAAO,IAAI,CAAC1B,QAAQ,CAAC0B,YAAY;AACnC;IACA,IAAIA,YAAAA,CAAad,KAAa,EAAE;AAC9B,QAAA,IAAI,CAACZ,QAAQ,CAAC0B,YAAY,GAAGd,KAAAA;AAC/B;2DAEA,IAAIe,WAAc,GAAA;AAChB,QAAA,OAAO,IAAI,CAAC3B,QAAQ,CAAC2B,WAAW;AAClC;IACA,IAAIA,WAAAA,CAAYf,KAAa,EAAE;AAC7B,QAAA,IAAI,CAACZ,QAAQ,CAAC2B,WAAW,GAAGf,KAAAA;AAC9B;sDAEA,IAAIgB,cAAiB,GAAA;AACnB,QAAA,OAAO,IAAI,CAAC5B,QAAQ,CAAC4B,cAAc;AACrC;IACA,IAAIA,cAAAA,CAAehB,KAAa,EAAE;AAChC,QAAA,IAAI,CAACZ,QAAQ,CAAC4B,cAAc,GAAGhB,KAAAA;AACjC;0DAEA,IAAIiB,kBAAqB,GAAA;AACvB,QAAA,OAAO,IAAI,CAAC7B,QAAQ,CAAC6B,kBAAkB;AACzC;IACA,IAAIA,kBAAAA,CAAmBjB,KAAa,EAAE;AACpC,QAAA,IAAI,CAACZ,QAAQ,CAAC6B,kBAAkB,GAAGjB,KAAAA;AACrC;6CAEA,IAAIkB,YAAe,GAAA;AACjB,QAAA,OAAO,IAAI,CAAC9B,QAAQ,CAAC8B,YAAY;AACnC;IACA,IAAIA,YAAAA,CAAalB,KAAa,EAAE;AAC9B,QAAA,IAAI,CAACZ,QAAQ,CAAC8B,YAAY,GAAGlB,KAAAA;AAC/B;AACA;;;;;;;AAOC,MACD,IAAImB,mBAAsB,GAAA;AACxB,QAAA,OAAO,IAAI,CAAC/B,QAAQ,CAAC+B,mBAAmB;AAC1C;IACA,IAAIA,mBAAAA,CAAoBnB,KAAa,EAAE;AACrC,QAAA,IAAI,CAACZ,QAAQ,CAAC+B,mBAAmB,GAAGnB,KAAAA;AACtC;uDAEA,IAAIoB,cAAqC,GAAA;AACvC,QAAA,OAAO,IAAI,CAAChC,QAAQ,CAACgC,cAAc;AACrC;IACA,IAAIA,cAAAA,CAAepB,KAAyB,EAAE;AAC5C,QAAA,IAAI,CAACZ,QAAQ,CAACgC,cAAc,GAAGpB,KAAAA;AACjC;;;;AAMA;;;;;;;AAOC,MACD,IAAIqB,iBAAoB,GAAA;AACtB,QAAA,OAAO,IAAI,CAACjC,QAAQ,CAACiC,iBAAiB;AACxC;IACA,IAAIA,iBAAAA,CAAkB1C,GAAW,EAAE;AACjC,QAAA,IAAIA,QAAQ,IAAI,CAACS,QAAQ,CAACiC,iBAAiB,EAAE;AAC3C,YAAA,IAAI,CAACjC,QAAQ,CAACiC,iBAAiB,GAAG1C,GAAAA;AAClC,YAAA,IAAI,CAACkB,cAAc,EAAA;AACrB;AACF;8DAEA,IAAIyB,gBAAmB,GAAA;AACrB,QAAA,OAAO,IAAI,CAAClC,QAAQ,CAACkC,gBAAgB;AACvC;IACA,IAAIA,gBAAAA,CAAiBtB,KAAa,EAAE;AAClC,QAAA,IAAI,CAACZ,QAAQ,CAACkC,gBAAgB,GAAGtB,KAAAA;AACnC;wDAEA,IAAIuB,cAAiB,GAAA;AACnB,QAAA,OAAO,IAAI,CAACnC,QAAQ,CAACmC,cAAc;AACrC;IACA,IAAIA,cAAAA,CAAevB,KAAa,EAAE;AAChC,QAAA,IAAI,CAACZ,QAAQ,CAACmC,cAAc,GAAGvB,KAAAA;AACjC;AACA;;;;;;;AAOC,MACD,IAAIwB,aAAgB,GAAA;AAClB,QAAA,OAAO,IAAI,CAACpC,QAAQ,CAACoC,aAAa;AACpC;IACA,IAAIA,aAAAA,CAAcxB,KAAa,EAAE;AAC/B,QAAA,IAAI,CAACZ,QAAQ,CAACoC,aAAa,GAAGxB,KAAAA;AAChC;AACA;;;;;AAKC,MACD,IAAIyB,eAAkB,GAAA;AACpB,QAAA,OAAO,IAAI,CAACrC,QAAQ,CAACqC,eAAe;AACtC;IACA,IAAIA,eAAAA,CAAgBzB,KAAa,EAAE;AACjC,QAAA,IAAI,CAACZ,QAAQ,CAACqC,eAAe,GAAGzB,KAAAA;AAClC;AACA;;;;;;;;;;;;;AAaC,MACD,IAAI0B,aAAgB,GAAA;AAClB,QAAA,OAAO,IAAI,CAACtC,QAAQ,CAACsC,aAAa;AACpC;IACA,IAAIA,aAAAA,CAAc1B,KAAa,EAAE;AAC/B,QAAA,IAAI,CAACZ,QAAQ,CAACsC,aAAa,GAAG1B,KAAAA;AAChC;AACA;;;;;;AAMC,MACD,IAAI2B,kBAAqB,GAAA;AACvB,QAAA,OAAO,IAAI,CAACvC,QAAQ,CAACuC,kBAAkB;AACzC;IACA,IAAIA,kBAAAA,CAAmB3B,KAAa,EAAE;AACpC,QAAA,IAAI,CAACZ,QAAQ,CAACuC,kBAAkB,GAAG3B,KAAAA;AACrC;uFAEA,IAAI4B,SAAY,GAAA;AACd,QAAA,OAAO,IAAI,CAACxC,QAAQ,CAACwC,SAAS;AAChC;IACA,IAAIA,SAAAA,CAAU5B,KAAc,EAAE;AAC5B,QAAA,IAAI,CAACZ,QAAQ,CAACwC,SAAS,GAAG5B,KAAAA;AAC5B;uEAEA,IAAI6B,iBAAoB,GAAA;AACtB,QAAA,OAAO,IAAI,CAACzC,QAAQ,CAACyC,iBAAiB;AACxC;IACA,IAAIA,iBAAAA,CAAkB7B,KAAa,EAAE;AACnC,QAAA,IAAI,CAACZ,QAAQ,CAACyC,iBAAiB,GAAG7B,KAAAA;AACpC;;;;AAMA;;;;;;;AAOC,MACD,IAAI8B,SAAuB,GAAA;AACzB,QAAA,OAAO,IAAI,CAAC1C,QAAQ,CAAC0C,SAAS;AAChC;IACA,IAAIA,SAAAA,CAAU9B,KAAgB,EAAE;AAC9B,QAAA,IAAI,CAACZ,QAAQ,CAAC0C,SAAS,GAAG9B,KAAAA;AAC5B;sDAEA,IAAI+B,WAAc,GAAA;AAChB,QAAA,OAAO,IAAI,CAAC3C,QAAQ,CAAC2C,WAAW;AAClC;IACA,IAAIA,WAAAA,CAAY/B,KAAa,EAAE;AAC7B,QAAA,IAAI,CAACZ,QAAQ,CAAC2C,WAAW,GAAG/B,KAAAA;AAC9B;+EAEA,IAAIgC,WAAc,GAAA;AAChB,QAAA,OAAO,IAAI,CAAC5C,QAAQ,CAAC4C,WAAW;AAClC;IACA,IAAIA,WAAAA,CAAYhC,KAAc,EAAE;AAC9B,QAAA,IAAI,CAACZ,QAAQ,CAAC4C,WAAW,GAAGhC,KAAAA;AAC9B;AACA;;;;;;;;;;AAUC,MACD,IAAIiC,uBAA0B,GAAA;AAC5B,QAAA,OAAO,IAAI,CAAC7C,QAAQ,CAAC6C,uBAAuB;AAC9C;IACA,IAAIA,uBAAAA,CAAwBjC,KAAc,EAAE;AAC1C,QAAA,IAAI,CAACZ,QAAQ,CAAC6C,uBAAuB,GAAGjC,KAAAA;AAC1C;wDAEA,IAAIkC,UAAa,GAAA;QACf,OAAO,IAAI,CAAC/F,WAAW;AACzB;IACA,IAAI+F,UAAAA,CAAWvD,GAAY,EAAE;AAC3B,QAAA,IAAI,CAACxC,WAAW,GAAG,CAAC,CAACwC,GAAAA;AACvB;uFAEA,IAAIwD,uBAA0B,GAAA;AAC5B,QAAA,OAAO,IAAI,CAAC/C,QAAQ,CAAC+C,uBAAuB;AAC9C;IACA,IAAIA,uBAAAA,CAAwBnC,KAAc,EAAE;AAC1C,QAAA,IAAI,CAACZ,QAAQ,CAAC+C,uBAAuB,GAAGnC,KAAAA;AAC1C;yDAEA,IAAIoC,iBAAoB,GAAA;AACtB,QAAA,OAAO,IAAI,CAAChD,QAAQ,CAACgD,iBAAiB;AACxC;IACA,IAAIA,iBAAAA,CAAkBpC,KAAa,EAAE;AACnC,QAAA,IAAI,CAACZ,QAAQ,CAACgD,iBAAiB,GAAGpC,KAAAA;AACpC;;;;AAMA;;;;;;AAMC,MACD,IAAIqC,iBAAoB,GAAA;QACtB,OAAO,IAAI,CAAC3F,kBAAkB;AAChC;IACA,IAAI2F,iBAAAA,CAAkB1D,GAAY,EAAE;QAClC,MAAM2D,OAAAA,GAAU,CAAC,CAAC3D,GAAAA;AAClB,QAAA,IAAI2D,OAAY,KAAA,IAAI,CAAC5F,kBAAkB,EAAE;AACvC,YAAA;AACF;QACA,IAAI,CAACA,kBAAkB,GAAG4F,OAAAA;AAC1B,QAAA,IAAIA,OAAS,EAAA;AACX,YAAA,IAAI,CAACxC,iBAAiB,EAAA;SACjB,MAAA;AACL,YAAA,IAAI,CAACZ,kBAAkB,EAAA;;;YAGvB,IAAI,IAAI,CAAC9C,OAAO,EAAE;AAChB,gBAAA,IAAI,CAACJ,QAAQ,CAAC+C,GAAG,EAAII,EAAAA,OAAAA,EAAAA;gBACrB,IAAI,CAACnD,QAAQ,CAACuD,GAAG,CAAC,IAAID,cAAAA,CAAe,IAAI,CAAClD,OAAO,CAAA,CAAA;gBACjD,IAAI,CAACgD,QAAQ,CAACN,OAAO,GAAG,IAAI,CAAC9C,QAAQ,CAAC+C,GAAG,EAAA;AAC3C;;AAEA,YAAA,IAAI,CAACM,wBAAwB,EAAA;AAC/B;AACF;AACA;;;;;;AAMC,MACD,IAAIkD,UAA0C,GAAA;QAC5C,OAAO,IAAI,CAAC9F,WAAW;AACzB;sDAEA,IAAIG,OAA8B,GAAA;AAChC,QAAA,OAAO,IAAI,CAACD,kBAAkB,CAACC,OAAO;AACxC;IACA,IAAIA,OAAAA,CAAQoD,KAAc,EAAE;AAC1B,QAAA,IAAI,CAACrD,kBAAkB,CAACC,OAAO,GAAG,IAAIC,OAAQmD,CAAAA,KAAAA,CAAAA;QAC9C,IAAI,IAAI,CAACvD,WAAW,EAAE;YACpB,IAAI,CAACA,WAAW,CAACG,OAAO,GAAG,IAAI,CAACD,kBAAkB,CAACC,OAAO;AAC5D;AACF;AACA;;;;;;;;;AASC,MACD,IAAIK,cAAiB,GAAA;AACnB,QAAA,OAAO,IAAI,CAACN,kBAAkB,CAACM,cAAc;AAC/C;IACA,IAAIA,cAAAA,CAAe+C,KAAa,EAAE;AAChC,QAAA,IAAI,CAACrD,kBAAkB,CAACM,cAAc,GAAG+C,KAAAA;QACzC,IAAI,IAAI,CAACvD,WAAW,EAAE;AACpB,YAAA,IAAI,CAACA,WAAW,CAACQ,cAAc,GAAG+C,KAAAA;AACpC;AACF;sDAEA,IAAI9C,eAAkB,GAAA;AACpB,QAAA,OAAO,IAAI,CAACP,kBAAkB,CAACO,eAAe;AAChD;IACA,IAAIA,eAAAA,CAAgB8C,KAAa,EAAE;AACjC,QAAA,IAAI,CAACrD,kBAAkB,CAACO,eAAe,GAAG8C,KAAAA;QAC1C,IAAI,IAAI,CAACvD,WAAW,EAAE;AACpB,YAAA,IAAI,CAACA,WAAW,CAACS,eAAe,GAAG8C,KAAAA;AACrC;AACF;AACA;;;;;;;;;AASC,MACD,IAAIjD,eAAkB,GAAA;AACpB,QAAA,OAAO,IAAI,CAACJ,kBAAkB,CAACI,eAAe;AAChD;IACA,IAAIA,eAAAA,CAAgBiD,KAAa,EAAE;AACjC,QAAA,IAAI,CAACrD,kBAAkB,CAACI,eAAe,GAAGiD,KAAAA;QAC1C,IAAI,IAAI,CAACvD,WAAW,EAAE;AACpB,YAAA,IAAI,CAACA,WAAW,CAACM,eAAe,GAAGiD,KAAAA;AACrC;AACF;kFAEA,IAAIhD,WAAc,GAAA;AAChB,QAAA,OAAO,IAAI,CAACL,kBAAkB,CAACK,WAAW;AAC5C;IACA,IAAIA,WAAAA,CAAYgD,KAAa,EAAE;AAC7B,QAAA,IAAI,CAACrD,kBAAkB,CAACK,WAAW,GAAGgD,KAAAA;QACtC,IAAI,IAAI,CAACvD,WAAW,EAAE;AACpB,YAAA,IAAI,CAACA,WAAW,CAACO,WAAW,GAAGgD,KAAAA;AACjC;AACF;AACA;;;;;;;AAOC,MACD,IAAI7C,UAAa,GAAA;AACf,QAAA,OAAO,IAAI,CAACR,kBAAkB,CAACQ,UAAU;AAC3C;IACA,IAAIA,UAAAA,CAAW6C,KAAa,EAAE;AAC5B,QAAA,IAAI,CAACrD,kBAAkB,CAACQ,UAAU,GAAG6C,KAAAA;QACrC,IAAI,IAAI,CAACvD,WAAW,EAAE;AACpB,YAAA,IAAI,CAACA,WAAW,CAACU,UAAU,GAAG6C,KAAAA;AAChC;AACF;+CAEA,IAAIlD,OAAU,GAAA;AACZ,QAAA,OAAO,IAAI,CAACH,kBAAkB,CAACG,OAAO;AACxC;IACA,IAAIA,OAAAA,CAAQkD,KAAa,EAAE;AACzB,QAAA,IAAI,CAACrD,kBAAkB,CAACG,OAAO,GAAGkD,KAAAA;QAClC,IAAI,IAAI,CAACvD,WAAW,EAAE;AACpB,YAAA,IAAI,CAACA,WAAW,CAACK,OAAO,GAAGkD,KAAAA;AAC7B;AACF;8DAEA,IAAIzC,QAAW,GAAA;AACb,QAAA,OAAO,IAAI,CAACZ,kBAAkB,CAACY,QAAQ;AACzC;IACA,IAAIA,QAAAA,CAASyC,KAAa,EAAE;AAC1B,QAAA,IAAI,CAACrD,kBAAkB,CAACY,QAAQ,GAAGyC,KAAAA;QACnC,IAAI,IAAI,CAACvD,WAAW,EAAE;AACpB,YAAA,IAAI,CAACA,WAAW,CAACc,QAAQ,GAAGyC,KAAAA;AAC9B;AACF;AACA;;;;;;;AAOC,MACD,IAAI5C,QAAW,GAAA;AACb,QAAA,OAAO,IAAI,CAACT,kBAAkB,CAACS,QAAQ;AACzC;IACA,IAAIA,QAAAA,CAAS4C,KAAa,EAAE;AAC1B,QAAA,IAAI,CAACrD,kBAAkB,CAACS,QAAQ,GAAG4C,KAAAA;QACnC,IAAI,IAAI,CAACvD,WAAW,EAAE;AACpB,YAAA,IAAI,CAACA,WAAW,CAACW,QAAQ,GAAG4C,KAAAA;AAC9B;AACF;mFAEA,IAAI3C,iBAAoB,GAAA;AACtB,QAAA,OAAO,IAAI,CAACV,kBAAkB,CAACU,iBAAiB;AAClD;IACA,IAAIA,iBAAAA,CAAkB2C,KAAa,EAAE;AACnC,QAAA,IAAI,CAACrD,kBAAkB,CAACU,iBAAiB,GAAG2C,KAAAA;QAC5C,IAAI,IAAI,CAACvD,WAAW,EAAE;AACpB,YAAA,IAAI,CAACA,WAAW,CAACY,iBAAiB,GAAG2C,KAAAA;AACvC;AACF;AACA;;;;;;AAMC,MACD,IAAIxC,cAAiB,GAAA;AACnB,QAAA,OAAO,IAAI,CAACb,kBAAkB,CAACa,cAAc;AAC/C;IACA,IAAIA,cAAAA,CAAewC,KAAa,EAAE;AAChC,QAAA,IAAI,CAACrD,kBAAkB,CAACa,cAAc,GAAGwC,KAAAA;QACzC,IAAI,IAAI,CAACvD,WAAW,EAAE;AACpB,YAAA,IAAI,CAACA,WAAW,CAACe,cAAc,GAAGwC,KAAAA;AACpC;AACF;gDAEA,IAAI1C,QAAW,GAAA;AACb,QAAA,OAAO,IAAI,CAACX,kBAAkB,CAACW,QAAQ;AACzC;IACA,IAAIA,QAAAA,CAAS0C,KAAa,EAAE;AAC1B,QAAA,IAAI,CAACrD,kBAAkB,CAACW,QAAQ,GAAG0C,KAAAA;QACnC,IAAI,IAAI,CAACvD,WAAW,EAAE;AACpB,YAAA,IAAI,CAACA,WAAW,CAACa,QAAQ,GAAG0C,KAAAA;AAC9B;AACF;;;;AAMA;;;;;;AAMC,MACDwC,OAAOC,OAAe,EAAEC,gBAAwB,EAAEC,cAAsB,EAAE;QACxE,KAAK,CAACH,MAAOC,CAAAA,OAAAA,EAASC,gBAAkBC,EAAAA,cAAAA,CAAAA;QACxC,MAAMJ,UAAAA,GAAa,IAAI,CAAC9F,WAAW;AACnC,QAAA,IAAI8F,YAAYD,OAAS,EAAA;AACvBC,YAAAA,UAAAA,CAAWC,MAAM,CAACG,cAAgB,EAAA,IAAI,CAACC,WAAW,CAAA;AAClD,YAAA,IAAI,CAACnH,KAAK,EAAEoH,eAAAA,CAAgB,IAAI,CAAA;AAClC;AACF;AACA;;;;;;;;;;;;AAYC,MACDC,qBAA+C,GAAA;AAC7C,QAAA,IAAI,CAAC,IAAI,CAAC7G,OAAO,EAAE;YACjB,OAAO,IAAA;AACT;AACA,QAAA,MAAM8G,GAAM,GAAA,IAAIC,WAAY,CAAA,IAAI,CAAC/G,OAAO,CAAA;QACxC,IAAI,IAAI,CAACQ,WAAW,EAAE;YACpB,MAAMwG,GAAAA,GAAM,IAAI,CAAC/G,gBAAgB;YACjC6G,GAAIG,CAAAA,QAAQ,CAACC,MAAM,CAACJ,IAAIG,QAAQ,CAACE,CAAC,GAAGH,GAAAA,EAAKF,IAAIG,QAAQ,CAACG,CAAC,GAAGJ,GAAAA,EAAKF,IAAIG,QAAQ,CAACI,CAAC,GAAGL,GAAAA,CAAAA;YACjFF,GAAIQ,CAAAA,QAAQ,CAACJ,MAAM,CAACJ,IAAIQ,QAAQ,CAACH,CAAC,GAAGH,GAAAA,EAAKF,IAAIQ,QAAQ,CAACF,CAAC,GAAGJ,GAAAA,EAAKF,IAAIQ,QAAQ,CAACD,CAAC,GAAGL,GAAAA,CAAAA;AACnF;QACA,OAAOF,GAAAA;AACT;AACA,0CACAS,MAA2B,GAAA;QACzB,OAAO,IAAA;AACT;AACA,gDACAC,aAAgB,GAAA;QACd,OAAO,IAAI,CAAC/H,WAAW;AACzB;AACA,8CACAgI,WAAc,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC9H,SAAS,CAACmD,GAAG,EAAA;AAC3B;AACA,+CACA4E,YAAe,GAAA;AACb,QAAA,OAAO,IAAI,CAAC5H,UAAU,CAACgD,GAAG,EAAA;AAC5B;AACA,+CACA6E,YAAe,GAAA;QACb,OAAO,IAAA;AACT;AACA,+CACAC,YAAe,GAAA;QACb,OAAO,IAAA;AACT;AACA,uDACAC,oBAAuB,GAAA;QACrB,OAAO,IAAA;AACT;AACA,+CACAC,YAAe,GAAA;AACb,QAAA,OAAO,IAAI,CAACnI,SAAS,CAACmD,GAAG,IAAIgF,YAAkBC,EAAAA,IAAAA,YAAAA;AACjD;AACA,0CACAC,OAAU,GAAA;AACR,QAAA,OAAO,CAAC,IAAI,CAACrI,SAAS,CAACmD,GAAG,EAAImF,EAAAA,eAAAA,EAAAA;AAChC;AACA,iDACAC,cAAiB,GAAA;AACf,QAAA,OAAO,IAAI,CAACvI,SAAS,CAACmD,GAAG,IAAIoF,cAAoB,EAAA,IAAA,KAAA;AACnD;AACA,iDACAC,cAAiB,GAAA;AACf,QAAA,OAAO,IAAI,CAACxI,SAAS,CAACmD,GAAG,IAAIqF,cAAoB,EAAA,IAAA,KAAA;AACnD;AACA,uCACAC,IAAAA,CAAKC,GAAgB,EAAEC,WAAkC,EAAE;AACzD,QAAA,MAAMnF,QAAW,GAAA,IAAI,CAACxD,SAAS,CAACmD,GAAG,EAAA;AACnC,QAAA,MAAMyF,SAAY,GAAA,IAAI,CAACzI,UAAU,CAACgD,GAAG,EAAA;;;AAGrC,QAAA,IAAIK,QAAYoF,IAAAA,SAAAA,IAAapF,QAASqF,CAAAA,WAAW,GAAG,CAAG,EAAA;YACrD,IAAI,CAACC,IAAI,CAACJ,GAAKC,EAAAA,WAAAA,CAAAA;YACfnF,QAASiF,CAAAA,IAAI,CAACG,SAAWF,EAAAA,GAAAA,CAAAA;AAC3B;AACF;IACUK,SAAY,GAAA;AACpB,QAAA,KAAK,CAACA,SAAAA,EAAAA;AACN,QAAA,IAAI,CAACzF,kBAAkB,EAAA;QACvB,IAAI,CAACnD,UAAU,CAACoD,OAAO,EAAA;QACvB,IAAI,CAACnD,QAAQ,CAACmD,OAAO,EAAA;QACrB,IAAI,CAACvD,SAAS,CAACuD,OAAO,EAAA;QACtB,IAAI,CAAC7C,YAAY,GAAG,IAAA;QACpB,IAAI,CAACF,OAAO,GAAG,IAAA;QACf,IAAI,CAACH,OAAO,GAAG,IAAA;AACjB;;;;AAMA;;;AAGC,MACD,IAAYmD,QAAW,GAAA;AACrB,QAAA,OAAO,IAAI,CAACxD,SAAS,CAACmD,GAAG,EAAA;AAC3B;AACA;;;AAGC,MACD,qBAAgC,GAAA;QAC9B,MAAMhB,MAAAA,GAAS,IAAI,CAACzB,YAAY;AAChC,QAAA,IAAI,CAACyB,MAAQ,EAAA;AACX,YAAA;AACF;;;;AAIA,QAAA,IAAI,CAACD,UAAU,CACb8G,sBAAAA,CACEC,uBAAuB9G,MAAQ,EAAA;YAC7BW,YAAc,EAAA,IAAI,CAACnC,aAAa;YAChCsC,UAAY,EAAA,IAAI,CAACrC;AACnB,SAAA,CAAA,CAAA,CAAA;AAGN;AACA;;;AAGC,MACD,iBAA4B,GAAA;AAC1B,QAAA,IAAI,CAAC0C,kBAAkB,EAAA;AACvB,QAAA,MAAMlB,IAAO,GAAA,IAAI,CAAChC,QAAQ,CAAC+C,GAAG,EAAA;QAC9B,IAAI,CAACf,QAAQ,CAAC,IAAI,CAAC5B,OAAO,IAAI,CAAC0I,yBAA6B,EAAA,EAAA;AAC1D,YAAA;AACF;QACA,MAAMvC,UAAAA,GAAa,IAAIwC,iBAAAA,CAAkB/G,IAAM,EAAA,IAAI,CAAC5B,OAAO,EAAE,IAAI,CAACO,kBAAkB,CAAA;QACpF,IAAI4F,UAAAA,CAAWD,OAAO,EAAE;YACtB,IAAI,CAAC7F,WAAW,GAAG8F,UAAAA;;;;AAInB,YAAA,IAAI,CAACnD,QAAQ,CAAC4F,UAAU,GAAGzC,WAAW0C,gBAAgB;;AAEtD,YAAA,IAAI,CAAC5F,wBAAwB,EAAA;AAC7B,YAAA,IAAI,CAAC5D,KAAK,EAAEoH,eAAAA,CAAgB,IAAI,CAAA;SAC3B,MAAA;AACLtE,YAAAA,OAAAA,CAAQ2G,IAAI,CAAC3C,UAAW4C,CAAAA,cAAc,IAAI,qCAAA,CAAA;AAC1C5C,YAAAA,UAAAA,CAAWpD,OAAO,EAAA;AACpB;AACF;qBAEA,kBAA6B,GAAA;AAC3B,QAAA,IAAI,CAACC,QAAQ,CAAC4F,UAAU,GAAG,IAAA;QAC3B,IAAI,CAACvI,WAAW,EAAE0C,OAAAA,EAAAA;QAClB,IAAI,CAAC1C,WAAW,GAAG,IAAA;AACrB;AACA;;;;;;;;AAQC,MACD,gBAA2B,GAAA;AACzB,QAAA,IAAI,IAAI,CAACV,UAAU,CAACgD,GAAG,EAAI,EAAA;AACzB,YAAA;AACF;AACA,QAAA,MAAMyF,YAAY,IAAIY,SAAAA,EAAAA;AACtBZ,QAAAA,SAAAA,CAAUa,wBAAwB,CAAC,gBAAkB,EAAA,IAAIC,YAAa,CAAA,CAAA,CAAA,CAAA;AACtEd,QAAAA,SAAAA,CAAUe,aAAa,GAAG,eAAA;AAC1B,QAAA,IAAI,CAACxJ,UAAU,CAACwD,GAAG,CAACiF,SAAAA,CAAAA;AACtB;AACA;;;;;;;AAOC,MACD,cAAyB,GAAA;AACvB,QAAA,MAAMA,SAAY,GAAA,IAAI,CAACzI,UAAU,CAACgD,GAAG,EAAA;AACrC,QAAA,IAAIyF,SAAW,EAAA;AACbA,YAAAA,SAAAA,CAAUgB,UAAU,GAAG,IAAI,CAACpG,QAAQ,CAACqF,WAAW;AAClD;AACF;AACF;AAEA;;;;;;;;;;;;IAaA,SAAShF,qBAAqBR,MAAwB,EAAA;IAIpD,MAAMwG,KAAAA,GAAQxG,MAAOwG,CAAAA,KAAK,IAAI,CAAA;IAC9B,MAAMC,SAAAA,GAAYzG,OAAOyG,SAAS;AAClC,IAAA,MAAM3C,MAAM,IAAIC,WAAAA,EAAAA;AAChBD,IAAAA,GAAAA,CAAI4C,WAAW,EAAA;AACf,IAAA,IAAIhG,eAAkB,GAAA,CAAA;AACtB,IAAA,IAAIiG,KAAQ,GAAA,CAAA;IACZ,IAAK,IAAIC,IAAI,CAAGA,EAAAA,CAAAA,GAAI5G,OAAO6G,WAAW,CAACC,MAAM,EAAEF,CAAK,EAAA,CAAA;AAClD,QAAA,MAAMG,KAAQ/G,GAAAA,MAAAA,CAAO6G,WAAW,CAACD,CAAE,CAAA;AACnC,QAAA,IAAIE,MAAS,GAAA,CAAA;AACb,QAAA,IAAK,IAAIE,CAAAA,GAAI,CAAGA,EAAAA,CAAAA,GAAID,OAAOC,CAAK,EAAA,CAAA;AAC9B,YAAA,MAAMC,CAAI,GAACN,CAAAA,KAAAA,GAAQK,CAAAA,IAAK,CAAA;AACxB,YAAA,MAAM7C,CAAIsC,GAAAA,SAAS,CAACQ,CAAAA,CAAE,GAAGT,KAAAA;AACzB,YAAA,MAAMpC,CAAIqC,GAAAA,SAAS,CAACQ,CAAAA,GAAI,EAAE,GAAGT,KAAAA;AAC7B,YAAA,MAAMnC,CAAIoC,GAAAA,SAAS,CAACQ,CAAAA,GAAI,EAAE,GAAGT,KAAAA;YAC7B1C,GAAIoD,CAAAA,OAAO,CAAC/C,CAAAA,EAAGC,CAAGC,EAAAA,CAAAA,CAAAA;AAClB,YAAA,IAAI2C,IAAI,CAAG,EAAA;gBACTF,MAAUK,IAAAA,IAAAA,CAAKC,KAAK,CAClBjD,CAAAA,GAAIsC,SAAS,CAACQ,CAAAA,GAAI,CAAE,CAAA,GAAGT,KACvBpC,EAAAA,CAAAA,GAAIqC,SAAS,CAACQ,CAAAA,GAAI,EAAE,GAAGT,KAAAA,EACvBnC,IAAIoC,SAAS,CAACQ,CAAI,GAAA,CAAA,CAAE,GAAGT,KAAAA,CAAAA;AAE3B;AACF;AACA,QAAA,IAAIM,SAASpG,eAAiB,EAAA;YAC5BA,eAAkBoG,GAAAA,MAAAA;AACpB;QACAH,KAASI,IAAAA,KAAAA;AACX;IACA,IAAIM,MAAAA,GAASrH,MAAOsH,CAAAA,YAAY,IAAI,MAAA;IACpC,IAAItH,MAAAA,CAAOuH,MAAM,EAAE;QACjB,IAAK,IAAIP,IAAI,CAAGA,EAAAA,CAAAA,GAAIhH,OAAOuH,MAAM,CAACT,MAAM,EAAEE,CAAK,EAAA,CAAA;AAC7C,YAAA,IAAIhH,MAAOuH,CAAAA,MAAM,CAACP,CAAAA,CAAE,GAAGK,MAAQ,EAAA;gBAC7BA,MAASrH,GAAAA,MAAAA,CAAOuH,MAAM,CAACP,CAAE,CAAA;AAC3B;AACF;AACF;AACA,IAAA,MAAMhD,MAAMqD,MAASb,GAAAA,KAAAA,IAASxG,MAAOwH,CAAAA,UAAU,IAAI,CAAA,CAAA;IACnD1D,GAAIG,CAAAA,QAAQ,CAACC,MAAM,CAACJ,IAAIG,QAAQ,CAACE,CAAC,GAAGH,GAAAA,EAAKF,IAAIG,QAAQ,CAACG,CAAC,GAAGJ,GAAAA,EAAKF,IAAIG,QAAQ,CAACI,CAAC,GAAGL,GAAAA,CAAAA;IACjFF,GAAIQ,CAAAA,QAAQ,CAACJ,MAAM,CAACJ,IAAIQ,QAAQ,CAACH,CAAC,GAAGH,GAAAA,EAAKF,IAAIQ,QAAQ,CAACF,CAAC,GAAGJ,GAAAA,EAAKF,IAAIQ,QAAQ,CAACD,CAAC,GAAGL,GAAAA,CAAAA;IACjF,OAAO;QAAEvD,MAAQqD,EAAAA,GAAAA;AAAKpD,QAAAA;AAAgB,KAAA;AACxC;;;;"}
@@ -592,7 +592,11 @@ export abstract class AmbientLight extends BaseLight {
592
592
  }
593
593
  /** @internal */ computeBoundingVolume() {
594
594
  const bbox = new BoundingBox();
595
- const cosCutoff = this.scene?.lightingMode === 'physical' ? Math.cos(this._outerConeAngle) : Math.cos(this._cutoff);
595
+ // In legacy mode `_cutoff` already stores the cosine of the cone half-angle (see the
596
+ // constructor default and computeUniforms), so it must be used as-is. Physical mode keeps the
597
+ // half-angle in radians instead, hence the conversion there.
598
+ // The lower clamp keeps the radius finite for half-angles at or beyond 90 degrees.
599
+ const cosCutoff = Math.min(1, Math.max(0.0001, this.scene?.lightingMode === 'physical' ? Math.cos(this._outerConeAngle) : this._cutoff));
596
600
  const range = this.positionAndRange.w;
597
601
  const r = range / cosCutoff * Math.sqrt(1 - cosCutoff * cosCutoff);
598
602
  bbox.minPoint = new Vector3(-r, -r, 0);
@@ -1 +1 @@
1
- {"version":3,"file":"light.js","sources":["../../src/scene/light.ts"],"sourcesContent":["import type { Immutable, Matrix4x4, Nullable } from '@zephyr3d/base';\r\nimport { Vector3, Vector4, DWeakRef } from '@zephyr3d/base';\r\nimport { GraphNode } from './graph_node';\r\nimport { BoundingBox } from '../utility/bounding_volume';\r\nimport { ShadowMapper } from '../shadow/shadowmapper';\r\nimport { LIGHT_TYPE_DIRECTIONAL, LIGHT_TYPE_POINT, LIGHT_TYPE_SPOT, LIGHT_TYPE_RECT } from '../values';\r\nimport type { Scene } from './scene';\r\n\r\n// Cutoff for auto-ranged physical lights; bounds clustered-culling radius.\r\nconst PHYSICAL_LIGHT_CUTOFF_LUX = 0.25;\r\n\r\n/**\r\n * Pack a light's color and intensity into the shader's `diffuseAndIntensity` vector.\r\n *\r\n * @remarks\r\n * The color is stored as authored in both lighting modes, matching Filament, which keeps color and\r\n * intensity strictly separate. Normalizing the color by its luminance (so the photometric value\r\n * describes total light output regardless of hue) was tried and rejected: a saturated primary has a\r\n * low Rec.709 luminance, so the division inflates its channels by up to ~13.8x and pushes them out\r\n * of the half-float range.\r\n */\r\nfunction makeColorIntensity(color: Vector4, intensity: number): Vector4 {\r\n return new Vector4(color.x, color.y, color.z, intensity);\r\n}\r\n\r\n/**\r\n * Base class for any kind of light node\r\n * @public\r\n */\r\nexport abstract class BaseLight extends GraphNode {\r\n /** @internal */\r\n protected _type: number;\r\n /** @internal */\r\n protected _intensity: number;\r\n /** @internal */\r\n protected _positionRange: Nullable<Vector4>;\r\n /** @internal */\r\n protected _directionCutoff: Nullable<Vector4>;\r\n /** @internal */\r\n protected _diffuseIntensity: Nullable<Vector4>;\r\n /** @internal */\r\n protected _extraParams: Nullable<Vector4>;\r\n /**\r\n * Creates a light node\r\n * @param scene - The scene to which the light node belongs\r\n * @param type - Type of the light node\r\n */\r\n constructor(scene: Scene, type: number) {\r\n super(scene);\r\n this._intensity = 1;\r\n this._type = type;\r\n this._positionRange = null;\r\n this._directionCutoff = null;\r\n this._diffuseIntensity = null;\r\n this._extraParams = null;\r\n }\r\n /** Gets the light type */\r\n get lightType() {\r\n return this._type;\r\n }\r\n /** Intensity of the light */\r\n get intensity() {\r\n return this._intensity;\r\n }\r\n set intensity(val) {\r\n this.setIntensity(val);\r\n }\r\n /**\r\n * Position and range of the light\r\n *\r\n * @remarks\r\n * Gets the position in world space of the light.\r\n * Light range is encoded into the W component.\r\n */\r\n get positionAndRange(): Immutable<Vector4> {\r\n if (!this._positionRange) {\r\n this.computeUniforms();\r\n }\r\n return this._positionRange!;\r\n }\r\n /**\r\n * Direction and cutoff of the light\r\n *\r\n * @remarks\r\n * Gets the direction in world space of the light\r\n * Light cutoff (for spot light only) is encoded into the W component.\r\n */\r\n get directionAndCutoff() {\r\n if (!this._directionCutoff) {\r\n this.computeUniforms();\r\n }\r\n return this._directionCutoff!;\r\n }\r\n /**\r\n * Color and intensity of the light\r\n *\r\n * @remarks\r\n * Gets the color of the light.\r\n * Light intensity is encoded into the W component.\r\n */\r\n get diffuseAndIntensity() {\r\n if (!this._diffuseIntensity) {\r\n this.computeUniforms();\r\n }\r\n return this._diffuseIntensity!;\r\n }\r\n /**\r\n * Extra parameters of the light\r\n *\r\n * @remarks\r\n * Custom data for advanced light types.\r\n */\r\n get extraParams() {\r\n if (!this._extraParams) {\r\n this.computeUniforms();\r\n }\r\n return this._extraParams!;\r\n }\r\n /**\r\n * View matrix of the light\r\n *\r\n * @remarks\r\n * The view matrix of the light is used to transform a point\r\n * from the world space to the light space.\r\n */\r\n get viewMatrix(): Immutable<Matrix4x4> {\r\n return this.invWorldMatrix;\r\n }\r\n /**\r\n * Sets the intensity of the light\r\n * @param val - Intensity of the light\r\n * @returns self\r\n */\r\n setIntensity(val: number) {\r\n if (this._intensity !== val) {\r\n this._intensity = val;\r\n this.invalidateUniforms();\r\n }\r\n return this;\r\n }\r\n /** @internal */\r\n invalidateUniforms() {\r\n this._positionRange = null;\r\n this._directionCutoff = null;\r\n this._diffuseIntensity = null;\r\n this._extraParams = null;\r\n }\r\n /** {@inheritDoc SceneNode.isLight} */\r\n isLight(): this is BaseLight {\r\n return true;\r\n }\r\n /** {@inheritDoc SceneNode.isPunctualLight} */\r\n isPunctualLight(): this is PunctualLight {\r\n return false;\r\n }\r\n /** returns true if this is a directional light */\r\n isDirectionLight(): this is DirectionalLight {\r\n return false;\r\n }\r\n /** returns true if this is a point light */\r\n isPointLight(): this is PointLight {\r\n return false;\r\n }\r\n /** returns true if this is a spot light */\r\n isSpotLight(): this is SpotLight {\r\n return false;\r\n }\r\n /** returns true if this is a rect light */\r\n isRectLight(): this is RectLight {\r\n return false;\r\n }\r\n /** @internal */\r\n abstract computeUniforms(): void;\r\n}\r\n\r\n/*\r\nexport abstract class AmbientLight extends BaseLight {\r\n constructor(scene: Scene, type: number) {\r\n super(scene, type);\r\n }\r\n isAmbientLight(): this is AmbientLight {\r\n return true;\r\n }\r\n}\r\n*/\r\n\r\n/**\r\n * Base class for any kind of puncual light\r\n * @public\r\n */\r\nexport class PunctualLight extends BaseLight {\r\n /** @internal */\r\n protected _color!: Vector4;\r\n /** @internal */\r\n protected _castShadow!: boolean;\r\n /** @internal */\r\n protected _shadowMapper!: ShadowMapper;\r\n /**\r\n * Creates an instance of punctual light\r\n * @param scene - The scene to which the punctual light belongs\r\n * @param type - The light type\r\n */\r\n constructor(scene: Scene, type: number) {\r\n super(scene, type);\r\n this.ensurePunctualState();\r\n }\r\n /** @internal */\r\n protected ensurePunctualState() {\r\n if (!this._color) {\r\n this._color = Vector4.one();\r\n }\r\n if (this._castShadow == null) {\r\n this._castShadow = false;\r\n }\r\n if (!this._shadowMapper) {\r\n this._shadowMapper = new ShadowMapper(this);\r\n }\r\n }\r\n /** Color of the light */\r\n get color() {\r\n this.ensurePunctualState();\r\n return this._color.clone();\r\n }\r\n set color(color) {\r\n this.setColor(color);\r\n }\r\n /**\r\n * Sets color of the light\r\n * @param color - The color to set\r\n * @returns self\r\n */\r\n setColor(color: Vector4 | Vector3) {\r\n this.ensurePunctualState();\r\n this._color.set(color);\r\n this.invalidateUniforms();\r\n return this;\r\n }\r\n /** Whether this light casts shadows */\r\n get castShadow() {\r\n this.ensurePunctualState();\r\n return this._castShadow;\r\n }\r\n set castShadow(b) {\r\n this.setCastShadow(b);\r\n }\r\n /**\r\n * Sets whether this light casts shadows\r\n * @param b - true if the light casts shadows\r\n * @returns self\r\n */\r\n setCastShadow(b: boolean): this {\r\n this.ensurePunctualState();\r\n if (this._castShadow !== !!b) {\r\n this._castShadow = !!b;\r\n if (this._castShadow && this.isDirectionLight() && !this.shadow.shadowRegion) {\r\n this.shadow.updateDirectionalShadowRegion(true);\r\n }\r\n }\r\n return this;\r\n }\r\n /** The shadow mapper for this light */\r\n get shadow() {\r\n this.ensurePunctualState();\r\n return this._shadowMapper;\r\n }\r\n /**\r\n * {@inheritDoc BaseLight.isPunctualLight}\r\n * @override\r\n */\r\n isPunctualLight(): this is PunctualLight {\r\n return true;\r\n }\r\n /** @internal */\r\n protected _onTransformChanged(invalidateLocal: boolean) {\r\n super._onTransformChanged(invalidateLocal);\r\n this.invalidateUniforms();\r\n }\r\n /** Disposes the punctual light node */\r\n protected onDispose() {\r\n super.onDispose();\r\n this._shadowMapper?.dispose();\r\n }\r\n /** @internal */\r\n computeUniforms() {}\r\n}\r\n\r\n/**\r\n * Directional light\r\n * @public\r\n */\r\nexport class DirectionalLight extends PunctualLight {\r\n private static readonly _currentSunLight: WeakMap<Scene, DWeakRef<DirectionalLight>> = new WeakMap();\r\n private _illuminance: number;\r\n /**\r\n * Creates an instance of directional light\r\n * @param scene - The scene to which the light belongs\r\n */\r\n constructor(scene: Scene) {\r\n super(scene, LIGHT_TYPE_DIRECTIONAL);\r\n this.intensity = 10;\r\n this._illuminance = 100000;\r\n if (!DirectionalLight.getSunLight(scene)) {\r\n DirectionalLight.setSunLight(scene, this);\r\n }\r\n }\r\n /** Physical illuminance in lux. */\r\n get illuminance() {\r\n return this._illuminance;\r\n }\r\n set illuminance(val: number) {\r\n const illuminance = Math.max(0, val);\r\n if (illuminance !== this._illuminance) {\r\n this._illuminance = illuminance;\r\n this.invalidateUniforms();\r\n }\r\n }\r\n static getSunLight(scene: Scene) {\r\n return this._currentSunLight.get(scene)?.get() ?? null;\r\n }\r\n static setSunLight(scene: Scene, light: Nullable<DirectionalLight>) {\r\n if (light && scene !== light.scene) {\r\n throw new Error('setSunLight(): Light does not belongs to scene');\r\n }\r\n const ref = this._currentSunLight.get(scene);\r\n if (!ref) {\r\n this._currentSunLight.set(scene, new DWeakRef(light));\r\n } else {\r\n ref.set(light);\r\n }\r\n }\r\n /**\r\n * true if the light was defined as sun light\r\n *\r\n * @remarks\r\n * Only one directional light will be marked as sun light.\r\n **/\r\n get sunLight(): boolean {\r\n return DirectionalLight.getSunLight(this.scene!) === this;\r\n }\r\n set sunLight(val) {\r\n if (val) {\r\n DirectionalLight.setSunLight(this.scene!, this);\r\n } else if (DirectionalLight.getSunLight(this.scene!) === this) {\r\n DirectionalLight.setSunLight(this.scene!, null);\r\n }\r\n }\r\n /**\r\n * {@inheritDoc BaseLight.isDirectionLight}\r\n * @override\r\n */\r\n isDirectionLight(): this is DirectionalLight {\r\n return true;\r\n }\r\n /** @internal */\r\n computeBoundingVolume() {\r\n return null;\r\n }\r\n /** @internal */\r\n computeUniforms() {\r\n const a = this.worldMatrix.getRow(3);\r\n const b = this.worldMatrix.getRow(2).scaleBy(-1);\r\n this._positionRange = new Vector4(a.x, a.y, a.z, -1);\r\n this._directionCutoff = new Vector4(b.x, b.y, b.z, 0);\r\n const physical = this.scene?.lightingMode === 'physical';\r\n this._diffuseIntensity = makeColorIntensity(this.color, physical ? this.illuminance : this.intensity);\r\n this._extraParams = new Vector4(0, 0, 0, this.lightType);\r\n }\r\n // adapt from DXSDK\r\n /*\r\n private _computeNearAndFar(\r\n frustumMin: Vector3,\r\n frustumMax: Vector3,\r\n aabbLightSpace: Vector3[]\r\n ): [number, number] {\r\n type Triangle = { pt: [Vector3, Vector3, Vector3]; culled: boolean };\r\n function dupTriangle(src: Triangle): Triangle {\r\n return {\r\n pt: [\r\n src.pt[0] ? new Vector3(src.pt[0]) : null,\r\n src.pt[1] ? new Vector3(src.pt[1]) : null,\r\n src.pt[2] ? new Vector3(src.pt[2]) : null\r\n ],\r\n culled: src.culled\r\n };\r\n }\r\n let nearPlane = Number.MAX_VALUE;\r\n let farPlane = -Number.MAX_VALUE;\r\n const triangleList: Triangle[] = Array.from({ length: 16 }).map((val) => ({\r\n pt: [null, null, null],\r\n culled: false\r\n }));\r\n let triangleCount = 1;\r\n triangleList[0].pt[0] = aabbLightSpace[0];\r\n triangleList[0].pt[1] = aabbLightSpace[1];\r\n triangleList[0].pt[2] = aabbLightSpace[2];\r\n const triIndices = [\r\n 0, 1, 2, 1, 2, 3, 4, 5, 6, 5, 6, 7, 0, 2, 4, 2, 4, 6, 1, 3, 5, 3, 5, 7, 0, 1, 4, 1, 4, 5, 2, 3, 6, 3, 6,\r\n 7\r\n ];\r\n const pointPassesCollision: number[] = [0, 0, 0];\r\n const minx = frustumMin.x;\r\n const maxx = frustumMax.x;\r\n const miny = frustumMin.y;\r\n const maxy = frustumMax.y;\r\n for (let i = 0; i < 12; i++) {\r\n triangleList[0].pt[0] = aabbLightSpace[triIndices[i * 3 + 0]];\r\n triangleList[0].pt[1] = aabbLightSpace[triIndices[i * 3 + 1]];\r\n triangleList[0].pt[2] = aabbLightSpace[triIndices[i * 3 + 2]];\r\n triangleList[0].culled = false;\r\n triangleCount = 1;\r\n for (let j = 0; j < 4; j++) {\r\n let edge: number, comp: number;\r\n if (j === 0) {\r\n edge = minx;\r\n comp = 0;\r\n } else if (j === 1) {\r\n edge = maxx;\r\n comp = 0;\r\n } else if (j === 2) {\r\n edge = miny;\r\n comp = 1;\r\n } else {\r\n edge = maxy;\r\n comp = 1;\r\n }\r\n let k = 0;\r\n while (k < triangleCount) {\r\n if (!triangleList[k].culled) {\r\n let insideVertCount = 0;\r\n let tempOrder: Vector3 = null;\r\n if (j === 0) {\r\n for (let t = 0; t < 3; t++) {\r\n if (triangleList[k].pt[t].x > minx) {\r\n pointPassesCollision[t] = 1;\r\n } else {\r\n pointPassesCollision[t] = 0;\r\n }\r\n insideVertCount += pointPassesCollision[t];\r\n }\r\n } else if (j === 1) {\r\n for (let t = 0; t < 3; t++) {\r\n if (triangleList[k].pt[t].x < maxx) {\r\n pointPassesCollision[t] = 1;\r\n } else {\r\n pointPassesCollision[t] = 0;\r\n }\r\n insideVertCount += pointPassesCollision[t];\r\n }\r\n } else if (j === 2) {\r\n for (let t = 0; t < 3; t++) {\r\n if (triangleList[k].pt[t].y > miny) {\r\n pointPassesCollision[t] = 1;\r\n } else {\r\n pointPassesCollision[t] = 0;\r\n }\r\n insideVertCount += pointPassesCollision[t];\r\n }\r\n } else {\r\n for (let t = 0; t < 3; t++) {\r\n if (triangleList[k].pt[t].y < maxy) {\r\n pointPassesCollision[t] = 1;\r\n } else {\r\n pointPassesCollision[t] = 0;\r\n }\r\n insideVertCount += pointPassesCollision[t];\r\n }\r\n }\r\n if (pointPassesCollision[1] && !pointPassesCollision[0]) {\r\n tempOrder = triangleList[k].pt[0];\r\n triangleList[k].pt[0] = triangleList[k].pt[1];\r\n triangleList[k].pt[1] = tempOrder;\r\n pointPassesCollision[0] = 1;\r\n pointPassesCollision[1] = 0;\r\n }\r\n if (pointPassesCollision[2] && !pointPassesCollision[1]) {\r\n tempOrder = triangleList[k].pt[1];\r\n triangleList[k].pt[1] = triangleList[k].pt[2];\r\n triangleList[k].pt[2] = tempOrder;\r\n pointPassesCollision[1] = 1;\r\n pointPassesCollision[2] = 0;\r\n }\r\n if (pointPassesCollision[1] && !pointPassesCollision[0]) {\r\n tempOrder = triangleList[k].pt[0];\r\n triangleList[k].pt[0] = triangleList[k].pt[1];\r\n triangleList[k].pt[1] = tempOrder;\r\n pointPassesCollision[0] = 1;\r\n pointPassesCollision[1] = 0;\r\n }\r\n if (insideVertCount === 0) {\r\n triangleList[k].culled = true;\r\n } else if (insideVertCount === 1) {\r\n triangleList[k].culled = false;\r\n const v0Tov1 = Vector3.sub(triangleList[k].pt[1], triangleList[k].pt[0]);\r\n const v0Tov2 = Vector3.sub(triangleList[k].pt[2], triangleList[k].pt[0]);\r\n const hitPointTimeRatio = edge - triangleList[k].pt[0][comp];\r\n const distanceAlongV1 = hitPointTimeRatio / v0Tov1[comp];\r\n const distanceAloneV2 = hitPointTimeRatio / v0Tov2[comp];\r\n v0Tov1.scaleBy(distanceAlongV1);\r\n v0Tov1.addBy(triangleList[k].pt[0]);\r\n v0Tov2.scaleBy(distanceAloneV2);\r\n v0Tov2.addBy(triangleList[k].pt[0]);\r\n triangleList[k].pt[1] = v0Tov2;\r\n triangleList[k].pt[2] = v0Tov1;\r\n } else if (insideVertCount === 2) {\r\n triangleList[triangleCount] = dupTriangle(triangleList[k + 1]);\r\n triangleList[k].culled = false;\r\n triangleList[k + 1].culled = false;\r\n const v2Tov0 = Vector3.sub(triangleList[k].pt[0], triangleList[k].pt[2]);\r\n const v2Tov1 = Vector3.sub(triangleList[k].pt[1], triangleList[k].pt[2]);\r\n const hitPointTime_2_0 = edge - triangleList[k].pt[2][comp];\r\n const distanceAloneVec_2_0 = hitPointTime_2_0 / v2Tov0[comp];\r\n v2Tov0.scaleBy(distanceAloneVec_2_0);\r\n v2Tov0.addBy(triangleList[k].pt[2]);\r\n triangleList[k + 1].pt[0] = new Vector3(triangleList[k].pt[0]);\r\n triangleList[k + 1].pt[1] = new Vector3(triangleList[k].pt[1]);\r\n triangleList[k + 1].pt[2] = v2Tov0;\r\n const hitPointTime_2_1 = edge - triangleList[k].pt[2][comp];\r\n const distanceAloneVec_2_1 = hitPointTime_2_1 / v2Tov1[comp];\r\n v2Tov1.scaleBy(distanceAloneVec_2_1);\r\n v2Tov1.addBy(triangleList[k].pt[2]);\r\n triangleList[k].pt[0] = new Vector3(triangleList[k + 1].pt[1]);\r\n triangleList[k].pt[1] = new Vector3(triangleList[k + 1].pt[2]);\r\n triangleList[k].pt[2] = v2Tov1;\r\n triangleCount++;\r\n k++;\r\n } else {\r\n triangleList[k].culled = false;\r\n }\r\n }\r\n k++;\r\n }\r\n }\r\n for (let index = 0; index < triangleCount; index++) {\r\n if (!triangleList[index].culled) {\r\n for (let v = 0; v < 3; v++) {\r\n const z = triangleList[index].pt[v].z;\r\n if (nearPlane > z) {\r\n nearPlane = z;\r\n }\r\n if (farPlane < z) {\r\n farPlane = z;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return [nearPlane, farPlane];\r\n }\r\n */\r\n}\r\n\r\n/**\r\n * Point light\r\n * @public\r\n */\r\nexport class PointLight extends PunctualLight {\r\n /** @internal */\r\n protected _range: number;\r\n /** @internal */\r\n protected _diffuseScale: number;\r\n /** @internal */\r\n protected _specularScale: number;\r\n /** @internal */\r\n protected _sourceRadius: number;\r\n /** @internal Physical luminous intensity in candela. */\r\n protected _luminousIntensity: number;\r\n /**\r\n * Creates an instance of point light\r\n * @param scene - The scene to which the light belongs\r\n */\r\n constructor(scene: Scene) {\r\n super(scene, LIGHT_TYPE_POINT);\r\n this._range = 0;\r\n this._diffuseScale = 1;\r\n this._specularScale = 1;\r\n this._sourceRadius = 0;\r\n this._luminousIntensity = 100;\r\n this.invalidateBoundingVolume();\r\n }\r\n /** The range of the light */\r\n get range() {\r\n return this._range;\r\n }\r\n set range(val: number) {\r\n this.setRange(val);\r\n }\r\n /** Diffuse scale of the point light */\r\n get diffuseScale() {\r\n return this._diffuseScale;\r\n }\r\n set diffuseScale(val: number) {\r\n this.setDiffuseScale(val);\r\n }\r\n /** Specular scale of the point light */\r\n get specularScale() {\r\n return this._specularScale;\r\n }\r\n set specularScale(val: number) {\r\n this.setSpecularScale(val);\r\n }\r\n /** Source radius of the point light */\r\n get sourceRadius() {\r\n return this._sourceRadius;\r\n }\r\n set sourceRadius(val: number) {\r\n this.setSourceRadius(val);\r\n }\r\n /** Physical luminous intensity in candela. */\r\n get luminousIntensity() {\r\n return this._luminousIntensity;\r\n }\r\n set luminousIntensity(val: number) {\r\n const intensity = Math.max(0, val);\r\n if (intensity !== this._luminousIntensity) {\r\n this._luminousIntensity = intensity;\r\n this.invalidateUniforms();\r\n if (this._range <= 0) {\r\n this.invalidateBoundingVolume();\r\n }\r\n }\r\n }\r\n /**\r\n * One-sided luminous flux in lumen.\r\n *\r\n * @remarks\r\n * Derived from {@link luminousIntensity} with Filament's point-light conversion, `Φ = 4π·I`.\r\n */\r\n get luminousPower() {\r\n return this._luminousIntensity * 4 * Math.PI;\r\n }\r\n set luminousPower(val: number) {\r\n this.luminousIntensity = Math.max(0, val) / (4 * Math.PI);\r\n }\r\n /**\r\n * Sets the range of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setRange(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._range !== val) {\r\n this._range = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /**\r\n * Sets the diffuse scale of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setDiffuseScale(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._diffuseScale !== val) {\r\n this._diffuseScale = val;\r\n this.invalidateUniforms();\r\n }\r\n return this;\r\n }\r\n /**\r\n * Sets the specular scale of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setSpecularScale(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._specularScale !== val) {\r\n this._specularScale = val;\r\n this.invalidateUniforms();\r\n }\r\n return this;\r\n }\r\n /**\r\n * Sets the source radius of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setSourceRadius(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._sourceRadius !== val) {\r\n this._sourceRadius = val;\r\n this.invalidateUniforms();\r\n }\r\n return this;\r\n }\r\n /**\r\n * {@inheritDoc BaseLight.isPointLight}\r\n * @override\r\n */\r\n isPointLight(): this is PointLight {\r\n return true;\r\n }\r\n /** @internal */\r\n computeBoundingVolume() {\r\n const range = this.positionAndRange.w;\r\n const bbox = new BoundingBox();\r\n bbox.minPoint = new Vector3(-range, -range, -range);\r\n bbox.maxPoint = new Vector3(range, range, range);\r\n return bbox;\r\n }\r\n /** @internal */\r\n computeUniforms() {\r\n const a = this.worldMatrix.getRow(3);\r\n const b = this.worldMatrix.getRow(2);\r\n const physical = this.scene?.lightingMode === 'physical';\r\n const metersPerUnit = this.scene?.metersPerUnit ?? 1;\r\n // diffuse/specular scales still multiply the shaded result, so the auto-derived influence\r\n // radius has to account for them. SpotLight has no equivalent scales, hence no such factor.\r\n const physicalScale = Math.max(this._diffuseScale, this._specularScale);\r\n const range =\r\n this.range <= 0\r\n ? physical\r\n ? Math.sqrt(Math.max(0, this.luminousIntensity * physicalScale) / PHYSICAL_LIGHT_CUTOFF_LUX) /\r\n metersPerUnit\r\n : 32 * Math.sqrt(Math.max(0.0001, this.intensity * physicalScale))\r\n : this.range;\r\n const resolvedIntensity = physical\r\n ? this.luminousIntensity / (metersPerUnit * metersPerUnit)\r\n : this.intensity;\r\n this._positionRange = new Vector4(a.x, a.y, a.z, range);\r\n this._directionCutoff = new Vector4(b.x, b.y, b.z, -1);\r\n this._diffuseIntensity = makeColorIntensity(this.color, resolvedIntensity);\r\n this._extraParams = new Vector4(\r\n this._diffuseScale,\r\n this._specularScale,\r\n this._sourceRadius,\r\n this.lightType\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Spot light\r\n * @public\r\n */\r\nexport class SpotLight extends PunctualLight {\r\n /** @internal Smallest cone half-angle, matching Filament's 0.5 degree clamp. */\r\n private static readonly MIN_CONE_ANGLE = (0.5 * Math.PI) / 180;\r\n /** @internal */\r\n protected _range: number;\r\n /** @internal */\r\n protected _cutoff: number;\r\n /** @internal Physical luminous intensity in candela. */\r\n protected _luminousIntensity: number;\r\n /** @internal Physical inner cone half-angle in radians. */\r\n protected _innerConeAngle: number;\r\n /** @internal Physical outer cone half-angle in radians. */\r\n protected _outerConeAngle: number;\r\n /**\r\n * Creates an instance of spot light\r\n * @param scene - The scene to which the light belongs\r\n */\r\n constructor(scene: Scene) {\r\n super(scene, LIGHT_TYPE_SPOT);\r\n this._range = 0;\r\n this._cutoff = Math.cos(Math.PI / 4);\r\n this._luminousIntensity = 1000;\r\n this._innerConeAngle = Math.PI / 8;\r\n this._outerConeAngle = Math.PI / 4;\r\n this.invalidateBoundingVolume();\r\n }\r\n /** The range of the light */\r\n get range() {\r\n return this._range;\r\n }\r\n set range(val: number) {\r\n this.setRange(val);\r\n }\r\n /**\r\n * Sets the range of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setRange(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._range !== val) {\r\n this._range = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /** The cutoff of the light */\r\n get cutoff() {\r\n return this._cutoff;\r\n }\r\n set cutoff(val: number) {\r\n this.setCutoff(val);\r\n }\r\n /** Physical luminous intensity in candela. */\r\n get luminousIntensity() {\r\n return this._luminousIntensity;\r\n }\r\n set luminousIntensity(val: number) {\r\n const intensity = Math.max(0, val);\r\n if (intensity !== this._luminousIntensity) {\r\n this._luminousIntensity = intensity;\r\n this.invalidateUniforms();\r\n if (this._range <= 0) {\r\n this.invalidateBoundingVolume();\r\n }\r\n }\r\n }\r\n /**\r\n * One-sided luminous flux in lumen.\r\n *\r\n * @remarks\r\n * Derived from {@link luminousIntensity} with Filament's focused-spot conversion,\r\n * `Φ = I · 2π(1 - cos(θouter))`, so authoring in either unit stays consistent.\r\n */\r\n get luminousPower() {\r\n return this._luminousIntensity * SpotLight.luminousPowerPerIntensity(this._outerConeAngle);\r\n }\r\n set luminousPower(val: number) {\r\n this.luminousIntensity = Math.max(0, val) / SpotLight.luminousPowerPerIntensity(this._outerConeAngle);\r\n }\r\n /** @internal Filament focused-spot conversion factor: 2π(1 - cos(θouter)). */\r\n private static luminousPowerPerIntensity(outerConeAngle: number) {\r\n return Math.max(2 * Math.PI * (1 - Math.cos(outerConeAngle)), 1e-6);\r\n }\r\n /** Physical inner cone half-angle in radians. */\r\n get innerConeAngle() {\r\n return this._innerConeAngle;\r\n }\r\n set innerConeAngle(val: number) {\r\n // Filament clamps to [0.5 degrees, outer]; the shader's scale/offset also guards inner == outer.\r\n const angle = Math.max(SpotLight.MIN_CONE_ANGLE, Math.min(Math.abs(val), this._outerConeAngle));\r\n if (angle !== this._innerConeAngle) {\r\n this._innerConeAngle = angle;\r\n this.invalidateUniforms();\r\n }\r\n }\r\n /** Physical outer cone half-angle in radians. */\r\n get outerConeAngle() {\r\n return this._outerConeAngle;\r\n }\r\n set outerConeAngle(val: number) {\r\n // Filament clamps both cone half-angles to [0.5 degrees, 90 degrees].\r\n const angle = Math.max(SpotLight.MIN_CONE_ANGLE, Math.min(Math.abs(val), Math.PI * 0.5));\r\n if (angle !== this._outerConeAngle) {\r\n this._outerConeAngle = angle;\r\n this._innerConeAngle = Math.min(this._innerConeAngle, angle);\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n }\r\n /**\r\n * @internal\r\n *\r\n * Cone angle attenuation packed as `(scale, offset)` so the shader evaluates\r\n * `saturate(cos(theta) * scale + offset)^2`, matching Filament's `getAngleAttenuation`.\r\n * The `1/1024` floor keeps a degenerate `inner == outer` cone finite instead of dividing by zero.\r\n */\r\n private getAngleScaleOffset(): [number, number] {\r\n const cosOuter = Math.cos(this._outerConeAngle);\r\n const cosInner = Math.cos(Math.min(this._innerConeAngle, this._outerConeAngle));\r\n const scale = 1 / Math.max(1 / 1024, cosInner - cosOuter);\r\n return [scale, -cosOuter * scale];\r\n }\r\n /**\r\n * Sets the cutoff of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setCutoff(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._cutoff !== val) {\r\n this._cutoff = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /**\r\n * {@inheritDoc BaseLight.isSpotLight}\r\n * @override\r\n */\r\n isSpotLight(): this is SpotLight {\r\n return true;\r\n }\r\n /** @internal */\r\n computeBoundingVolume() {\r\n const bbox = new BoundingBox();\r\n const cosCutoff =\r\n this.scene?.lightingMode === 'physical' ? Math.cos(this._outerConeAngle) : Math.cos(this._cutoff);\r\n const range = this.positionAndRange.w;\r\n const r = (range / cosCutoff) * Math.sqrt(1 - cosCutoff * cosCutoff);\r\n bbox.minPoint = new Vector3(-r, -r, 0);\r\n bbox.maxPoint = new Vector3(r, r, range);\r\n return bbox;\r\n }\r\n /** @internal */\r\n computeUniforms() {\r\n const a = this.worldMatrix.getRow(3);\r\n const b = this.worldMatrix.getRow(2).scaleBy(-1);\r\n const physical = this.scene?.lightingMode === 'physical';\r\n const metersPerUnit = this.scene?.metersPerUnit ?? 1;\r\n const range =\r\n this.range <= 0\r\n ? physical\r\n ? Math.sqrt(Math.max(0, this.luminousIntensity) / PHYSICAL_LIGHT_CUTOFF_LUX) / metersPerUnit\r\n : 32 * Math.sqrt(Math.max(0.0001, this.intensity))\r\n : this.range;\r\n const resolvedIntensity = physical\r\n ? this.luminousIntensity / (metersPerUnit * metersPerUnit)\r\n : this.intensity;\r\n this._positionRange = new Vector4(a.x, a.y, a.z, range);\r\n this._directionCutoff = new Vector4(\r\n b.x,\r\n b.y,\r\n b.z,\r\n physical ? Math.cos(this.outerConeAngle) : this.cutoff\r\n );\r\n this._diffuseIntensity = makeColorIntensity(this.color, resolvedIntensity);\r\n const [angleScale, angleOffset] = physical ? this.getAngleScaleOffset() : [0, 0];\r\n this._extraParams = new Vector4(angleScale, angleOffset, 0, this.lightType);\r\n }\r\n}\r\n\r\n/**\r\n * Rectangular area light\r\n * @public\r\n */\r\nexport class RectLight extends PunctualLight {\r\n /** @internal */\r\n protected _range: number;\r\n /** @internal */\r\n protected _width: number;\r\n /** @internal */\r\n protected _height: number;\r\n /** @internal Physical luminance in cd/m². */\r\n protected _luminance: number;\r\n /**\r\n * Creates an instance of rect light\r\n * @param scene - The scene to which the light belongs\r\n */\r\n constructor(scene: Scene) {\r\n super(scene, LIGHT_TYPE_RECT);\r\n this._range = 10;\r\n this._width = 1;\r\n this._height = 1;\r\n this._luminance = 100;\r\n this.invalidateBoundingVolume();\r\n }\r\n /** The range of the light */\r\n get range() {\r\n return this._range;\r\n }\r\n set range(val: number) {\r\n this.setRange(val);\r\n }\r\n /**\r\n * Sets the range of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setRange(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._range !== val) {\r\n this._range = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /** The width of the light */\r\n get width() {\r\n return this._width;\r\n }\r\n set width(val: number) {\r\n this.setWidth(val);\r\n }\r\n /**\r\n * Sets the width of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setWidth(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._width !== val) {\r\n this._width = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /** The height of the light */\r\n get height() {\r\n return this._height;\r\n }\r\n set height(val: number) {\r\n this.setHeight(val);\r\n }\r\n /** Physical luminance in cd/m² (nit). */\r\n get luminance() {\r\n return this._luminance;\r\n }\r\n set luminance(val: number) {\r\n const luminance = Math.max(0, val);\r\n if (luminance !== this._luminance) {\r\n this._luminance = luminance;\r\n this.invalidateUniforms();\r\n }\r\n }\r\n /**\r\n * One-sided Lambertian luminous flux in lumen.\r\n *\r\n * @remarks\r\n * Derived from {@link luminance}: `phi = L * pi * area`. Named `luminousFlux` rather than\r\n * `luminousPower` because an area light is authored by its luminance, with flux as the derived\r\n * convenience; point and spot lights are the other way round.\r\n */\r\n get luminousFlux() {\r\n const metersPerUnit = this.scene?.metersPerUnit ?? 1;\r\n return this.luminance * Math.PI * this.width * this.height * metersPerUnit * metersPerUnit;\r\n }\r\n set luminousFlux(val: number) {\r\n const metersPerUnit = this.scene?.metersPerUnit ?? 1;\r\n const area = this.width * this.height * metersPerUnit * metersPerUnit;\r\n this.luminance = area > 0 ? Math.max(0, val) / (Math.PI * area) : 0;\r\n }\r\n /**\r\n * Sets the height of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setHeight(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._height !== val) {\r\n this._height = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /**\r\n * {@inheritDoc BaseLight.isRectLight}\r\n * @override\r\n */\r\n isRectLight(): this is RectLight {\r\n return true;\r\n }\r\n /**\r\n * Rect light supports shadow in current pipeline\r\n */\r\n /** @internal */\r\n computeBoundingVolume() {\r\n const bbox = new BoundingBox();\r\n const r = this._range;\r\n bbox.minPoint = new Vector3(-r, -r, -r);\r\n bbox.maxPoint = new Vector3(r, r, r);\r\n return bbox;\r\n }\r\n /** @internal */\r\n computeUniforms() {\r\n const pos = this.worldMatrix.getRow(3);\r\n const axisX = this.worldMatrix\r\n .getRow(0)\r\n .inplaceNormalize()\r\n .scaleBy(this._width * 0.5);\r\n const axisY = this.worldMatrix\r\n .getRow(1)\r\n .inplaceNormalize()\r\n .scaleBy(this._height * 0.5);\r\n this._positionRange = new Vector4(pos.x, pos.y, pos.z, this.range);\r\n this._directionCutoff = new Vector4(axisX.x, axisX.y, axisX.z, 0);\r\n const physical = this.scene?.lightingMode === 'physical';\r\n this._diffuseIntensity = makeColorIntensity(this.color, physical ? this.luminance : this.intensity);\r\n this._extraParams = new Vector4(axisY.x, axisY.y, axisY.z, this.lightType);\r\n }\r\n}\r\n"],"names":["PHYSICAL_LIGHT_CUTOFF_LUX","makeColorIntensity","color","intensity","Vector4","x","y","z","BaseLight","GraphNode","scene","type","_intensity","_type","_positionRange","_directionCutoff","_diffuseIntensity","_extraParams","lightType","val","setIntensity","positionAndRange","computeUniforms","directionAndCutoff","diffuseAndIntensity","extraParams","viewMatrix","invWorldMatrix","invalidateUniforms","isLight","isPunctualLight","isDirectionLight","isPointLight","isSpotLight","isRectLight","PunctualLight","ensurePunctualState","_color","one","_castShadow","_shadowMapper","ShadowMapper","clone","setColor","set","castShadow","b","setCastShadow","shadow","shadowRegion","updateDirectionalShadowRegion","_onTransformChanged","invalidateLocal","onDispose","dispose","DirectionalLight","_currentSunLight","WeakMap","_illuminance","LIGHT_TYPE_DIRECTIONAL","getSunLight","setSunLight","illuminance","Math","max","get","light","Error","ref","DWeakRef","sunLight","computeBoundingVolume","a","worldMatrix","getRow","scaleBy","physical","lightingMode","PointLight","LIGHT_TYPE_POINT","_range","_diffuseScale","_specularScale","_sourceRadius","_luminousIntensity","invalidateBoundingVolume","range","setRange","diffuseScale","setDiffuseScale","specularScale","setSpecularScale","sourceRadius","setSourceRadius","luminousIntensity","luminousPower","PI","w","bbox","BoundingBox","minPoint","Vector3","maxPoint","metersPerUnit","physicalScale","sqrt","resolvedIntensity","SpotLight","MIN_CONE_ANGLE","LIGHT_TYPE_SPOT","_cutoff","cos","_innerConeAngle","_outerConeAngle","cutoff","setCutoff","luminousPowerPerIntensity","outerConeAngle","innerConeAngle","angle","min","abs","cosOuter","cosInner","scale","cosCutoff","r","angleScale","angleOffset","getAngleScaleOffset","RectLight","LIGHT_TYPE_RECT","_width","_height","_luminance","width","setWidth","height","setHeight","luminance","luminousFlux","area","pos","axisX","inplaceNormalize","axisY"],"mappings":"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"}
1
+ {"version":3,"file":"light.js","sources":["../../src/scene/light.ts"],"sourcesContent":["import type { Immutable, Matrix4x4, Nullable } from '@zephyr3d/base';\r\nimport { Vector3, Vector4, DWeakRef } from '@zephyr3d/base';\r\nimport { GraphNode } from './graph_node';\r\nimport { BoundingBox } from '../utility/bounding_volume';\r\nimport { ShadowMapper } from '../shadow/shadowmapper';\r\nimport { LIGHT_TYPE_DIRECTIONAL, LIGHT_TYPE_POINT, LIGHT_TYPE_SPOT, LIGHT_TYPE_RECT } from '../values';\r\nimport type { Scene } from './scene';\r\n\r\n// Cutoff for auto-ranged physical lights; bounds clustered-culling radius.\r\nconst PHYSICAL_LIGHT_CUTOFF_LUX = 0.25;\r\n\r\n/**\r\n * Pack a light's color and intensity into the shader's `diffuseAndIntensity` vector.\r\n *\r\n * @remarks\r\n * The color is stored as authored in both lighting modes, matching Filament, which keeps color and\r\n * intensity strictly separate. Normalizing the color by its luminance (so the photometric value\r\n * describes total light output regardless of hue) was tried and rejected: a saturated primary has a\r\n * low Rec.709 luminance, so the division inflates its channels by up to ~13.8x and pushes them out\r\n * of the half-float range.\r\n */\r\nfunction makeColorIntensity(color: Vector4, intensity: number): Vector4 {\r\n return new Vector4(color.x, color.y, color.z, intensity);\r\n}\r\n\r\n/**\r\n * Base class for any kind of light node\r\n * @public\r\n */\r\nexport abstract class BaseLight extends GraphNode {\r\n /** @internal */\r\n protected _type: number;\r\n /** @internal */\r\n protected _intensity: number;\r\n /** @internal */\r\n protected _positionRange: Nullable<Vector4>;\r\n /** @internal */\r\n protected _directionCutoff: Nullable<Vector4>;\r\n /** @internal */\r\n protected _diffuseIntensity: Nullable<Vector4>;\r\n /** @internal */\r\n protected _extraParams: Nullable<Vector4>;\r\n /**\r\n * Creates a light node\r\n * @param scene - The scene to which the light node belongs\r\n * @param type - Type of the light node\r\n */\r\n constructor(scene: Scene, type: number) {\r\n super(scene);\r\n this._intensity = 1;\r\n this._type = type;\r\n this._positionRange = null;\r\n this._directionCutoff = null;\r\n this._diffuseIntensity = null;\r\n this._extraParams = null;\r\n }\r\n /** Gets the light type */\r\n get lightType() {\r\n return this._type;\r\n }\r\n /** Intensity of the light */\r\n get intensity() {\r\n return this._intensity;\r\n }\r\n set intensity(val) {\r\n this.setIntensity(val);\r\n }\r\n /**\r\n * Position and range of the light\r\n *\r\n * @remarks\r\n * Gets the position in world space of the light.\r\n * Light range is encoded into the W component.\r\n */\r\n get positionAndRange(): Immutable<Vector4> {\r\n if (!this._positionRange) {\r\n this.computeUniforms();\r\n }\r\n return this._positionRange!;\r\n }\r\n /**\r\n * Direction and cutoff of the light\r\n *\r\n * @remarks\r\n * Gets the direction in world space of the light\r\n * Light cutoff (for spot light only) is encoded into the W component.\r\n */\r\n get directionAndCutoff() {\r\n if (!this._directionCutoff) {\r\n this.computeUniforms();\r\n }\r\n return this._directionCutoff!;\r\n }\r\n /**\r\n * Color and intensity of the light\r\n *\r\n * @remarks\r\n * Gets the color of the light.\r\n * Light intensity is encoded into the W component.\r\n */\r\n get diffuseAndIntensity() {\r\n if (!this._diffuseIntensity) {\r\n this.computeUniforms();\r\n }\r\n return this._diffuseIntensity!;\r\n }\r\n /**\r\n * Extra parameters of the light\r\n *\r\n * @remarks\r\n * Custom data for advanced light types.\r\n */\r\n get extraParams() {\r\n if (!this._extraParams) {\r\n this.computeUniforms();\r\n }\r\n return this._extraParams!;\r\n }\r\n /**\r\n * View matrix of the light\r\n *\r\n * @remarks\r\n * The view matrix of the light is used to transform a point\r\n * from the world space to the light space.\r\n */\r\n get viewMatrix(): Immutable<Matrix4x4> {\r\n return this.invWorldMatrix;\r\n }\r\n /**\r\n * Sets the intensity of the light\r\n * @param val - Intensity of the light\r\n * @returns self\r\n */\r\n setIntensity(val: number) {\r\n if (this._intensity !== val) {\r\n this._intensity = val;\r\n this.invalidateUniforms();\r\n }\r\n return this;\r\n }\r\n /** @internal */\r\n invalidateUniforms() {\r\n this._positionRange = null;\r\n this._directionCutoff = null;\r\n this._diffuseIntensity = null;\r\n this._extraParams = null;\r\n }\r\n /** {@inheritDoc SceneNode.isLight} */\r\n isLight(): this is BaseLight {\r\n return true;\r\n }\r\n /** {@inheritDoc SceneNode.isPunctualLight} */\r\n isPunctualLight(): this is PunctualLight {\r\n return false;\r\n }\r\n /** returns true if this is a directional light */\r\n isDirectionLight(): this is DirectionalLight {\r\n return false;\r\n }\r\n /** returns true if this is a point light */\r\n isPointLight(): this is PointLight {\r\n return false;\r\n }\r\n /** returns true if this is a spot light */\r\n isSpotLight(): this is SpotLight {\r\n return false;\r\n }\r\n /** returns true if this is a rect light */\r\n isRectLight(): this is RectLight {\r\n return false;\r\n }\r\n /** @internal */\r\n abstract computeUniforms(): void;\r\n}\r\n\r\n/*\r\nexport abstract class AmbientLight extends BaseLight {\r\n constructor(scene: Scene, type: number) {\r\n super(scene, type);\r\n }\r\n isAmbientLight(): this is AmbientLight {\r\n return true;\r\n }\r\n}\r\n*/\r\n\r\n/**\r\n * Base class for any kind of puncual light\r\n * @public\r\n */\r\nexport class PunctualLight extends BaseLight {\r\n /** @internal */\r\n protected _color!: Vector4;\r\n /** @internal */\r\n protected _castShadow!: boolean;\r\n /** @internal */\r\n protected _shadowMapper!: ShadowMapper;\r\n /**\r\n * Creates an instance of punctual light\r\n * @param scene - The scene to which the punctual light belongs\r\n * @param type - The light type\r\n */\r\n constructor(scene: Scene, type: number) {\r\n super(scene, type);\r\n this.ensurePunctualState();\r\n }\r\n /** @internal */\r\n protected ensurePunctualState() {\r\n if (!this._color) {\r\n this._color = Vector4.one();\r\n }\r\n if (this._castShadow == null) {\r\n this._castShadow = false;\r\n }\r\n if (!this._shadowMapper) {\r\n this._shadowMapper = new ShadowMapper(this);\r\n }\r\n }\r\n /** Color of the light */\r\n get color() {\r\n this.ensurePunctualState();\r\n return this._color.clone();\r\n }\r\n set color(color) {\r\n this.setColor(color);\r\n }\r\n /**\r\n * Sets color of the light\r\n * @param color - The color to set\r\n * @returns self\r\n */\r\n setColor(color: Vector4 | Vector3) {\r\n this.ensurePunctualState();\r\n this._color.set(color);\r\n this.invalidateUniforms();\r\n return this;\r\n }\r\n /** Whether this light casts shadows */\r\n get castShadow() {\r\n this.ensurePunctualState();\r\n return this._castShadow;\r\n }\r\n set castShadow(b) {\r\n this.setCastShadow(b);\r\n }\r\n /**\r\n * Sets whether this light casts shadows\r\n * @param b - true if the light casts shadows\r\n * @returns self\r\n */\r\n setCastShadow(b: boolean): this {\r\n this.ensurePunctualState();\r\n if (this._castShadow !== !!b) {\r\n this._castShadow = !!b;\r\n if (this._castShadow && this.isDirectionLight() && !this.shadow.shadowRegion) {\r\n this.shadow.updateDirectionalShadowRegion(true);\r\n }\r\n }\r\n return this;\r\n }\r\n /** The shadow mapper for this light */\r\n get shadow() {\r\n this.ensurePunctualState();\r\n return this._shadowMapper;\r\n }\r\n /**\r\n * {@inheritDoc BaseLight.isPunctualLight}\r\n * @override\r\n */\r\n isPunctualLight(): this is PunctualLight {\r\n return true;\r\n }\r\n /** @internal */\r\n protected _onTransformChanged(invalidateLocal: boolean) {\r\n super._onTransformChanged(invalidateLocal);\r\n this.invalidateUniforms();\r\n }\r\n /** Disposes the punctual light node */\r\n protected onDispose() {\r\n super.onDispose();\r\n this._shadowMapper?.dispose();\r\n }\r\n /** @internal */\r\n computeUniforms() {}\r\n}\r\n\r\n/**\r\n * Directional light\r\n * @public\r\n */\r\nexport class DirectionalLight extends PunctualLight {\r\n private static readonly _currentSunLight: WeakMap<Scene, DWeakRef<DirectionalLight>> = new WeakMap();\r\n private _illuminance: number;\r\n /**\r\n * Creates an instance of directional light\r\n * @param scene - The scene to which the light belongs\r\n */\r\n constructor(scene: Scene) {\r\n super(scene, LIGHT_TYPE_DIRECTIONAL);\r\n this.intensity = 10;\r\n this._illuminance = 100000;\r\n if (!DirectionalLight.getSunLight(scene)) {\r\n DirectionalLight.setSunLight(scene, this);\r\n }\r\n }\r\n /** Physical illuminance in lux. */\r\n get illuminance() {\r\n return this._illuminance;\r\n }\r\n set illuminance(val: number) {\r\n const illuminance = Math.max(0, val);\r\n if (illuminance !== this._illuminance) {\r\n this._illuminance = illuminance;\r\n this.invalidateUniforms();\r\n }\r\n }\r\n static getSunLight(scene: Scene) {\r\n return this._currentSunLight.get(scene)?.get() ?? null;\r\n }\r\n static setSunLight(scene: Scene, light: Nullable<DirectionalLight>) {\r\n if (light && scene !== light.scene) {\r\n throw new Error('setSunLight(): Light does not belongs to scene');\r\n }\r\n const ref = this._currentSunLight.get(scene);\r\n if (!ref) {\r\n this._currentSunLight.set(scene, new DWeakRef(light));\r\n } else {\r\n ref.set(light);\r\n }\r\n }\r\n /**\r\n * true if the light was defined as sun light\r\n *\r\n * @remarks\r\n * Only one directional light will be marked as sun light.\r\n **/\r\n get sunLight(): boolean {\r\n return DirectionalLight.getSunLight(this.scene!) === this;\r\n }\r\n set sunLight(val) {\r\n if (val) {\r\n DirectionalLight.setSunLight(this.scene!, this);\r\n } else if (DirectionalLight.getSunLight(this.scene!) === this) {\r\n DirectionalLight.setSunLight(this.scene!, null);\r\n }\r\n }\r\n /**\r\n * {@inheritDoc BaseLight.isDirectionLight}\r\n * @override\r\n */\r\n isDirectionLight(): this is DirectionalLight {\r\n return true;\r\n }\r\n /** @internal */\r\n computeBoundingVolume() {\r\n return null;\r\n }\r\n /** @internal */\r\n computeUniforms() {\r\n const a = this.worldMatrix.getRow(3);\r\n const b = this.worldMatrix.getRow(2).scaleBy(-1);\r\n this._positionRange = new Vector4(a.x, a.y, a.z, -1);\r\n this._directionCutoff = new Vector4(b.x, b.y, b.z, 0);\r\n const physical = this.scene?.lightingMode === 'physical';\r\n this._diffuseIntensity = makeColorIntensity(this.color, physical ? this.illuminance : this.intensity);\r\n this._extraParams = new Vector4(0, 0, 0, this.lightType);\r\n }\r\n // adapt from DXSDK\r\n /*\r\n private _computeNearAndFar(\r\n frustumMin: Vector3,\r\n frustumMax: Vector3,\r\n aabbLightSpace: Vector3[]\r\n ): [number, number] {\r\n type Triangle = { pt: [Vector3, Vector3, Vector3]; culled: boolean };\r\n function dupTriangle(src: Triangle): Triangle {\r\n return {\r\n pt: [\r\n src.pt[0] ? new Vector3(src.pt[0]) : null,\r\n src.pt[1] ? new Vector3(src.pt[1]) : null,\r\n src.pt[2] ? new Vector3(src.pt[2]) : null\r\n ],\r\n culled: src.culled\r\n };\r\n }\r\n let nearPlane = Number.MAX_VALUE;\r\n let farPlane = -Number.MAX_VALUE;\r\n const triangleList: Triangle[] = Array.from({ length: 16 }).map((val) => ({\r\n pt: [null, null, null],\r\n culled: false\r\n }));\r\n let triangleCount = 1;\r\n triangleList[0].pt[0] = aabbLightSpace[0];\r\n triangleList[0].pt[1] = aabbLightSpace[1];\r\n triangleList[0].pt[2] = aabbLightSpace[2];\r\n const triIndices = [\r\n 0, 1, 2, 1, 2, 3, 4, 5, 6, 5, 6, 7, 0, 2, 4, 2, 4, 6, 1, 3, 5, 3, 5, 7, 0, 1, 4, 1, 4, 5, 2, 3, 6, 3, 6,\r\n 7\r\n ];\r\n const pointPassesCollision: number[] = [0, 0, 0];\r\n const minx = frustumMin.x;\r\n const maxx = frustumMax.x;\r\n const miny = frustumMin.y;\r\n const maxy = frustumMax.y;\r\n for (let i = 0; i < 12; i++) {\r\n triangleList[0].pt[0] = aabbLightSpace[triIndices[i * 3 + 0]];\r\n triangleList[0].pt[1] = aabbLightSpace[triIndices[i * 3 + 1]];\r\n triangleList[0].pt[2] = aabbLightSpace[triIndices[i * 3 + 2]];\r\n triangleList[0].culled = false;\r\n triangleCount = 1;\r\n for (let j = 0; j < 4; j++) {\r\n let edge: number, comp: number;\r\n if (j === 0) {\r\n edge = minx;\r\n comp = 0;\r\n } else if (j === 1) {\r\n edge = maxx;\r\n comp = 0;\r\n } else if (j === 2) {\r\n edge = miny;\r\n comp = 1;\r\n } else {\r\n edge = maxy;\r\n comp = 1;\r\n }\r\n let k = 0;\r\n while (k < triangleCount) {\r\n if (!triangleList[k].culled) {\r\n let insideVertCount = 0;\r\n let tempOrder: Vector3 = null;\r\n if (j === 0) {\r\n for (let t = 0; t < 3; t++) {\r\n if (triangleList[k].pt[t].x > minx) {\r\n pointPassesCollision[t] = 1;\r\n } else {\r\n pointPassesCollision[t] = 0;\r\n }\r\n insideVertCount += pointPassesCollision[t];\r\n }\r\n } else if (j === 1) {\r\n for (let t = 0; t < 3; t++) {\r\n if (triangleList[k].pt[t].x < maxx) {\r\n pointPassesCollision[t] = 1;\r\n } else {\r\n pointPassesCollision[t] = 0;\r\n }\r\n insideVertCount += pointPassesCollision[t];\r\n }\r\n } else if (j === 2) {\r\n for (let t = 0; t < 3; t++) {\r\n if (triangleList[k].pt[t].y > miny) {\r\n pointPassesCollision[t] = 1;\r\n } else {\r\n pointPassesCollision[t] = 0;\r\n }\r\n insideVertCount += pointPassesCollision[t];\r\n }\r\n } else {\r\n for (let t = 0; t < 3; t++) {\r\n if (triangleList[k].pt[t].y < maxy) {\r\n pointPassesCollision[t] = 1;\r\n } else {\r\n pointPassesCollision[t] = 0;\r\n }\r\n insideVertCount += pointPassesCollision[t];\r\n }\r\n }\r\n if (pointPassesCollision[1] && !pointPassesCollision[0]) {\r\n tempOrder = triangleList[k].pt[0];\r\n triangleList[k].pt[0] = triangleList[k].pt[1];\r\n triangleList[k].pt[1] = tempOrder;\r\n pointPassesCollision[0] = 1;\r\n pointPassesCollision[1] = 0;\r\n }\r\n if (pointPassesCollision[2] && !pointPassesCollision[1]) {\r\n tempOrder = triangleList[k].pt[1];\r\n triangleList[k].pt[1] = triangleList[k].pt[2];\r\n triangleList[k].pt[2] = tempOrder;\r\n pointPassesCollision[1] = 1;\r\n pointPassesCollision[2] = 0;\r\n }\r\n if (pointPassesCollision[1] && !pointPassesCollision[0]) {\r\n tempOrder = triangleList[k].pt[0];\r\n triangleList[k].pt[0] = triangleList[k].pt[1];\r\n triangleList[k].pt[1] = tempOrder;\r\n pointPassesCollision[0] = 1;\r\n pointPassesCollision[1] = 0;\r\n }\r\n if (insideVertCount === 0) {\r\n triangleList[k].culled = true;\r\n } else if (insideVertCount === 1) {\r\n triangleList[k].culled = false;\r\n const v0Tov1 = Vector3.sub(triangleList[k].pt[1], triangleList[k].pt[0]);\r\n const v0Tov2 = Vector3.sub(triangleList[k].pt[2], triangleList[k].pt[0]);\r\n const hitPointTimeRatio = edge - triangleList[k].pt[0][comp];\r\n const distanceAlongV1 = hitPointTimeRatio / v0Tov1[comp];\r\n const distanceAloneV2 = hitPointTimeRatio / v0Tov2[comp];\r\n v0Tov1.scaleBy(distanceAlongV1);\r\n v0Tov1.addBy(triangleList[k].pt[0]);\r\n v0Tov2.scaleBy(distanceAloneV2);\r\n v0Tov2.addBy(triangleList[k].pt[0]);\r\n triangleList[k].pt[1] = v0Tov2;\r\n triangleList[k].pt[2] = v0Tov1;\r\n } else if (insideVertCount === 2) {\r\n triangleList[triangleCount] = dupTriangle(triangleList[k + 1]);\r\n triangleList[k].culled = false;\r\n triangleList[k + 1].culled = false;\r\n const v2Tov0 = Vector3.sub(triangleList[k].pt[0], triangleList[k].pt[2]);\r\n const v2Tov1 = Vector3.sub(triangleList[k].pt[1], triangleList[k].pt[2]);\r\n const hitPointTime_2_0 = edge - triangleList[k].pt[2][comp];\r\n const distanceAloneVec_2_0 = hitPointTime_2_0 / v2Tov0[comp];\r\n v2Tov0.scaleBy(distanceAloneVec_2_0);\r\n v2Tov0.addBy(triangleList[k].pt[2]);\r\n triangleList[k + 1].pt[0] = new Vector3(triangleList[k].pt[0]);\r\n triangleList[k + 1].pt[1] = new Vector3(triangleList[k].pt[1]);\r\n triangleList[k + 1].pt[2] = v2Tov0;\r\n const hitPointTime_2_1 = edge - triangleList[k].pt[2][comp];\r\n const distanceAloneVec_2_1 = hitPointTime_2_1 / v2Tov1[comp];\r\n v2Tov1.scaleBy(distanceAloneVec_2_1);\r\n v2Tov1.addBy(triangleList[k].pt[2]);\r\n triangleList[k].pt[0] = new Vector3(triangleList[k + 1].pt[1]);\r\n triangleList[k].pt[1] = new Vector3(triangleList[k + 1].pt[2]);\r\n triangleList[k].pt[2] = v2Tov1;\r\n triangleCount++;\r\n k++;\r\n } else {\r\n triangleList[k].culled = false;\r\n }\r\n }\r\n k++;\r\n }\r\n }\r\n for (let index = 0; index < triangleCount; index++) {\r\n if (!triangleList[index].culled) {\r\n for (let v = 0; v < 3; v++) {\r\n const z = triangleList[index].pt[v].z;\r\n if (nearPlane > z) {\r\n nearPlane = z;\r\n }\r\n if (farPlane < z) {\r\n farPlane = z;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return [nearPlane, farPlane];\r\n }\r\n */\r\n}\r\n\r\n/**\r\n * Point light\r\n * @public\r\n */\r\nexport class PointLight extends PunctualLight {\r\n /** @internal */\r\n protected _range: number;\r\n /** @internal */\r\n protected _diffuseScale: number;\r\n /** @internal */\r\n protected _specularScale: number;\r\n /** @internal */\r\n protected _sourceRadius: number;\r\n /** @internal Physical luminous intensity in candela. */\r\n protected _luminousIntensity: number;\r\n /**\r\n * Creates an instance of point light\r\n * @param scene - The scene to which the light belongs\r\n */\r\n constructor(scene: Scene) {\r\n super(scene, LIGHT_TYPE_POINT);\r\n this._range = 0;\r\n this._diffuseScale = 1;\r\n this._specularScale = 1;\r\n this._sourceRadius = 0;\r\n this._luminousIntensity = 100;\r\n this.invalidateBoundingVolume();\r\n }\r\n /** The range of the light */\r\n get range() {\r\n return this._range;\r\n }\r\n set range(val: number) {\r\n this.setRange(val);\r\n }\r\n /** Diffuse scale of the point light */\r\n get diffuseScale() {\r\n return this._diffuseScale;\r\n }\r\n set diffuseScale(val: number) {\r\n this.setDiffuseScale(val);\r\n }\r\n /** Specular scale of the point light */\r\n get specularScale() {\r\n return this._specularScale;\r\n }\r\n set specularScale(val: number) {\r\n this.setSpecularScale(val);\r\n }\r\n /** Source radius of the point light */\r\n get sourceRadius() {\r\n return this._sourceRadius;\r\n }\r\n set sourceRadius(val: number) {\r\n this.setSourceRadius(val);\r\n }\r\n /** Physical luminous intensity in candela. */\r\n get luminousIntensity() {\r\n return this._luminousIntensity;\r\n }\r\n set luminousIntensity(val: number) {\r\n const intensity = Math.max(0, val);\r\n if (intensity !== this._luminousIntensity) {\r\n this._luminousIntensity = intensity;\r\n this.invalidateUniforms();\r\n if (this._range <= 0) {\r\n this.invalidateBoundingVolume();\r\n }\r\n }\r\n }\r\n /**\r\n * One-sided luminous flux in lumen.\r\n *\r\n * @remarks\r\n * Derived from {@link luminousIntensity} with Filament's point-light conversion, `Φ = 4π·I`.\r\n */\r\n get luminousPower() {\r\n return this._luminousIntensity * 4 * Math.PI;\r\n }\r\n set luminousPower(val: number) {\r\n this.luminousIntensity = Math.max(0, val) / (4 * Math.PI);\r\n }\r\n /**\r\n * Sets the range of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setRange(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._range !== val) {\r\n this._range = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /**\r\n * Sets the diffuse scale of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setDiffuseScale(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._diffuseScale !== val) {\r\n this._diffuseScale = val;\r\n this.invalidateUniforms();\r\n }\r\n return this;\r\n }\r\n /**\r\n * Sets the specular scale of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setSpecularScale(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._specularScale !== val) {\r\n this._specularScale = val;\r\n this.invalidateUniforms();\r\n }\r\n return this;\r\n }\r\n /**\r\n * Sets the source radius of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setSourceRadius(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._sourceRadius !== val) {\r\n this._sourceRadius = val;\r\n this.invalidateUniforms();\r\n }\r\n return this;\r\n }\r\n /**\r\n * {@inheritDoc BaseLight.isPointLight}\r\n * @override\r\n */\r\n isPointLight(): this is PointLight {\r\n return true;\r\n }\r\n /** @internal */\r\n computeBoundingVolume() {\r\n const range = this.positionAndRange.w;\r\n const bbox = new BoundingBox();\r\n bbox.minPoint = new Vector3(-range, -range, -range);\r\n bbox.maxPoint = new Vector3(range, range, range);\r\n return bbox;\r\n }\r\n /** @internal */\r\n computeUniforms() {\r\n const a = this.worldMatrix.getRow(3);\r\n const b = this.worldMatrix.getRow(2);\r\n const physical = this.scene?.lightingMode === 'physical';\r\n const metersPerUnit = this.scene?.metersPerUnit ?? 1;\r\n // diffuse/specular scales still multiply the shaded result, so the auto-derived influence\r\n // radius has to account for them. SpotLight has no equivalent scales, hence no such factor.\r\n const physicalScale = Math.max(this._diffuseScale, this._specularScale);\r\n const range =\r\n this.range <= 0\r\n ? physical\r\n ? Math.sqrt(Math.max(0, this.luminousIntensity * physicalScale) / PHYSICAL_LIGHT_CUTOFF_LUX) /\r\n metersPerUnit\r\n : 32 * Math.sqrt(Math.max(0.0001, this.intensity * physicalScale))\r\n : this.range;\r\n const resolvedIntensity = physical\r\n ? this.luminousIntensity / (metersPerUnit * metersPerUnit)\r\n : this.intensity;\r\n this._positionRange = new Vector4(a.x, a.y, a.z, range);\r\n this._directionCutoff = new Vector4(b.x, b.y, b.z, -1);\r\n this._diffuseIntensity = makeColorIntensity(this.color, resolvedIntensity);\r\n this._extraParams = new Vector4(\r\n this._diffuseScale,\r\n this._specularScale,\r\n this._sourceRadius,\r\n this.lightType\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Spot light\r\n * @public\r\n */\r\nexport class SpotLight extends PunctualLight {\r\n /** @internal Smallest cone half-angle, matching Filament's 0.5 degree clamp. */\r\n private static readonly MIN_CONE_ANGLE = (0.5 * Math.PI) / 180;\r\n /** @internal */\r\n protected _range: number;\r\n /** @internal */\r\n protected _cutoff: number;\r\n /** @internal Physical luminous intensity in candela. */\r\n protected _luminousIntensity: number;\r\n /** @internal Physical inner cone half-angle in radians. */\r\n protected _innerConeAngle: number;\r\n /** @internal Physical outer cone half-angle in radians. */\r\n protected _outerConeAngle: number;\r\n /**\r\n * Creates an instance of spot light\r\n * @param scene - The scene to which the light belongs\r\n */\r\n constructor(scene: Scene) {\r\n super(scene, LIGHT_TYPE_SPOT);\r\n this._range = 0;\r\n this._cutoff = Math.cos(Math.PI / 4);\r\n this._luminousIntensity = 1000;\r\n this._innerConeAngle = Math.PI / 8;\r\n this._outerConeAngle = Math.PI / 4;\r\n this.invalidateBoundingVolume();\r\n }\r\n /** The range of the light */\r\n get range() {\r\n return this._range;\r\n }\r\n set range(val: number) {\r\n this.setRange(val);\r\n }\r\n /**\r\n * Sets the range of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setRange(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._range !== val) {\r\n this._range = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /** The cutoff of the light */\r\n get cutoff() {\r\n return this._cutoff;\r\n }\r\n set cutoff(val: number) {\r\n this.setCutoff(val);\r\n }\r\n /** Physical luminous intensity in candela. */\r\n get luminousIntensity() {\r\n return this._luminousIntensity;\r\n }\r\n set luminousIntensity(val: number) {\r\n const intensity = Math.max(0, val);\r\n if (intensity !== this._luminousIntensity) {\r\n this._luminousIntensity = intensity;\r\n this.invalidateUniforms();\r\n if (this._range <= 0) {\r\n this.invalidateBoundingVolume();\r\n }\r\n }\r\n }\r\n /**\r\n * One-sided luminous flux in lumen.\r\n *\r\n * @remarks\r\n * Derived from {@link luminousIntensity} with Filament's focused-spot conversion,\r\n * `Φ = I · 2π(1 - cos(θouter))`, so authoring in either unit stays consistent.\r\n */\r\n get luminousPower() {\r\n return this._luminousIntensity * SpotLight.luminousPowerPerIntensity(this._outerConeAngle);\r\n }\r\n set luminousPower(val: number) {\r\n this.luminousIntensity = Math.max(0, val) / SpotLight.luminousPowerPerIntensity(this._outerConeAngle);\r\n }\r\n /** @internal Filament focused-spot conversion factor: 2π(1 - cos(θouter)). */\r\n private static luminousPowerPerIntensity(outerConeAngle: number) {\r\n return Math.max(2 * Math.PI * (1 - Math.cos(outerConeAngle)), 1e-6);\r\n }\r\n /** Physical inner cone half-angle in radians. */\r\n get innerConeAngle() {\r\n return this._innerConeAngle;\r\n }\r\n set innerConeAngle(val: number) {\r\n // Filament clamps to [0.5 degrees, outer]; the shader's scale/offset also guards inner == outer.\r\n const angle = Math.max(SpotLight.MIN_CONE_ANGLE, Math.min(Math.abs(val), this._outerConeAngle));\r\n if (angle !== this._innerConeAngle) {\r\n this._innerConeAngle = angle;\r\n this.invalidateUniforms();\r\n }\r\n }\r\n /** Physical outer cone half-angle in radians. */\r\n get outerConeAngle() {\r\n return this._outerConeAngle;\r\n }\r\n set outerConeAngle(val: number) {\r\n // Filament clamps both cone half-angles to [0.5 degrees, 90 degrees].\r\n const angle = Math.max(SpotLight.MIN_CONE_ANGLE, Math.min(Math.abs(val), Math.PI * 0.5));\r\n if (angle !== this._outerConeAngle) {\r\n this._outerConeAngle = angle;\r\n this._innerConeAngle = Math.min(this._innerConeAngle, angle);\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n }\r\n /**\r\n * @internal\r\n *\r\n * Cone angle attenuation packed as `(scale, offset)` so the shader evaluates\r\n * `saturate(cos(theta) * scale + offset)^2`, matching Filament's `getAngleAttenuation`.\r\n * The `1/1024` floor keeps a degenerate `inner == outer` cone finite instead of dividing by zero.\r\n */\r\n private getAngleScaleOffset(): [number, number] {\r\n const cosOuter = Math.cos(this._outerConeAngle);\r\n const cosInner = Math.cos(Math.min(this._innerConeAngle, this._outerConeAngle));\r\n const scale = 1 / Math.max(1 / 1024, cosInner - cosOuter);\r\n return [scale, -cosOuter * scale];\r\n }\r\n /**\r\n * Sets the cutoff of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setCutoff(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._cutoff !== val) {\r\n this._cutoff = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /**\r\n * {@inheritDoc BaseLight.isSpotLight}\r\n * @override\r\n */\r\n isSpotLight(): this is SpotLight {\r\n return true;\r\n }\r\n /** @internal */\r\n computeBoundingVolume() {\r\n const bbox = new BoundingBox();\r\n // In legacy mode `_cutoff` already stores the cosine of the cone half-angle (see the\r\n // constructor default and computeUniforms), so it must be used as-is. Physical mode keeps the\r\n // half-angle in radians instead, hence the conversion there.\r\n // The lower clamp keeps the radius finite for half-angles at or beyond 90 degrees.\r\n const cosCutoff = Math.min(\r\n 1,\r\n Math.max(\r\n 0.0001,\r\n this.scene?.lightingMode === 'physical' ? Math.cos(this._outerConeAngle) : this._cutoff\r\n )\r\n );\r\n const range = this.positionAndRange.w;\r\n const r = (range / cosCutoff) * Math.sqrt(1 - cosCutoff * cosCutoff);\r\n bbox.minPoint = new Vector3(-r, -r, 0);\r\n bbox.maxPoint = new Vector3(r, r, range);\r\n return bbox;\r\n }\r\n /** @internal */\r\n computeUniforms() {\r\n const a = this.worldMatrix.getRow(3);\r\n const b = this.worldMatrix.getRow(2).scaleBy(-1);\r\n const physical = this.scene?.lightingMode === 'physical';\r\n const metersPerUnit = this.scene?.metersPerUnit ?? 1;\r\n const range =\r\n this.range <= 0\r\n ? physical\r\n ? Math.sqrt(Math.max(0, this.luminousIntensity) / PHYSICAL_LIGHT_CUTOFF_LUX) / metersPerUnit\r\n : 32 * Math.sqrt(Math.max(0.0001, this.intensity))\r\n : this.range;\r\n const resolvedIntensity = physical\r\n ? this.luminousIntensity / (metersPerUnit * metersPerUnit)\r\n : this.intensity;\r\n this._positionRange = new Vector4(a.x, a.y, a.z, range);\r\n this._directionCutoff = new Vector4(\r\n b.x,\r\n b.y,\r\n b.z,\r\n physical ? Math.cos(this.outerConeAngle) : this.cutoff\r\n );\r\n this._diffuseIntensity = makeColorIntensity(this.color, resolvedIntensity);\r\n const [angleScale, angleOffset] = physical ? this.getAngleScaleOffset() : [0, 0];\r\n this._extraParams = new Vector4(angleScale, angleOffset, 0, this.lightType);\r\n }\r\n}\r\n\r\n/**\r\n * Rectangular area light\r\n * @public\r\n */\r\nexport class RectLight extends PunctualLight {\r\n /** @internal */\r\n protected _range: number;\r\n /** @internal */\r\n protected _width: number;\r\n /** @internal */\r\n protected _height: number;\r\n /** @internal Physical luminance in cd/m². */\r\n protected _luminance: number;\r\n /**\r\n * Creates an instance of rect light\r\n * @param scene - The scene to which the light belongs\r\n */\r\n constructor(scene: Scene) {\r\n super(scene, LIGHT_TYPE_RECT);\r\n this._range = 10;\r\n this._width = 1;\r\n this._height = 1;\r\n this._luminance = 100;\r\n this.invalidateBoundingVolume();\r\n }\r\n /** The range of the light */\r\n get range() {\r\n return this._range;\r\n }\r\n set range(val: number) {\r\n this.setRange(val);\r\n }\r\n /**\r\n * Sets the range of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setRange(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._range !== val) {\r\n this._range = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /** The width of the light */\r\n get width() {\r\n return this._width;\r\n }\r\n set width(val: number) {\r\n this.setWidth(val);\r\n }\r\n /**\r\n * Sets the width of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setWidth(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._width !== val) {\r\n this._width = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /** The height of the light */\r\n get height() {\r\n return this._height;\r\n }\r\n set height(val: number) {\r\n this.setHeight(val);\r\n }\r\n /** Physical luminance in cd/m² (nit). */\r\n get luminance() {\r\n return this._luminance;\r\n }\r\n set luminance(val: number) {\r\n const luminance = Math.max(0, val);\r\n if (luminance !== this._luminance) {\r\n this._luminance = luminance;\r\n this.invalidateUniforms();\r\n }\r\n }\r\n /**\r\n * One-sided Lambertian luminous flux in lumen.\r\n *\r\n * @remarks\r\n * Derived from {@link luminance}: `phi = L * pi * area`. Named `luminousFlux` rather than\r\n * `luminousPower` because an area light is authored by its luminance, with flux as the derived\r\n * convenience; point and spot lights are the other way round.\r\n */\r\n get luminousFlux() {\r\n const metersPerUnit = this.scene?.metersPerUnit ?? 1;\r\n return this.luminance * Math.PI * this.width * this.height * metersPerUnit * metersPerUnit;\r\n }\r\n set luminousFlux(val: number) {\r\n const metersPerUnit = this.scene?.metersPerUnit ?? 1;\r\n const area = this.width * this.height * metersPerUnit * metersPerUnit;\r\n this.luminance = area > 0 ? Math.max(0, val) / (Math.PI * area) : 0;\r\n }\r\n /**\r\n * Sets the height of the light\r\n * @param val - The value to set\r\n * @returns self\r\n */\r\n setHeight(val: number) {\r\n val = val < 0 ? 0 : val;\r\n if (this._height !== val) {\r\n this._height = val;\r\n this.invalidateUniforms();\r\n this.invalidateBoundingVolume();\r\n }\r\n return this;\r\n }\r\n /**\r\n * {@inheritDoc BaseLight.isRectLight}\r\n * @override\r\n */\r\n isRectLight(): this is RectLight {\r\n return true;\r\n }\r\n /**\r\n * Rect light supports shadow in current pipeline\r\n */\r\n /** @internal */\r\n computeBoundingVolume() {\r\n const bbox = new BoundingBox();\r\n const r = this._range;\r\n bbox.minPoint = new Vector3(-r, -r, -r);\r\n bbox.maxPoint = new Vector3(r, r, r);\r\n return bbox;\r\n }\r\n /** @internal */\r\n computeUniforms() {\r\n const pos = this.worldMatrix.getRow(3);\r\n const axisX = this.worldMatrix\r\n .getRow(0)\r\n .inplaceNormalize()\r\n .scaleBy(this._width * 0.5);\r\n const axisY = this.worldMatrix\r\n .getRow(1)\r\n .inplaceNormalize()\r\n .scaleBy(this._height * 0.5);\r\n this._positionRange = new Vector4(pos.x, pos.y, pos.z, this.range);\r\n this._directionCutoff = new Vector4(axisX.x, axisX.y, axisX.z, 0);\r\n const physical = this.scene?.lightingMode === 'physical';\r\n this._diffuseIntensity = makeColorIntensity(this.color, physical ? this.luminance : this.intensity);\r\n this._extraParams = new Vector4(axisY.x, axisY.y, axisY.z, this.lightType);\r\n }\r\n}\r\n"],"names":["PHYSICAL_LIGHT_CUTOFF_LUX","makeColorIntensity","color","intensity","Vector4","x","y","z","BaseLight","GraphNode","scene","type","_intensity","_type","_positionRange","_directionCutoff","_diffuseIntensity","_extraParams","lightType","val","setIntensity","positionAndRange","computeUniforms","directionAndCutoff","diffuseAndIntensity","extraParams","viewMatrix","invWorldMatrix","invalidateUniforms","isLight","isPunctualLight","isDirectionLight","isPointLight","isSpotLight","isRectLight","PunctualLight","ensurePunctualState","_color","one","_castShadow","_shadowMapper","ShadowMapper","clone","setColor","set","castShadow","b","setCastShadow","shadow","shadowRegion","updateDirectionalShadowRegion","_onTransformChanged","invalidateLocal","onDispose","dispose","DirectionalLight","_currentSunLight","WeakMap","_illuminance","LIGHT_TYPE_DIRECTIONAL","getSunLight","setSunLight","illuminance","Math","max","get","light","Error","ref","DWeakRef","sunLight","computeBoundingVolume","a","worldMatrix","getRow","scaleBy","physical","lightingMode","PointLight","LIGHT_TYPE_POINT","_range","_diffuseScale","_specularScale","_sourceRadius","_luminousIntensity","invalidateBoundingVolume","range","setRange","diffuseScale","setDiffuseScale","specularScale","setSpecularScale","sourceRadius","setSourceRadius","luminousIntensity","luminousPower","PI","w","bbox","BoundingBox","minPoint","Vector3","maxPoint","metersPerUnit","physicalScale","sqrt","resolvedIntensity","SpotLight","MIN_CONE_ANGLE","LIGHT_TYPE_SPOT","_cutoff","cos","_innerConeAngle","_outerConeAngle","cutoff","setCutoff","luminousPowerPerIntensity","outerConeAngle","innerConeAngle","angle","min","abs","cosOuter","cosInner","scale","cosCutoff","r","angleScale","angleOffset","getAngleScaleOffset","RectLight","LIGHT_TYPE_RECT","_width","_height","_luminance","width","setWidth","height","setHeight","luminance","luminousFlux","area","pos","axisX","inplaceNormalize","axisY"],"mappings":";;;;;;AAQA;AACA,MAAMA,yBAA4B,GAAA,IAAA;AAElC;;;;;;;;;AASC,IACD,SAASC,kBAAAA,CAAmBC,KAAc,EAAEC,SAAiB,EAAA;IAC3D,OAAO,IAAIC,OAAQF,CAAAA,KAAAA,CAAMG,CAAC,EAAEH,MAAMI,CAAC,EAAEJ,KAAMK,CAAAA,CAAC,EAAEJ,SAAAA,CAAAA;AAChD;AAEA;;;IAIO,MAAeK,SAAkBC,SAAAA,SAAAA,CAAAA;qBAEtC,KAAwB;qBAExB,UAA6B;qBAE7B,cAA4C;qBAE5C,gBAA8C;qBAE9C,iBAA+C;qBAE/C,YAA0C;AAC1C;;;;AAIC,MACD,WAAYC,CAAAA,KAAY,EAAEC,IAAY,CAAE;AACtC,QAAA,KAAK,CAACD,KAAAA,CAAAA;QACN,IAAI,CAACE,UAAU,GAAG,CAAA;QAClB,IAAI,CAACC,KAAK,GAAGF,IAAAA;QACb,IAAI,CAACG,cAAc,GAAG,IAAA;QACtB,IAAI,CAACC,gBAAgB,GAAG,IAAA;QACxB,IAAI,CAACC,iBAAiB,GAAG,IAAA;QACzB,IAAI,CAACC,YAAY,GAAG,IAAA;AACtB;+BAEA,IAAIC,SAAY,GAAA;QACd,OAAO,IAAI,CAACL,KAAK;AACnB;kCAEA,IAAIV,SAAY,GAAA;QACd,OAAO,IAAI,CAACS,UAAU;AACxB;IACA,IAAIT,SAAAA,CAAUgB,GAAG,EAAE;QACjB,IAAI,CAACC,YAAY,CAACD,GAAAA,CAAAA;AACpB;AACA;;;;;;AAMC,MACD,IAAIE,gBAAuC,GAAA;AACzC,QAAA,IAAI,CAAC,IAAI,CAACP,cAAc,EAAE;AACxB,YAAA,IAAI,CAACQ,eAAe,EAAA;AACtB;QACA,OAAO,IAAI,CAACR,cAAc;AAC5B;AACA;;;;;;AAMC,MACD,IAAIS,kBAAqB,GAAA;AACvB,QAAA,IAAI,CAAC,IAAI,CAACR,gBAAgB,EAAE;AAC1B,YAAA,IAAI,CAACO,eAAe,EAAA;AACtB;QACA,OAAO,IAAI,CAACP,gBAAgB;AAC9B;AACA;;;;;;AAMC,MACD,IAAIS,mBAAsB,GAAA;AACxB,QAAA,IAAI,CAAC,IAAI,CAACR,iBAAiB,EAAE;AAC3B,YAAA,IAAI,CAACM,eAAe,EAAA;AACtB;QACA,OAAO,IAAI,CAACN,iBAAiB;AAC/B;AACA;;;;;AAKC,MACD,IAAIS,WAAc,GAAA;AAChB,QAAA,IAAI,CAAC,IAAI,CAACR,YAAY,EAAE;AACtB,YAAA,IAAI,CAACK,eAAe,EAAA;AACtB;QACA,OAAO,IAAI,CAACL,YAAY;AAC1B;AACA;;;;;;AAMC,MACD,IAAIS,UAAmC,GAAA;QACrC,OAAO,IAAI,CAACC,cAAc;AAC5B;AACA;;;;MAKAP,YAAAA,CAAaD,GAAW,EAAE;AACxB,QAAA,IAAI,IAAI,CAACP,UAAU,KAAKO,GAAK,EAAA;YAC3B,IAAI,CAACP,UAAU,GAAGO,GAAAA;AAClB,YAAA,IAAI,CAACS,kBAAkB,EAAA;AACzB;AACA,QAAA,OAAO,IAAI;AACb;AACA,qBACAA,kBAAqB,GAAA;QACnB,IAAI,CAACd,cAAc,GAAG,IAAA;QACtB,IAAI,CAACC,gBAAgB,GAAG,IAAA;QACxB,IAAI,CAACC,iBAAiB,GAAG,IAAA;QACzB,IAAI,CAACC,YAAY,GAAG,IAAA;AACtB;AACA,2CACAY,OAA6B,GAAA;QAC3B,OAAO,IAAA;AACT;AACA,mDACAC,eAAyC,GAAA;QACvC,OAAO,KAAA;AACT;AACA,uDACAC,gBAA6C,GAAA;QAC3C,OAAO,KAAA;AACT;AACA,iDACAC,YAAmC,GAAA;QACjC,OAAO,KAAA;AACT;AACA,gDACAC,WAAiC,GAAA;QAC/B,OAAO,KAAA;AACT;AACA,gDACAC,WAAiC,GAAA;QAC/B,OAAO,KAAA;AACT;AAGF;AAEA;;;;;;;;;AASA;;;IAMO,MAAMC,aAAsB3B,SAAAA,SAAAA,CAAAA;qBAEjC,MAA2B;qBAE3B,WAAgC;qBAEhC,aAAuC;AACvC;;;;AAIC,MACD,WAAYE,CAAAA,KAAY,EAAEC,IAAY,CAAE;AACtC,QAAA,KAAK,CAACD,KAAOC,EAAAA,IAAAA,CAAAA;AACb,QAAA,IAAI,CAACyB,mBAAmB,EAAA;AAC1B;qBAEA,mBAAgC,GAAA;AAC9B,QAAA,IAAI,CAAC,IAAI,CAACC,MAAM,EAAE;AAChB,YAAA,IAAI,CAACA,MAAM,GAAGjC,OAAAA,CAAQkC,GAAG,EAAA;AAC3B;AACA,QAAA,IAAI,IAAI,CAACC,WAAW,IAAI,IAAM,EAAA;YAC5B,IAAI,CAACA,WAAW,GAAG,KAAA;AACrB;AACA,QAAA,IAAI,CAAC,IAAI,CAACC,aAAa,EAAE;AACvB,YAAA,IAAI,CAACA,aAAa,GAAG,IAAIC,aAAa,IAAI,CAAA;AAC5C;AACF;8BAEA,IAAIvC,KAAQ,GAAA;AACV,QAAA,IAAI,CAACkC,mBAAmB,EAAA;AACxB,QAAA,OAAO,IAAI,CAACC,MAAM,CAACK,KAAK,EAAA;AAC1B;IACA,IAAIxC,KAAAA,CAAMA,KAAK,EAAE;QACf,IAAI,CAACyC,QAAQ,CAACzC,KAAAA,CAAAA;AAChB;AACA;;;;MAKAyC,QAAAA,CAASzC,KAAwB,EAAE;AACjC,QAAA,IAAI,CAACkC,mBAAmB,EAAA;AACxB,QAAA,IAAI,CAACC,MAAM,CAACO,GAAG,CAAC1C,KAAAA,CAAAA;AAChB,QAAA,IAAI,CAAC0B,kBAAkB,EAAA;AACvB,QAAA,OAAO,IAAI;AACb;4CAEA,IAAIiB,UAAa,GAAA;AACf,QAAA,IAAI,CAACT,mBAAmB,EAAA;QACxB,OAAO,IAAI,CAACG,WAAW;AACzB;IACA,IAAIM,UAAAA,CAAWC,CAAC,EAAE;QAChB,IAAI,CAACC,aAAa,CAACD,CAAAA,CAAAA;AACrB;AACA;;;;MAKAC,aAAAA,CAAcD,CAAU,EAAQ;AAC9B,QAAA,IAAI,CAACV,mBAAmB,EAAA;AACxB,QAAA,IAAI,IAAI,CAACG,WAAW,KAAK,CAAC,CAACO,CAAG,EAAA;AAC5B,YAAA,IAAI,CAACP,WAAW,GAAG,CAAC,CAACO,CAAAA;AACrB,YAAA,IAAI,IAAI,CAACP,WAAW,IAAI,IAAI,CAACR,gBAAgB,EAAM,IAAA,CAAC,IAAI,CAACiB,MAAM,CAACC,YAAY,EAAE;AAC5E,gBAAA,IAAI,CAACD,MAAM,CAACE,6BAA6B,CAAC,IAAA,CAAA;AAC5C;AACF;AACA,QAAA,OAAO,IAAI;AACb;4CAEA,IAAIF,MAAS,GAAA;AACX,QAAA,IAAI,CAACZ,mBAAmB,EAAA;QACxB,OAAO,IAAI,CAACI,aAAa;AAC3B;AACA;;;AAGC,MACDV,eAAyC,GAAA;QACvC,OAAO,IAAA;AACT;AACA,qBACUqB,mBAAoBC,CAAAA,eAAwB,EAAE;AACtD,QAAA,KAAK,CAACD,mBAAoBC,CAAAA,eAAAA,CAAAA;AAC1B,QAAA,IAAI,CAACxB,kBAAkB,EAAA;AACzB;4CAEA,SAAsB,GAAA;AACpB,QAAA,KAAK,CAACyB,SAAAA,EAAAA;QACN,IAAI,CAACb,aAAa,EAAEc,OAAAA,EAAAA;AACtB;qBAEAhC,kBAAkB;AACpB;AAEA;;;IAIO,MAAMiC,gBAAyBpB,SAAAA,aAAAA,CAAAA;IACpC,OAAwBqB,gBAAAA,GAA+D,IAAIC,OAAU,EAAA;IAC7FC,YAAqB;AAC7B;;;MAIA,WAAA,CAAYhD,KAAY,CAAE;AACxB,QAAA,KAAK,CAACA,KAAOiD,EAAAA,sBAAAA,CAAAA;QACb,IAAI,CAACxD,SAAS,GAAG,EAAA;QACjB,IAAI,CAACuD,YAAY,GAAG,MAAA;AACpB,QAAA,IAAI,CAACH,gBAAAA,CAAiBK,WAAW,CAAClD,KAAQ,CAAA,EAAA;YACxC6C,gBAAiBM,CAAAA,WAAW,CAACnD,KAAAA,EAAO,IAAI,CAAA;AAC1C;AACF;wCAEA,IAAIoD,WAAc,GAAA;QAChB,OAAO,IAAI,CAACJ,YAAY;AAC1B;IACA,IAAII,WAAAA,CAAY3C,GAAW,EAAE;AAC3B,QAAA,MAAM2C,WAAcC,GAAAA,IAAAA,CAAKC,GAAG,CAAC,CAAG7C,EAAAA,GAAAA,CAAAA;AAChC,QAAA,IAAI2C,WAAgB,KAAA,IAAI,CAACJ,YAAY,EAAE;YACrC,IAAI,CAACA,YAAY,GAAGI,WAAAA;AACpB,YAAA,IAAI,CAAClC,kBAAkB,EAAA;AACzB;AACF;IACA,OAAOgC,WAAAA,CAAYlD,KAAY,EAAE;AAC/B,QAAA,OAAO,IAAI,CAAC8C,gBAAgB,CAACS,GAAG,CAACvD,QAAQuD,GAAS,EAAA,IAAA,IAAA;AACpD;AACA,IAAA,OAAOJ,WAAYnD,CAAAA,KAAY,EAAEwD,KAAiC,EAAE;AAClE,QAAA,IAAIA,KAASxD,IAAAA,KAAAA,KAAUwD,KAAMxD,CAAAA,KAAK,EAAE;AAClC,YAAA,MAAM,IAAIyD,KAAM,CAAA,gDAAA,CAAA;AAClB;AACA,QAAA,MAAMC,MAAM,IAAI,CAACZ,gBAAgB,CAACS,GAAG,CAACvD,KAAAA,CAAAA;AACtC,QAAA,IAAI,CAAC0D,GAAK,EAAA;AACR,YAAA,IAAI,CAACZ,gBAAgB,CAACZ,GAAG,CAAClC,KAAAA,EAAO,IAAI2D,QAASH,CAAAA,KAAAA,CAAAA,CAAAA;SACzC,MAAA;AACLE,YAAAA,GAAAA,CAAIxB,GAAG,CAACsB,KAAAA,CAAAA;AACV;AACF;AACA;;;;;AAKE,OACF,IAAII,QAAoB,GAAA;AACtB,QAAA,OAAOf,iBAAiBK,WAAW,CAAC,IAAI,CAAClD,KAAK,MAAO,IAAI;AAC3D;IACA,IAAI4D,QAAAA,CAASnD,GAAG,EAAE;AAChB,QAAA,IAAIA,GAAK,EAAA;AACPoC,YAAAA,gBAAAA,CAAiBM,WAAW,CAAC,IAAI,CAACnD,KAAK,EAAG,IAAI,CAAA;SACzC,MAAA,IAAI6C,iBAAiBK,WAAW,CAAC,IAAI,CAAClD,KAAK,CAAO,KAAA,IAAI,EAAE;AAC7D6C,YAAAA,gBAAAA,CAAiBM,WAAW,CAAC,IAAI,CAACnD,KAAK,EAAG,IAAA,CAAA;AAC5C;AACF;AACA;;;AAGC,MACDqB,gBAA6C,GAAA;QAC3C,OAAO,IAAA;AACT;AACA,qBACAwC,qBAAwB,GAAA;QACtB,OAAO,IAAA;AACT;AACA,qBACAjD,eAAkB,GAAA;AAChB,QAAA,MAAMkD,IAAI,IAAI,CAACC,WAAW,CAACC,MAAM,CAAC,CAAA,CAAA;QAClC,MAAM5B,CAAAA,GAAI,IAAI,CAAC2B,WAAW,CAACC,MAAM,CAAC,CAAA,CAAA,CAAGC,OAAO,CAAC,EAAC,CAAA;AAC9C,QAAA,IAAI,CAAC7D,cAAc,GAAG,IAAIV,QAAQoE,CAAEnE,CAAAA,CAAC,EAAEmE,CAAAA,CAAElE,CAAC,EAAEkE,CAAEjE,CAAAA,CAAC,EAAE,EAAC,CAAA;AAClD,QAAA,IAAI,CAACQ,gBAAgB,GAAG,IAAIX,OAAQ0C,CAAAA,CAAAA,CAAEzC,CAAC,EAAEyC,CAAExC,CAAAA,CAAC,EAAEwC,CAAAA,CAAEvC,CAAC,EAAE,CAAA,CAAA;AACnD,QAAA,MAAMqE,QAAW,GAAA,IAAI,CAAClE,KAAK,EAAEmE,YAAiB,KAAA,UAAA;AAC9C,QAAA,IAAI,CAAC7D,iBAAiB,GAAGf,kBAAAA,CAAmB,IAAI,CAACC,KAAK,EAAE0E,QAAAA,GAAW,IAAI,CAACd,WAAW,GAAG,IAAI,CAAC3D,SAAS,CAAA;QACpG,IAAI,CAACc,YAAY,GAAG,IAAIb,OAAAA,CAAQ,GAAG,CAAG,EAAA,CAAA,EAAG,IAAI,CAACc,SAAS,CAAA;AACzD;AAuLF;AAEA;;;IAIO,MAAM4D,UAAmB3C,SAAAA,aAAAA,CAAAA;qBAE9B,MAAyB;qBAEzB,aAAgC;qBAEhC,cAAiC;qBAEjC,aAAgC;6DAEhC,kBAAqC;AACrC;;;MAIA,WAAA,CAAYzB,KAAY,CAAE;AACxB,QAAA,KAAK,CAACA,KAAOqE,EAAAA,gBAAAA,CAAAA;QACb,IAAI,CAACC,MAAM,GAAG,CAAA;QACd,IAAI,CAACC,aAAa,GAAG,CAAA;QACrB,IAAI,CAACC,cAAc,GAAG,CAAA;QACtB,IAAI,CAACC,aAAa,GAAG,CAAA;QACrB,IAAI,CAACC,kBAAkB,GAAG,GAAA;AAC1B,QAAA,IAAI,CAACC,wBAAwB,EAAA;AAC/B;kCAEA,IAAIC,KAAQ,GAAA;QACV,OAAO,IAAI,CAACN,MAAM;AACpB;IACA,IAAIM,KAAAA,CAAMnE,GAAW,EAAE;QACrB,IAAI,CAACoE,QAAQ,CAACpE,GAAAA,CAAAA;AAChB;4CAEA,IAAIqE,YAAe,GAAA;QACjB,OAAO,IAAI,CAACP,aAAa;AAC3B;IACA,IAAIO,YAAAA,CAAarE,GAAW,EAAE;QAC5B,IAAI,CAACsE,eAAe,CAACtE,GAAAA,CAAAA;AACvB;6CAEA,IAAIuE,aAAgB,GAAA;QAClB,OAAO,IAAI,CAACR,cAAc;AAC5B;IACA,IAAIQ,aAAAA,CAAcvE,GAAW,EAAE;QAC7B,IAAI,CAACwE,gBAAgB,CAACxE,GAAAA,CAAAA;AACxB;4CAEA,IAAIyE,YAAe,GAAA;QACjB,OAAO,IAAI,CAACT,aAAa;AAC3B;IACA,IAAIS,YAAAA,CAAazE,GAAW,EAAE;QAC5B,IAAI,CAAC0E,eAAe,CAAC1E,GAAAA,CAAAA;AACvB;mDAEA,IAAI2E,iBAAoB,GAAA;QACtB,OAAO,IAAI,CAACV,kBAAkB;AAChC;IACA,IAAIU,iBAAAA,CAAkB3E,GAAW,EAAE;AACjC,QAAA,MAAMhB,SAAY4D,GAAAA,IAAAA,CAAKC,GAAG,CAAC,CAAG7C,EAAAA,GAAAA,CAAAA;AAC9B,QAAA,IAAIhB,SAAc,KAAA,IAAI,CAACiF,kBAAkB,EAAE;YACzC,IAAI,CAACA,kBAAkB,GAAGjF,SAAAA;AAC1B,YAAA,IAAI,CAACyB,kBAAkB,EAAA;AACvB,YAAA,IAAI,IAAI,CAACoD,MAAM,IAAI,CAAG,EAAA;AACpB,gBAAA,IAAI,CAACK,wBAAwB,EAAA;AAC/B;AACF;AACF;AACA;;;;;AAKC,MACD,IAAIU,aAAgB,GAAA;AAClB,QAAA,OAAO,IAAI,CAACX,kBAAkB,GAAG,CAAA,GAAIrB,KAAKiC,EAAE;AAC9C;IACA,IAAID,aAAAA,CAAc5E,GAAW,EAAE;AAC7B,QAAA,IAAI,CAAC2E,iBAAiB,GAAG/B,IAAAA,CAAKC,GAAG,CAAC,CAAG7C,EAAAA,GAAAA,CAAAA,IAAQ,CAAA,GAAI4C,IAAKiC,CAAAA,EAAE,CAAD;AACzD;AACA;;;;MAKAT,QAAAA,CAASpE,GAAW,EAAE;QACpBA,GAAMA,GAAAA,GAAAA,GAAM,IAAI,CAAIA,GAAAA,GAAAA;AACpB,QAAA,IAAI,IAAI,CAAC6D,MAAM,KAAK7D,GAAK,EAAA;YACvB,IAAI,CAAC6D,MAAM,GAAG7D,GAAAA;AACd,YAAA,IAAI,CAACS,kBAAkB,EAAA;AACvB,YAAA,IAAI,CAACyD,wBAAwB,EAAA;AAC/B;AACA,QAAA,OAAO,IAAI;AACb;AACA;;;;MAKAI,eAAAA,CAAgBtE,GAAW,EAAE;QAC3BA,GAAMA,GAAAA,GAAAA,GAAM,IAAI,CAAIA,GAAAA,GAAAA;AACpB,QAAA,IAAI,IAAI,CAAC8D,aAAa,KAAK9D,GAAK,EAAA;YAC9B,IAAI,CAAC8D,aAAa,GAAG9D,GAAAA;AACrB,YAAA,IAAI,CAACS,kBAAkB,EAAA;AACzB;AACA,QAAA,OAAO,IAAI;AACb;AACA;;;;MAKA+D,gBAAAA,CAAiBxE,GAAW,EAAE;QAC5BA,GAAMA,GAAAA,GAAAA,GAAM,IAAI,CAAIA,GAAAA,GAAAA;AACpB,QAAA,IAAI,IAAI,CAAC+D,cAAc,KAAK/D,GAAK,EAAA;YAC/B,IAAI,CAAC+D,cAAc,GAAG/D,GAAAA;AACtB,YAAA,IAAI,CAACS,kBAAkB,EAAA;AACzB;AACA,QAAA,OAAO,IAAI;AACb;AACA;;;;MAKAiE,eAAAA,CAAgB1E,GAAW,EAAE;QAC3BA,GAAMA,GAAAA,GAAAA,GAAM,IAAI,CAAIA,GAAAA,GAAAA;AACpB,QAAA,IAAI,IAAI,CAACgE,aAAa,KAAKhE,GAAK,EAAA;YAC9B,IAAI,CAACgE,aAAa,GAAGhE,GAAAA;AACrB,YAAA,IAAI,CAACS,kBAAkB,EAAA;AACzB;AACA,QAAA,OAAO,IAAI;AACb;AACA;;;AAGC,MACDI,YAAmC,GAAA;QACjC,OAAO,IAAA;AACT;AACA,qBACAuC,qBAAwB,GAAA;AACtB,QAAA,MAAMe,KAAQ,GAAA,IAAI,CAACjE,gBAAgB,CAAC4E,CAAC;AACrC,QAAA,MAAMC,OAAO,IAAIC,WAAAA,EAAAA;QACjBD,IAAKE,CAAAA,QAAQ,GAAG,IAAIC,OAAAA,CAAQ,CAACf,KAAO,EAAA,CAACA,OAAO,CAACA,KAAAA,CAAAA;AAC7CY,QAAAA,IAAAA,CAAKI,QAAQ,GAAG,IAAID,OAAAA,CAAQf,OAAOA,KAAOA,EAAAA,KAAAA,CAAAA;QAC1C,OAAOY,IAAAA;AACT;AACA,qBACA5E,eAAkB,GAAA;AAChB,QAAA,MAAMkD,IAAI,IAAI,CAACC,WAAW,CAACC,MAAM,CAAC,CAAA,CAAA;AAClC,QAAA,MAAM5B,IAAI,IAAI,CAAC2B,WAAW,CAACC,MAAM,CAAC,CAAA,CAAA;AAClC,QAAA,MAAME,QAAW,GAAA,IAAI,CAAClE,KAAK,EAAEmE,YAAiB,KAAA,UAAA;AAC9C,QAAA,MAAM0B,aAAgB,GAAA,IAAI,CAAC7F,KAAK,EAAE6F,aAAiB,IAAA,CAAA;;;QAGnD,MAAMC,aAAAA,GAAgBzC,IAAKC,CAAAA,GAAG,CAAC,IAAI,CAACiB,aAAa,EAAE,IAAI,CAACC,cAAc,CAAA;AACtE,QAAA,MAAMI,QACJ,IAAI,CAACA,KAAK,IAAI,IACVV,QACEb,GAAAA,IAAAA,CAAK0C,IAAI,CAAC1C,KAAKC,GAAG,CAAC,CAAG,EAAA,IAAI,CAAC8B,iBAAiB,GAAGU,aAAiBxG,CAAAA,GAAAA,yBAAAA,CAAAA,GAChEuG,gBACA,EAAKxC,GAAAA,IAAAA,CAAK0C,IAAI,CAAC1C,KAAKC,GAAG,CAAC,MAAQ,EAAA,IAAI,CAAC7D,SAAS,GAAGqG,aACnD,CAAA,CAAA,GAAA,IAAI,CAAClB,KAAK;AAChB,QAAA,MAAMoB,iBAAoB9B,GAAAA,QAAAA,GACtB,IAAI,CAACkB,iBAAiB,IAAIS,aAAAA,GAAgBA,aAAY,CAAA,GACtD,IAAI,CAACpG,SAAS;AAClB,QAAA,IAAI,CAACW,cAAc,GAAG,IAAIV,OAAQoE,CAAAA,CAAAA,CAAEnE,CAAC,EAAEmE,CAAElE,CAAAA,CAAC,EAAEkE,CAAAA,CAAEjE,CAAC,EAAE+E,KAAAA,CAAAA;AACjD,QAAA,IAAI,CAACvE,gBAAgB,GAAG,IAAIX,QAAQ0C,CAAEzC,CAAAA,CAAC,EAAEyC,CAAAA,CAAExC,CAAC,EAAEwC,CAAEvC,CAAAA,CAAC,EAAE,EAAC,CAAA;AACpD,QAAA,IAAI,CAACS,iBAAiB,GAAGf,mBAAmB,IAAI,CAACC,KAAK,EAAEwG,iBAAAA,CAAAA;AACxD,QAAA,IAAI,CAACzF,YAAY,GAAG,IAAIb,OACtB,CAAA,IAAI,CAAC6E,aAAa,EAClB,IAAI,CAACC,cAAc,EACnB,IAAI,CAACC,aAAa,EAClB,IAAI,CAACjE,SAAS,CAAA;AAElB;AACF;AAEA;;;IAIO,MAAMyF,SAAkBxE,SAAAA,aAAAA,CAAAA;qFAE7B,OAAwByE,cAAiB,GAAC,MAAM7C,IAAKiC,CAAAA,EAAE,GAAI,GAAI;qBAE/D,MAAyB;qBAEzB,OAA0B;6DAE1B,kBAAqC;gEAErC,eAAkC;gEAElC,eAAkC;AAClC;;;MAIA,WAAA,CAAYtF,KAAY,CAAE;AACxB,QAAA,KAAK,CAACA,KAAOmG,EAAAA,eAAAA,CAAAA;QACb,IAAI,CAAC7B,MAAM,GAAG,CAAA;QACd,IAAI,CAAC8B,OAAO,GAAG/C,IAAAA,CAAKgD,GAAG,CAAChD,IAAAA,CAAKiC,EAAE,GAAG,CAAA,CAAA;QAClC,IAAI,CAACZ,kBAAkB,GAAG,IAAA;AAC1B,QAAA,IAAI,CAAC4B,eAAe,GAAGjD,IAAAA,CAAKiC,EAAE,GAAG,CAAA;AACjC,QAAA,IAAI,CAACiB,eAAe,GAAGlD,IAAAA,CAAKiC,EAAE,GAAG,CAAA;AACjC,QAAA,IAAI,CAACX,wBAAwB,EAAA;AAC/B;kCAEA,IAAIC,KAAQ,GAAA;QACV,OAAO,IAAI,CAACN,MAAM;AACpB;IACA,IAAIM,KAAAA,CAAMnE,GAAW,EAAE;QACrB,IAAI,CAACoE,QAAQ,CAACpE,GAAAA,CAAAA;AAChB;AACA;;;;MAKAoE,QAAAA,CAASpE,GAAW,EAAE;QACpBA,GAAMA,GAAAA,GAAAA,GAAM,IAAI,CAAIA,GAAAA,GAAAA;AACpB,QAAA,IAAI,IAAI,CAAC6D,MAAM,KAAK7D,GAAK,EAAA;YACvB,IAAI,CAAC6D,MAAM,GAAG7D,GAAAA;AACd,YAAA,IAAI,CAACS,kBAAkB,EAAA;AACvB,YAAA,IAAI,CAACyD,wBAAwB,EAAA;AAC/B;AACA,QAAA,OAAO,IAAI;AACb;mCAEA,IAAI6B,MAAS,GAAA;QACX,OAAO,IAAI,CAACJ,OAAO;AACrB;IACA,IAAII,MAAAA,CAAO/F,GAAW,EAAE;QACtB,IAAI,CAACgG,SAAS,CAAChG,GAAAA,CAAAA;AACjB;mDAEA,IAAI2E,iBAAoB,GAAA;QACtB,OAAO,IAAI,CAACV,kBAAkB;AAChC;IACA,IAAIU,iBAAAA,CAAkB3E,GAAW,EAAE;AACjC,QAAA,MAAMhB,SAAY4D,GAAAA,IAAAA,CAAKC,GAAG,CAAC,CAAG7C,EAAAA,GAAAA,CAAAA;AAC9B,QAAA,IAAIhB,SAAc,KAAA,IAAI,CAACiF,kBAAkB,EAAE;YACzC,IAAI,CAACA,kBAAkB,GAAGjF,SAAAA;AAC1B,YAAA,IAAI,CAACyB,kBAAkB,EAAA;AACvB,YAAA,IAAI,IAAI,CAACoD,MAAM,IAAI,CAAG,EAAA;AACpB,gBAAA,IAAI,CAACK,wBAAwB,EAAA;AAC/B;AACF;AACF;AACA;;;;;;AAMC,MACD,IAAIU,aAAgB,GAAA;QAClB,OAAO,IAAI,CAACX,kBAAkB,GAAGuB,UAAUS,yBAAyB,CAAC,IAAI,CAACH,eAAe,CAAA;AAC3F;IACA,IAAIlB,aAAAA,CAAc5E,GAAW,EAAE;AAC7B,QAAA,IAAI,CAAC2E,iBAAiB,GAAG/B,IAAAA,CAAKC,GAAG,CAAC,CAAG7C,EAAAA,GAAAA,CAAAA,GAAOwF,SAAUS,CAAAA,yBAAyB,CAAC,IAAI,CAACH,eAAe,CAAA;AACtG;AACA,mFACA,OAAeG,yBAA0BC,CAAAA,cAAsB,EAAE;AAC/D,QAAA,OAAOtD,IAAKC,CAAAA,GAAG,CAAC,CAAA,GAAID,IAAKiC,CAAAA,EAAE,IAAI,CAAIjC,GAAAA,IAAAA,CAAKgD,GAAG,CAACM,eAAc,CAAI,EAAA,IAAA,CAAA;AAChE;sDAEA,IAAIC,cAAiB,GAAA;QACnB,OAAO,IAAI,CAACN,eAAe;AAC7B;IACA,IAAIM,cAAAA,CAAenG,GAAW,EAAE;;AAE9B,QAAA,MAAMoG,QAAQxD,IAAKC,CAAAA,GAAG,CAAC2C,SAAAA,CAAUC,cAAc,EAAE7C,IAAAA,CAAKyD,GAAG,CAACzD,KAAK0D,GAAG,CAACtG,GAAM,CAAA,EAAA,IAAI,CAAC8F,eAAe,CAAA,CAAA;AAC7F,QAAA,IAAIM,KAAU,KAAA,IAAI,CAACP,eAAe,EAAE;YAClC,IAAI,CAACA,eAAe,GAAGO,KAAAA;AACvB,YAAA,IAAI,CAAC3F,kBAAkB,EAAA;AACzB;AACF;sDAEA,IAAIyF,cAAiB,GAAA;QACnB,OAAO,IAAI,CAACJ,eAAe;AAC7B;IACA,IAAII,cAAAA,CAAelG,GAAW,EAAE;;AAE9B,QAAA,MAAMoG,QAAQxD,IAAKC,CAAAA,GAAG,CAAC2C,SAAAA,CAAUC,cAAc,EAAE7C,IAAAA,CAAKyD,GAAG,CAACzD,KAAK0D,GAAG,CAACtG,GAAM4C,CAAAA,EAAAA,IAAAA,CAAKiC,EAAE,GAAG,GAAA,CAAA,CAAA;AACnF,QAAA,IAAIuB,KAAU,KAAA,IAAI,CAACN,eAAe,EAAE;YAClC,IAAI,CAACA,eAAe,GAAGM,KAAAA;YACvB,IAAI,CAACP,eAAe,GAAGjD,IAAAA,CAAKyD,GAAG,CAAC,IAAI,CAACR,eAAe,EAAEO,KAAAA,CAAAA;AACtD,YAAA,IAAI,CAAC3F,kBAAkB,EAAA;AACvB,YAAA,IAAI,CAACyD,wBAAwB,EAAA;AAC/B;AACF;AACA;;;;;;AAMC,MACD,mBAAgD,GAAA;AAC9C,QAAA,MAAMqC,WAAW3D,IAAKgD,CAAAA,GAAG,CAAC,IAAI,CAACE,eAAe,CAAA;AAC9C,QAAA,MAAMU,QAAW5D,GAAAA,IAAAA,CAAKgD,GAAG,CAAChD,IAAKyD,CAAAA,GAAG,CAAC,IAAI,CAACR,eAAe,EAAE,IAAI,CAACC,eAAe,CAAA,CAAA;AAC7E,QAAA,MAAMW,QAAQ,CAAI7D,GAAAA,IAAAA,CAAKC,GAAG,CAAC,CAAA,GAAI,MAAM2D,QAAWD,GAAAA,QAAAA,CAAAA;QAChD,OAAO;AAACE,YAAAA,KAAAA;AAAO,YAAA,CAACF,QAAWE,GAAAA;AAAM,SAAA;AACnC;AACA;;;;MAKAT,SAAAA,CAAUhG,GAAW,EAAE;QACrBA,GAAMA,GAAAA,GAAAA,GAAM,IAAI,CAAIA,GAAAA,GAAAA;AACpB,QAAA,IAAI,IAAI,CAAC2F,OAAO,KAAK3F,GAAK,EAAA;YACxB,IAAI,CAAC2F,OAAO,GAAG3F,GAAAA;AACf,YAAA,IAAI,CAACS,kBAAkB,EAAA;AACvB,YAAA,IAAI,CAACyD,wBAAwB,EAAA;AAC/B;AACA,QAAA,OAAO,IAAI;AACb;AACA;;;AAGC,MACDpD,WAAiC,GAAA;QAC/B,OAAO,IAAA;AACT;AACA,qBACAsC,qBAAwB,GAAA;AACtB,QAAA,MAAM2B,OAAO,IAAIC,WAAAA,EAAAA;;;;;QAKjB,MAAM0B,SAAAA,GAAY9D,IAAKyD,CAAAA,GAAG,CACxB,CAAA,EACAzD,KAAKC,GAAG,CACN,MACA,EAAA,IAAI,CAACtD,KAAK,EAAEmE,YAAiB,KAAA,UAAA,GAAad,IAAKgD,CAAAA,GAAG,CAAC,IAAI,CAACE,eAAe,CAAA,GAAI,IAAI,CAACH,OAAO,CAAA,CAAA;AAG3F,QAAA,MAAMxB,KAAQ,GAAA,IAAI,CAACjE,gBAAgB,CAAC4E,CAAC;QACrC,MAAM6B,CAAAA,GAAI,KAASD,GAAAA,SAAAA,GAAa9D,KAAK0C,IAAI,CAAC,IAAIoB,SAAYA,GAAAA,SAAAA,CAAAA;AAC1D3B,QAAAA,IAAAA,CAAKE,QAAQ,GAAG,IAAIC,QAAQ,CAACyB,CAAAA,EAAG,CAACA,CAAG,EAAA,CAAA,CAAA;AACpC5B,QAAAA,IAAAA,CAAKI,QAAQ,GAAG,IAAID,OAAAA,CAAQyB,GAAGA,CAAGxC,EAAAA,KAAAA,CAAAA;QAClC,OAAOY,IAAAA;AACT;AACA,qBACA5E,eAAkB,GAAA;AAChB,QAAA,MAAMkD,IAAI,IAAI,CAACC,WAAW,CAACC,MAAM,CAAC,CAAA,CAAA;QAClC,MAAM5B,CAAAA,GAAI,IAAI,CAAC2B,WAAW,CAACC,MAAM,CAAC,CAAA,CAAA,CAAGC,OAAO,CAAC,EAAC,CAAA;AAC9C,QAAA,MAAMC,QAAW,GAAA,IAAI,CAAClE,KAAK,EAAEmE,YAAiB,KAAA,UAAA;AAC9C,QAAA,MAAM0B,aAAgB,GAAA,IAAI,CAAC7F,KAAK,EAAE6F,aAAiB,IAAA,CAAA;AACnD,QAAA,MAAMjB,KACJ,GAAA,IAAI,CAACA,KAAK,IAAI,CACVV,GAAAA,QAAAA,GACEb,IAAK0C,CAAAA,IAAI,CAAC1C,IAAKC,CAAAA,GAAG,CAAC,CAAA,EAAG,IAAI,CAAC8B,iBAAiB,CAAI9F,GAAAA,yBAAAA,CAAAA,GAA6BuG,aAC7E,GAAA,EAAA,GAAKxC,IAAK0C,CAAAA,IAAI,CAAC1C,IAAKC,CAAAA,GAAG,CAAC,MAAA,EAAQ,IAAI,CAAC7D,SAAS,CAChD,CAAA,GAAA,IAAI,CAACmF,KAAK;AAChB,QAAA,MAAMoB,iBAAoB9B,GAAAA,QAAAA,GACtB,IAAI,CAACkB,iBAAiB,IAAIS,aAAAA,GAAgBA,aAAY,CAAA,GACtD,IAAI,CAACpG,SAAS;AAClB,QAAA,IAAI,CAACW,cAAc,GAAG,IAAIV,OAAQoE,CAAAA,CAAAA,CAAEnE,CAAC,EAAEmE,CAAElE,CAAAA,CAAC,EAAEkE,CAAAA,CAAEjE,CAAC,EAAE+E,KAAAA,CAAAA;QACjD,IAAI,CAACvE,gBAAgB,GAAG,IAAIX,OAAAA,CAC1B0C,EAAEzC,CAAC,EACHyC,CAAExC,CAAAA,CAAC,EACHwC,CAAAA,CAAEvC,CAAC,EACHqE,QAAAA,GAAWb,IAAKgD,CAAAA,GAAG,CAAC,IAAI,CAACM,cAAc,CAAA,GAAI,IAAI,CAACH,MAAM,CAAA;AAExD,QAAA,IAAI,CAAClG,iBAAiB,GAAGf,mBAAmB,IAAI,CAACC,KAAK,EAAEwG,iBAAAA,CAAAA;QACxD,MAAM,CAACqB,YAAYC,WAAY,CAAA,GAAGpD,WAAW,IAAI,CAACqD,mBAAmB,EAAK,GAAA;AAAC,YAAA,CAAA;AAAG,YAAA;AAAE,SAAA;QAChF,IAAI,CAAChH,YAAY,GAAG,IAAIb,OAAAA,CAAQ2H,YAAYC,WAAa,EAAA,CAAA,EAAG,IAAI,CAAC9G,SAAS,CAAA;AAC5E;AACF;AAEA;;;IAIO,MAAMgH,SAAkB/F,SAAAA,aAAAA,CAAAA;qBAE7B,MAAyB;qBAEzB,MAAyB;qBAEzB,OAA0B;kDAE1B,UAA6B;AAC7B;;;MAIA,WAAA,CAAYzB,KAAY,CAAE;AACxB,QAAA,KAAK,CAACA,KAAOyH,EAAAA,eAAAA,CAAAA;QACb,IAAI,CAACnD,MAAM,GAAG,EAAA;QACd,IAAI,CAACoD,MAAM,GAAG,CAAA;QACd,IAAI,CAACC,OAAO,GAAG,CAAA;QACf,IAAI,CAACC,UAAU,GAAG,GAAA;AAClB,QAAA,IAAI,CAACjD,wBAAwB,EAAA;AAC/B;kCAEA,IAAIC,KAAQ,GAAA;QACV,OAAO,IAAI,CAACN,MAAM;AACpB;IACA,IAAIM,KAAAA,CAAMnE,GAAW,EAAE;QACrB,IAAI,CAACoE,QAAQ,CAACpE,GAAAA,CAAAA;AAChB;AACA;;;;MAKAoE,QAAAA,CAASpE,GAAW,EAAE;QACpBA,GAAMA,GAAAA,GAAAA,GAAM,IAAI,CAAIA,GAAAA,GAAAA;AACpB,QAAA,IAAI,IAAI,CAAC6D,MAAM,KAAK7D,GAAK,EAAA;YACvB,IAAI,CAAC6D,MAAM,GAAG7D,GAAAA;AACd,YAAA,IAAI,CAACS,kBAAkB,EAAA;AACvB,YAAA,IAAI,CAACyD,wBAAwB,EAAA;AAC/B;AACA,QAAA,OAAO,IAAI;AACb;kCAEA,IAAIkD,KAAQ,GAAA;QACV,OAAO,IAAI,CAACH,MAAM;AACpB;IACA,IAAIG,KAAAA,CAAMpH,GAAW,EAAE;QACrB,IAAI,CAACqH,QAAQ,CAACrH,GAAAA,CAAAA;AAChB;AACA;;;;MAKAqH,QAAAA,CAASrH,GAAW,EAAE;QACpBA,GAAMA,GAAAA,GAAAA,GAAM,IAAI,CAAIA,GAAAA,GAAAA;AACpB,QAAA,IAAI,IAAI,CAACiH,MAAM,KAAKjH,GAAK,EAAA;YACvB,IAAI,CAACiH,MAAM,GAAGjH,GAAAA;AACd,YAAA,IAAI,CAACS,kBAAkB,EAAA;AACvB,YAAA,IAAI,CAACyD,wBAAwB,EAAA;AAC/B;AACA,QAAA,OAAO,IAAI;AACb;mCAEA,IAAIoD,MAAS,GAAA;QACX,OAAO,IAAI,CAACJ,OAAO;AACrB;IACA,IAAII,MAAAA,CAAOtH,GAAW,EAAE;QACtB,IAAI,CAACuH,SAAS,CAACvH,GAAAA,CAAAA;AACjB;8CAEA,IAAIwH,SAAY,GAAA;QACd,OAAO,IAAI,CAACL,UAAU;AACxB;IACA,IAAIK,SAAAA,CAAUxH,GAAW,EAAE;AACzB,QAAA,MAAMwH,SAAY5E,GAAAA,IAAAA,CAAKC,GAAG,CAAC,CAAG7C,EAAAA,GAAAA,CAAAA;AAC9B,QAAA,IAAIwH,SAAc,KAAA,IAAI,CAACL,UAAU,EAAE;YACjC,IAAI,CAACA,UAAU,GAAGK,SAAAA;AAClB,YAAA,IAAI,CAAC/G,kBAAkB,EAAA;AACzB;AACF;AACA;;;;;;;AAOC,MACD,IAAIgH,YAAe,GAAA;AACjB,QAAA,MAAMrC,aAAgB,GAAA,IAAI,CAAC7F,KAAK,EAAE6F,aAAiB,IAAA,CAAA;AACnD,QAAA,OAAO,IAAI,CAACoC,SAAS,GAAG5E,KAAKiC,EAAE,GAAG,IAAI,CAACuC,KAAK,GAAG,IAAI,CAACE,MAAM,GAAGlC,aAAgBA,GAAAA,aAAAA;AAC/E;IACA,IAAIqC,YAAAA,CAAazH,GAAW,EAAE;AAC5B,QAAA,MAAMoF,aAAgB,GAAA,IAAI,CAAC7F,KAAK,EAAE6F,aAAiB,IAAA,CAAA;QACnD,MAAMsC,IAAAA,GAAO,IAAI,CAACN,KAAK,GAAG,IAAI,CAACE,MAAM,GAAGlC,aAAgBA,GAAAA,aAAAA;AACxD,QAAA,IAAI,CAACoC,SAAS,GAAGE,IAAAA,GAAO,IAAI9E,IAAKC,CAAAA,GAAG,CAAC,CAAA,EAAG7C,QAAQ4C,IAAAA,CAAKiC,EAAE,GAAG6C,IAAG,CAAK,GAAA,CAAA;AACpE;AACA;;;;MAKAH,SAAAA,CAAUvH,GAAW,EAAE;QACrBA,GAAMA,GAAAA,GAAAA,GAAM,IAAI,CAAIA,GAAAA,GAAAA;AACpB,QAAA,IAAI,IAAI,CAACkH,OAAO,KAAKlH,GAAK,EAAA;YACxB,IAAI,CAACkH,OAAO,GAAGlH,GAAAA;AACf,YAAA,IAAI,CAACS,kBAAkB,EAAA;AACvB,YAAA,IAAI,CAACyD,wBAAwB,EAAA;AAC/B;AACA,QAAA,OAAO,IAAI;AACb;AACA;;;AAGC,MACDnD,WAAiC,GAAA;QAC/B,OAAO,IAAA;AACT;AACA;;uBAIAqC,qBAAwB,GAAA;AACtB,QAAA,MAAM2B,OAAO,IAAIC,WAAAA,EAAAA;QACjB,MAAM2B,CAAAA,GAAI,IAAI,CAAC9C,MAAM;QACrBkB,IAAKE,CAAAA,QAAQ,GAAG,IAAIC,OAAAA,CAAQ,CAACyB,CAAG,EAAA,CAACA,GAAG,CAACA,CAAAA,CAAAA;AACrC5B,QAAAA,IAAAA,CAAKI,QAAQ,GAAG,IAAID,OAAAA,CAAQyB,GAAGA,CAAGA,EAAAA,CAAAA,CAAAA;QAClC,OAAO5B,IAAAA;AACT;AACA,qBACA5E,eAAkB,GAAA;AAChB,QAAA,MAAMwH,MAAM,IAAI,CAACrE,WAAW,CAACC,MAAM,CAAC,CAAA,CAAA;AACpC,QAAA,MAAMqE,KAAQ,GAAA,IAAI,CAACtE,WAAW,CAC3BC,MAAM,CAAC,CACPsE,CAAAA,CAAAA,gBAAgB,GAChBrE,OAAO,CAAC,IAAI,CAACyD,MAAM,GAAG,GAAA,CAAA;AACzB,QAAA,MAAMa,KAAQ,GAAA,IAAI,CAACxE,WAAW,CAC3BC,MAAM,CAAC,CACPsE,CAAAA,CAAAA,gBAAgB,GAChBrE,OAAO,CAAC,IAAI,CAAC0D,OAAO,GAAG,GAAA,CAAA;AAC1B,QAAA,IAAI,CAACvH,cAAc,GAAG,IAAIV,OAAAA,CAAQ0I,IAAIzI,CAAC,EAAEyI,GAAIxI,CAAAA,CAAC,EAAEwI,GAAIvI,CAAAA,CAAC,EAAE,IAAI,CAAC+E,KAAK,CAAA;AACjE,QAAA,IAAI,CAACvE,gBAAgB,GAAG,IAAIX,OAAQ2I,CAAAA,KAAAA,CAAM1I,CAAC,EAAE0I,KAAMzI,CAAAA,CAAC,EAAEyI,KAAAA,CAAMxI,CAAC,EAAE,CAAA,CAAA;AAC/D,QAAA,MAAMqE,QAAW,GAAA,IAAI,CAAClE,KAAK,EAAEmE,YAAiB,KAAA,UAAA;AAC9C,QAAA,IAAI,CAAC7D,iBAAiB,GAAGf,kBAAAA,CAAmB,IAAI,CAACC,KAAK,EAAE0E,QAAAA,GAAW,IAAI,CAAC+D,SAAS,GAAG,IAAI,CAACxI,SAAS,CAAA;AAClG,QAAA,IAAI,CAACc,YAAY,GAAG,IAAIb,OAAAA,CAAQ6I,MAAM5I,CAAC,EAAE4I,KAAM3I,CAAAA,CAAC,EAAE2I,KAAM1I,CAAAA,CAAC,EAAE,IAAI,CAACW,SAAS,CAAA;AAC3E;AACF;;;;"}