@zephyr3d/scene 0.9.25 → 0.9.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
  2. package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
  3. package/dist/animation/joint_dynamics/controller.js +7 -5
  4. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  5. package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
  6. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  7. package/dist/animation/morphtrack.js +3 -4
  8. package/dist/animation/morphtrack.js.map +1 -1
  9. package/dist/animation/skeleton.js +58 -24
  10. package/dist/animation/skeleton.js.map +1 -1
  11. package/dist/animation/spring/multi_chain_spring_system.js +577 -179
  12. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  13. package/dist/animation/spring/spring_collider.js +4 -3
  14. package/dist/animation/spring/spring_collider.js.map +1 -1
  15. package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
  16. package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
  17. package/dist/animation/spring/spring_particle.js +2 -0
  18. package/dist/animation/spring/spring_particle.js.map +1 -1
  19. package/dist/animation/spring/spring_system.js +11 -3
  20. package/dist/animation/spring/spring_system.js.map +1 -1
  21. package/dist/animation/spring_modifier.js +10 -0
  22. package/dist/animation/spring_modifier.js.map +1 -1
  23. package/dist/app/engine.js +53 -43
  24. package/dist/app/engine.js.map +1 -1
  25. package/dist/app/scriptingsystem.js +119 -6
  26. package/dist/app/scriptingsystem.js.map +1 -1
  27. package/dist/app/scriptregistry.js +3 -2
  28. package/dist/app/scriptregistry.js.map +1 -1
  29. package/dist/asset/assetmanager.js +284 -67
  30. package/dist/asset/assetmanager.js.map +1 -1
  31. package/dist/asset/loaders/zhair/zhair_format.js +288 -0
  32. package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
  33. package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
  34. package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
  35. package/dist/asset/model.js +178 -67
  36. package/dist/asset/model.js.map +1 -1
  37. package/dist/camera/camera.js +193 -21
  38. package/dist/camera/camera.js.map +1 -1
  39. package/dist/camera/perspectivecamera.js +3 -1
  40. package/dist/camera/perspectivecamera.js.map +1 -1
  41. package/dist/index.d.ts +4019 -1278
  42. package/dist/index.js +15 -5
  43. package/dist/index.js.map +1 -1
  44. package/dist/material/eye.js +932 -0
  45. package/dist/material/eye.js.map +1 -0
  46. package/dist/material/hair.js +917 -0
  47. package/dist/material/hair.js.map +1 -0
  48. package/dist/material/hairstrand.js +842 -0
  49. package/dist/material/hairstrand.js.map +1 -0
  50. package/dist/material/hairstrand_data.js +162 -0
  51. package/dist/material/hairstrand_data.js.map +1 -0
  52. package/dist/material/lambert.js +5 -2
  53. package/dist/material/lambert.js.map +1 -1
  54. package/dist/material/material.js +338 -300
  55. package/dist/material/material.js.map +1 -1
  56. package/dist/material/meshmaterial.js +120 -19
  57. package/dist/material/meshmaterial.js.map +1 -1
  58. package/dist/material/mixins/albedocolor.js +1 -1
  59. package/dist/material/mixins/albedocolor.js.map +1 -1
  60. package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
  61. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  62. package/dist/material/mixins/lightmodel/lambert.js +5 -4
  63. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  64. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
  65. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  66. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
  67. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  68. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
  69. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  70. package/dist/material/mixins/lit.js +73 -18
  71. package/dist/material/mixins/lit.js.map +1 -1
  72. package/dist/material/mixins/pbr/common.js +4 -4
  73. package/dist/material/mixins/pbr/common.js.map +1 -1
  74. package/dist/material/mixins/texture.js +48 -11
  75. package/dist/material/mixins/texture.js.map +1 -1
  76. package/dist/material/mtoon.js +6 -5
  77. package/dist/material/mtoon.js.map +1 -1
  78. package/dist/material/pbrblueprint.js +146 -28
  79. package/dist/material/pbrblueprint.js.map +1 -1
  80. package/dist/material/pbrblueprint_instance.js +501 -0
  81. package/dist/material/pbrblueprint_instance.js.map +1 -0
  82. package/dist/material/pbrmr.js +15 -16
  83. package/dist/material/pbrmr.js.map +1 -1
  84. package/dist/material/shader/helper.js +330 -20
  85. package/dist/material/shader/helper.js.map +1 -1
  86. package/dist/material/shader/terrain_blend.js +55 -0
  87. package/dist/material/shader/terrain_blend.js.map +1 -0
  88. package/dist/material/skin.js +192 -32
  89. package/dist/material/skin.js.map +1 -1
  90. package/dist/material/spriteblueprint.js +16 -1
  91. package/dist/material/spriteblueprint.js.map +1 -1
  92. package/dist/material/subsurfaceprofile.js +86 -23
  93. package/dist/material/subsurfaceprofile.js.map +1 -1
  94. package/dist/material/water.js +3 -1
  95. package/dist/material/water.js.map +1 -1
  96. package/dist/posteffect/bloom.js +167 -7
  97. package/dist/posteffect/bloom.js.map +1 -1
  98. package/dist/posteffect/coloradjust.js +2 -1
  99. package/dist/posteffect/coloradjust.js.map +1 -1
  100. package/dist/posteffect/compositor.js.map +1 -1
  101. package/dist/posteffect/fxaa.js +2 -1
  102. package/dist/posteffect/fxaa.js.map +1 -1
  103. package/dist/posteffect/grayscale.js +3 -1
  104. package/dist/posteffect/grayscale.js.map +1 -1
  105. package/dist/posteffect/motionblur.js +4 -1
  106. package/dist/posteffect/motionblur.js.map +1 -1
  107. package/dist/posteffect/posteffect.js.map +1 -1
  108. package/dist/posteffect/skinsss.js +368 -69
  109. package/dist/posteffect/skinsss.js.map +1 -1
  110. package/dist/posteffect/ssgi.js +16 -9
  111. package/dist/posteffect/ssgi.js.map +1 -1
  112. package/dist/posteffect/ssr.js +3 -0
  113. package/dist/posteffect/ssr.js.map +1 -1
  114. package/dist/posteffect/sss.js +91 -34
  115. package/dist/posteffect/sss.js.map +1 -1
  116. package/dist/posteffect/taa.js.map +1 -1
  117. package/dist/posteffect/tonemap.js +44 -1
  118. package/dist/posteffect/tonemap.js.map +1 -1
  119. package/dist/render/abuffer_oit.js +45 -39
  120. package/dist/render/abuffer_oit.js.map +1 -1
  121. package/dist/render/cull_visitor.js +19 -0
  122. package/dist/render/cull_visitor.js.map +1 -1
  123. package/dist/render/depthpass.js +36 -2
  124. package/dist/render/depthpass.js.map +1 -1
  125. package/dist/render/drawable_mixin.js +26 -1
  126. package/dist/render/drawable_mixin.js.map +1 -1
  127. package/dist/render/dualdepthpeeling_oit.js +52 -51
  128. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  129. package/dist/render/envlight.js +1 -1
  130. package/dist/render/envlight.js.map +1 -1
  131. package/dist/render/fbm_wavegenerator.js +3 -0
  132. package/dist/render/fbm_wavegenerator.js.map +1 -1
  133. package/dist/render/gerstner_wavegenerator.js +3 -0
  134. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  135. package/dist/render/globalbindgroup_allocator.js +3 -0
  136. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  137. package/dist/render/oit.js +29 -0
  138. package/dist/render/oit.js.map +1 -0
  139. package/dist/render/render_queue.js +3 -0
  140. package/dist/render/render_queue.js.map +1 -1
  141. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  142. package/dist/render/rendergraph/executor.js +2 -0
  143. package/dist/render/rendergraph/executor.js.map +1 -1
  144. package/dist/render/rendergraph/forward_plus_builder.js +61 -1
  145. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  146. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  147. package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
  148. package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
  149. package/dist/render/rendergraph/types.js.map +1 -1
  150. package/dist/render/shadow_mask_pass.js +73 -8
  151. package/dist/render/shadow_mask_pass.js.map +1 -1
  152. package/dist/render/sky.js +166 -126
  153. package/dist/render/sky.js.map +1 -1
  154. package/dist/render/weightedblended_oit.js +36 -35
  155. package/dist/render/weightedblended_oit.js.map +1 -1
  156. package/dist/scene/basesprite.js +8 -0
  157. package/dist/scene/basesprite.js.map +1 -1
  158. package/dist/scene/batchgroup.js +3 -0
  159. package/dist/scene/batchgroup.js.map +1 -1
  160. package/dist/scene/environment.js +4 -1
  161. package/dist/scene/environment.js.map +1 -1
  162. package/dist/scene/hair.js +963 -0
  163. package/dist/scene/hair.js.map +1 -0
  164. package/dist/scene/light.js +5 -1
  165. package/dist/scene/light.js.map +1 -1
  166. package/dist/scene/mesh.js +481 -47
  167. package/dist/scene/mesh.js.map +1 -1
  168. package/dist/scene/meshdrawable.js +6 -0
  169. package/dist/scene/meshdrawable.js.map +1 -1
  170. package/dist/scene/msdftext.js +3 -0
  171. package/dist/scene/msdftext.js.map +1 -1
  172. package/dist/scene/msdftextsprite.js +3 -0
  173. package/dist/scene/msdftextsprite.js.map +1 -1
  174. package/dist/scene/particlesys.js +6 -0
  175. package/dist/scene/particlesys.js.map +1 -1
  176. package/dist/scene/scene.js +3 -0
  177. package/dist/scene/scene.js.map +1 -1
  178. package/dist/scene/scene_node.js +6 -1
  179. package/dist/scene/scene_node.js.map +1 -1
  180. package/dist/scene/terrain-cm/grass.js +3 -0
  181. package/dist/scene/terrain-cm/grass.js.map +1 -1
  182. package/dist/scene/terrain-cm/grassmaterial.js +3 -0
  183. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  184. package/dist/scene/terrain-cm/terrain-cm.js +6 -0
  185. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  186. package/dist/scene/terrain-cm/texture_cache.js +309 -0
  187. package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
  188. package/dist/scene/water.js +6 -0
  189. package/dist/scene/water.js.map +1 -1
  190. package/dist/shaders/atmosphere.js.map +1 -1
  191. package/dist/shaders/diffusion.js +54 -0
  192. package/dist/shaders/diffusion.js.map +1 -0
  193. package/dist/shaders/shadow.js +33 -21
  194. package/dist/shaders/shadow.js.map +1 -1
  195. package/dist/shaders/temporal.js +71 -33
  196. package/dist/shaders/temporal.js.map +1 -1
  197. package/dist/shadow/dom.js +546 -0
  198. package/dist/shadow/dom.js.map +1 -0
  199. package/dist/shadow/pcf_opt.js +3 -5
  200. package/dist/shadow/pcf_opt.js.map +1 -1
  201. package/dist/shadow/pcf_pd.js +1 -1
  202. package/dist/shadow/pcf_pd.js.map +1 -1
  203. package/dist/shadow/receiver_bias.js +41 -0
  204. package/dist/shadow/receiver_bias.js.map +1 -0
  205. package/dist/shadow/shader.js +20 -60
  206. package/dist/shadow/shader.js.map +1 -1
  207. package/dist/shadow/shadow_impl.js +89 -0
  208. package/dist/shadow/shadow_impl.js.map +1 -1
  209. package/dist/shadow/shadow_region.js +50 -50
  210. package/dist/shadow/shadow_region.js.map +1 -1
  211. package/dist/shadow/shadowmapper.js +150 -37
  212. package/dist/shadow/shadowmapper.js.map +1 -1
  213. package/dist/shapes/shape.js +11 -2
  214. package/dist/shapes/shape.js.map +1 -1
  215. package/dist/shapes/sphere.js +50 -9
  216. package/dist/shapes/sphere.js.map +1 -1
  217. package/dist/utility/blueprint/common/constants.js +112 -2
  218. package/dist/utility/blueprint/common/constants.js.map +1 -1
  219. package/dist/utility/blueprint/material/func.js +142 -49
  220. package/dist/utility/blueprint/material/func.js.map +1 -1
  221. package/dist/utility/blueprint/material/ir.js +490 -25
  222. package/dist/utility/blueprint/material/ir.js.map +1 -1
  223. package/dist/utility/blueprint/material/texture.js +898 -4
  224. package/dist/utility/blueprint/material/texture.js.map +1 -1
  225. package/dist/utility/serialization/manager.js +431 -100
  226. package/dist/utility/serialization/manager.js.map +1 -1
  227. package/dist/utility/serialization/scene/animation.js +370 -3
  228. package/dist/utility/serialization/scene/animation.js.map +1 -1
  229. package/dist/utility/serialization/scene/batch.js +4 -0
  230. package/dist/utility/serialization/scene/batch.js.map +1 -1
  231. package/dist/utility/serialization/scene/camera.js +133 -1
  232. package/dist/utility/serialization/scene/camera.js.map +1 -1
  233. package/dist/utility/serialization/scene/common.js +26 -5
  234. package/dist/utility/serialization/scene/common.js.map +1 -1
  235. package/dist/utility/serialization/scene/hair.js +1141 -0
  236. package/dist/utility/serialization/scene/hair.js.map +1 -0
  237. package/dist/utility/serialization/scene/light.js +84 -4
  238. package/dist/utility/serialization/scene/light.js.map +1 -1
  239. package/dist/utility/serialization/scene/material.js +1867 -166
  240. package/dist/utility/serialization/scene/material.js.map +1 -1
  241. package/dist/utility/serialization/scene/mesh.js +231 -14
  242. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  243. package/dist/utility/serialization/scene/node.js +141 -7
  244. package/dist/utility/serialization/scene/node.js.map +1 -1
  245. package/dist/utility/serialization/scene/particle.js +4 -0
  246. package/dist/utility/serialization/scene/particle.js.map +1 -1
  247. package/dist/utility/serialization/scene/primitive.js +18 -0
  248. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  249. package/dist/utility/serialization/scene/sprite.js +4 -0
  250. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  251. package/dist/utility/serialization/scene/terrain.js +4 -0
  252. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  253. package/dist/utility/serialization/scene/text.js +4 -0
  254. package/dist/utility/serialization/scene/text.js.map +1 -1
  255. package/dist/utility/serialization/scene/water.js +4 -0
  256. package/dist/utility/serialization/scene/water.js.map +1 -1
  257. package/dist/utility/serialization/types.js.map +1 -1
  258. package/dist/utility/shprojector.js +96 -95
  259. package/dist/utility/shprojector.js.map +1 -1
  260. package/dist/values.js +49 -2
  261. package/dist/values.js.map +1 -1
  262. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"multi_chain_spring_system.js","sources":["../../../src/animation/spring/multi_chain_spring_system.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { Vector3, Quaternion } from '@zephyr3d/base';\r\nimport type { SpringChain } from './spring_chain';\r\nimport type { SpringConstraint } from './spring_constraint';\r\nimport { IKUtils } from '../ik/ik_utils';\r\n\r\n/**\r\n * Constraint between particles in different chains\r\n *\r\n * @public\r\n */\r\nexport interface InterChainConstraint {\r\n /** Index of the first chain */\r\n chainAIndex: number;\r\n /** Index of the second chain */\r\n chainBIndex: number;\r\n /** Index of particle in chain A */\r\n particleAIndex: number;\r\n /** Index of particle in chain B */\r\n particleBIndex: number;\r\n /** Desired distance between particles */\r\n restLength: number;\r\n /** Constraint strength [0-1], used by Verlet solver */\r\n stiffness: number;\r\n /**\r\n * XPBD compliance (inverse stiffness) in m/N.\r\n * Only used when solver is 'xpbd'.\r\n */\r\n compliance: number;\r\n /** XPBD Lagrange multiplier accumulator, reset each time step. */\r\n lambda: number;\r\n}\r\n\r\n/**\r\n * Options for creating a MultiChainSpringSystem\r\n *\r\n * @public\r\n */\r\nexport interface MultiChainSpringSystemOptions {\r\n /** Number of constraint solver iterations (default: 5) */\r\n iterations?: number;\r\n /** Gravity force vector (default: (0, -9.8, 0)) */\r\n gravity?: Vector3;\r\n /** Wind force vector (default: (0, 0, 0)) */\r\n wind?: Vector3;\r\n /** Enable inertial forces (centrifugal/Coriolis) when root rotates (default: true) */\r\n enableInertialForces?: boolean;\r\n /** Centrifugal force multiplier (default: 1.0) */\r\n centrifugalScale?: number;\r\n /** Coriolis force multiplier (default: 1.0) */\r\n coriolisScale?: number;\r\n /**\r\n * Constraint solver type (default: 'verlet').\r\n * - 'verlet': stiffness [0-1] controls per-iteration correction strength.\r\n * - 'xpbd': compliance (m/N) gives physically correct, iteration-independent results.\r\n */\r\n solver?: 'verlet' | 'xpbd';\r\n}\r\n\r\n/**\r\n * Physics engine for multiple spring chains with inter-chain constraints\r\n * Suitable for cloth, skirts, capes, and other multi-chain simulations\r\n *\r\n * @deprecated Use the new {@link JointDynamicsSystem} class instead.\r\n *\r\n * @public\r\n */\r\nexport class MultiChainSpringSystem {\r\n private _chains: SpringChain[];\r\n private _interChainConstraints: InterChainConstraint[];\r\n private _iterations: number;\r\n private _gravity: Vector3;\r\n private _wind: Vector3;\r\n private _enableInertialForces: boolean;\r\n private _centrifugalScale: number;\r\n private _coriolisScale: number;\r\n private _solver: 'verlet' | 'xpbd';\r\n\r\n constructor(options?: MultiChainSpringSystemOptions) {\r\n this._chains = [];\r\n this._interChainConstraints = [];\r\n this._iterations = options?.iterations ?? 5;\r\n this._gravity = options?.gravity?.clone() ?? new Vector3(0, -9.8, 0);\r\n this._wind = options?.wind?.clone() ?? new Vector3(0, 0, 0);\r\n this._enableInertialForces = options?.enableInertialForces ?? true;\r\n this._centrifugalScale = options?.centrifugalScale ?? 1.0;\r\n this._coriolisScale = options?.coriolisScale ?? 1.0;\r\n this._solver = options?.solver ?? 'verlet';\r\n }\r\n\r\n /**\r\n * Adds a spring chain to the system\r\n * @param chain - The chain to add\r\n * @returns The index of the added chain\r\n */\r\n addChain(chain: SpringChain): number {\r\n this._chains.push(chain);\r\n return this._chains.length - 1;\r\n }\r\n\r\n /**\r\n * Adds an inter-chain constraint\r\n * @param constraint - The constraint to add\r\n */\r\n addInterChainConstraint(constraint: InterChainConstraint): void {\r\n this._interChainConstraints.push(constraint);\r\n }\r\n\r\n /**\r\n * Creates radial constraints between adjacent chains\r\n * Useful for skirts, capes, and other radial multi-chain structures\r\n * @param options - Configuration options\r\n */\r\n createRadialConstraints(options: {\r\n /** Constraint stiffness [0-1], used by Verlet solver */\r\n stiffness: number;\r\n /** Maximum distance to create constraints (particles further apart are not connected) */\r\n maxDistance: number;\r\n /** Skip first N rows of particles (e.g., anchor points at waist) */\r\n skipRows?: number;\r\n /** Connect to next N chains (default: 1, only adjacent chains) */\r\n connectDistance?: number;\r\n /** XPBD compliance in m/N (default: 0 = rigid). Only used when solver is 'xpbd'. */\r\n compliance?: number;\r\n }): void {\r\n const skipRows = options.skipRows ?? 0;\r\n const connectDistance = options.connectDistance ?? 1;\r\n const compliance = options.compliance ?? 0;\r\n\r\n for (let i = 0; i < this._chains.length; i++) {\r\n for (let offset = 1; offset <= connectDistance; offset++) {\r\n const j = (i + offset) % this._chains.length;\r\n const chainA = this._chains[i];\r\n const chainB = this._chains[j];\r\n\r\n const minLength = Math.min(chainA.particles.length, chainB.particles.length);\r\n\r\n for (let row = skipRows; row < minLength; row++) {\r\n const pA = chainA.particles[row];\r\n const pB = chainB.particles[row];\r\n const distance = Vector3.distance(pA.position, pB.position);\r\n\r\n if (distance <= options.maxDistance) {\r\n this.addInterChainConstraint({\r\n chainAIndex: i,\r\n chainBIndex: j,\r\n particleAIndex: row,\r\n particleBIndex: row,\r\n restLength: distance,\r\n stiffness: options.stiffness,\r\n compliance,\r\n lambda: 0\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates the physics simulation for all chains\r\n * @param deltaTime - Time step in seconds\r\n */\r\n update(deltaTime: number): void {\r\n const dt = Math.min(deltaTime, 0.033);\r\n\r\n // Save all particle positions before updating\r\n if (this._enableInertialForces) {\r\n for (const chain of this._chains) {\r\n for (const p of chain.particles) {\r\n p.lastFramePosition.set(p.position);\r\n }\r\n }\r\n }\r\n\r\n this.updateFixedParticles();\r\n\r\n // Calculate global rotation parameters\r\n let rotationCenter: Nullable<Vector3> = null;\r\n let angularVelocity: Nullable<Vector3> = null;\r\n\r\n if (this._enableInertialForces && dt > 0.0001) {\r\n const result = this.calculateGlobalRotation(dt);\r\n rotationCenter = result.center;\r\n angularVelocity = result.omega;\r\n }\r\n\r\n for (const chain of this._chains) {\r\n for (const particle of chain.particles) {\r\n if (particle.fixed) {\r\n continue;\r\n }\r\n\r\n const velocity = Vector3.sub(particle.position, particle.prevPosition, new Vector3());\r\n velocity.scaleBy(particle.damping);\r\n\r\n const acceleration = Vector3.add(this._gravity, this._wind, new Vector3());\r\n\r\n // Apply inertial forces\r\n if (this._enableInertialForces && rotationCenter && angularVelocity) {\r\n const inertialAccel = this.calculateInertialAcceleration(\r\n particle,\r\n rotationCenter,\r\n angularVelocity,\r\n velocity,\r\n this._centrifugalScale,\r\n this._coriolisScale\r\n );\r\n Vector3.add(acceleration, inertialAccel, acceleration);\r\n }\r\n\r\n const positionDelta = Vector3.scale(acceleration, dt * dt, new Vector3());\r\n Vector3.add(velocity, positionDelta, velocity);\r\n\r\n particle.prevPosition.set(particle.position);\r\n Vector3.add(particle.position, velocity, particle.position);\r\n }\r\n }\r\n\r\n if (this._solver === 'xpbd') {\r\n for (const chain of this._chains) {\r\n for (const c of chain.constraints) {\r\n c.lambda = 0;\r\n }\r\n }\r\n for (const c of this._interChainConstraints) {\r\n c.lambda = 0;\r\n }\r\n }\r\n for (let iter = 0; iter < this._iterations; iter++) {\r\n for (const chain of this._chains) {\r\n for (const constraint of chain.constraints) {\r\n if (this._solver === 'xpbd') {\r\n this.solveConstraintXPBD(chain, constraint, dt);\r\n } else {\r\n this.solveConstraint(chain, constraint);\r\n }\r\n }\r\n }\r\n\r\n for (const constraint of this._interChainConstraints) {\r\n if (this._solver === 'xpbd') {\r\n this.solveInterChainConstraintXPBD(constraint, dt);\r\n } else {\r\n this.solveInterChainConstraint(constraint);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private updateFixedParticles(): void {\r\n for (const chain of this._chains) {\r\n for (const particle of chain.particles) {\r\n if (particle.fixed && particle.node) {\r\n const worldPos = new Vector3(\r\n particle.node.worldMatrix.m03,\r\n particle.node.worldMatrix.m13,\r\n particle.node.worldMatrix.m23\r\n );\r\n particle.position.set(worldPos);\r\n particle.prevPosition.set(worldPos);\r\n\r\n // Maintain position history\r\n if (this._enableInertialForces) {\r\n if (!particle.positionHistory) {\r\n particle.positionHistory = [];\r\n }\r\n particle.positionHistory.push(worldPos.clone());\r\n if (particle.positionHistory.length > 5) {\r\n particle.positionHistory.shift();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private calculateGlobalRotation(dt: number): { center: Vector3; omega: Vector3 } {\r\n const fixedParticles: any[] = [];\r\n const velocities: Vector3[] = [];\r\n\r\n for (const chain of this._chains) {\r\n for (const p of chain.particles) {\r\n if (!p.fixed) {\r\n continue;\r\n }\r\n\r\n const velocity = Vector3.sub(p.position, p.lastFramePosition, new Vector3());\r\n velocity.scaleBy(1.0 / dt);\r\n\r\n if (velocity.magnitudeSq > 0.001) {\r\n fixedParticles.push(p);\r\n velocities.push(velocity);\r\n }\r\n }\r\n }\r\n\r\n if (fixedParticles.length === 0) {\r\n return { center: new Vector3(0, 0, 0), omega: new Vector3(0, 0, 0) };\r\n }\r\n\r\n // Estimate rotation center\r\n let center: Vector3;\r\n\r\n if (fixedParticles.length === 1) {\r\n center = this.estimateRotationCenterFromHistory(fixedParticles[0], velocities[0]);\r\n } else {\r\n center = new Vector3(0, 0, 0);\r\n for (const p of fixedParticles) {\r\n Vector3.add(center, p.position, center);\r\n }\r\n center.scaleBy(1.0 / fixedParticles.length);\r\n }\r\n\r\n // Estimate angular velocity\r\n let sumOmega = new Vector3(0, 0, 0);\r\n let count = 0;\r\n\r\n for (let i = 0; i < fixedParticles.length; i++) {\r\n const r = Vector3.sub(fixedParticles[i].position, center, new Vector3());\r\n const v = velocities[i];\r\n const rLengthSq = r.magnitudeSq;\r\n\r\n if (rLengthSq > 0.0001) {\r\n const omega = Vector3.cross(r, v, new Vector3());\r\n omega.scaleBy(1.0 / rLengthSq);\r\n Vector3.add(sumOmega, omega, sumOmega);\r\n count++;\r\n }\r\n }\r\n\r\n if (count > 0) {\r\n sumOmega.scaleBy(1.0 / count);\r\n }\r\n\r\n return { center, omega: sumOmega };\r\n }\r\n\r\n private estimateRotationCenterFromHistory(particle: any, currentVelocity: Vector3): Vector3 {\r\n const history = particle.positionHistory;\r\n if (!history || history.length < 3) {\r\n const speed = currentVelocity.magnitude;\r\n if (speed < 0.001) {\r\n return particle.position.clone();\r\n }\r\n\r\n const estimatedRadius = Math.max(0.5, speed * 0.5);\r\n const up = new Vector3(0, 1, 0);\r\n const perpDir = Vector3.cross(currentVelocity, up, new Vector3());\r\n\r\n if (perpDir.magnitudeSq < 0.0001) {\r\n perpDir.set(new Vector3(1, 0, 0));\r\n } else {\r\n Vector3.normalize(perpDir, perpDir);\r\n }\r\n\r\n const center = Vector3.add(\r\n particle.position,\r\n Vector3.scale(perpDir, estimatedRadius, new Vector3()),\r\n new Vector3()\r\n );\r\n return center;\r\n }\r\n\r\n const p1 = history[0];\r\n const p2 = history[Math.floor(history.length / 2)];\r\n const p3 = history[history.length - 1];\r\n\r\n const center = this.calculateCircleCenter(p1, p2, p3);\r\n return center;\r\n }\r\n\r\n private calculateCircleCenter(p1: Vector3, p2: Vector3, p3: Vector3): Vector3 {\r\n const mid12 = Vector3.scale(Vector3.add(p1, p2, new Vector3()), 0.5, new Vector3());\r\n const mid23 = Vector3.scale(Vector3.add(p2, p3, new Vector3()), 0.5, new Vector3());\r\n\r\n const dir12 = Vector3.sub(p2, p1, new Vector3());\r\n const dir23 = Vector3.sub(p3, p2, new Vector3());\r\n\r\n const normal = Vector3.cross(dir12, dir23, new Vector3());\r\n\r\n if (normal.magnitudeSq < 0.0001) {\r\n return Vector3.scale(\r\n Vector3.add(Vector3.add(p1, p2, new Vector3()), p3, new Vector3()),\r\n 1.0 / 3.0,\r\n new Vector3()\r\n );\r\n }\r\n\r\n Vector3.normalize(normal, normal);\r\n\r\n const perp12 = Vector3.cross(dir12, normal, new Vector3());\r\n Vector3.normalize(perp12, perp12);\r\n\r\n const perp23 = Vector3.cross(dir23, normal, new Vector3());\r\n Vector3.normalize(perp23, perp23);\r\n\r\n const diff = Vector3.sub(mid23, mid12, new Vector3());\r\n\r\n const det = perp12.x * perp23.y - perp12.y * perp23.x;\r\n\r\n if (Math.abs(det) > 0.0001) {\r\n const t = (diff.x * perp23.y - diff.y * perp23.x) / det;\r\n const center = Vector3.add(mid12, Vector3.scale(perp12, t, new Vector3()), new Vector3());\r\n return center;\r\n }\r\n\r\n return Vector3.scale(\r\n Vector3.add(Vector3.add(p1, p2, new Vector3()), p3, new Vector3()),\r\n 1.0 / 3.0,\r\n new Vector3()\r\n );\r\n }\r\n\r\n private calculateInertialAcceleration(\r\n particle: any,\r\n rotationCenter: Vector3,\r\n angularVelocity: Vector3,\r\n particleVelocity: Vector3,\r\n centrifugalScale: number,\r\n coriolisScale: number\r\n ): Vector3 {\r\n const r = Vector3.sub(particle.position, rotationCenter, new Vector3());\r\n\r\n const omegaCrossR = Vector3.cross(angularVelocity, r, new Vector3());\r\n const centrifugalAccel = Vector3.cross(angularVelocity, omegaCrossR, new Vector3());\r\n centrifugalAccel.scaleBy(centrifugalScale);\r\n\r\n const coriolisAccel = Vector3.cross(angularVelocity, particleVelocity, new Vector3());\r\n coriolisAccel.scaleBy(-2.0 * coriolisScale);\r\n\r\n const totalAccel = Vector3.add(centrifugalAccel, coriolisAccel, new Vector3());\r\n return totalAccel;\r\n }\r\n\r\n private solveConstraint(chain: SpringChain, constraint: SpringConstraint): void {\r\n const pA = chain.particles[constraint.particleA];\r\n const pB = chain.particles[constraint.particleB];\r\n\r\n const delta = Vector3.sub(pB.position, pA.position, new Vector3());\r\n const currentLength = delta.magnitude;\r\n\r\n if (currentLength < 0.0001) {\r\n return;\r\n }\r\n\r\n const diff = (currentLength - constraint.restLength) / currentLength;\r\n const correction = Vector3.scale(delta, diff * constraint.stiffness * 0.5, new Vector3());\r\n\r\n if (!pA.fixed) {\r\n Vector3.add(pA.position, correction, pA.position);\r\n }\r\n if (!pB.fixed) {\r\n Vector3.sub(pB.position, correction, pB.position);\r\n }\r\n }\r\n\r\n private solveInterChainConstraint(constraint: InterChainConstraint): void {\r\n const chainA = this._chains[constraint.chainAIndex];\r\n const chainB = this._chains[constraint.chainBIndex];\r\n const pA = chainA.particles[constraint.particleAIndex];\r\n const pB = chainB.particles[constraint.particleBIndex];\r\n\r\n const delta = Vector3.sub(pB.position, pA.position, new Vector3());\r\n const currentLength = delta.magnitude;\r\n\r\n if (currentLength < 0.0001) {\r\n return;\r\n }\r\n\r\n const diff = (currentLength - constraint.restLength) / currentLength;\r\n const correction = Vector3.scale(delta, diff * constraint.stiffness * 0.5, new Vector3());\r\n\r\n if (!pA.fixed) {\r\n Vector3.add(pA.position, correction, pA.position);\r\n }\r\n if (!pB.fixed) {\r\n Vector3.sub(pB.position, correction, pB.position);\r\n }\r\n }\r\n\r\n private solveConstraintXPBD(chain: SpringChain, constraint: SpringConstraint, dt: number): void {\r\n const pA = chain.particles[constraint.particleA];\r\n const pB = chain.particles[constraint.particleB];\r\n\r\n const wA = pA.fixed ? 0 : 1.0 / pA.mass;\r\n const wB = pB.fixed ? 0 : 1.0 / pB.mass;\r\n const wSum = wA + wB;\r\n if (wSum < 1e-10) {\r\n return;\r\n }\r\n\r\n const delta = Vector3.sub(pB.position, pA.position, new Vector3());\r\n const currentLength = delta.magnitude;\r\n if (currentLength < 0.0001) {\r\n return;\r\n }\r\n\r\n const C = currentLength - constraint.restLength;\r\n const alphaTilde = constraint.compliance / (dt * dt);\r\n const deltaLambda = (-C - alphaTilde * constraint.lambda) / (wSum + alphaTilde);\r\n constraint.lambda += deltaLambda;\r\n\r\n const n = Vector3.scale(delta, 1.0 / currentLength, new Vector3());\r\n if (!pA.fixed) {\r\n Vector3.add(pA.position, Vector3.scale(n, -wA * deltaLambda, new Vector3()), pA.position);\r\n }\r\n if (!pB.fixed) {\r\n Vector3.add(pB.position, Vector3.scale(n, wB * deltaLambda, new Vector3()), pB.position);\r\n }\r\n }\r\n\r\n private solveInterChainConstraintXPBD(constraint: InterChainConstraint, dt: number): void {\r\n const chainA = this._chains[constraint.chainAIndex];\r\n const chainB = this._chains[constraint.chainBIndex];\r\n const pA = chainA.particles[constraint.particleAIndex];\r\n const pB = chainB.particles[constraint.particleBIndex];\r\n\r\n const wA = pA.fixed ? 0 : 1.0 / pA.mass;\r\n const wB = pB.fixed ? 0 : 1.0 / pB.mass;\r\n const wSum = wA + wB;\r\n if (wSum < 1e-10) {\r\n return;\r\n }\r\n\r\n const delta = Vector3.sub(pB.position, pA.position, new Vector3());\r\n const currentLength = delta.magnitude;\r\n if (currentLength < 0.0001) {\r\n return;\r\n }\r\n\r\n const C = currentLength - constraint.restLength;\r\n const alphaTilde = constraint.compliance / (dt * dt);\r\n const deltaLambda = (-C - alphaTilde * constraint.lambda) / (wSum + alphaTilde);\r\n constraint.lambda += deltaLambda;\r\n\r\n const n = Vector3.scale(delta, 1.0 / currentLength, new Vector3());\r\n if (!pA.fixed) {\r\n Vector3.add(pA.position, Vector3.scale(n, -wA * deltaLambda, new Vector3()), pA.position);\r\n }\r\n if (!pB.fixed) {\r\n Vector3.add(pB.position, Vector3.scale(n, wB * deltaLambda, new Vector3()), pB.position);\r\n }\r\n }\r\n\r\n /**\r\n * Applies simulation results to scene nodes\r\n * @param weight - Blend weight [0-1] (default: 1.0)\r\n */\r\n applyToNodes(weight: number = 1.0): void {\r\n for (const chain of this._chains) {\r\n this.applyChainToNodes(chain, weight);\r\n }\r\n }\r\n\r\n private applyChainToNodes(chain: SpringChain, weight: number): void {\r\n for (let i = 0; i < chain.particles.length - 1; i++) {\r\n const particle = chain.particles[i];\r\n const nextParticle = chain.particles[i + 1];\r\n\r\n if (!particle.node) {\r\n continue;\r\n }\r\n\r\n // Get current bone direction from node's world matrix (before physics)\r\n const currentBonePos = new Vector3(\r\n particle.node.worldMatrix.m03,\r\n particle.node.worldMatrix.m13,\r\n particle.node.worldMatrix.m23\r\n );\r\n\r\n const nextNode = nextParticle.node;\r\n if (!nextNode) {\r\n continue;\r\n }\r\n\r\n const nextBonePos = new Vector3(\r\n nextNode.worldMatrix.m03,\r\n nextNode.worldMatrix.m13,\r\n nextNode.worldMatrix.m23\r\n );\r\n const originalDir = Vector3.sub(nextBonePos, currentBonePos, new Vector3());\r\n\r\n // Get current bone rotation from node's world matrix\r\n const currentBoneRotation = new Quaternion();\r\n particle.node.worldMatrix.decompose(null, currentBoneRotation, null);\r\n\r\n // Calculate new direction from physics simulation\r\n const newDir = Vector3.sub(nextParticle.position, particle.position, new Vector3());\r\n\r\n const deltaRotation = new Quaternion();\r\n IKUtils.fromToRotation(originalDir, newDir, deltaRotation);\r\n\r\n let worldRotation = Quaternion.multiply(deltaRotation, currentBoneRotation, new Quaternion());\r\n\r\n if (weight < 1) {\r\n Quaternion.slerp(currentBoneRotation, worldRotation, weight, worldRotation);\r\n }\r\n\r\n const parent = particle.node.parent;\r\n if (parent) {\r\n const parentWorldRotation = new Quaternion();\r\n parent.worldMatrix.decompose(null, parentWorldRotation, null);\r\n const parentInvRotation = Quaternion.conjugate(parentWorldRotation, new Quaternion());\r\n const localRotation = Quaternion.multiply(parentInvRotation, worldRotation, new Quaternion());\r\n particle.node.rotation = localRotation;\r\n } else {\r\n particle.node.rotation = worldRotation;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Resets the simulation to initial state\r\n */\r\n reset(): void {\r\n for (const chain of this._chains) {\r\n chain.reset();\r\n }\r\n }\r\n\r\n /**\r\n * Gets the spring chains\r\n */\r\n get chains(): SpringChain[] {\r\n return this._chains;\r\n }\r\n\r\n /**\r\n * Gets the inter-chain constraints\r\n */\r\n get interChainConstraints(): InterChainConstraint[] {\r\n return this._interChainConstraints;\r\n }\r\n\r\n /**\r\n * Gets the current gravity\r\n */\r\n get gravity(): Vector3 {\r\n return this._gravity;\r\n }\r\n\r\n set gravity(gravity: Vector3) {\r\n this._gravity.set(gravity);\r\n }\r\n\r\n /**\r\n * Gets the current wind\r\n */\r\n get wind(): Vector3 {\r\n return this._wind;\r\n }\r\n\r\n set wind(wind: Vector3) {\r\n this._wind.set(wind);\r\n }\r\n\r\n /**\r\n * Gets the number of iterations\r\n */\r\n get iterations(): number {\r\n return this._iterations;\r\n }\r\n\r\n set iterations(count: number) {\r\n this._iterations = Math.max(1, count);\r\n }\r\n\r\n /**\r\n * Gets whether inertial forces are enabled\r\n */\r\n get enableInertialForces(): boolean {\r\n return this._enableInertialForces;\r\n }\r\n\r\n set enableInertialForces(enabled: boolean) {\r\n this._enableInertialForces = enabled;\r\n }\r\n\r\n /**\r\n * Gets the centrifugal force scale\r\n */\r\n get centrifugalScale(): number {\r\n return this._centrifugalScale;\r\n }\r\n\r\n set centrifugalScale(scale: number) {\r\n this._centrifugalScale = Math.max(0, scale);\r\n }\r\n\r\n /**\r\n * Gets the Coriolis force scale\r\n */\r\n get coriolisScale(): number {\r\n return this._coriolisScale;\r\n }\r\n\r\n set coriolisScale(scale: number) {\r\n this._coriolisScale = Math.max(0, scale);\r\n }\r\n\r\n get solver(): 'verlet' | 'xpbd' {\r\n return this._solver;\r\n }\r\n\r\n set solver(type: 'verlet' | 'xpbd') {\r\n if (this._solver !== type) {\r\n this._solver = type;\r\n if (type === 'xpbd') {\r\n for (const chain of this._chains) {\r\n for (const c of chain.constraints) {\r\n c.lambda = 0;\r\n }\r\n }\r\n for (const c of this._interChainConstraints) {\r\n c.lambda = 0;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n"],"names":["MultiChainSpringSystem","_chains","_interChainConstraints","_iterations","_gravity","_wind","_enableInertialForces","_centrifugalScale","_coriolisScale","_solver","options","iterations","gravity","clone","Vector3","wind","enableInertialForces","centrifugalScale","coriolisScale","solver","addChain","chain","push","length","addInterChainConstraint","constraint","createRadialConstraints","skipRows","connectDistance","compliance","i","offset","j","chainA","chainB","minLength","Math","min","particles","row","pA","pB","distance","position","maxDistance","chainAIndex","chainBIndex","particleAIndex","particleBIndex","restLength","stiffness","lambda","update","deltaTime","dt","p","lastFramePosition","set","updateFixedParticles","rotationCenter","angularVelocity","result","calculateGlobalRotation","center","omega","particle","fixed","velocity","sub","prevPosition","scaleBy","damping","acceleration","add","inertialAccel","calculateInertialAcceleration","positionDelta","scale","c","constraints","iter","solveConstraintXPBD","solveConstraint","solveInterChainConstraintXPBD","solveInterChainConstraint","node","worldPos","worldMatrix","m03","m13","m23","positionHistory","shift","fixedParticles","velocities","magnitudeSq","estimateRotationCenterFromHistory","sumOmega","count","r","v","rLengthSq","cross","currentVelocity","history","speed","magnitude","estimatedRadius","max","up","perpDir","normalize","p1","p2","floor","p3","calculateCircleCenter","mid12","mid23","dir12","dir23","normal","perp12","perp23","diff","det","x","y","abs","t","particleVelocity","omegaCrossR","centrifugalAccel","coriolisAccel","totalAccel","particleA","particleB","delta","currentLength","correction","wA","mass","wB","wSum","C","alphaTilde","deltaLambda","n","applyToNodes","weight","applyChainToNodes","nextParticle","currentBonePos","nextNode","nextBonePos","originalDir","currentBoneRotation","Quaternion","decompose","newDir","deltaRotation","IKUtils","fromToRotation","worldRotation","multiply","slerp","parent","parentWorldRotation","parentInvRotation","conjugate","localRotation","rotation","reset","chains","interChainConstraints","enabled","type"],"mappings":"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"}
1
+ {"version":3,"file":"multi_chain_spring_system.js","sources":["../../../src/animation/spring/multi_chain_spring_system.ts"],"sourcesContent":["import { Vector3, Quaternion } from '@zephyr3d/base';\r\nimport type { SceneNode } from '../../scene/scene_node';\r\nimport type { SpringChain } from './spring_chain';\r\nimport type { SpringParticle } from './spring_particle';\r\nimport type { SpringConstraint } from './spring_constraint';\r\nimport { IKUtils } from '../ik/ik_utils';\r\nimport type { SpringCollider } from './spring_collider';\r\nimport {\r\n resolveSphereCollision,\r\n resolveCapsuleCollision,\r\n resolvePlaneCollision,\r\n type CapsuleCollider,\r\n type PlaneCollider,\r\n type SphereCollider,\r\n updateColliderFromNode\r\n} from './spring_collider';\r\nimport { SpringNodePoseTracker } from './spring_node_pose_tracker';\r\n\r\nexport interface InterChainConstraint {\r\n chainAIndex: number;\r\n chainBIndex: number;\r\n particleAIndex: number;\r\n particleBIndex: number;\r\n restLength: number;\r\n stiffness: number;\r\n compliance: number;\r\n lambda: number;\r\n}\r\n\r\nexport interface MultiChainSpringSystemOptions {\r\n iterations?: number;\r\n gravity?: Vector3;\r\n wind?: Vector3;\r\n enableInertialForces?: boolean;\r\n centrifugalScale?: number;\r\n coriolisScale?: number;\r\n solver?: 'verlet' | 'xpbd';\r\n poseFollow?: number;\r\n poseFollowRoot?: number;\r\n poseFollowTip?: number;\r\n poseFollowExponent?: number;\r\n maxPoseOffset?: number;\r\n maxPoseOffsetRoot?: number;\r\n maxPoseOffsetTip?: number;\r\n}\r\n\r\n/** Options used when rebuilding runtime spring state from the current node pose. */\r\nexport interface SpringPoseReinitializeOptions {\r\n /** Recompute maintained anchor offsets against runtime-remapped anchor nodes. */\r\n recomputeAnchorOffsets?: boolean;\r\n /** Recompute structural and inter-chain rest lengths from the current pose. */\r\n recalculateRestLengths?: boolean;\r\n}\r\n\r\nconst FIXED_SIMULATION_TIME_STEP = 1 / 60;\r\nconst MAX_ACCUMULATED_SIMULATION_TIME = 1 / 20;\r\nconst MAX_SIMULATION_STEPS_PER_UPDATE = Math.max(\r\n 1,\r\n Math.ceil(MAX_ACCUMULATED_SIMULATION_TIME / FIXED_SIMULATION_TIME_STEP)\r\n);\r\nconst DEFAULT_PARTICLE_TARGET_SMOOTHING_TIME = 1 / 30;\r\nconst DEFAULT_COLLIDER_SMOOTHING_TIME = 1 / 30;\r\n\r\nexport class MultiChainSpringSystem {\r\n private _chains: SpringChain[];\r\n private _interChainConstraints: InterChainConstraint[];\r\n private _iterations: number;\r\n private _gravity: Vector3;\r\n private _wind: Vector3;\r\n private _enableInertialForces: boolean;\r\n private _centrifugalScale: number;\r\n private _coriolisScale: number;\r\n private _solver: 'verlet' | 'xpbd';\r\n private _poseFollow: number;\r\n private _maxPoseOffset: number;\r\n private _poseFollowRoot: number;\r\n private _poseFollowTip: number;\r\n private _poseFollowExponent: number;\r\n private _maxPoseOffsetRoot: number;\r\n private _maxPoseOffsetTip: number;\r\n private _colliders: SpringCollider[];\r\n private _timeAccumulator: number;\r\n private _smoothedParticleTargets: WeakMap<object, Vector3>;\r\n private _smoothedSphereCenters: WeakMap<SphereCollider, Vector3>;\r\n private _smoothedCapsuleEndpoints: WeakMap<CapsuleCollider, { start: Vector3; end: Vector3 }>;\r\n private _smoothedPlaneData: WeakMap<PlaneCollider, { point: Vector3; normal: Vector3 }>;\r\n private _runtimeNodeMap: ReadonlyMap<SceneNode, SceneNode> | null;\r\n private _runtimeAnchorOffsets: WeakMap<SpringParticle, Vector3>;\r\n private _runtimeRestLengths: WeakMap<object, number>;\r\n private _nodePoseTracker: SpringNodePoseTracker;\r\n\r\n constructor(options?: MultiChainSpringSystemOptions) {\r\n this._chains = [];\r\n this._interChainConstraints = [];\r\n this._iterations = options?.iterations ?? 5;\r\n this._gravity = options?.gravity?.clone() ?? new Vector3(0, -9.8, 0);\r\n this._wind = options?.wind?.clone() ?? new Vector3(0, 0, 0);\r\n this._enableInertialForces = options?.enableInertialForces ?? true;\r\n this._centrifugalScale = options?.centrifugalScale ?? 1.0;\r\n this._coriolisScale = options?.coriolisScale ?? 1.0;\r\n this._solver = options?.solver ?? 'verlet';\r\n this._poseFollow = Math.max(0, Math.min(1, options?.poseFollow ?? 0.35));\r\n this._maxPoseOffset = Math.max(0, options?.maxPoseOffset ?? 0);\r\n this._poseFollowRoot = Math.max(0, Math.min(1, options?.poseFollowRoot ?? this._poseFollow));\r\n this._poseFollowTip = Math.max(0, Math.min(1, options?.poseFollowTip ?? this._poseFollow));\r\n this._poseFollowExponent = Math.max(0.1, options?.poseFollowExponent ?? 1.6);\r\n this._maxPoseOffsetRoot = Math.max(0, options?.maxPoseOffsetRoot ?? this._maxPoseOffset);\r\n this._maxPoseOffsetTip = Math.max(0, options?.maxPoseOffsetTip ?? this._maxPoseOffset);\r\n this._colliders = [];\r\n this._timeAccumulator = 0;\r\n this._smoothedParticleTargets = new WeakMap();\r\n this._smoothedSphereCenters = new WeakMap();\r\n this._smoothedCapsuleEndpoints = new WeakMap();\r\n this._smoothedPlaneData = new WeakMap();\r\n this._runtimeNodeMap = null;\r\n this._runtimeAnchorOffsets = new WeakMap();\r\n this._runtimeRestLengths = new WeakMap();\r\n this._nodePoseTracker = new SpringNodePoseTracker();\r\n }\r\n\r\n addChain(chain: SpringChain): number {\r\n this._chains.push(chain);\r\n return this._chains.length - 1;\r\n }\r\n\r\n addInterChainConstraint(constraint: InterChainConstraint): void {\r\n this._interChainConstraints.push(constraint);\r\n }\r\n\r\n createRadialConstraints(options: {\r\n stiffness: number;\r\n maxDistance: number;\r\n skipRows?: number;\r\n connectDistance?: number;\r\n compliance?: number;\r\n }): void {\r\n const skipRows = options.skipRows ?? 0;\r\n const connectDistance = options.connectDistance ?? 1;\r\n const compliance = options.compliance ?? 0;\r\n\r\n for (let i = 0; i < this._chains.length; i++) {\r\n for (let offset = 1; offset <= connectDistance; offset++) {\r\n const j = (i + offset) % this._chains.length;\r\n const chainA = this._chains[i];\r\n const chainB = this._chains[j];\r\n const minLength = Math.min(chainA.particles.length, chainB.particles.length);\r\n\r\n for (let row = skipRows; row < minLength; row++) {\r\n const pA = chainA.particles[row];\r\n const pB = chainB.particles[row];\r\n const distance = Vector3.distance(pA.position, pB.position);\r\n if (distance <= options.maxDistance) {\r\n this.addInterChainConstraint({\r\n chainAIndex: i,\r\n chainBIndex: j,\r\n particleAIndex: row,\r\n particleBIndex: row,\r\n restLength: distance,\r\n stiffness: options.stiffness,\r\n compliance,\r\n lambda: 0\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n update(deltaTime: number): void {\r\n this._nodePoseTracker.restoreInputPose();\r\n const frameDt = Math.min(Math.max(Number(deltaTime) || 0, 0), MAX_ACCUMULATED_SIMULATION_TIME);\r\n if (frameDt <= 0) {\r\n return;\r\n }\r\n this._timeAccumulator = Math.min(this._timeAccumulator + frameDt, MAX_ACCUMULATED_SIMULATION_TIME);\r\n const stepCount = Math.min(\r\n MAX_SIMULATION_STEPS_PER_UPDATE,\r\n Math.floor((this._timeAccumulator + 1e-8) / FIXED_SIMULATION_TIME_STEP)\r\n );\r\n if (stepCount <= 0) {\r\n return;\r\n }\r\n this._timeAccumulator = Math.max(0, this._timeAccumulator - stepCount * FIXED_SIMULATION_TIME_STEP);\r\n for (let i = 0; i < stepCount; i++) {\r\n this.simulateStep(FIXED_SIMULATION_TIME_STEP, i === 0 ? frameDt : 0);\r\n }\r\n }\r\n\r\n applyToNodes(weight: number = 1.0): void {\r\n const baseNodeStates = new Map<any, { position: Vector3; rotation: Quaternion }>();\r\n const desiredWorldRotations = new Map<any, Quaternion>();\r\n\r\n for (const chain of this._chains) {\r\n this.collectChainNodeRotations(chain, weight, baseNodeStates, desiredWorldRotations);\r\n }\r\n\r\n const nodes = Array.from(desiredWorldRotations.keys());\r\n nodes.sort((a, b) => this.getNodeDepth(a) - this.getNodeDepth(b));\r\n\r\n for (const node of nodes) {\r\n const worldRotation = desiredWorldRotations.get(node);\r\n if (!worldRotation) {\r\n continue;\r\n }\r\n const parent = node.parent;\r\n const inputRotation = node.rotation.clone();\r\n if (parent) {\r\n const parentWorldRotation = new Quaternion();\r\n parent.worldMatrix.decompose(null, parentWorldRotation, null);\r\n const parentInvRotation = Quaternion.conjugate(parentWorldRotation, new Quaternion());\r\n const localRotation = Quaternion.multiply(parentInvRotation, worldRotation, new Quaternion());\r\n node.rotation = localRotation;\r\n this._nodePoseTracker.recordAppliedRotation(node, inputRotation, localRotation);\r\n } else {\r\n node.rotation = worldRotation;\r\n this._nodePoseTracker.recordAppliedRotation(node, inputRotation, worldRotation);\r\n }\r\n }\r\n }\r\n\r\n reset(): void {\r\n this._nodePoseTracker.clear(true);\r\n for (const chain of this._chains) {\r\n chain.reset();\r\n for (const particle of chain.particles) {\r\n particle.animPosition.set(particle.originalPosition);\r\n particle.lastFramePosition.set(particle.originalPosition);\r\n if (particle.positionHistory) {\r\n particle.positionHistory.length = 0;\r\n }\r\n }\r\n }\r\n for (const constraint of this._interChainConstraints) {\r\n constraint.lambda = 0;\r\n }\r\n this._timeAccumulator = 0;\r\n this._smoothedParticleTargets = new WeakMap();\r\n this._smoothedSphereCenters = new WeakMap();\r\n this._smoothedCapsuleEndpoints = new WeakMap();\r\n this._smoothedPlaneData = new WeakMap();\r\n }\r\n\r\n get chains(): SpringChain[] {\r\n return this._chains;\r\n }\r\n\r\n get interChainConstraints(): InterChainConstraint[] {\r\n return this._interChainConstraints;\r\n }\r\n\r\n get gravity(): Vector3 {\r\n return this._gravity;\r\n }\r\n\r\n set gravity(gravity: Vector3) {\r\n this._gravity.set(gravity);\r\n }\r\n\r\n get wind(): Vector3 {\r\n return this._wind;\r\n }\r\n\r\n set wind(wind: Vector3) {\r\n this._wind.set(wind);\r\n }\r\n\r\n get iterations(): number {\r\n return this._iterations;\r\n }\r\n\r\n set iterations(count: number) {\r\n this._iterations = Math.max(1, count);\r\n }\r\n\r\n get enableInertialForces(): boolean {\r\n return this._enableInertialForces;\r\n }\r\n\r\n set enableInertialForces(enabled: boolean) {\r\n this._enableInertialForces = enabled;\r\n }\r\n\r\n get centrifugalScale(): number {\r\n return this._centrifugalScale;\r\n }\r\n\r\n set centrifugalScale(scale: number) {\r\n this._centrifugalScale = Math.max(0, scale);\r\n }\r\n\r\n get coriolisScale(): number {\r\n return this._coriolisScale;\r\n }\r\n\r\n set coriolisScale(scale: number) {\r\n this._coriolisScale = Math.max(0, scale);\r\n }\r\n\r\n get solver(): 'verlet' | 'xpbd' {\r\n return this._solver;\r\n }\r\n\r\n set solver(type: 'verlet' | 'xpbd') {\r\n if (this._solver !== type) {\r\n this._solver = type;\r\n if (type === 'xpbd') {\r\n this.resetConstraintLambdas();\r\n }\r\n }\r\n }\r\n\r\n get poseFollow(): number {\r\n return this._poseFollow;\r\n }\r\n\r\n set poseFollow(value: number) {\r\n const v = Math.max(0, Math.min(1, value));\r\n this._poseFollow = v;\r\n this._poseFollowRoot = v;\r\n this._poseFollowTip = v;\r\n }\r\n\r\n get poseFollowRoot(): number {\r\n return this._poseFollowRoot;\r\n }\r\n\r\n set poseFollowRoot(value: number) {\r\n this._poseFollowRoot = Math.max(0, Math.min(1, value));\r\n }\r\n\r\n get poseFollowTip(): number {\r\n return this._poseFollowTip;\r\n }\r\n\r\n set poseFollowTip(value: number) {\r\n this._poseFollowTip = Math.max(0, Math.min(1, value));\r\n }\r\n\r\n get poseFollowExponent(): number {\r\n return this._poseFollowExponent;\r\n }\r\n\r\n set poseFollowExponent(value: number) {\r\n this._poseFollowExponent = Math.max(0.1, value);\r\n }\r\n\r\n get maxPoseOffset(): number {\r\n return this._maxPoseOffset;\r\n }\r\n\r\n set maxPoseOffset(value: number) {\r\n const v = Math.max(0, value);\r\n this._maxPoseOffset = v;\r\n this._maxPoseOffsetRoot = v;\r\n this._maxPoseOffsetTip = v;\r\n }\r\n\r\n get maxPoseOffsetRoot(): number {\r\n return this._maxPoseOffsetRoot;\r\n }\r\n\r\n set maxPoseOffsetRoot(value: number) {\r\n this._maxPoseOffsetRoot = Math.max(0, value);\r\n }\r\n\r\n get maxPoseOffsetTip(): number {\r\n return this._maxPoseOffsetTip;\r\n }\r\n\r\n set maxPoseOffsetTip(value: number) {\r\n this._maxPoseOffsetTip = Math.max(0, value);\r\n }\r\n\r\n addCollider(collider: SpringCollider): void {\r\n this._colliders.push(collider);\r\n this._smoothedSphereCenters = new WeakMap();\r\n this._smoothedCapsuleEndpoints = new WeakMap();\r\n this._smoothedPlaneData = new WeakMap();\r\n }\r\n\r\n removeCollider(collider: SpringCollider): boolean {\r\n const index = this._colliders.indexOf(collider);\r\n if (index >= 0) {\r\n this._colliders.splice(index, 1);\r\n this._smoothedSphereCenters = new WeakMap();\r\n this._smoothedCapsuleEndpoints = new WeakMap();\r\n this._smoothedPlaneData = new WeakMap();\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n clearColliders(): void {\r\n this._colliders = [];\r\n this._smoothedSphereCenters = new WeakMap();\r\n this._smoothedCapsuleEndpoints = new WeakMap();\r\n this._smoothedPlaneData = new WeakMap();\r\n }\r\n\r\n get colliders(): SpringCollider[] {\r\n return this._colliders;\r\n }\r\n\r\n /**\r\n * Sets a runtime-only node remapping used by particles, anchors and colliders.\r\n * The authored node references remain unchanged and therefore serialize normally.\r\n */\r\n setRuntimeNodeMap(nodeMap: ReadonlyMap<SceneNode, SceneNode> | null): void {\r\n this._nodePoseTracker.clear(false);\r\n this._runtimeNodeMap = nodeMap;\r\n this._runtimeAnchorOffsets = new WeakMap();\r\n this._runtimeRestLengths = new WeakMap();\r\n this.clearRuntimeCaches();\r\n }\r\n\r\n /**\r\n * Rebuilds particle history from the current runtime-remapped node pose.\r\n * This must be called after a hierarchy graft or skeleton rebind.\r\n */\r\n reinitializeFromCurrentPose(options?: SpringPoseReinitializeOptions): void {\r\n this._nodePoseTracker.clear(false);\r\n const recomputeAnchorOffsets = options?.recomputeAnchorOffsets ?? true;\r\n const recalculateRestLengths = options?.recalculateRestLengths ?? true;\r\n this._runtimeAnchorOffsets = new WeakMap();\r\n this._runtimeRestLengths = new WeakMap();\r\n\r\n for (const chain of this._chains) {\r\n for (const particle of chain.particles) {\r\n const particleNode = this.resolveRuntimeNode(particle.node);\r\n let position = particleNode\r\n ? new Vector3(\r\n particleNode.worldMatrix.m03,\r\n particleNode.worldMatrix.m13,\r\n particleNode.worldMatrix.m23\r\n )\r\n : particle.position.clone();\r\n const anchorNode = this.resolveRuntimeNode(particle.anchorNode);\r\n if (particle.fixed && anchorNode) {\r\n let anchorOffset = particle.anchorOffset;\r\n if (recomputeAnchorOffsets && anchorOffset && particleNode) {\r\n anchorOffset = anchorNode.worldToThis(position, new Vector3());\r\n this._runtimeAnchorOffsets.set(particle, anchorOffset);\r\n }\r\n position = anchorOffset\r\n ? anchorNode.worldMatrix.transformPointAffine(anchorOffset, new Vector3())\r\n : new Vector3(anchorNode.worldMatrix.m03, anchorNode.worldMatrix.m13, anchorNode.worldMatrix.m23);\r\n }\r\n particle.position.set(position);\r\n particle.prevPosition.set(position);\r\n particle.animPosition.set(position);\r\n particle.lastFramePosition.set(position);\r\n if (particle.positionHistory) {\r\n particle.positionHistory.length = 0;\r\n }\r\n }\r\n\r\n for (const constraint of chain.constraints) {\r\n constraint.lambda = 0;\r\n if (recalculateRestLengths) {\r\n this._runtimeRestLengths.set(\r\n constraint,\r\n Vector3.distance(\r\n chain.particles[constraint.particleA].position,\r\n chain.particles[constraint.particleB].position\r\n )\r\n );\r\n }\r\n }\r\n }\r\n\r\n for (const constraint of this._interChainConstraints) {\r\n constraint.lambda = 0;\r\n if (recalculateRestLengths) {\r\n const particleA = this._chains[constraint.chainAIndex]?.particles[constraint.particleAIndex];\r\n const particleB = this._chains[constraint.chainBIndex]?.particles[constraint.particleBIndex];\r\n if (particleA && particleB) {\r\n this._runtimeRestLengths.set(constraint, Vector3.distance(particleA.position, particleB.position));\r\n }\r\n }\r\n }\r\n\r\n for (const collider of this._colliders) {\r\n const colliderNode = this.resolveRuntimeNode(collider.node);\r\n if (colliderNode) {\r\n updateColliderFromNode(collider, colliderNode);\r\n }\r\n }\r\n this.clearRuntimeCaches();\r\n }\r\n\r\n private simulateStep(dt: number, inputDeltaTime: number): void {\r\n if (this._enableInertialForces) {\r\n for (const chain of this._chains) {\r\n for (const particle of chain.particles) {\r\n particle.lastFramePosition.set(particle.position);\r\n }\r\n }\r\n }\r\n\r\n this.updateFixedParticles(inputDeltaTime);\r\n\r\n let rotationCenter: Vector3 | null = null;\r\n let angularVelocity: Vector3 | null = null;\r\n\r\n if (this._enableInertialForces && dt > 0.0001) {\r\n const result = this.calculateGlobalRotation(dt);\r\n rotationCenter = result.center;\r\n angularVelocity = result.omega;\r\n }\r\n\r\n for (const chain of this._chains) {\r\n for (const particle of chain.particles) {\r\n if (particle.fixed) {\r\n continue;\r\n }\r\n\r\n const velocity = Vector3.sub(particle.position, particle.prevPosition, new Vector3());\r\n velocity.scaleBy(particle.damping);\r\n\r\n const acceleration = Vector3.add(this._gravity, this._wind, new Vector3());\r\n if (this._enableInertialForces && rotationCenter && angularVelocity) {\r\n const inertialAccel = this.calculateInertialAcceleration(\r\n particle,\r\n rotationCenter,\r\n angularVelocity,\r\n velocity,\r\n this._centrifugalScale,\r\n this._coriolisScale\r\n );\r\n Vector3.add(acceleration, inertialAccel, acceleration);\r\n }\r\n\r\n const positionDelta = Vector3.scale(acceleration, dt * dt, new Vector3());\r\n Vector3.add(velocity, positionDelta, velocity);\r\n\r\n particle.prevPosition.set(particle.position);\r\n Vector3.add(particle.position, velocity, particle.position);\r\n }\r\n }\r\n\r\n if (this._solver === 'xpbd') {\r\n this.resetConstraintLambdas();\r\n }\r\n\r\n for (let iter = 0; iter < this._iterations; iter++) {\r\n for (const chain of this._chains) {\r\n for (const constraint of chain.constraints) {\r\n if (this._solver === 'xpbd') {\r\n this.solveConstraintXPBD(chain, constraint, dt);\r\n } else {\r\n this.solveConstraint(chain, constraint);\r\n }\r\n }\r\n }\r\n\r\n for (const constraint of this._interChainConstraints) {\r\n if (this._solver === 'xpbd') {\r\n this.solveInterChainConstraintXPBD(constraint, dt);\r\n } else {\r\n this.solveInterChainConstraint(constraint);\r\n }\r\n }\r\n\r\n this.solvePosePreservation(this._iterations);\r\n this.solveCollisions(inputDeltaTime);\r\n }\r\n }\r\n\r\n private updateFixedParticles(deltaTime: number): void {\r\n const blend = this.getTemporalBlendFactor(deltaTime, DEFAULT_PARTICLE_TARGET_SMOOTHING_TIME);\r\n for (const chain of this._chains) {\r\n for (const particle of chain.particles) {\r\n const sourceNode = this.resolveRuntimeNode(particle.anchorNode ?? particle.node);\r\n if (!sourceNode) {\r\n continue;\r\n }\r\n const anchorOffset = this._runtimeAnchorOffsets.get(particle) ?? particle.anchorOffset;\r\n const worldPos = anchorOffset\r\n ? sourceNode.worldMatrix.transformPointAffine(anchorOffset)\r\n : new Vector3(sourceNode.worldMatrix.m03, sourceNode.worldMatrix.m13, sourceNode.worldMatrix.m23);\r\n const smoothedTarget = this.getSmoothedParticleTarget(particle, worldPos, blend);\r\n particle.animPosition.set(smoothedTarget);\r\n if (particle.fixed) {\r\n particle.position.set(smoothedTarget);\r\n particle.prevPosition.set(smoothedTarget);\r\n if (this._enableInertialForces) {\r\n if (!particle.positionHistory) {\r\n particle.positionHistory = [];\r\n }\r\n particle.positionHistory.push(smoothedTarget.clone());\r\n if (particle.positionHistory.length > 5) {\r\n particle.positionHistory.shift();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private solvePosePreservation(totalIterations: number): void {\r\n if (this._poseFollowRoot <= 0 && this._poseFollowTip <= 0) {\r\n return;\r\n }\r\n\r\n for (const chain of this._chains) {\r\n const lastIndex = Math.max(1, chain.particles.length - 1);\r\n for (let i = 0; i < chain.particles.length; i++) {\r\n const particle = chain.particles[i];\r\n if (particle.fixed) {\r\n continue;\r\n }\r\n\r\n const t = Math.pow(i / lastIndex, this._poseFollowExponent);\r\n const particlePoseFollow = this.lerp(this._poseFollowRoot, this._poseFollowTip, t);\r\n const iterationFollow =\r\n totalIterations > 1\r\n ? 1 - Math.pow(Math.max(0, 1 - particlePoseFollow), 1 / totalIterations)\r\n : particlePoseFollow;\r\n const toAnim = Vector3.sub(particle.animPosition, particle.position, new Vector3());\r\n const correction = Vector3.scale(toAnim, iterationFollow, new Vector3());\r\n Vector3.add(particle.position, correction, particle.position);\r\n\r\n const particleMaxPoseOffset = this.lerp(this._maxPoseOffsetRoot, this._maxPoseOffsetTip, t);\r\n if (particleMaxPoseOffset > 0) {\r\n const offset = Vector3.sub(particle.position, particle.animPosition, new Vector3());\r\n const offsetLen = offset.magnitude;\r\n if (offsetLen > particleMaxPoseOffset && offsetLen > 1e-6) {\r\n offset.scaleBy(particleMaxPoseOffset / offsetLen);\r\n Vector3.add(particle.animPosition, offset, particle.position);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private solveCollisions(deltaTime: number): void {\r\n const blend = this.getTemporalBlendFactor(deltaTime, DEFAULT_COLLIDER_SMOOTHING_TIME);\r\n const spheres: SphereCollider[] = [];\r\n const capsules: CapsuleCollider[] = [];\r\n const planes: PlaneCollider[] = [];\r\n\r\n for (const collider of this._colliders) {\r\n const colliderNode = this.resolveRuntimeNode(collider.node);\r\n if (colliderNode) {\r\n updateColliderFromNode(collider, colliderNode);\r\n }\r\n if (!collider.enabled) {\r\n continue;\r\n }\r\n switch (collider.type) {\r\n case 'sphere': {\r\n const source = collider as SphereCollider;\r\n spheres.push({\r\n ...source,\r\n center: this.getSmoothedSphereCenter(source, blend)\r\n });\r\n break;\r\n }\r\n case 'capsule': {\r\n const source = collider as CapsuleCollider;\r\n const endpoints = this.getSmoothedCapsuleEndpoints(source, blend);\r\n capsules.push({\r\n ...source,\r\n start: endpoints.start,\r\n end: endpoints.end\r\n });\r\n break;\r\n }\r\n case 'plane': {\r\n const source = collider as PlaneCollider;\r\n const plane = this.getSmoothedPlaneData(source, blend);\r\n planes.push({\r\n ...source,\r\n point: plane.point,\r\n normal: plane.normal\r\n });\r\n break;\r\n }\r\n }\r\n }\r\n\r\n for (const chain of this._chains) {\r\n for (const particle of chain.particles) {\r\n if (particle.fixed) {\r\n continue;\r\n }\r\n const positionBeforeCollision = particle.position.clone();\r\n let collided = false;\r\n for (const collider of spheres) {\r\n collided = resolveSphereCollision(particle.position, collider) || collided;\r\n }\r\n for (const collider of capsules) {\r\n collided = resolveCapsuleCollision(particle.position, collider) || collided;\r\n }\r\n for (const collider of planes) {\r\n collided = resolvePlaneCollision(particle.position, collider) || collided;\r\n }\r\n if (collided) {\r\n Vector3.add(\r\n particle.prevPosition,\r\n Vector3.sub(particle.position, positionBeforeCollision, new Vector3()),\r\n particle.prevPosition\r\n );\r\n }\r\n }\r\n }\r\n }\r\n\r\n private calculateGlobalRotation(dt: number): { center: Vector3; omega: Vector3 } {\r\n const fixedParticles: any[] = [];\r\n const velocities: Vector3[] = [];\r\n const drivenNodes = new Set<SceneNode>();\r\n\r\n for (const chain of this._chains) {\r\n for (const particle of chain.particles) {\r\n const node = this.resolveRuntimeNode(particle.node);\r\n if (node) {\r\n drivenNodes.add(node);\r\n }\r\n }\r\n }\r\n\r\n for (const chain of this._chains) {\r\n for (const particle of chain.particles) {\r\n if (!particle.fixed || !this.isExternalInertialAnchor(particle, drivenNodes)) {\r\n continue;\r\n }\r\n const velocity = Vector3.sub(particle.position, particle.lastFramePosition, new Vector3());\r\n velocity.scaleBy(1.0 / dt);\r\n if (velocity.magnitudeSq > 0.001) {\r\n fixedParticles.push(particle);\r\n velocities.push(velocity);\r\n }\r\n }\r\n }\r\n\r\n if (fixedParticles.length === 0) {\r\n return { center: new Vector3(0, 0, 0), omega: new Vector3(0, 0, 0) };\r\n }\r\n\r\n let center: Vector3;\r\n if (fixedParticles.length === 1) {\r\n center = this.estimateRotationCenterFromHistory(fixedParticles[0], velocities[0]);\r\n } else {\r\n center = new Vector3(0, 0, 0);\r\n for (const particle of fixedParticles) {\r\n Vector3.add(center, particle.position, center);\r\n }\r\n center.scaleBy(1.0 / fixedParticles.length);\r\n }\r\n\r\n let sumOmega = new Vector3(0, 0, 0);\r\n let count = 0;\r\n for (let i = 0; i < fixedParticles.length; i++) {\r\n const r = Vector3.sub(fixedParticles[i].position, center, new Vector3());\r\n const v = velocities[i];\r\n const rLengthSq = r.magnitudeSq;\r\n if (rLengthSq > 0.0001) {\r\n const omega = Vector3.cross(r, v, new Vector3());\r\n omega.scaleBy(1.0 / rLengthSq);\r\n Vector3.add(sumOmega, omega, sumOmega);\r\n count++;\r\n }\r\n }\r\n\r\n if (count > 0) {\r\n sumOmega.scaleBy(1.0 / count);\r\n }\r\n return { center, omega: sumOmega };\r\n }\r\n\r\n private estimateRotationCenterFromHistory(particle: any, currentVelocity: Vector3): Vector3 {\r\n const history = particle.positionHistory;\r\n if (!history || history.length < 3) {\r\n const speed = currentVelocity.magnitude;\r\n if (speed < 0.001) {\r\n return particle.position.clone();\r\n }\r\n\r\n const estimatedRadius = Math.max(0.5, speed * 0.5);\r\n const up = new Vector3(0, 1, 0);\r\n const perpDir = Vector3.cross(currentVelocity, up, new Vector3());\r\n if (perpDir.magnitudeSq < 0.0001) {\r\n perpDir.set(new Vector3(1, 0, 0));\r\n } else {\r\n perpDir.inplaceNormalize();\r\n }\r\n\r\n return Vector3.add(\r\n particle.position,\r\n Vector3.scale(perpDir, estimatedRadius, new Vector3()),\r\n new Vector3()\r\n );\r\n }\r\n\r\n const p1 = history[0];\r\n const p2 = history[Math.floor(history.length / 2)];\r\n const p3 = history[history.length - 1];\r\n return this.calculateCircleCenter(p1, p2, p3);\r\n }\r\n\r\n private calculateCircleCenter(p1: Vector3, p2: Vector3, p3: Vector3): Vector3 {\r\n const mid12 = Vector3.scale(Vector3.add(p1, p2, new Vector3()), 0.5, new Vector3());\r\n const mid23 = Vector3.scale(Vector3.add(p2, p3, new Vector3()), 0.5, new Vector3());\r\n const dir12 = Vector3.sub(p2, p1, new Vector3());\r\n const dir23 = Vector3.sub(p3, p2, new Vector3());\r\n const normal = Vector3.cross(dir12, dir23, new Vector3());\r\n\r\n if (normal.magnitudeSq < 0.0001) {\r\n return Vector3.scale(\r\n Vector3.add(Vector3.add(p1, p2, new Vector3()), p3, new Vector3()),\r\n 1.0 / 3.0,\r\n new Vector3()\r\n );\r\n }\r\n\r\n normal.inplaceNormalize();\r\n const perp12 = Vector3.cross(dir12, normal, new Vector3()).inplaceNormalize();\r\n const perp23 = Vector3.cross(dir23, normal, new Vector3()).inplaceNormalize();\r\n const diff = Vector3.sub(mid23, mid12, new Vector3());\r\n const det = perp12.x * perp23.y - perp12.y * perp23.x;\r\n\r\n if (Math.abs(det) > 0.0001) {\r\n const t = (diff.x * perp23.y - diff.y * perp23.x) / det;\r\n return Vector3.add(mid12, Vector3.scale(perp12, t, new Vector3()), new Vector3());\r\n }\r\n\r\n return Vector3.scale(\r\n Vector3.add(Vector3.add(p1, p2, new Vector3()), p3, new Vector3()),\r\n 1.0 / 3.0,\r\n new Vector3()\r\n );\r\n }\r\n\r\n private calculateInertialAcceleration(\r\n particle: any,\r\n rotationCenter: Vector3,\r\n angularVelocity: Vector3,\r\n particleVelocity: Vector3,\r\n centrifugalScale: number,\r\n coriolisScale: number\r\n ): Vector3 {\r\n const r = Vector3.sub(particle.position, rotationCenter, new Vector3());\r\n const omegaCrossR = Vector3.cross(angularVelocity, r, new Vector3());\r\n const centrifugalAccel = Vector3.cross(angularVelocity, omegaCrossR, new Vector3());\r\n centrifugalAccel.scaleBy(centrifugalScale);\r\n const coriolisAccel = Vector3.cross(angularVelocity, particleVelocity, new Vector3());\r\n coriolisAccel.scaleBy(-2.0 * coriolisScale);\r\n return Vector3.add(centrifugalAccel, coriolisAccel, new Vector3());\r\n }\r\n\r\n private solveConstraint(chain: SpringChain, constraint: SpringConstraint): void {\r\n const pA = chain.particles[constraint.particleA];\r\n const pB = chain.particles[constraint.particleB];\r\n const delta = Vector3.sub(pB.position, pA.position, new Vector3());\r\n const currentLength = delta.magnitude;\r\n if (currentLength < 0.0001) {\r\n return;\r\n }\r\n const diff = (currentLength - this.getRuntimeRestLength(constraint)) / currentLength;\r\n const correction = Vector3.scale(delta, diff * constraint.stiffness * 0.5, new Vector3());\r\n if (!pA.fixed) {\r\n Vector3.add(pA.position, correction, pA.position);\r\n }\r\n if (!pB.fixed) {\r\n Vector3.sub(pB.position, correction, pB.position);\r\n }\r\n }\r\n\r\n private solveInterChainConstraint(constraint: InterChainConstraint): void {\r\n const chainA = this._chains[constraint.chainAIndex];\r\n const chainB = this._chains[constraint.chainBIndex];\r\n const pA = chainA.particles[constraint.particleAIndex];\r\n const pB = chainB.particles[constraint.particleBIndex];\r\n const delta = Vector3.sub(pB.position, pA.position, new Vector3());\r\n const currentLength = delta.magnitude;\r\n if (currentLength < 0.0001) {\r\n return;\r\n }\r\n const diff = (currentLength - this.getRuntimeRestLength(constraint)) / currentLength;\r\n const correction = Vector3.scale(delta, diff * constraint.stiffness * 0.5, new Vector3());\r\n if (!pA.fixed) {\r\n Vector3.add(pA.position, correction, pA.position);\r\n }\r\n if (!pB.fixed) {\r\n Vector3.sub(pB.position, correction, pB.position);\r\n }\r\n }\r\n\r\n private solveConstraintXPBD(chain: SpringChain, constraint: SpringConstraint, dt: number): void {\r\n const pA = chain.particles[constraint.particleA];\r\n const pB = chain.particles[constraint.particleB];\r\n const wA = pA.fixed ? 0 : 1.0 / pA.mass;\r\n const wB = pB.fixed ? 0 : 1.0 / pB.mass;\r\n const wSum = wA + wB;\r\n if (wSum < 1e-10) {\r\n return;\r\n }\r\n const delta = Vector3.sub(pB.position, pA.position, new Vector3());\r\n const currentLength = delta.magnitude;\r\n if (currentLength < 0.0001) {\r\n return;\r\n }\r\n const C = currentLength - this.getRuntimeRestLength(constraint);\r\n const alphaTilde = constraint.compliance / (dt * dt);\r\n const deltaLambda = (-C - alphaTilde * constraint.lambda) / (wSum + alphaTilde);\r\n constraint.lambda += deltaLambda;\r\n const n = Vector3.scale(delta, 1.0 / currentLength, new Vector3());\r\n if (!pA.fixed) {\r\n Vector3.add(pA.position, Vector3.scale(n, -wA * deltaLambda, new Vector3()), pA.position);\r\n }\r\n if (!pB.fixed) {\r\n Vector3.add(pB.position, Vector3.scale(n, wB * deltaLambda, new Vector3()), pB.position);\r\n }\r\n }\r\n\r\n private solveInterChainConstraintXPBD(constraint: InterChainConstraint, dt: number): void {\r\n const chainA = this._chains[constraint.chainAIndex];\r\n const chainB = this._chains[constraint.chainBIndex];\r\n const pA = chainA.particles[constraint.particleAIndex];\r\n const pB = chainB.particles[constraint.particleBIndex];\r\n const wA = pA.fixed ? 0 : 1.0 / pA.mass;\r\n const wB = pB.fixed ? 0 : 1.0 / pB.mass;\r\n const wSum = wA + wB;\r\n if (wSum < 1e-10) {\r\n return;\r\n }\r\n const delta = Vector3.sub(pB.position, pA.position, new Vector3());\r\n const currentLength = delta.magnitude;\r\n if (currentLength < 0.0001) {\r\n return;\r\n }\r\n const C = currentLength - this.getRuntimeRestLength(constraint);\r\n const alphaTilde = constraint.compliance / (dt * dt);\r\n const deltaLambda = (-C - alphaTilde * constraint.lambda) / (wSum + alphaTilde);\r\n constraint.lambda += deltaLambda;\r\n const n = Vector3.scale(delta, 1.0 / currentLength, new Vector3());\r\n if (!pA.fixed) {\r\n Vector3.add(pA.position, Vector3.scale(n, -wA * deltaLambda, new Vector3()), pA.position);\r\n }\r\n if (!pB.fixed) {\r\n Vector3.add(pB.position, Vector3.scale(n, wB * deltaLambda, new Vector3()), pB.position);\r\n }\r\n }\r\n\r\n private collectChainNodeRotations(\r\n chain: SpringChain,\r\n weight: number,\r\n baseNodeStates: Map<any, { position: Vector3; rotation: Quaternion }>,\r\n desiredWorldRotations: Map<any, Quaternion>\r\n ): void {\r\n for (let i = 0; i < chain.particles.length - 1; i++) {\r\n const particle = chain.particles[i];\r\n const nextParticle = chain.particles[i + 1];\r\n const node = this.resolveRuntimeNode(particle.node);\r\n if (!node) {\r\n continue;\r\n }\r\n\r\n const nextNode = this.resolveRuntimeNode(nextParticle.node);\r\n if (!nextNode) {\r\n continue;\r\n }\r\n\r\n let nodeState = baseNodeStates.get(node);\r\n if (!nodeState) {\r\n const currentBoneRotation = new Quaternion();\r\n node.worldMatrix.decompose(null, currentBoneRotation, null);\r\n nodeState = {\r\n position: new Vector3(node.worldMatrix.m03, node.worldMatrix.m13, node.worldMatrix.m23),\r\n rotation: currentBoneRotation\r\n };\r\n baseNodeStates.set(node, nodeState);\r\n }\r\n let nextNodeState = baseNodeStates.get(nextNode);\r\n if (!nextNodeState) {\r\n const nextBoneRotation = new Quaternion();\r\n nextNode.worldMatrix.decompose(null, nextBoneRotation, null);\r\n nextNodeState = {\r\n position: new Vector3(nextNode.worldMatrix.m03, nextNode.worldMatrix.m13, nextNode.worldMatrix.m23),\r\n rotation: nextBoneRotation\r\n };\r\n baseNodeStates.set(nextNode, nextNodeState);\r\n }\r\n\r\n const originalDir = Vector3.sub(nextNodeState.position, nodeState.position, new Vector3());\r\n const currentBoneRotation = nodeState.rotation;\r\n\r\n const newDir = Vector3.sub(nextParticle.position, particle.position, new Vector3());\r\n const deltaRotation = new Quaternion();\r\n IKUtils.fromToRotation(originalDir, newDir, deltaRotation);\r\n let worldRotation = Quaternion.multiply(deltaRotation, currentBoneRotation, new Quaternion());\r\n\r\n if (weight < 1) {\r\n Quaternion.slerp(currentBoneRotation, worldRotation, weight, worldRotation);\r\n }\r\n\r\n desiredWorldRotations.set(node, worldRotation);\r\n }\r\n }\r\n\r\n private getNodeDepth(node: any): number {\r\n let depth = 0;\r\n let current = node?.parent;\r\n while (current) {\r\n depth++;\r\n current = current.parent;\r\n }\r\n return depth;\r\n }\r\n\r\n private resetConstraintLambdas(): void {\r\n for (const chain of this._chains) {\r\n for (const constraint of chain.constraints) {\r\n constraint.lambda = 0;\r\n }\r\n }\r\n for (const constraint of this._interChainConstraints) {\r\n constraint.lambda = 0;\r\n }\r\n }\r\n\r\n private resolveRuntimeNode(node: SceneNode | null | undefined): SceneNode | null {\r\n return node ? (this._runtimeNodeMap?.get(node) ?? node) : null;\r\n }\r\n\r\n private isExternalInertialAnchor(particle: SpringParticle, drivenNodes: Set<SceneNode>): boolean {\r\n const particleNode = this.resolveRuntimeNode(particle.node);\r\n let current = this.resolveRuntimeNode(particle.anchorNode ?? particle.node);\r\n while (current) {\r\n if (current !== particleNode && drivenNodes.has(current)) {\r\n return false;\r\n }\r\n current = current.parent;\r\n }\r\n return true;\r\n }\r\n\r\n private getRuntimeRestLength(constraint: SpringConstraint | InterChainConstraint): number {\r\n return this._runtimeRestLengths.get(constraint) ?? constraint.restLength;\r\n }\r\n\r\n private clearRuntimeCaches(): void {\r\n this._timeAccumulator = 0;\r\n this._smoothedParticleTargets = new WeakMap();\r\n this._smoothedSphereCenters = new WeakMap();\r\n this._smoothedCapsuleEndpoints = new WeakMap();\r\n this._smoothedPlaneData = new WeakMap();\r\n }\r\n\r\n private lerp(a: number, b: number, t: number): number {\r\n return a + (b - a) * t;\r\n }\r\n\r\n private getTemporalBlendFactor(deltaTime: number, smoothingTime: number): number {\r\n const dt = Math.min(Math.max(Number(deltaTime) || 0, 0), MAX_ACCUMULATED_SIMULATION_TIME);\r\n if (smoothingTime <= 0) {\r\n return 1;\r\n }\r\n if (dt <= 0) {\r\n return 0;\r\n }\r\n return 1 - Math.exp(-dt / smoothingTime);\r\n }\r\n\r\n private getSmoothedParticleTarget(target: object, current: Vector3, blend: number): Vector3 {\r\n const cached = this._smoothedParticleTargets.get(target);\r\n if (!cached || blend >= 1) {\r\n const next = current.clone();\r\n this._smoothedParticleTargets.set(target, next);\r\n return next;\r\n }\r\n cached.setXYZ(\r\n cached.x + (current.x - cached.x) * blend,\r\n cached.y + (current.y - cached.y) * blend,\r\n cached.z + (current.z - cached.z) * blend\r\n );\r\n return cached;\r\n }\r\n\r\n private getSmoothedSphereCenter(collider: SphereCollider, blend: number): Vector3 {\r\n const current = collider.center?.clone() ?? new Vector3();\r\n const cached = this._smoothedSphereCenters.get(collider);\r\n if (!cached || blend >= 1) {\r\n this._smoothedSphereCenters.set(collider, current);\r\n return current;\r\n }\r\n cached.setXYZ(\r\n cached.x + (current.x - cached.x) * blend,\r\n cached.y + (current.y - cached.y) * blend,\r\n cached.z + (current.z - cached.z) * blend\r\n );\r\n return cached;\r\n }\r\n\r\n private getSmoothedCapsuleEndpoints(\r\n collider: CapsuleCollider,\r\n blend: number\r\n ): { start: Vector3; end: Vector3 } {\r\n const currentStart = collider.start?.clone() ?? new Vector3();\r\n const currentEnd = collider.end?.clone() ?? new Vector3();\r\n const cached = this._smoothedCapsuleEndpoints.get(collider);\r\n if (!cached || blend >= 1) {\r\n const next = { start: currentStart, end: currentEnd };\r\n this._smoothedCapsuleEndpoints.set(collider, next);\r\n return next;\r\n }\r\n cached.start.setXYZ(\r\n cached.start.x + (currentStart.x - cached.start.x) * blend,\r\n cached.start.y + (currentStart.y - cached.start.y) * blend,\r\n cached.start.z + (currentStart.z - cached.start.z) * blend\r\n );\r\n cached.end.setXYZ(\r\n cached.end.x + (currentEnd.x - cached.end.x) * blend,\r\n cached.end.y + (currentEnd.y - cached.end.y) * blend,\r\n cached.end.z + (currentEnd.z - cached.end.z) * blend\r\n );\r\n return cached;\r\n }\r\n\r\n private getSmoothedPlaneData(collider: PlaneCollider, blend: number): { point: Vector3; normal: Vector3 } {\r\n const currentPoint = collider.point?.clone() ?? new Vector3();\r\n const currentNormal = collider.normal?.clone() ?? new Vector3(0, 1, 0);\r\n const cached = this._smoothedPlaneData.get(collider);\r\n if (!cached || blend >= 1) {\r\n const next = { point: currentPoint, normal: currentNormal };\r\n this._smoothedPlaneData.set(collider, next);\r\n return next;\r\n }\r\n cached.point.setXYZ(\r\n cached.point.x + (currentPoint.x - cached.point.x) * blend,\r\n cached.point.y + (currentPoint.y - cached.point.y) * blend,\r\n cached.point.z + (currentPoint.z - cached.point.z) * blend\r\n );\r\n cached.normal.setXYZ(\r\n cached.normal.x + (currentNormal.x - cached.normal.x) * blend,\r\n cached.normal.y + (currentNormal.y - cached.normal.y) * blend,\r\n cached.normal.z + (currentNormal.z - cached.normal.z) * blend\r\n );\r\n cached.normal.inplaceNormalize();\r\n return cached;\r\n }\r\n}\r\n"],"names":["FIXED_SIMULATION_TIME_STEP","MAX_ACCUMULATED_SIMULATION_TIME","MAX_SIMULATION_STEPS_PER_UPDATE","Math","max","ceil","DEFAULT_PARTICLE_TARGET_SMOOTHING_TIME","DEFAULT_COLLIDER_SMOOTHING_TIME","MultiChainSpringSystem","_chains","_interChainConstraints","_iterations","_gravity","_wind","_enableInertialForces","_centrifugalScale","_coriolisScale","_solver","_poseFollow","_maxPoseOffset","_poseFollowRoot","_poseFollowTip","_poseFollowExponent","_maxPoseOffsetRoot","_maxPoseOffsetTip","_colliders","_timeAccumulator","_smoothedParticleTargets","_smoothedSphereCenters","_smoothedCapsuleEndpoints","_smoothedPlaneData","_runtimeNodeMap","_runtimeAnchorOffsets","_runtimeRestLengths","_nodePoseTracker","options","iterations","gravity","clone","Vector3","wind","enableInertialForces","centrifugalScale","coriolisScale","solver","min","poseFollow","maxPoseOffset","poseFollowRoot","poseFollowTip","poseFollowExponent","maxPoseOffsetRoot","maxPoseOffsetTip","WeakMap","SpringNodePoseTracker","addChain","chain","push","length","addInterChainConstraint","constraint","createRadialConstraints","skipRows","connectDistance","compliance","i","offset","j","chainA","chainB","minLength","particles","row","pA","pB","distance","position","maxDistance","chainAIndex","chainBIndex","particleAIndex","particleBIndex","restLength","stiffness","lambda","update","deltaTime","restoreInputPose","frameDt","Number","stepCount","floor","simulateStep","applyToNodes","weight","baseNodeStates","Map","desiredWorldRotations","collectChainNodeRotations","nodes","Array","from","keys","sort","a","b","getNodeDepth","node","worldRotation","get","parent","inputRotation","rotation","parentWorldRotation","Quaternion","worldMatrix","decompose","parentInvRotation","conjugate","localRotation","multiply","recordAppliedRotation","reset","clear","particle","animPosition","set","originalPosition","lastFramePosition","positionHistory","chains","interChainConstraints","count","enabled","scale","type","resetConstraintLambdas","value","v","addCollider","collider","removeCollider","index","indexOf","splice","clearColliders","colliders","setRuntimeNodeMap","nodeMap","clearRuntimeCaches","reinitializeFromCurrentPose","recomputeAnchorOffsets","recalculateRestLengths","particleNode","resolveRuntimeNode","m03","m13","m23","anchorNode","fixed","anchorOffset","worldToThis","transformPointAffine","prevPosition","constraints","particleA","particleB","colliderNode","updateColliderFromNode","dt","inputDeltaTime","updateFixedParticles","rotationCenter","angularVelocity","result","calculateGlobalRotation","center","omega","velocity","sub","scaleBy","damping","acceleration","add","inertialAccel","calculateInertialAcceleration","positionDelta","iter","solveConstraintXPBD","solveConstraint","solveInterChainConstraintXPBD","solveInterChainConstraint","solvePosePreservation","solveCollisions","blend","getTemporalBlendFactor","sourceNode","worldPos","smoothedTarget","getSmoothedParticleTarget","shift","totalIterations","lastIndex","t","pow","particlePoseFollow","lerp","iterationFollow","toAnim","correction","particleMaxPoseOffset","offsetLen","magnitude","spheres","capsules","planes","source","getSmoothedSphereCenter","endpoints","getSmoothedCapsuleEndpoints","start","end","plane","getSmoothedPlaneData","point","normal","positionBeforeCollision","collided","resolveSphereCollision","resolveCapsuleCollision","resolvePlaneCollision","fixedParticles","velocities","drivenNodes","Set","isExternalInertialAnchor","magnitudeSq","estimateRotationCenterFromHistory","sumOmega","r","rLengthSq","cross","currentVelocity","history","speed","estimatedRadius","up","perpDir","inplaceNormalize","p1","p2","p3","calculateCircleCenter","mid12","mid23","dir12","dir23","perp12","perp23","diff","det","x","y","abs","particleVelocity","omegaCrossR","centrifugalAccel","coriolisAccel","delta","currentLength","getRuntimeRestLength","wA","mass","wB","wSum","C","alphaTilde","deltaLambda","n","nextParticle","nextNode","nodeState","currentBoneRotation","nextNodeState","nextBoneRotation","originalDir","newDir","deltaRotation","IKUtils","fromToRotation","slerp","depth","current","has","smoothingTime","exp","target","cached","next","setXYZ","z","currentStart","currentEnd","currentPoint","currentNormal"],"mappings":";;;;;AAsDA,MAAMA,6BAA6B,CAAI,GAAA,EAAA;AACvC,MAAMC,kCAAkC,CAAI,GAAA,EAAA;AAC5C,MAAMC,+BAAAA,GAAkCC,KAAKC,GAAG,CAC9C,GACAD,IAAKE,CAAAA,IAAI,CAACJ,+BAAkCD,GAAAA,0BAAAA,CAAAA,CAAAA;AAE9C,MAAMM,yCAAyC,CAAI,GAAA,EAAA;AACnD,MAAMC,kCAAkC,CAAI,GAAA,EAAA;AAErC,MAAMC,sBAAAA,CAAAA;IACHC,OAAuB;IACvBC,sBAA+C;IAC/CC,WAAoB;IACpBC,QAAkB;IAClBC,KAAe;IACfC,qBAA+B;IAC/BC,iBAA0B;IAC1BC,cAAuB;IACvBC,OAA2B;IAC3BC,WAAoB;IACpBC,cAAuB;IACvBC,eAAwB;IACxBC,cAAuB;IACvBC,mBAA4B;IAC5BC,kBAA2B;IAC3BC,iBAA0B;IAC1BC,UAA6B;IAC7BC,gBAAyB;IACzBC,wBAAmD;IACnDC,sBAAyD;IACzDC,yBAAsF;IACtFC,kBAAgF;IAChFC,eAA0D;IAC1DC,qBAAwD;IACxDC,mBAA6C;IAC7CC,gBAAwC;AAEhD,IAAA,WAAA,CAAYC,OAAuC,CAAE;QACnD,IAAI,CAAC1B,OAAO,GAAG,EAAE;QACjB,IAAI,CAACC,sBAAsB,GAAG,EAAE;AAChC,QAAA,IAAI,CAACC,WAAW,GAAGwB,OAAAA,EAASC,UAAc,IAAA,CAAA;QAC1C,IAAI,CAACxB,QAAQ,GAAGuB,OAASE,EAAAA,OAAAA,EAASC,WAAW,IAAIC,OAAAA,CAAQ,CAAG,EAAA,IAAM,EAAA,CAAA,CAAA;QAClE,IAAI,CAAC1B,KAAK,GAAGsB,OAAAA,EAASK,MAAMF,KAAW,EAAA,IAAA,IAAIC,OAAQ,CAAA,CAAA,EAAG,CAAG,EAAA,CAAA,CAAA;AACzD,QAAA,IAAI,CAACzB,qBAAqB,GAAGqB,OAAAA,EAASM,oBAAwB,IAAA,IAAA;AAC9D,QAAA,IAAI,CAAC1B,iBAAiB,GAAGoB,OAAAA,EAASO,gBAAoB,IAAA,GAAA;AACtD,QAAA,IAAI,CAAC1B,cAAc,GAAGmB,OAAAA,EAASQ,aAAiB,IAAA,GAAA;AAChD,QAAA,IAAI,CAAC1B,OAAO,GAAGkB,OAAAA,EAASS,MAAU,IAAA,QAAA;AAClC,QAAA,IAAI,CAAC1B,WAAW,GAAGf,IAAAA,CAAKC,GAAG,CAAC,CAAGD,EAAAA,IAAAA,CAAK0C,GAAG,CAAC,CAAGV,EAAAA,OAAAA,EAASW,UAAc,IAAA,IAAA,CAAA,CAAA;QAClE,IAAI,CAAC3B,cAAc,GAAGhB,IAAAA,CAAKC,GAAG,CAAC,CAAA,EAAG+B,SAASY,aAAiB,IAAA,CAAA,CAAA;AAC5D,QAAA,IAAI,CAAC3B,eAAe,GAAGjB,IAAAA,CAAKC,GAAG,CAAC,CAAA,EAAGD,IAAK0C,CAAAA,GAAG,CAAC,CAAGV,EAAAA,OAAAA,EAASa,cAAkB,IAAA,IAAI,CAAC9B,WAAW,CAAA,CAAA;AAC1F,QAAA,IAAI,CAACG,cAAc,GAAGlB,IAAAA,CAAKC,GAAG,CAAC,CAAA,EAAGD,IAAK0C,CAAAA,GAAG,CAAC,CAAGV,EAAAA,OAAAA,EAASc,aAAiB,IAAA,IAAI,CAAC/B,WAAW,CAAA,CAAA;QACxF,IAAI,CAACI,mBAAmB,GAAGnB,IAAAA,CAAKC,GAAG,CAAC,GAAA,EAAK+B,SAASe,kBAAsB,IAAA,GAAA,CAAA;QACxE,IAAI,CAAC3B,kBAAkB,GAAGpB,IAAKC,CAAAA,GAAG,CAAC,CAAA,EAAG+B,OAASgB,EAAAA,iBAAAA,IAAqB,IAAI,CAAChC,cAAc,CAAA;QACvF,IAAI,CAACK,iBAAiB,GAAGrB,IAAKC,CAAAA,GAAG,CAAC,CAAA,EAAG+B,OAASiB,EAAAA,gBAAAA,IAAoB,IAAI,CAACjC,cAAc,CAAA;QACrF,IAAI,CAACM,UAAU,GAAG,EAAE;QACpB,IAAI,CAACC,gBAAgB,GAAG,CAAA;QACxB,IAAI,CAACC,wBAAwB,GAAG,IAAI0B,OAAAA,EAAAA;QACpC,IAAI,CAACzB,sBAAsB,GAAG,IAAIyB,OAAAA,EAAAA;QAClC,IAAI,CAACxB,yBAAyB,GAAG,IAAIwB,OAAAA,EAAAA;QACrC,IAAI,CAACvB,kBAAkB,GAAG,IAAIuB,OAAAA,EAAAA;QAC9B,IAAI,CAACtB,eAAe,GAAG,IAAA;QACvB,IAAI,CAACC,qBAAqB,GAAG,IAAIqB,OAAAA,EAAAA;QACjC,IAAI,CAACpB,mBAAmB,GAAG,IAAIoB,OAAAA,EAAAA;QAC/B,IAAI,CAACnB,gBAAgB,GAAG,IAAIoB,qBAAAA,EAAAA;AAC9B;AAEAC,IAAAA,QAAAA,CAASC,KAAkB,EAAU;AACnC,QAAA,IAAI,CAAC/C,OAAO,CAACgD,IAAI,CAACD,KAAAA,CAAAA;AAClB,QAAA,OAAO,IAAI,CAAC/C,OAAO,CAACiD,MAAM,GAAG,CAAA;AAC/B;AAEAC,IAAAA,uBAAAA,CAAwBC,UAAgC,EAAQ;AAC9D,QAAA,IAAI,CAAClD,sBAAsB,CAAC+C,IAAI,CAACG,UAAAA,CAAAA;AACnC;AAEAC,IAAAA,uBAAAA,CAAwB1B,OAMvB,EAAQ;QACP,MAAM2B,QAAAA,GAAW3B,OAAQ2B,CAAAA,QAAQ,IAAI,CAAA;QACrC,MAAMC,eAAAA,GAAkB5B,OAAQ4B,CAAAA,eAAe,IAAI,CAAA;QACnD,MAAMC,UAAAA,GAAa7B,OAAQ6B,CAAAA,UAAU,IAAI,CAAA;QAEzC,IAAK,IAAIC,CAAI,GAAA,CAAA,EAAGA,CAAI,GAAA,IAAI,CAACxD,OAAO,CAACiD,MAAM,EAAEO,CAAK,EAAA,CAAA;AAC5C,YAAA,IAAK,IAAIC,MAAAA,GAAS,CAAGA,EAAAA,MAAAA,IAAUH,iBAAiBG,MAAU,EAAA,CAAA;gBACxD,MAAMC,CAAAA,GAAI,CAACF,CAAIC,GAAAA,MAAK,IAAK,IAAI,CAACzD,OAAO,CAACiD,MAAM;AAC5C,gBAAA,MAAMU,MAAS,GAAA,IAAI,CAAC3D,OAAO,CAACwD,CAAE,CAAA;AAC9B,gBAAA,MAAMI,MAAS,GAAA,IAAI,CAAC5D,OAAO,CAAC0D,CAAE,CAAA;AAC9B,gBAAA,MAAMG,SAAYnE,GAAAA,IAAAA,CAAK0C,GAAG,CAACuB,MAAOG,CAAAA,SAAS,CAACb,MAAM,EAAEW,MAAAA,CAAOE,SAAS,CAACb,MAAM,CAAA;AAE3E,gBAAA,IAAK,IAAIc,GAAAA,GAAMV,QAAUU,EAAAA,GAAAA,GAAMF,WAAWE,GAAO,EAAA,CAAA;AAC/C,oBAAA,MAAMC,EAAKL,GAAAA,MAAAA,CAAOG,SAAS,CAACC,GAAI,CAAA;AAChC,oBAAA,MAAME,EAAKL,GAAAA,MAAAA,CAAOE,SAAS,CAACC,GAAI,CAAA;oBAChC,MAAMG,QAAAA,GAAWpC,QAAQoC,QAAQ,CAACF,GAAGG,QAAQ,EAAEF,GAAGE,QAAQ,CAAA;oBAC1D,IAAID,QAAAA,IAAYxC,OAAQ0C,CAAAA,WAAW,EAAE;wBACnC,IAAI,CAAClB,uBAAuB,CAAC;4BAC3BmB,WAAab,EAAAA,CAAAA;4BACbc,WAAaZ,EAAAA,CAAAA;4BACba,cAAgBR,EAAAA,GAAAA;4BAChBS,cAAgBT,EAAAA,GAAAA;4BAChBU,UAAYP,EAAAA,QAAAA;AACZQ,4BAAAA,SAAAA,EAAWhD,QAAQgD,SAAS;AAC5BnB,4BAAAA,UAAAA;4BACAoB,MAAQ,EAAA;AACV,yBAAA,CAAA;AACF;AACF;AACF;AACF;AACF;AAEAC,IAAAA,MAAAA,CAAOC,SAAiB,EAAQ;QAC9B,IAAI,CAACpD,gBAAgB,CAACqD,gBAAgB,EAAA;QACtC,MAAMC,OAAAA,GAAUrF,IAAK0C,CAAAA,GAAG,CAAC1C,IAAAA,CAAKC,GAAG,CAACqF,MAAAA,CAAOH,SAAc,CAAA,IAAA,CAAA,EAAG,CAAIrF,CAAAA,EAAAA,+BAAAA,CAAAA;AAC9D,QAAA,IAAIuF,WAAW,CAAG,EAAA;AAChB,YAAA;AACF;QACA,IAAI,CAAC9D,gBAAgB,GAAGvB,IAAK0C,CAAAA,GAAG,CAAC,IAAI,CAACnB,gBAAgB,GAAG8D,OAASvF,EAAAA,+BAAAA,CAAAA;AAClE,QAAA,MAAMyF,SAAYvF,GAAAA,IAAAA,CAAK0C,GAAG,CACxB3C,iCACAC,IAAKwF,CAAAA,KAAK,CAAE,CAAA,IAAI,CAACjE,gBAAgB,GAAG,IAAG,IAAK1B,0BAAAA,CAAAA,CAAAA;AAE9C,QAAA,IAAI0F,aAAa,CAAG,EAAA;AAClB,YAAA;AACF;QACA,IAAI,CAAChE,gBAAgB,GAAGvB,IAAKC,CAAAA,GAAG,CAAC,CAAA,EAAG,IAAI,CAACsB,gBAAgB,GAAGgE,SAAY1F,GAAAA,0BAAAA,CAAAA;AACxE,QAAA,IAAK,IAAIiE,CAAAA,GAAI,CAAGA,EAAAA,CAAAA,GAAIyB,WAAWzB,CAAK,EAAA,CAAA;AAClC,YAAA,IAAI,CAAC2B,YAAY,CAAC5F,0BAA4BiE,EAAAA,CAAAA,KAAM,IAAIuB,OAAU,GAAA,CAAA,CAAA;AACpE;AACF;IAEAK,YAAaC,CAAAA,MAAAA,GAAiB,GAAG,EAAQ;AACvC,QAAA,MAAMC,iBAAiB,IAAIC,GAAAA,EAAAA;AAC3B,QAAA,MAAMC,wBAAwB,IAAID,GAAAA,EAAAA;AAElC,QAAA,KAAK,MAAMxC,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;AAChC,YAAA,IAAI,CAACyF,yBAAyB,CAAC1C,KAAAA,EAAOsC,QAAQC,cAAgBE,EAAAA,qBAAAA,CAAAA;AAChE;AAEA,QAAA,MAAME,KAAQC,GAAAA,KAAAA,CAAMC,IAAI,CAACJ,sBAAsBK,IAAI,EAAA,CAAA;AACnDH,QAAAA,KAAAA,CAAMI,IAAI,CAAC,CAACC,CAAAA,EAAGC,CAAM,GAAA,IAAI,CAACC,YAAY,CAACF,CAAAA,CAAAA,GAAK,IAAI,CAACE,YAAY,CAACD,CAAAA,CAAAA,CAAAA;QAE9D,KAAK,MAAME,QAAQR,KAAO,CAAA;YACxB,MAAMS,aAAAA,GAAgBX,qBAAsBY,CAAAA,GAAG,CAACF,IAAAA,CAAAA;AAChD,YAAA,IAAI,CAACC,aAAe,EAAA;AAClB,gBAAA;AACF;YACA,MAAME,MAAAA,GAASH,KAAKG,MAAM;AAC1B,YAAA,MAAMC,aAAgBJ,GAAAA,IAAAA,CAAKK,QAAQ,CAAC1E,KAAK,EAAA;AACzC,YAAA,IAAIwE,MAAQ,EAAA;AACV,gBAAA,MAAMG,sBAAsB,IAAIC,UAAAA,EAAAA;AAChCJ,gBAAAA,MAAAA,CAAOK,WAAW,CAACC,SAAS,CAAC,MAAMH,mBAAqB,EAAA,IAAA,CAAA;AACxD,gBAAA,MAAMI,iBAAoBH,GAAAA,UAAAA,CAAWI,SAAS,CAACL,qBAAqB,IAAIC,UAAAA,EAAAA,CAAAA;AACxE,gBAAA,MAAMK,gBAAgBL,UAAWM,CAAAA,QAAQ,CAACH,iBAAAA,EAAmBT,eAAe,IAAIM,UAAAA,EAAAA,CAAAA;AAChFP,gBAAAA,IAAAA,CAAKK,QAAQ,GAAGO,aAAAA;AAChB,gBAAA,IAAI,CAACrF,gBAAgB,CAACuF,qBAAqB,CAACd,MAAMI,aAAeQ,EAAAA,aAAAA,CAAAA;aAC5D,MAAA;AACLZ,gBAAAA,IAAAA,CAAKK,QAAQ,GAAGJ,aAAAA;AAChB,gBAAA,IAAI,CAAC1E,gBAAgB,CAACuF,qBAAqB,CAACd,MAAMI,aAAeH,EAAAA,aAAAA,CAAAA;AACnE;AACF;AACF;IAEAc,KAAc,GAAA;AACZ,QAAA,IAAI,CAACxF,gBAAgB,CAACyF,KAAK,CAAC,IAAA,CAAA;AAC5B,QAAA,KAAK,MAAMnE,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;AAChC+C,YAAAA,KAAAA,CAAMkE,KAAK,EAAA;AACX,YAAA,KAAK,MAAME,QAAAA,IAAYpE,KAAMe,CAAAA,SAAS,CAAE;AACtCqD,gBAAAA,QAAAA,CAASC,YAAY,CAACC,GAAG,CAACF,SAASG,gBAAgB,CAAA;AACnDH,gBAAAA,QAAAA,CAASI,iBAAiB,CAACF,GAAG,CAACF,SAASG,gBAAgB,CAAA;gBACxD,IAAIH,QAAAA,CAASK,eAAe,EAAE;oBAC5BL,QAASK,CAAAA,eAAe,CAACvE,MAAM,GAAG,CAAA;AACpC;AACF;AACF;AACA,QAAA,KAAK,MAAME,UAAAA,IAAc,IAAI,CAAClD,sBAAsB,CAAE;AACpDkD,YAAAA,UAAAA,CAAWwB,MAAM,GAAG,CAAA;AACtB;QACA,IAAI,CAAC1D,gBAAgB,GAAG,CAAA;QACxB,IAAI,CAACC,wBAAwB,GAAG,IAAI0B,OAAAA,EAAAA;QACpC,IAAI,CAACzB,sBAAsB,GAAG,IAAIyB,OAAAA,EAAAA;QAClC,IAAI,CAACxB,yBAAyB,GAAG,IAAIwB,OAAAA,EAAAA;QACrC,IAAI,CAACvB,kBAAkB,GAAG,IAAIuB,OAAAA,EAAAA;AAChC;AAEA,IAAA,IAAI6E,MAAwB,GAAA;QAC1B,OAAO,IAAI,CAACzH,OAAO;AACrB;AAEA,IAAA,IAAI0H,qBAAgD,GAAA;QAClD,OAAO,IAAI,CAACzH,sBAAsB;AACpC;AAEA,IAAA,IAAI2B,OAAmB,GAAA;QACrB,OAAO,IAAI,CAACzB,QAAQ;AACtB;IAEA,IAAIyB,OAAAA,CAAQA,OAAgB,EAAE;AAC5B,QAAA,IAAI,CAACzB,QAAQ,CAACkH,GAAG,CAACzF,OAAAA,CAAAA;AACpB;AAEA,IAAA,IAAIG,IAAgB,GAAA;QAClB,OAAO,IAAI,CAAC3B,KAAK;AACnB;IAEA,IAAI2B,IAAAA,CAAKA,IAAa,EAAE;AACtB,QAAA,IAAI,CAAC3B,KAAK,CAACiH,GAAG,CAACtF,IAAAA,CAAAA;AACjB;AAEA,IAAA,IAAIJ,UAAqB,GAAA;QACvB,OAAO,IAAI,CAACzB,WAAW;AACzB;IAEA,IAAIyB,UAAAA,CAAWgG,KAAa,EAAE;AAC5B,QAAA,IAAI,CAACzH,WAAW,GAAGR,IAAKC,CAAAA,GAAG,CAAC,CAAGgI,EAAAA,KAAAA,CAAAA;AACjC;AAEA,IAAA,IAAI3F,oBAAgC,GAAA;QAClC,OAAO,IAAI,CAAC3B,qBAAqB;AACnC;IAEA,IAAI2B,oBAAAA,CAAqB4F,OAAgB,EAAE;QACzC,IAAI,CAACvH,qBAAqB,GAAGuH,OAAAA;AAC/B;AAEA,IAAA,IAAI3F,gBAA2B,GAAA;QAC7B,OAAO,IAAI,CAAC3B,iBAAiB;AAC/B;IAEA,IAAI2B,gBAAAA,CAAiB4F,KAAa,EAAE;AAClC,QAAA,IAAI,CAACvH,iBAAiB,GAAGZ,IAAKC,CAAAA,GAAG,CAAC,CAAGkI,EAAAA,KAAAA,CAAAA;AACvC;AAEA,IAAA,IAAI3F,aAAwB,GAAA;QAC1B,OAAO,IAAI,CAAC3B,cAAc;AAC5B;IAEA,IAAI2B,aAAAA,CAAc2F,KAAa,EAAE;AAC/B,QAAA,IAAI,CAACtH,cAAc,GAAGb,IAAKC,CAAAA,GAAG,CAAC,CAAGkI,EAAAA,KAAAA,CAAAA;AACpC;AAEA,IAAA,IAAI1F,MAA4B,GAAA;QAC9B,OAAO,IAAI,CAAC3B,OAAO;AACrB;IAEA,IAAI2B,MAAAA,CAAO2F,IAAuB,EAAE;AAClC,QAAA,IAAI,IAAI,CAACtH,OAAO,KAAKsH,IAAM,EAAA;YACzB,IAAI,CAACtH,OAAO,GAAGsH,IAAAA;AACf,YAAA,IAAIA,SAAS,MAAQ,EAAA;AACnB,gBAAA,IAAI,CAACC,sBAAsB,EAAA;AAC7B;AACF;AACF;AAEA,IAAA,IAAI1F,UAAqB,GAAA;QACvB,OAAO,IAAI,CAAC5B,WAAW;AACzB;IAEA,IAAI4B,UAAAA,CAAW2F,KAAa,EAAE;QAC5B,MAAMC,CAAAA,GAAIvI,KAAKC,GAAG,CAAC,GAAGD,IAAK0C,CAAAA,GAAG,CAAC,CAAG4F,EAAAA,KAAAA,CAAAA,CAAAA;QAClC,IAAI,CAACvH,WAAW,GAAGwH,CAAAA;QACnB,IAAI,CAACtH,eAAe,GAAGsH,CAAAA;QACvB,IAAI,CAACrH,cAAc,GAAGqH,CAAAA;AACxB;AAEA,IAAA,IAAI1F,cAAyB,GAAA;QAC3B,OAAO,IAAI,CAAC5B,eAAe;AAC7B;IAEA,IAAI4B,cAAAA,CAAeyF,KAAa,EAAE;QAChC,IAAI,CAACrH,eAAe,GAAGjB,IAAKC,CAAAA,GAAG,CAAC,CAAGD,EAAAA,IAAAA,CAAK0C,GAAG,CAAC,CAAG4F,EAAAA,KAAAA,CAAAA,CAAAA;AACjD;AAEA,IAAA,IAAIxF,aAAwB,GAAA;QAC1B,OAAO,IAAI,CAAC5B,cAAc;AAC5B;IAEA,IAAI4B,aAAAA,CAAcwF,KAAa,EAAE;QAC/B,IAAI,CAACpH,cAAc,GAAGlB,IAAKC,CAAAA,GAAG,CAAC,CAAGD,EAAAA,IAAAA,CAAK0C,GAAG,CAAC,CAAG4F,EAAAA,KAAAA,CAAAA,CAAAA;AAChD;AAEA,IAAA,IAAIvF,kBAA6B,GAAA;QAC/B,OAAO,IAAI,CAAC5B,mBAAmB;AACjC;IAEA,IAAI4B,kBAAAA,CAAmBuF,KAAa,EAAE;AACpC,QAAA,IAAI,CAACnH,mBAAmB,GAAGnB,IAAKC,CAAAA,GAAG,CAAC,GAAKqI,EAAAA,KAAAA,CAAAA;AAC3C;AAEA,IAAA,IAAI1F,aAAwB,GAAA;QAC1B,OAAO,IAAI,CAAC5B,cAAc;AAC5B;IAEA,IAAI4B,aAAAA,CAAc0F,KAAa,EAAE;AAC/B,QAAA,MAAMC,CAAIvI,GAAAA,IAAAA,CAAKC,GAAG,CAAC,CAAGqI,EAAAA,KAAAA,CAAAA;QACtB,IAAI,CAACtH,cAAc,GAAGuH,CAAAA;QACtB,IAAI,CAACnH,kBAAkB,GAAGmH,CAAAA;QAC1B,IAAI,CAAClH,iBAAiB,GAAGkH,CAAAA;AAC3B;AAEA,IAAA,IAAIvF,iBAA4B,GAAA;QAC9B,OAAO,IAAI,CAAC5B,kBAAkB;AAChC;IAEA,IAAI4B,iBAAAA,CAAkBsF,KAAa,EAAE;AACnC,QAAA,IAAI,CAAClH,kBAAkB,GAAGpB,IAAKC,CAAAA,GAAG,CAAC,CAAGqI,EAAAA,KAAAA,CAAAA;AACxC;AAEA,IAAA,IAAIrF,gBAA2B,GAAA;QAC7B,OAAO,IAAI,CAAC5B,iBAAiB;AAC/B;IAEA,IAAI4B,gBAAAA,CAAiBqF,KAAa,EAAE;AAClC,QAAA,IAAI,CAACjH,iBAAiB,GAAGrB,IAAKC,CAAAA,GAAG,CAAC,CAAGqI,EAAAA,KAAAA,CAAAA;AACvC;AAEAE,IAAAA,WAAAA,CAAYC,QAAwB,EAAQ;AAC1C,QAAA,IAAI,CAACnH,UAAU,CAACgC,IAAI,CAACmF,QAAAA,CAAAA;QACrB,IAAI,CAAChH,sBAAsB,GAAG,IAAIyB,OAAAA,EAAAA;QAClC,IAAI,CAACxB,yBAAyB,GAAG,IAAIwB,OAAAA,EAAAA;QACrC,IAAI,CAACvB,kBAAkB,GAAG,IAAIuB,OAAAA,EAAAA;AAChC;AAEAwF,IAAAA,cAAAA,CAAeD,QAAwB,EAAW;AAChD,QAAA,MAAME,QAAQ,IAAI,CAACrH,UAAU,CAACsH,OAAO,CAACH,QAAAA,CAAAA;AACtC,QAAA,IAAIE,SAAS,CAAG,EAAA;AACd,YAAA,IAAI,CAACrH,UAAU,CAACuH,MAAM,CAACF,KAAO,EAAA,CAAA,CAAA;YAC9B,IAAI,CAAClH,sBAAsB,GAAG,IAAIyB,OAAAA,EAAAA;YAClC,IAAI,CAACxB,yBAAyB,GAAG,IAAIwB,OAAAA,EAAAA;YACrC,IAAI,CAACvB,kBAAkB,GAAG,IAAIuB,OAAAA,EAAAA;YAC9B,OAAO,IAAA;AACT;QACA,OAAO,KAAA;AACT;IAEA4F,cAAuB,GAAA;QACrB,IAAI,CAACxH,UAAU,GAAG,EAAE;QACpB,IAAI,CAACG,sBAAsB,GAAG,IAAIyB,OAAAA,EAAAA;QAClC,IAAI,CAACxB,yBAAyB,GAAG,IAAIwB,OAAAA,EAAAA;QACrC,IAAI,CAACvB,kBAAkB,GAAG,IAAIuB,OAAAA,EAAAA;AAChC;AAEA,IAAA,IAAI6F,SAA8B,GAAA;QAChC,OAAO,IAAI,CAACzH,UAAU;AACxB;AAEA;;;MAIA0H,iBAAAA,CAAkBC,OAAiD,EAAQ;AACzE,QAAA,IAAI,CAAClH,gBAAgB,CAACyF,KAAK,CAAC,KAAA,CAAA;QAC5B,IAAI,CAAC5F,eAAe,GAAGqH,OAAAA;QACvB,IAAI,CAACpH,qBAAqB,GAAG,IAAIqB,OAAAA,EAAAA;QACjC,IAAI,CAACpB,mBAAmB,GAAG,IAAIoB,OAAAA,EAAAA;AAC/B,QAAA,IAAI,CAACgG,kBAAkB,EAAA;AACzB;AAEA;;;MAIAC,2BAAAA,CAA4BnH,OAAuC,EAAQ;AACzE,QAAA,IAAI,CAACD,gBAAgB,CAACyF,KAAK,CAAC,KAAA,CAAA;QAC5B,MAAM4B,sBAAAA,GAAyBpH,SAASoH,sBAA0B,IAAA,IAAA;QAClE,MAAMC,sBAAAA,GAAyBrH,SAASqH,sBAA0B,IAAA,IAAA;QAClE,IAAI,CAACxH,qBAAqB,GAAG,IAAIqB,OAAAA,EAAAA;QACjC,IAAI,CAACpB,mBAAmB,GAAG,IAAIoB,OAAAA,EAAAA;AAE/B,QAAA,KAAK,MAAMG,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;AAChC,YAAA,KAAK,MAAMmH,QAAAA,IAAYpE,KAAMe,CAAAA,SAAS,CAAE;AACtC,gBAAA,MAAMkF,eAAe,IAAI,CAACC,kBAAkB,CAAC9B,SAASjB,IAAI,CAAA;gBAC1D,IAAI/B,QAAAA,GAAW6E,eACX,IAAIlH,OAAAA,CACFkH,aAAatC,WAAW,CAACwC,GAAG,EAC5BF,YAAatC,CAAAA,WAAW,CAACyC,GAAG,EAC5BH,aAAatC,WAAW,CAAC0C,GAAG,CAE9BjC,GAAAA,QAAAA,CAAShD,QAAQ,CAACtC,KAAK,EAAA;AAC3B,gBAAA,MAAMwH,aAAa,IAAI,CAACJ,kBAAkB,CAAC9B,SAASkC,UAAU,CAAA;gBAC9D,IAAIlC,QAAAA,CAASmC,KAAK,IAAID,UAAY,EAAA;oBAChC,IAAIE,YAAAA,GAAepC,SAASoC,YAAY;oBACxC,IAAIT,sBAAAA,IAA0BS,gBAAgBP,YAAc,EAAA;AAC1DO,wBAAAA,YAAAA,GAAeF,UAAWG,CAAAA,WAAW,CAACrF,QAAAA,EAAU,IAAIrC,OAAAA,EAAAA,CAAAA;AACpD,wBAAA,IAAI,CAACP,qBAAqB,CAAC8F,GAAG,CAACF,QAAUoC,EAAAA,YAAAA,CAAAA;AAC3C;oBACApF,QAAWoF,GAAAA,YAAAA,GACPF,UAAW3C,CAAAA,WAAW,CAAC+C,oBAAoB,CAACF,YAAc,EAAA,IAAIzH,OAC9D,EAAA,CAAA,GAAA,IAAIA,OAAQuH,CAAAA,UAAAA,CAAW3C,WAAW,CAACwC,GAAG,EAAEG,UAAAA,CAAW3C,WAAW,CAACyC,GAAG,EAAEE,UAAAA,CAAW3C,WAAW,CAAC0C,GAAG,CAAA;AACpG;gBACAjC,QAAShD,CAAAA,QAAQ,CAACkD,GAAG,CAAClD,QAAAA,CAAAA;gBACtBgD,QAASuC,CAAAA,YAAY,CAACrC,GAAG,CAAClD,QAAAA,CAAAA;gBAC1BgD,QAASC,CAAAA,YAAY,CAACC,GAAG,CAAClD,QAAAA,CAAAA;gBAC1BgD,QAASI,CAAAA,iBAAiB,CAACF,GAAG,CAAClD,QAAAA,CAAAA;gBAC/B,IAAIgD,QAAAA,CAASK,eAAe,EAAE;oBAC5BL,QAASK,CAAAA,eAAe,CAACvE,MAAM,GAAG,CAAA;AACpC;AACF;AAEA,YAAA,KAAK,MAAME,UAAAA,IAAcJ,KAAM4G,CAAAA,WAAW,CAAE;AAC1CxG,gBAAAA,UAAAA,CAAWwB,MAAM,GAAG,CAAA;AACpB,gBAAA,IAAIoE,sBAAwB,EAAA;oBAC1B,IAAI,CAACvH,mBAAmB,CAAC6F,GAAG,CAC1BlE,YACArB,OAAQoC,CAAAA,QAAQ,CACdnB,KAAAA,CAAMe,SAAS,CAACX,WAAWyG,SAAS,CAAC,CAACzF,QAAQ,EAC9CpB,KAAAA,CAAMe,SAAS,CAACX,UAAW0G,CAAAA,SAAS,CAAC,CAAC1F,QAAQ,CAAA,CAAA;AAGpD;AACF;AACF;AAEA,QAAA,KAAK,MAAMhB,UAAAA,IAAc,IAAI,CAAClD,sBAAsB,CAAE;AACpDkD,YAAAA,UAAAA,CAAWwB,MAAM,GAAG,CAAA;AACpB,YAAA,IAAIoE,sBAAwB,EAAA;AAC1B,gBAAA,MAAMa,SAAY,GAAA,IAAI,CAAC5J,OAAO,CAACmD,UAAAA,CAAWkB,WAAW,CAAC,EAAEP,SAAS,CAACX,UAAAA,CAAWoB,cAAc,CAAC;AAC5F,gBAAA,MAAMsF,SAAY,GAAA,IAAI,CAAC7J,OAAO,CAACmD,UAAAA,CAAWmB,WAAW,CAAC,EAAER,SAAS,CAACX,UAAAA,CAAWqB,cAAc,CAAC;AAC5F,gBAAA,IAAIoF,aAAaC,SAAW,EAAA;AAC1B,oBAAA,IAAI,CAACrI,mBAAmB,CAAC6F,GAAG,CAAClE,UAAAA,EAAYrB,OAAQoC,CAAAA,QAAQ,CAAC0F,SAAAA,CAAUzF,QAAQ,EAAE0F,UAAU1F,QAAQ,CAAA,CAAA;AAClG;AACF;AACF;AAEA,QAAA,KAAK,MAAMgE,QAAAA,IAAY,IAAI,CAACnH,UAAU,CAAE;AACtC,YAAA,MAAM8I,eAAe,IAAI,CAACb,kBAAkB,CAACd,SAASjC,IAAI,CAAA;AAC1D,YAAA,IAAI4D,YAAc,EAAA;AAChBC,gBAAAA,sBAAAA,CAAuB5B,QAAU2B,EAAAA,YAAAA,CAAAA;AACnC;AACF;AACA,QAAA,IAAI,CAAClB,kBAAkB,EAAA;AACzB;IAEQzD,YAAa6E,CAAAA,EAAU,EAAEC,cAAsB,EAAQ;QAC7D,IAAI,IAAI,CAAC5J,qBAAqB,EAAE;AAC9B,YAAA,KAAK,MAAM0C,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;AAChC,gBAAA,KAAK,MAAMmH,QAAAA,IAAYpE,KAAMe,CAAAA,SAAS,CAAE;AACtCqD,oBAAAA,QAAAA,CAASI,iBAAiB,CAACF,GAAG,CAACF,SAAShD,QAAQ,CAAA;AAClD;AACF;AACF;QAEA,IAAI,CAAC+F,oBAAoB,CAACD,cAAAA,CAAAA;AAE1B,QAAA,IAAIE,cAAiC,GAAA,IAAA;AACrC,QAAA,IAAIC,eAAkC,GAAA,IAAA;AAEtC,QAAA,IAAI,IAAI,CAAC/J,qBAAqB,IAAI2J,KAAK,MAAQ,EAAA;AAC7C,YAAA,MAAMK,MAAS,GAAA,IAAI,CAACC,uBAAuB,CAACN,EAAAA,CAAAA;AAC5CG,YAAAA,cAAAA,GAAiBE,OAAOE,MAAM;AAC9BH,YAAAA,eAAAA,GAAkBC,OAAOG,KAAK;AAChC;AAEA,QAAA,KAAK,MAAMzH,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;AAChC,YAAA,KAAK,MAAMmH,QAAAA,IAAYpE,KAAMe,CAAAA,SAAS,CAAE;gBACtC,IAAIqD,QAAAA,CAASmC,KAAK,EAAE;AAClB,oBAAA;AACF;gBAEA,MAAMmB,QAAAA,GAAW3I,OAAQ4I,CAAAA,GAAG,CAACvD,QAAAA,CAAShD,QAAQ,EAAEgD,QAAAA,CAASuC,YAAY,EAAE,IAAI5H,OAAAA,EAAAA,CAAAA;gBAC3E2I,QAASE,CAAAA,OAAO,CAACxD,QAAAA,CAASyD,OAAO,CAAA;AAEjC,gBAAA,MAAMC,YAAe/I,GAAAA,OAAAA,CAAQgJ,GAAG,CAAC,IAAI,CAAC3K,QAAQ,EAAE,IAAI,CAACC,KAAK,EAAE,IAAI0B,OAAAA,EAAAA,CAAAA;AAChE,gBAAA,IAAI,IAAI,CAACzB,qBAAqB,IAAI8J,kBAAkBC,eAAiB,EAAA;AACnE,oBAAA,MAAMW,aAAgB,GAAA,IAAI,CAACC,6BAA6B,CACtD7D,QACAgD,EAAAA,cAAAA,EACAC,eACAK,EAAAA,QAAAA,EACA,IAAI,CAACnK,iBAAiB,EACtB,IAAI,CAACC,cAAc,CAAA;oBAErBuB,OAAQgJ,CAAAA,GAAG,CAACD,YAAAA,EAAcE,aAAeF,EAAAA,YAAAA,CAAAA;AAC3C;AAEA,gBAAA,MAAMI,gBAAgBnJ,OAAQ+F,CAAAA,KAAK,CAACgD,YAAcb,EAAAA,EAAAA,GAAKA,IAAI,IAAIlI,OAAAA,EAAAA,CAAAA;gBAC/DA,OAAQgJ,CAAAA,GAAG,CAACL,QAAAA,EAAUQ,aAAeR,EAAAA,QAAAA,CAAAA;AAErCtD,gBAAAA,QAAAA,CAASuC,YAAY,CAACrC,GAAG,CAACF,SAAShD,QAAQ,CAAA;AAC3CrC,gBAAAA,OAAAA,CAAQgJ,GAAG,CAAC3D,QAAAA,CAAShD,QAAQ,EAAEsG,QAAAA,EAAUtD,SAAShD,QAAQ,CAAA;AAC5D;AACF;AAEA,QAAA,IAAI,IAAI,CAAC3D,OAAO,KAAK,MAAQ,EAAA;AAC3B,YAAA,IAAI,CAACuH,sBAAsB,EAAA;AAC7B;QAEA,IAAK,IAAImD,OAAO,CAAGA,EAAAA,IAAAA,GAAO,IAAI,CAAChL,WAAW,EAAEgL,IAAQ,EAAA,CAAA;AAClD,YAAA,KAAK,MAAMnI,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;AAChC,gBAAA,KAAK,MAAMmD,UAAAA,IAAcJ,KAAM4G,CAAAA,WAAW,CAAE;AAC1C,oBAAA,IAAI,IAAI,CAACnJ,OAAO,KAAK,MAAQ,EAAA;AAC3B,wBAAA,IAAI,CAAC2K,mBAAmB,CAACpI,KAAAA,EAAOI,UAAY6G,EAAAA,EAAAA,CAAAA;qBACvC,MAAA;wBACL,IAAI,CAACoB,eAAe,CAACrI,KAAOI,EAAAA,UAAAA,CAAAA;AAC9B;AACF;AACF;AAEA,YAAA,KAAK,MAAMA,UAAAA,IAAc,IAAI,CAAClD,sBAAsB,CAAE;AACpD,gBAAA,IAAI,IAAI,CAACO,OAAO,KAAK,MAAQ,EAAA;oBAC3B,IAAI,CAAC6K,6BAA6B,CAAClI,UAAY6G,EAAAA,EAAAA,CAAAA;iBAC1C,MAAA;oBACL,IAAI,CAACsB,yBAAyB,CAACnI,UAAAA,CAAAA;AACjC;AACF;AAEA,YAAA,IAAI,CAACoI,qBAAqB,CAAC,IAAI,CAACrL,WAAW,CAAA;YAC3C,IAAI,CAACsL,eAAe,CAACvB,cAAAA,CAAAA;AACvB;AACF;AAEQC,IAAAA,oBAAAA,CAAqBrF,SAAiB,EAAQ;AACpD,QAAA,MAAM4G,KAAQ,GAAA,IAAI,CAACC,sBAAsB,CAAC7G,SAAWhF,EAAAA,sCAAAA,CAAAA;AACrD,QAAA,KAAK,MAAMkD,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;AAChC,YAAA,KAAK,MAAMmH,QAAAA,IAAYpE,KAAMe,CAAAA,SAAS,CAAE;gBACtC,MAAM6H,UAAAA,GAAa,IAAI,CAAC1C,kBAAkB,CAAC9B,QAASkC,CAAAA,UAAU,IAAIlC,QAAAA,CAASjB,IAAI,CAAA;AAC/E,gBAAA,IAAI,CAACyF,UAAY,EAAA;AACf,oBAAA;AACF;gBACA,MAAMpC,YAAAA,GAAe,IAAI,CAAChI,qBAAqB,CAAC6E,GAAG,CAACe,QAAaA,CAAAA,IAAAA,QAAAA,CAASoC,YAAY;gBACtF,MAAMqC,QAAAA,GAAWrC,eACboC,UAAWjF,CAAAA,WAAW,CAAC+C,oBAAoB,CAACF,YAC5C,CAAA,GAAA,IAAIzH,OAAQ6J,CAAAA,UAAAA,CAAWjF,WAAW,CAACwC,GAAG,EAAEyC,UAAAA,CAAWjF,WAAW,CAACyC,GAAG,EAAEwC,UAAAA,CAAWjF,WAAW,CAAC0C,GAAG,CAAA;AAClG,gBAAA,MAAMyC,iBAAiB,IAAI,CAACC,yBAAyB,CAAC3E,UAAUyE,QAAUH,EAAAA,KAAAA,CAAAA;gBAC1EtE,QAASC,CAAAA,YAAY,CAACC,GAAG,CAACwE,cAAAA,CAAAA;gBAC1B,IAAI1E,QAAAA,CAASmC,KAAK,EAAE;oBAClBnC,QAAShD,CAAAA,QAAQ,CAACkD,GAAG,CAACwE,cAAAA,CAAAA;oBACtB1E,QAASuC,CAAAA,YAAY,CAACrC,GAAG,CAACwE,cAAAA,CAAAA;oBAC1B,IAAI,IAAI,CAACxL,qBAAqB,EAAE;wBAC9B,IAAI,CAAC8G,QAASK,CAAAA,eAAe,EAAE;4BAC7BL,QAASK,CAAAA,eAAe,GAAG,EAAE;AAC/B;AACAL,wBAAAA,QAAAA,CAASK,eAAe,CAACxE,IAAI,CAAC6I,eAAehK,KAAK,EAAA,CAAA;AAClD,wBAAA,IAAIsF,QAASK,CAAAA,eAAe,CAACvE,MAAM,GAAG,CAAG,EAAA;4BACvCkE,QAASK,CAAAA,eAAe,CAACuE,KAAK,EAAA;AAChC;AACF;AACF;AACF;AACF;AACF;AAEQR,IAAAA,qBAAAA,CAAsBS,eAAuB,EAAQ;QAC3D,IAAI,IAAI,CAACrL,eAAe,IAAI,KAAK,IAAI,CAACC,cAAc,IAAI,CAAG,EAAA;AACzD,YAAA;AACF;AAEA,QAAA,KAAK,MAAMmC,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;YAChC,MAAMiM,SAAAA,GAAYvM,KAAKC,GAAG,CAAC,GAAGoD,KAAMe,CAAAA,SAAS,CAACb,MAAM,GAAG,CAAA,CAAA;YACvD,IAAK,IAAIO,IAAI,CAAGA,EAAAA,CAAAA,GAAIT,MAAMe,SAAS,CAACb,MAAM,EAAEO,CAAK,EAAA,CAAA;AAC/C,gBAAA,MAAM2D,QAAWpE,GAAAA,KAAAA,CAAMe,SAAS,CAACN,CAAE,CAAA;gBACnC,IAAI2D,QAAAA,CAASmC,KAAK,EAAE;AAClB,oBAAA;AACF;gBAEA,MAAM4C,CAAAA,GAAIxM,KAAKyM,GAAG,CAAC3I,IAAIyI,SAAW,EAAA,IAAI,CAACpL,mBAAmB,CAAA;AAC1D,gBAAA,MAAMuL,kBAAqB,GAAA,IAAI,CAACC,IAAI,CAAC,IAAI,CAAC1L,eAAe,EAAE,IAAI,CAACC,cAAc,EAAEsL,CAAAA,CAAAA;AAChF,gBAAA,MAAMI,eACJN,GAAAA,eAAAA,GAAkB,CACd,GAAA,CAAA,GAAItM,KAAKyM,GAAG,CAACzM,IAAKC,CAAAA,GAAG,CAAC,CAAA,EAAG,CAAIyM,GAAAA,kBAAAA,CAAAA,EAAqB,IAAIJ,eACtDI,CAAAA,GAAAA,kBAAAA;gBACN,MAAMG,MAAAA,GAASzK,OAAQ4I,CAAAA,GAAG,CAACvD,QAAAA,CAASC,YAAY,EAAED,QAAAA,CAAShD,QAAQ,EAAE,IAAIrC,OAAAA,EAAAA,CAAAA;AACzE,gBAAA,MAAM0K,aAAa1K,OAAQ+F,CAAAA,KAAK,CAAC0E,MAAAA,EAAQD,iBAAiB,IAAIxK,OAAAA,EAAAA,CAAAA;AAC9DA,gBAAAA,OAAAA,CAAQgJ,GAAG,CAAC3D,QAAAA,CAAShD,QAAQ,EAAEqI,UAAAA,EAAYrF,SAAShD,QAAQ,CAAA;AAE5D,gBAAA,MAAMsI,qBAAwB,GAAA,IAAI,CAACJ,IAAI,CAAC,IAAI,CAACvL,kBAAkB,EAAE,IAAI,CAACC,iBAAiB,EAAEmL,CAAAA,CAAAA;AACzF,gBAAA,IAAIO,wBAAwB,CAAG,EAAA;oBAC7B,MAAMhJ,MAAAA,GAAS3B,OAAQ4I,CAAAA,GAAG,CAACvD,QAAAA,CAAShD,QAAQ,EAAEgD,QAAAA,CAASC,YAAY,EAAE,IAAItF,OAAAA,EAAAA,CAAAA;oBACzE,MAAM4K,SAAAA,GAAYjJ,OAAOkJ,SAAS;oBAClC,IAAID,SAAAA,GAAYD,qBAAyBC,IAAAA,SAAAA,GAAY,IAAM,EAAA;wBACzDjJ,MAAOkH,CAAAA,OAAO,CAAC8B,qBAAwBC,GAAAA,SAAAA,CAAAA;AACvC5K,wBAAAA,OAAAA,CAAQgJ,GAAG,CAAC3D,QAAAA,CAASC,YAAY,EAAE3D,MAAAA,EAAQ0D,SAAShD,QAAQ,CAAA;AAC9D;AACF;AACF;AACF;AACF;AAEQqH,IAAAA,eAAAA,CAAgB3G,SAAiB,EAAQ;AAC/C,QAAA,MAAM4G,KAAQ,GAAA,IAAI,CAACC,sBAAsB,CAAC7G,SAAW/E,EAAAA,+BAAAA,CAAAA;AACrD,QAAA,MAAM8M,UAA4B,EAAE;AACpC,QAAA,MAAMC,WAA8B,EAAE;AACtC,QAAA,MAAMC,SAA0B,EAAE;AAElC,QAAA,KAAK,MAAM3E,QAAAA,IAAY,IAAI,CAACnH,UAAU,CAAE;AACtC,YAAA,MAAM8I,eAAe,IAAI,CAACb,kBAAkB,CAACd,SAASjC,IAAI,CAAA;AAC1D,YAAA,IAAI4D,YAAc,EAAA;AAChBC,gBAAAA,sBAAAA,CAAuB5B,QAAU2B,EAAAA,YAAAA,CAAAA;AACnC;YACA,IAAI,CAAC3B,QAASP,CAAAA,OAAO,EAAE;AACrB,gBAAA;AACF;AACA,YAAA,OAAQO,SAASL,IAAI;gBACnB,KAAK,QAAA;AAAU,oBAAA;AACb,wBAAA,MAAMiF,MAAS5E,GAAAA,QAAAA;AACfyE,wBAAAA,OAAAA,CAAQ5J,IAAI,CAAC;AACX,4BAAA,GAAG+J,MAAM;AACTxC,4BAAAA,MAAAA,EAAQ,IAAI,CAACyC,uBAAuB,CAACD,MAAQtB,EAAAA,KAAAA;AAC/C,yBAAA,CAAA;AACA,wBAAA;AACF;gBACA,KAAK,SAAA;AAAW,oBAAA;AACd,wBAAA,MAAMsB,MAAS5E,GAAAA,QAAAA;AACf,wBAAA,MAAM8E,SAAY,GAAA,IAAI,CAACC,2BAA2B,CAACH,MAAQtB,EAAAA,KAAAA,CAAAA;AAC3DoB,wBAAAA,QAAAA,CAAS7J,IAAI,CAAC;AACZ,4BAAA,GAAG+J,MAAM;AACTI,4BAAAA,KAAAA,EAAOF,UAAUE,KAAK;AACtBC,4BAAAA,GAAAA,EAAKH,UAAUG;AACjB,yBAAA,CAAA;AACA,wBAAA;AACF;gBACA,KAAK,OAAA;AAAS,oBAAA;AACZ,wBAAA,MAAML,MAAS5E,GAAAA,QAAAA;AACf,wBAAA,MAAMkF,KAAQ,GAAA,IAAI,CAACC,oBAAoB,CAACP,MAAQtB,EAAAA,KAAAA,CAAAA;AAChDqB,wBAAAA,MAAAA,CAAO9J,IAAI,CAAC;AACV,4BAAA,GAAG+J,MAAM;AACTQ,4BAAAA,KAAAA,EAAOF,MAAME,KAAK;AAClBC,4BAAAA,MAAAA,EAAQH,MAAMG;AAChB,yBAAA,CAAA;AACA,wBAAA;AACF;AACF;AACF;AAEA,QAAA,KAAK,MAAMzK,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;AAChC,YAAA,KAAK,MAAMmH,QAAAA,IAAYpE,KAAMe,CAAAA,SAAS,CAAE;gBACtC,IAAIqD,QAAAA,CAASmC,KAAK,EAAE;AAClB,oBAAA;AACF;AACA,gBAAA,MAAMmE,uBAA0BtG,GAAAA,QAAAA,CAAShD,QAAQ,CAACtC,KAAK,EAAA;AACvD,gBAAA,IAAI6L,QAAW,GAAA,KAAA;gBACf,KAAK,MAAMvF,YAAYyE,OAAS,CAAA;AAC9Bc,oBAAAA,QAAAA,GAAWC,sBAAuBxG,CAAAA,QAAAA,CAAShD,QAAQ,EAAEgE,QAAauF,CAAAA,IAAAA,QAAAA;AACpE;gBACA,KAAK,MAAMvF,YAAY0E,QAAU,CAAA;AAC/Ba,oBAAAA,QAAAA,GAAWE,uBAAwBzG,CAAAA,QAAAA,CAAShD,QAAQ,EAAEgE,QAAauF,CAAAA,IAAAA,QAAAA;AACrE;gBACA,KAAK,MAAMvF,YAAY2E,MAAQ,CAAA;AAC7BY,oBAAAA,QAAAA,GAAWG,qBAAsB1G,CAAAA,QAAAA,CAAShD,QAAQ,EAAEgE,QAAauF,CAAAA,IAAAA,QAAAA;AACnE;AACA,gBAAA,IAAIA,QAAU,EAAA;AACZ5L,oBAAAA,OAAAA,CAAQgJ,GAAG,CACT3D,QAASuC,CAAAA,YAAY,EACrB5H,OAAQ4I,CAAAA,GAAG,CAACvD,QAAAA,CAAShD,QAAQ,EAAEsJ,uBAAAA,EAAyB,IAAI3L,OAAAA,EAAAA,CAAAA,EAC5DqF,SAASuC,YAAY,CAAA;AAEzB;AACF;AACF;AACF;AAEQY,IAAAA,uBAAAA,CAAwBN,EAAU,EAAuC;AAC/E,QAAA,MAAM8D,iBAAwB,EAAE;AAChC,QAAA,MAAMC,aAAwB,EAAE;AAChC,QAAA,MAAMC,cAAc,IAAIC,GAAAA,EAAAA;AAExB,QAAA,KAAK,MAAMlL,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;AAChC,YAAA,KAAK,MAAMmH,QAAAA,IAAYpE,KAAMe,CAAAA,SAAS,CAAE;AACtC,gBAAA,MAAMoC,OAAO,IAAI,CAAC+C,kBAAkB,CAAC9B,SAASjB,IAAI,CAAA;AAClD,gBAAA,IAAIA,IAAM,EAAA;AACR8H,oBAAAA,WAAAA,CAAYlD,GAAG,CAAC5E,IAAAA,CAAAA;AAClB;AACF;AACF;AAEA,QAAA,KAAK,MAAMnD,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;AAChC,YAAA,KAAK,MAAMmH,QAAAA,IAAYpE,KAAMe,CAAAA,SAAS,CAAE;gBACtC,IAAI,CAACqD,QAASmC,CAAAA,KAAK,IAAI,CAAC,IAAI,CAAC4E,wBAAwB,CAAC/G,QAAAA,EAAU6G,WAAc,CAAA,EAAA;AAC5E,oBAAA;AACF;gBACA,MAAMvD,QAAAA,GAAW3I,OAAQ4I,CAAAA,GAAG,CAACvD,QAAAA,CAAShD,QAAQ,EAAEgD,QAAAA,CAASI,iBAAiB,EAAE,IAAIzF,OAAAA,EAAAA,CAAAA;gBAChF2I,QAASE,CAAAA,OAAO,CAAC,GAAMX,GAAAA,EAAAA,CAAAA;gBACvB,IAAIS,QAAAA,CAAS0D,WAAW,GAAG,KAAO,EAAA;AAChCL,oBAAAA,cAAAA,CAAe9K,IAAI,CAACmE,QAAAA,CAAAA;AACpB4G,oBAAAA,UAAAA,CAAW/K,IAAI,CAACyH,QAAAA,CAAAA;AAClB;AACF;AACF;QAEA,IAAIqD,cAAAA,CAAe7K,MAAM,KAAK,CAAG,EAAA;YAC/B,OAAO;gBAAEsH,MAAQ,EAAA,IAAIzI,OAAQ,CAAA,CAAA,EAAG,CAAG,EAAA,CAAA,CAAA;gBAAI0I,KAAO,EAAA,IAAI1I,OAAQ,CAAA,CAAA,EAAG,CAAG,EAAA,CAAA;AAAG,aAAA;AACrE;QAEA,IAAIyI,MAAAA;QACJ,IAAIuD,cAAAA,CAAe7K,MAAM,KAAK,CAAG,EAAA;YAC/BsH,MAAS,GAAA,IAAI,CAAC6D,iCAAiC,CAACN,cAAc,CAAC,CAAE,CAAA,EAAEC,UAAU,CAAC,CAAE,CAAA,CAAA;SAC3E,MAAA;YACLxD,MAAS,GAAA,IAAIzI,OAAQ,CAAA,CAAA,EAAG,CAAG,EAAA,CAAA,CAAA;YAC3B,KAAK,MAAMqF,YAAY2G,cAAgB,CAAA;AACrChM,gBAAAA,OAAAA,CAAQgJ,GAAG,CAACP,MAAQpD,EAAAA,QAAAA,CAAShD,QAAQ,EAAEoG,MAAAA,CAAAA;AACzC;AACAA,YAAAA,MAAAA,CAAOI,OAAO,CAAC,GAAMmD,GAAAA,cAAAA,CAAe7K,MAAM,CAAA;AAC5C;AAEA,QAAA,IAAIoL,QAAW,GAAA,IAAIvM,OAAQ,CAAA,CAAA,EAAG,CAAG,EAAA,CAAA,CAAA;AACjC,QAAA,IAAI6F,KAAQ,GAAA,CAAA;AACZ,QAAA,IAAK,IAAInE,CAAI,GAAA,CAAA,EAAGA,IAAIsK,cAAe7K,CAAAA,MAAM,EAAEO,CAAK,EAAA,CAAA;YAC9C,MAAM8K,CAAAA,GAAIxM,OAAQ4I,CAAAA,GAAG,CAACoD,cAAc,CAACtK,CAAAA,CAAE,CAACW,QAAQ,EAAEoG,MAAAA,EAAQ,IAAIzI,OAAAA,EAAAA,CAAAA;YAC9D,MAAMmG,CAAAA,GAAI8F,UAAU,CAACvK,CAAE,CAAA;YACvB,MAAM+K,SAAAA,GAAYD,EAAEH,WAAW;AAC/B,YAAA,IAAII,YAAY,MAAQ,EAAA;AACtB,gBAAA,MAAM/D,QAAQ1I,OAAQ0M,CAAAA,KAAK,CAACF,CAAAA,EAAGrG,GAAG,IAAInG,OAAAA,EAAAA,CAAAA;gBACtC0I,KAAMG,CAAAA,OAAO,CAAC,GAAM4D,GAAAA,SAAAA,CAAAA;gBACpBzM,OAAQgJ,CAAAA,GAAG,CAACuD,QAAAA,EAAU7D,KAAO6D,EAAAA,QAAAA,CAAAA;AAC7B1G,gBAAAA,KAAAA,EAAAA;AACF;AACF;AAEA,QAAA,IAAIA,QAAQ,CAAG,EAAA;YACb0G,QAAS1D,CAAAA,OAAO,CAAC,GAAMhD,GAAAA,KAAAA,CAAAA;AACzB;QACA,OAAO;AAAE4C,YAAAA,MAAAA;YAAQC,KAAO6D,EAAAA;AAAS,SAAA;AACnC;IAEQD,iCAAkCjH,CAAAA,QAAa,EAAEsH,eAAwB,EAAW;QAC1F,MAAMC,OAAAA,GAAUvH,SAASK,eAAe;AACxC,QAAA,IAAI,CAACkH,OAAAA,IAAWA,OAAQzL,CAAAA,MAAM,GAAG,CAAG,EAAA;YAClC,MAAM0L,KAAAA,GAAQF,gBAAgB9B,SAAS;AACvC,YAAA,IAAIgC,QAAQ,KAAO,EAAA;gBACjB,OAAOxH,QAAAA,CAAShD,QAAQ,CAACtC,KAAK,EAAA;AAChC;AAEA,YAAA,MAAM+M,eAAkBlP,GAAAA,IAAAA,CAAKC,GAAG,CAAC,KAAKgP,KAAQ,GAAA,GAAA,CAAA;AAC9C,YAAA,MAAME,EAAK,GAAA,IAAI/M,OAAQ,CAAA,CAAA,EAAG,CAAG,EAAA,CAAA,CAAA;AAC7B,YAAA,MAAMgN,UAAUhN,OAAQ0M,CAAAA,KAAK,CAACC,eAAAA,EAAiBI,IAAI,IAAI/M,OAAAA,EAAAA,CAAAA;YACvD,IAAIgN,OAAAA,CAAQX,WAAW,GAAG,MAAQ,EAAA;AAChCW,gBAAAA,OAAAA,CAAQzH,GAAG,CAAC,IAAIvF,OAAAA,CAAQ,GAAG,CAAG,EAAA,CAAA,CAAA,CAAA;aACzB,MAAA;AACLgN,gBAAAA,OAAAA,CAAQC,gBAAgB,EAAA;AAC1B;AAEA,YAAA,OAAOjN,OAAQgJ,CAAAA,GAAG,CAChB3D,QAAAA,CAAShD,QAAQ,EACjBrC,OAAQ+F,CAAAA,KAAK,CAACiH,OAAAA,EAASF,eAAiB,EAAA,IAAI9M,YAC5C,IAAIA,OAAAA,EAAAA,CAAAA;AAER;QAEA,MAAMkN,EAAAA,GAAKN,OAAO,CAAC,CAAE,CAAA;QACrB,MAAMO,EAAAA,GAAKP,OAAO,CAAChP,IAAAA,CAAKwF,KAAK,CAACwJ,OAAAA,CAAQzL,MAAM,GAAG,CAAG,CAAA,CAAA;AAClD,QAAA,MAAMiM,KAAKR,OAAO,CAACA,OAAQzL,CAAAA,MAAM,GAAG,CAAE,CAAA;AACtC,QAAA,OAAO,IAAI,CAACkM,qBAAqB,CAACH,IAAIC,EAAIC,EAAAA,EAAAA,CAAAA;AAC5C;AAEQC,IAAAA,qBAAAA,CAAsBH,EAAW,EAAEC,EAAW,EAAEC,EAAW,EAAW;AAC5E,QAAA,MAAME,KAAQtN,GAAAA,OAAAA,CAAQ+F,KAAK,CAAC/F,OAAQgJ,CAAAA,GAAG,CAACkE,EAAAA,EAAIC,EAAI,EAAA,IAAInN,OAAY,EAAA,CAAA,EAAA,GAAA,EAAK,IAAIA,OAAAA,EAAAA,CAAAA;AACzE,QAAA,MAAMuN,KAAQvN,GAAAA,OAAAA,CAAQ+F,KAAK,CAAC/F,OAAQgJ,CAAAA,GAAG,CAACmE,EAAAA,EAAIC,EAAI,EAAA,IAAIpN,OAAY,EAAA,CAAA,EAAA,GAAA,EAAK,IAAIA,OAAAA,EAAAA,CAAAA;AACzE,QAAA,MAAMwN,QAAQxN,OAAQ4I,CAAAA,GAAG,CAACuE,EAAAA,EAAID,IAAI,IAAIlN,OAAAA,EAAAA,CAAAA;AACtC,QAAA,MAAMyN,QAAQzN,OAAQ4I,CAAAA,GAAG,CAACwE,EAAAA,EAAID,IAAI,IAAInN,OAAAA,EAAAA,CAAAA;AACtC,QAAA,MAAM0L,SAAS1L,OAAQ0M,CAAAA,KAAK,CAACc,KAAAA,EAAOC,OAAO,IAAIzN,OAAAA,EAAAA,CAAAA;QAE/C,IAAI0L,MAAAA,CAAOW,WAAW,GAAG,MAAQ,EAAA;AAC/B,YAAA,OAAOrM,QAAQ+F,KAAK,CAClB/F,QAAQgJ,GAAG,CAAChJ,QAAQgJ,GAAG,CAACkE,EAAIC,EAAAA,EAAAA,EAAI,IAAInN,OAAYoN,EAAAA,CAAAA,EAAAA,EAAAA,EAAI,IAAIpN,OACxD,EAAA,CAAA,EAAA,GAAA,GAAM,KACN,IAAIA,OAAAA,EAAAA,CAAAA;AAER;AAEA0L,QAAAA,MAAAA,CAAOuB,gBAAgB,EAAA;QACvB,MAAMS,MAAAA,GAAS1N,QAAQ0M,KAAK,CAACc,OAAO9B,MAAQ,EAAA,IAAI1L,WAAWiN,gBAAgB,EAAA;QAC3E,MAAMU,MAAAA,GAAS3N,QAAQ0M,KAAK,CAACe,OAAO/B,MAAQ,EAAA,IAAI1L,WAAWiN,gBAAgB,EAAA;AAC3E,QAAA,MAAMW,OAAO5N,OAAQ4I,CAAAA,GAAG,CAAC2E,KAAAA,EAAOD,OAAO,IAAItN,OAAAA,EAAAA,CAAAA;QAC3C,MAAM6N,GAAAA,GAAMH,MAAOI,CAAAA,CAAC,GAAGH,MAAAA,CAAOI,CAAC,GAAGL,MAAOK,CAAAA,CAAC,GAAGJ,MAAAA,CAAOG,CAAC;AAErD,QAAA,IAAIlQ,IAAKoQ,CAAAA,GAAG,CAACH,GAAAA,CAAAA,GAAO,MAAQ,EAAA;AAC1B,YAAA,MAAMzD,CAAI,GAACwD,CAAAA,IAAAA,CAAKE,CAAC,GAAGH,MAAAA,CAAOI,CAAC,GAAGH,KAAKG,CAAC,GAAGJ,MAAOG,CAAAA,CAAC,IAAID,GAAAA;YACpD,OAAO7N,OAAAA,CAAQgJ,GAAG,CAACsE,KAAOtN,EAAAA,OAAAA,CAAQ+F,KAAK,CAAC2H,MAAQtD,EAAAA,CAAAA,EAAG,IAAIpK,OAAAA,EAAAA,CAAAA,EAAY,IAAIA,OAAAA,EAAAA,CAAAA;AACzE;AAEA,QAAA,OAAOA,QAAQ+F,KAAK,CAClB/F,QAAQgJ,GAAG,CAAChJ,QAAQgJ,GAAG,CAACkE,EAAIC,EAAAA,EAAAA,EAAI,IAAInN,OAAYoN,EAAAA,CAAAA,EAAAA,EAAAA,EAAI,IAAIpN,OACxD,EAAA,CAAA,EAAA,GAAA,GAAM,KACN,IAAIA,OAAAA,EAAAA,CAAAA;AAER;IAEQkJ,6BACN7D,CAAAA,QAAa,EACbgD,cAAuB,EACvBC,eAAwB,EACxB2F,gBAAyB,EACzB9N,gBAAwB,EACxBC,aAAqB,EACZ;QACT,MAAMoM,CAAAA,GAAIxM,QAAQ4I,GAAG,CAACvD,SAAShD,QAAQ,EAAEgG,gBAAgB,IAAIrI,OAAAA,EAAAA,CAAAA;AAC7D,QAAA,MAAMkO,cAAclO,OAAQ0M,CAAAA,KAAK,CAACpE,eAAAA,EAAiBkE,GAAG,IAAIxM,OAAAA,EAAAA,CAAAA;AAC1D,QAAA,MAAMmO,mBAAmBnO,OAAQ0M,CAAAA,KAAK,CAACpE,eAAAA,EAAiB4F,aAAa,IAAIlO,OAAAA,EAAAA,CAAAA;AACzEmO,QAAAA,gBAAAA,CAAiBtF,OAAO,CAAC1I,gBAAAA,CAAAA;AACzB,QAAA,MAAMiO,gBAAgBpO,OAAQ0M,CAAAA,KAAK,CAACpE,eAAAA,EAAiB2F,kBAAkB,IAAIjO,OAAAA,EAAAA,CAAAA;QAC3EoO,aAAcvF,CAAAA,OAAO,CAAC,EAAOzI,GAAAA,aAAAA,CAAAA;AAC7B,QAAA,OAAOJ,OAAQgJ,CAAAA,GAAG,CAACmF,gBAAAA,EAAkBC,eAAe,IAAIpO,OAAAA,EAAAA,CAAAA;AAC1D;IAEQsJ,eAAgBrI,CAAAA,KAAkB,EAAEI,UAA4B,EAAQ;AAC9E,QAAA,MAAMa,KAAKjB,KAAMe,CAAAA,SAAS,CAACX,UAAAA,CAAWyG,SAAS,CAAC;AAChD,QAAA,MAAM3F,KAAKlB,KAAMe,CAAAA,SAAS,CAACX,UAAAA,CAAW0G,SAAS,CAAC;QAChD,MAAMsG,KAAAA,GAAQrO,OAAQ4I,CAAAA,GAAG,CAACzG,EAAAA,CAAGE,QAAQ,EAAEH,EAAAA,CAAGG,QAAQ,EAAE,IAAIrC,OAAAA,EAAAA,CAAAA;QACxD,MAAMsO,aAAAA,GAAgBD,MAAMxD,SAAS;AACrC,QAAA,IAAIyD,gBAAgB,MAAQ,EAAA;AAC1B,YAAA;AACF;QACA,MAAMV,IAAAA,GAAO,CAACU,aAAAA,GAAgB,IAAI,CAACC,oBAAoB,CAAClN,UAAAA,CAAU,IAAKiN,aAAAA;QACvE,MAAM5D,UAAAA,GAAa1K,OAAQ+F,CAAAA,KAAK,CAACsI,KAAAA,EAAOT,OAAOvM,UAAWuB,CAAAA,SAAS,GAAG,GAAA,EAAK,IAAI5C,OAAAA,EAAAA,CAAAA;QAC/E,IAAI,CAACkC,EAAGsF,CAAAA,KAAK,EAAE;AACbxH,YAAAA,OAAAA,CAAQgJ,GAAG,CAAC9G,EAAAA,CAAGG,QAAQ,EAAEqI,UAAAA,EAAYxI,GAAGG,QAAQ,CAAA;AAClD;QACA,IAAI,CAACF,EAAGqF,CAAAA,KAAK,EAAE;AACbxH,YAAAA,OAAAA,CAAQ4I,GAAG,CAACzG,EAAAA,CAAGE,QAAQ,EAAEqI,UAAAA,EAAYvI,GAAGE,QAAQ,CAAA;AAClD;AACF;AAEQmH,IAAAA,yBAAAA,CAA0BnI,UAAgC,EAAQ;AACxE,QAAA,MAAMQ,SAAS,IAAI,CAAC3D,OAAO,CAACmD,UAAAA,CAAWkB,WAAW,CAAC;AACnD,QAAA,MAAMT,SAAS,IAAI,CAAC5D,OAAO,CAACmD,UAAAA,CAAWmB,WAAW,CAAC;AACnD,QAAA,MAAMN,KAAKL,MAAOG,CAAAA,SAAS,CAACX,UAAAA,CAAWoB,cAAc,CAAC;AACtD,QAAA,MAAMN,KAAKL,MAAOE,CAAAA,SAAS,CAACX,UAAAA,CAAWqB,cAAc,CAAC;QACtD,MAAM2L,KAAAA,GAAQrO,OAAQ4I,CAAAA,GAAG,CAACzG,EAAAA,CAAGE,QAAQ,EAAEH,EAAAA,CAAGG,QAAQ,EAAE,IAAIrC,OAAAA,EAAAA,CAAAA;QACxD,MAAMsO,aAAAA,GAAgBD,MAAMxD,SAAS;AACrC,QAAA,IAAIyD,gBAAgB,MAAQ,EAAA;AAC1B,YAAA;AACF;QACA,MAAMV,IAAAA,GAAO,CAACU,aAAAA,GAAgB,IAAI,CAACC,oBAAoB,CAAClN,UAAAA,CAAU,IAAKiN,aAAAA;QACvE,MAAM5D,UAAAA,GAAa1K,OAAQ+F,CAAAA,KAAK,CAACsI,KAAAA,EAAOT,OAAOvM,UAAWuB,CAAAA,SAAS,GAAG,GAAA,EAAK,IAAI5C,OAAAA,EAAAA,CAAAA;QAC/E,IAAI,CAACkC,EAAGsF,CAAAA,KAAK,EAAE;AACbxH,YAAAA,OAAAA,CAAQgJ,GAAG,CAAC9G,EAAAA,CAAGG,QAAQ,EAAEqI,UAAAA,EAAYxI,GAAGG,QAAQ,CAAA;AAClD;QACA,IAAI,CAACF,EAAGqF,CAAAA,KAAK,EAAE;AACbxH,YAAAA,OAAAA,CAAQ4I,GAAG,CAACzG,EAAAA,CAAGE,QAAQ,EAAEqI,UAAAA,EAAYvI,GAAGE,QAAQ,CAAA;AAClD;AACF;AAEQgH,IAAAA,mBAAAA,CAAoBpI,KAAkB,EAAEI,UAA4B,EAAE6G,EAAU,EAAQ;AAC9F,QAAA,MAAMhG,KAAKjB,KAAMe,CAAAA,SAAS,CAACX,UAAAA,CAAWyG,SAAS,CAAC;AAChD,QAAA,MAAM3F,KAAKlB,KAAMe,CAAAA,SAAS,CAACX,UAAAA,CAAW0G,SAAS,CAAC;AAChD,QAAA,MAAMyG,KAAKtM,EAAGsF,CAAAA,KAAK,GAAG,CAAI,GAAA,GAAA,GAAMtF,GAAGuM,IAAI;AACvC,QAAA,MAAMC,KAAKvM,EAAGqF,CAAAA,KAAK,GAAG,CAAI,GAAA,GAAA,GAAMrF,GAAGsM,IAAI;AACvC,QAAA,MAAME,OAAOH,EAAKE,GAAAA,EAAAA;AAClB,QAAA,IAAIC,OAAO,KAAO,EAAA;AAChB,YAAA;AACF;QACA,MAAMN,KAAAA,GAAQrO,OAAQ4I,CAAAA,GAAG,CAACzG,EAAAA,CAAGE,QAAQ,EAAEH,EAAAA,CAAGG,QAAQ,EAAE,IAAIrC,OAAAA,EAAAA,CAAAA;QACxD,MAAMsO,aAAAA,GAAgBD,MAAMxD,SAAS;AACrC,QAAA,IAAIyD,gBAAgB,MAAQ,EAAA;AAC1B,YAAA;AACF;AACA,QAAA,MAAMM,CAAIN,GAAAA,aAAAA,GAAgB,IAAI,CAACC,oBAAoB,CAAClN,UAAAA,CAAAA;AACpD,QAAA,MAAMwN,aAAaxN,UAAWI,CAAAA,UAAU,IAAIyG,KAAKA,EAAC,CAAA;AAClD,QAAA,MAAM4G,WAAc,GAAC,CAAA,CAACF,CAAIC,GAAAA,UAAAA,GAAaxN,UAAWwB,CAAAA,MAAM,KAAK8L,IAAAA,GAAOE,UAAS,CAAA;AAC7ExN,QAAAA,UAAAA,CAAWwB,MAAM,IAAIiM,WAAAA;AACrB,QAAA,MAAMC,IAAI/O,OAAQ+F,CAAAA,KAAK,CAACsI,KAAO,EAAA,GAAA,GAAMC,eAAe,IAAItO,OAAAA,EAAAA,CAAAA;QACxD,IAAI,CAACkC,EAAGsF,CAAAA,KAAK,EAAE;AACbxH,YAAAA,OAAAA,CAAQgJ,GAAG,CAAC9G,EAAGG,CAAAA,QAAQ,EAAErC,OAAQ+F,CAAAA,KAAK,CAACgJ,CAAAA,EAAG,CAACP,EAAKM,GAAAA,WAAAA,EAAa,IAAI9O,OAAAA,EAAAA,CAAAA,EAAYkC,GAAGG,QAAQ,CAAA;AAC1F;QACA,IAAI,CAACF,EAAGqF,CAAAA,KAAK,EAAE;AACbxH,YAAAA,OAAAA,CAAQgJ,GAAG,CAAC7G,EAAGE,CAAAA,QAAQ,EAAErC,OAAQ+F,CAAAA,KAAK,CAACgJ,CAAAA,EAAGL,EAAKI,GAAAA,WAAAA,EAAa,IAAI9O,OAAAA,EAAAA,CAAAA,EAAYmC,GAAGE,QAAQ,CAAA;AACzF;AACF;IAEQkH,6BAA8BlI,CAAAA,UAAgC,EAAE6G,EAAU,EAAQ;AACxF,QAAA,MAAMrG,SAAS,IAAI,CAAC3D,OAAO,CAACmD,UAAAA,CAAWkB,WAAW,CAAC;AACnD,QAAA,MAAMT,SAAS,IAAI,CAAC5D,OAAO,CAACmD,UAAAA,CAAWmB,WAAW,CAAC;AACnD,QAAA,MAAMN,KAAKL,MAAOG,CAAAA,SAAS,CAACX,UAAAA,CAAWoB,cAAc,CAAC;AACtD,QAAA,MAAMN,KAAKL,MAAOE,CAAAA,SAAS,CAACX,UAAAA,CAAWqB,cAAc,CAAC;AACtD,QAAA,MAAM8L,KAAKtM,EAAGsF,CAAAA,KAAK,GAAG,CAAI,GAAA,GAAA,GAAMtF,GAAGuM,IAAI;AACvC,QAAA,MAAMC,KAAKvM,EAAGqF,CAAAA,KAAK,GAAG,CAAI,GAAA,GAAA,GAAMrF,GAAGsM,IAAI;AACvC,QAAA,MAAME,OAAOH,EAAKE,GAAAA,EAAAA;AAClB,QAAA,IAAIC,OAAO,KAAO,EAAA;AAChB,YAAA;AACF;QACA,MAAMN,KAAAA,GAAQrO,OAAQ4I,CAAAA,GAAG,CAACzG,EAAAA,CAAGE,QAAQ,EAAEH,EAAAA,CAAGG,QAAQ,EAAE,IAAIrC,OAAAA,EAAAA,CAAAA;QACxD,MAAMsO,aAAAA,GAAgBD,MAAMxD,SAAS;AACrC,QAAA,IAAIyD,gBAAgB,MAAQ,EAAA;AAC1B,YAAA;AACF;AACA,QAAA,MAAMM,CAAIN,GAAAA,aAAAA,GAAgB,IAAI,CAACC,oBAAoB,CAAClN,UAAAA,CAAAA;AACpD,QAAA,MAAMwN,aAAaxN,UAAWI,CAAAA,UAAU,IAAIyG,KAAKA,EAAC,CAAA;AAClD,QAAA,MAAM4G,WAAc,GAAC,CAAA,CAACF,CAAIC,GAAAA,UAAAA,GAAaxN,UAAWwB,CAAAA,MAAM,KAAK8L,IAAAA,GAAOE,UAAS,CAAA;AAC7ExN,QAAAA,UAAAA,CAAWwB,MAAM,IAAIiM,WAAAA;AACrB,QAAA,MAAMC,IAAI/O,OAAQ+F,CAAAA,KAAK,CAACsI,KAAO,EAAA,GAAA,GAAMC,eAAe,IAAItO,OAAAA,EAAAA,CAAAA;QACxD,IAAI,CAACkC,EAAGsF,CAAAA,KAAK,EAAE;AACbxH,YAAAA,OAAAA,CAAQgJ,GAAG,CAAC9G,EAAGG,CAAAA,QAAQ,EAAErC,OAAQ+F,CAAAA,KAAK,CAACgJ,CAAAA,EAAG,CAACP,EAAKM,GAAAA,WAAAA,EAAa,IAAI9O,OAAAA,EAAAA,CAAAA,EAAYkC,GAAGG,QAAQ,CAAA;AAC1F;QACA,IAAI,CAACF,EAAGqF,CAAAA,KAAK,EAAE;AACbxH,YAAAA,OAAAA,CAAQgJ,GAAG,CAAC7G,EAAGE,CAAAA,QAAQ,EAAErC,OAAQ+F,CAAAA,KAAK,CAACgJ,CAAAA,EAAGL,EAAKI,GAAAA,WAAAA,EAAa,IAAI9O,OAAAA,EAAAA,CAAAA,EAAYmC,GAAGE,QAAQ,CAAA;AACzF;AACF;AAEQsB,IAAAA,yBAAAA,CACN1C,KAAkB,EAClBsC,MAAc,EACdC,cAAqE,EACrEE,qBAA2C,EACrC;QACN,IAAK,IAAIhC,CAAI,GAAA,CAAA,EAAGA,CAAIT,GAAAA,KAAAA,CAAMe,SAAS,CAACb,MAAM,GAAG,CAAA,EAAGO,CAAK,EAAA,CAAA;AACnD,YAAA,MAAM2D,QAAWpE,GAAAA,KAAAA,CAAMe,SAAS,CAACN,CAAE,CAAA;AACnC,YAAA,MAAMsN,YAAe/N,GAAAA,KAAAA,CAAMe,SAAS,CAACN,IAAI,CAAE,CAAA;AAC3C,YAAA,MAAM0C,OAAO,IAAI,CAAC+C,kBAAkB,CAAC9B,SAASjB,IAAI,CAAA;AAClD,YAAA,IAAI,CAACA,IAAM,EAAA;AACT,gBAAA;AACF;AAEA,YAAA,MAAM6K,WAAW,IAAI,CAAC9H,kBAAkB,CAAC6H,aAAa5K,IAAI,CAAA;AAC1D,YAAA,IAAI,CAAC6K,QAAU,EAAA;AACb,gBAAA;AACF;YAEA,IAAIC,SAAAA,GAAY1L,cAAec,CAAAA,GAAG,CAACF,IAAAA,CAAAA;AACnC,YAAA,IAAI,CAAC8K,SAAW,EAAA;AACd,gBAAA,MAAMC,sBAAsB,IAAIxK,UAAAA,EAAAA;AAChCP,gBAAAA,IAAAA,CAAKQ,WAAW,CAACC,SAAS,CAAC,MAAMsK,mBAAqB,EAAA,IAAA,CAAA;gBACtDD,SAAY,GAAA;AACV7M,oBAAAA,QAAAA,EAAU,IAAIrC,OAAAA,CAAQoE,IAAKQ,CAAAA,WAAW,CAACwC,GAAG,EAAEhD,IAAKQ,CAAAA,WAAW,CAACyC,GAAG,EAAEjD,IAAKQ,CAAAA,WAAW,CAAC0C,GAAG,CAAA;oBACtF7C,QAAU0K,EAAAA;AACZ,iBAAA;gBACA3L,cAAe+B,CAAAA,GAAG,CAACnB,IAAM8K,EAAAA,SAAAA,CAAAA;AAC3B;YACA,IAAIE,aAAAA,GAAgB5L,cAAec,CAAAA,GAAG,CAAC2K,QAAAA,CAAAA;AACvC,YAAA,IAAI,CAACG,aAAe,EAAA;AAClB,gBAAA,MAAMC,mBAAmB,IAAI1K,UAAAA,EAAAA;AAC7BsK,gBAAAA,QAAAA,CAASrK,WAAW,CAACC,SAAS,CAAC,MAAMwK,gBAAkB,EAAA,IAAA,CAAA;gBACvDD,aAAgB,GAAA;AACd/M,oBAAAA,QAAAA,EAAU,IAAIrC,OAAAA,CAAQiP,QAASrK,CAAAA,WAAW,CAACwC,GAAG,EAAE6H,QAASrK,CAAAA,WAAW,CAACyC,GAAG,EAAE4H,QAASrK,CAAAA,WAAW,CAAC0C,GAAG,CAAA;oBAClG7C,QAAU4K,EAAAA;AACZ,iBAAA;gBACA7L,cAAe+B,CAAAA,GAAG,CAAC0J,QAAUG,EAAAA,aAAAA,CAAAA;AAC/B;YAEA,MAAME,WAAAA,GAActP,OAAQ4I,CAAAA,GAAG,CAACwG,aAAAA,CAAc/M,QAAQ,EAAE6M,SAAAA,CAAU7M,QAAQ,EAAE,IAAIrC,OAAAA,EAAAA,CAAAA;YAChF,MAAMmP,mBAAAA,GAAsBD,UAAUzK,QAAQ;YAE9C,MAAM8K,MAAAA,GAASvP,OAAQ4I,CAAAA,GAAG,CAACoG,YAAAA,CAAa3M,QAAQ,EAAEgD,QAAAA,CAAShD,QAAQ,EAAE,IAAIrC,OAAAA,EAAAA,CAAAA;AACzE,YAAA,MAAMwP,gBAAgB,IAAI7K,UAAAA,EAAAA;YAC1B8K,OAAQC,CAAAA,cAAc,CAACJ,WAAAA,EAAaC,MAAQC,EAAAA,aAAAA,CAAAA;AAC5C,YAAA,IAAInL,gBAAgBM,UAAWM,CAAAA,QAAQ,CAACuK,aAAAA,EAAeL,qBAAqB,IAAIxK,UAAAA,EAAAA,CAAAA;AAEhF,YAAA,IAAIpB,SAAS,CAAG,EAAA;AACdoB,gBAAAA,UAAAA,CAAWgL,KAAK,CAACR,mBAAqB9K,EAAAA,aAAAA,EAAed,MAAQc,EAAAA,aAAAA,CAAAA;AAC/D;YAEAX,qBAAsB6B,CAAAA,GAAG,CAACnB,IAAMC,EAAAA,aAAAA,CAAAA;AAClC;AACF;AAEQF,IAAAA,YAAAA,CAAaC,IAAS,EAAU;AACtC,QAAA,IAAIwL,KAAQ,GAAA,CAAA;AACZ,QAAA,IAAIC,UAAUzL,IAAMG,EAAAA,MAAAA;AACpB,QAAA,MAAOsL,OAAS,CAAA;AACdD,YAAAA,KAAAA,EAAAA;AACAC,YAAAA,OAAAA,GAAUA,QAAQtL,MAAM;AAC1B;QACA,OAAOqL,KAAAA;AACT;IAEQ3J,sBAA+B,GAAA;AACrC,QAAA,KAAK,MAAMhF,KAAAA,IAAS,IAAI,CAAC/C,OAAO,CAAE;AAChC,YAAA,KAAK,MAAMmD,UAAAA,IAAcJ,KAAM4G,CAAAA,WAAW,CAAE;AAC1CxG,gBAAAA,UAAAA,CAAWwB,MAAM,GAAG,CAAA;AACtB;AACF;AACA,QAAA,KAAK,MAAMxB,UAAAA,IAAc,IAAI,CAAClD,sBAAsB,CAAE;AACpDkD,YAAAA,UAAAA,CAAWwB,MAAM,GAAG,CAAA;AACtB;AACF;AAEQsE,IAAAA,kBAAAA,CAAmB/C,IAAkC,EAAoB;AAC/E,QAAA,OAAOA,OAAQ,IAAI,CAAC5E,eAAe,EAAE8E,GAAAA,CAAIF,SAASA,IAAQ,GAAA,IAAA;AAC5D;IAEQgI,wBAAyB/G,CAAAA,QAAwB,EAAE6G,WAA2B,EAAW;AAC/F,QAAA,MAAMhF,eAAe,IAAI,CAACC,kBAAkB,CAAC9B,SAASjB,IAAI,CAAA;QAC1D,IAAIyL,OAAAA,GAAU,IAAI,CAAC1I,kBAAkB,CAAC9B,QAASkC,CAAAA,UAAU,IAAIlC,QAAAA,CAASjB,IAAI,CAAA;AAC1E,QAAA,MAAOyL,OAAS,CAAA;AACd,YAAA,IAAIA,OAAY3I,KAAAA,YAAAA,IAAgBgF,WAAY4D,CAAAA,GAAG,CAACD,OAAU,CAAA,EAAA;gBACxD,OAAO,KAAA;AACT;AACAA,YAAAA,OAAAA,GAAUA,QAAQtL,MAAM;AAC1B;QACA,OAAO,IAAA;AACT;AAEQgK,IAAAA,oBAAAA,CAAqBlN,UAAmD,EAAU;QACxF,OAAO,IAAI,CAAC3B,mBAAmB,CAAC4E,GAAG,CAACjD,UAAAA,CAAAA,IAAeA,WAAWsB,UAAU;AAC1E;IAEQmE,kBAA2B,GAAA;QACjC,IAAI,CAAC3H,gBAAgB,GAAG,CAAA;QACxB,IAAI,CAACC,wBAAwB,GAAG,IAAI0B,OAAAA,EAAAA;QACpC,IAAI,CAACzB,sBAAsB,GAAG,IAAIyB,OAAAA,EAAAA;QAClC,IAAI,CAACxB,yBAAyB,GAAG,IAAIwB,OAAAA,EAAAA;QACrC,IAAI,CAACvB,kBAAkB,GAAG,IAAIuB,OAAAA,EAAAA;AAChC;AAEQyJ,IAAAA,IAAAA,CAAKtG,CAAS,EAAEC,CAAS,EAAEkG,CAAS,EAAU;AACpD,QAAA,OAAOnG,CAAI,GAACC,CAAAA,CAAAA,GAAID,CAAAA,IAAKmG,CAAAA;AACvB;IAEQR,sBAAuB7G,CAAAA,SAAiB,EAAEgN,aAAqB,EAAU;QAC/E,MAAM7H,EAAAA,GAAKtK,IAAK0C,CAAAA,GAAG,CAAC1C,IAAAA,CAAKC,GAAG,CAACqF,MAAAA,CAAOH,SAAc,CAAA,IAAA,CAAA,EAAG,CAAIrF,CAAAA,EAAAA,+BAAAA,CAAAA;AACzD,QAAA,IAAIqS,iBAAiB,CAAG,EAAA;YACtB,OAAO,CAAA;AACT;AACA,QAAA,IAAI7H,MAAM,CAAG,EAAA;YACX,OAAO,CAAA;AACT;AACA,QAAA,OAAO,CAAItK,GAAAA,IAAAA,CAAKoS,GAAG,CAAC,CAAC9H,EAAK6H,GAAAA,aAAAA,CAAAA;AAC5B;AAEQ/F,IAAAA,yBAAAA,CAA0BiG,MAAc,EAAEJ,OAAgB,EAAElG,KAAa,EAAW;AAC1F,QAAA,MAAMuG,SAAS,IAAI,CAAC9Q,wBAAwB,CAACkF,GAAG,CAAC2L,MAAAA,CAAAA;QACjD,IAAI,CAACC,MAAUvG,IAAAA,KAAAA,IAAS,CAAG,EAAA;YACzB,MAAMwG,IAAAA,GAAON,QAAQ9P,KAAK,EAAA;AAC1B,YAAA,IAAI,CAACX,wBAAwB,CAACmG,GAAG,CAAC0K,MAAQE,EAAAA,IAAAA,CAAAA;YAC1C,OAAOA,IAAAA;AACT;AACAD,QAAAA,MAAAA,CAAOE,MAAM,CACXF,MAAAA,CAAOpC,CAAC,GAAG,CAAC+B,OAAAA,CAAQ/B,CAAC,GAAGoC,OAAOpC,CAAAA,IAAKnE,KACpCuG,EAAAA,MAAAA,CAAOnC,CAAC,GAAI8B,CAAAA,OAAAA,CAAQ9B,CAAC,GAAGmC,MAAAA,CAAOnC,CAAC,IAAIpE,OACpCuG,MAAOG,CAAAA,CAAC,GAAIR,CAAAA,OAAQQ,CAAAA,CAAC,GAAGH,MAAOG,CAAAA,CAAC,IAAI1G,KAAAA,CAAAA;QAEtC,OAAOuG,MAAAA;AACT;IAEQhF,uBAAwB7E,CAAAA,QAAwB,EAAEsD,KAAa,EAAW;AAChF,QAAA,MAAMkG,OAAUxJ,GAAAA,QAAAA,CAASoC,MAAM,EAAE1I,WAAW,IAAIC,OAAAA,EAAAA;AAChD,QAAA,MAAMkQ,SAAS,IAAI,CAAC7Q,sBAAsB,CAACiF,GAAG,CAAC+B,QAAAA,CAAAA;QAC/C,IAAI,CAAC6J,MAAUvG,IAAAA,KAAAA,IAAS,CAAG,EAAA;AACzB,YAAA,IAAI,CAACtK,sBAAsB,CAACkG,GAAG,CAACc,QAAUwJ,EAAAA,OAAAA,CAAAA;YAC1C,OAAOA,OAAAA;AACT;AACAK,QAAAA,MAAAA,CAAOE,MAAM,CACXF,MAAAA,CAAOpC,CAAC,GAAG,CAAC+B,OAAAA,CAAQ/B,CAAC,GAAGoC,OAAOpC,CAAAA,IAAKnE,KACpCuG,EAAAA,MAAAA,CAAOnC,CAAC,GAAI8B,CAAAA,OAAAA,CAAQ9B,CAAC,GAAGmC,MAAAA,CAAOnC,CAAC,IAAIpE,OACpCuG,MAAOG,CAAAA,CAAC,GAAIR,CAAAA,OAAQQ,CAAAA,CAAC,GAAGH,MAAOG,CAAAA,CAAC,IAAI1G,KAAAA,CAAAA;QAEtC,OAAOuG,MAAAA;AACT;IAEQ9E,2BACN/E,CAAAA,QAAyB,EACzBsD,KAAa,EACqB;AAClC,QAAA,MAAM2G,YAAejK,GAAAA,QAAAA,CAASgF,KAAK,EAAEtL,WAAW,IAAIC,OAAAA,EAAAA;AACpD,QAAA,MAAMuQ,UAAalK,GAAAA,QAAAA,CAASiF,GAAG,EAAEvL,WAAW,IAAIC,OAAAA,EAAAA;AAChD,QAAA,MAAMkQ,SAAS,IAAI,CAAC5Q,yBAAyB,CAACgF,GAAG,CAAC+B,QAAAA,CAAAA;QAClD,IAAI,CAAC6J,MAAUvG,IAAAA,KAAAA,IAAS,CAAG,EAAA;AACzB,YAAA,MAAMwG,IAAO,GAAA;gBAAE9E,KAAOiF,EAAAA,YAAAA;gBAAchF,GAAKiF,EAAAA;AAAW,aAAA;AACpD,YAAA,IAAI,CAACjR,yBAAyB,CAACiG,GAAG,CAACc,QAAU8J,EAAAA,IAAAA,CAAAA;YAC7C,OAAOA,IAAAA;AACT;QACAD,MAAO7E,CAAAA,KAAK,CAAC+E,MAAM,CACjBF,MAAAA,CAAO7E,KAAK,CAACyC,CAAC,GAAIwC,CAAAA,YAAAA,CAAaxC,CAAC,GAAGoC,MAAAA,CAAO7E,KAAK,CAACyC,CAAAA,IAAKnE,KACrDuG,EAAAA,MAAAA,CAAO7E,KAAK,CAAC0C,CAAC,GAAG,CAACuC,YAAAA,CAAavC,CAAC,GAAGmC,MAAO7E,CAAAA,KAAK,CAAC0C,CAAAA,IAAKpE,KAAAA,EACrDuG,MAAO7E,CAAAA,KAAK,CAACgF,CAAC,GAAG,CAACC,YAAaD,CAAAA,CAAC,GAAGH,MAAAA,CAAO7E,KAAK,CAACgF,CAAAA,IAAK1G,KAAAA,CAAAA;QAEvDuG,MAAO5E,CAAAA,GAAG,CAAC8E,MAAM,CACfF,MAAAA,CAAO5E,GAAG,CAACwC,CAAC,GAAIyC,CAAAA,UAAAA,CAAWzC,CAAC,GAAGoC,MAAAA,CAAO5E,GAAG,CAACwC,CAAAA,IAAKnE,KAC/CuG,EAAAA,MAAAA,CAAO5E,GAAG,CAACyC,CAAC,GAAG,CAACwC,UAAAA,CAAWxC,CAAC,GAAGmC,MAAO5E,CAAAA,GAAG,CAACyC,CAAAA,IAAKpE,KAAAA,EAC/CuG,MAAO5E,CAAAA,GAAG,CAAC+E,CAAC,GAAG,CAACE,UAAWF,CAAAA,CAAC,GAAGH,MAAAA,CAAO5E,GAAG,CAAC+E,CAAAA,IAAK1G,KAAAA,CAAAA;QAEjD,OAAOuG,MAAAA;AACT;IAEQ1E,oBAAqBnF,CAAAA,QAAuB,EAAEsD,KAAa,EAAuC;AACxG,QAAA,MAAM6G,YAAenK,GAAAA,QAAAA,CAASoF,KAAK,EAAE1L,WAAW,IAAIC,OAAAA,EAAAA;QACpD,MAAMyQ,aAAAA,GAAgBpK,SAASqF,MAAM,EAAE3L,WAAW,IAAIC,OAAAA,CAAQ,GAAG,CAAG,EAAA,CAAA,CAAA;AACpE,QAAA,MAAMkQ,SAAS,IAAI,CAAC3Q,kBAAkB,CAAC+E,GAAG,CAAC+B,QAAAA,CAAAA;QAC3C,IAAI,CAAC6J,MAAUvG,IAAAA,KAAAA,IAAS,CAAG,EAAA;AACzB,YAAA,MAAMwG,IAAO,GAAA;gBAAE1E,KAAO+E,EAAAA,YAAAA;gBAAc9E,MAAQ+E,EAAAA;AAAc,aAAA;AAC1D,YAAA,IAAI,CAAClR,kBAAkB,CAACgG,GAAG,CAACc,QAAU8J,EAAAA,IAAAA,CAAAA;YACtC,OAAOA,IAAAA;AACT;QACAD,MAAOzE,CAAAA,KAAK,CAAC2E,MAAM,CACjBF,MAAAA,CAAOzE,KAAK,CAACqC,CAAC,GAAI0C,CAAAA,YAAAA,CAAa1C,CAAC,GAAGoC,MAAAA,CAAOzE,KAAK,CAACqC,CAAAA,IAAKnE,KACrDuG,EAAAA,MAAAA,CAAOzE,KAAK,CAACsC,CAAC,GAAG,CAACyC,YAAAA,CAAazC,CAAC,GAAGmC,MAAOzE,CAAAA,KAAK,CAACsC,CAAAA,IAAKpE,KAAAA,EACrDuG,MAAOzE,CAAAA,KAAK,CAAC4E,CAAC,GAAG,CAACG,YAAaH,CAAAA,CAAC,GAAGH,MAAAA,CAAOzE,KAAK,CAAC4E,CAAAA,IAAK1G,KAAAA,CAAAA;QAEvDuG,MAAOxE,CAAAA,MAAM,CAAC0E,MAAM,CAClBF,MAAAA,CAAOxE,MAAM,CAACoC,CAAC,GAAI2C,CAAAA,aAAAA,CAAc3C,CAAC,GAAGoC,MAAAA,CAAOxE,MAAM,CAACoC,CAAAA,IAAKnE,KACxDuG,EAAAA,MAAAA,CAAOxE,MAAM,CAACqC,CAAC,GAAG,CAAC0C,aAAAA,CAAc1C,CAAC,GAAGmC,MAAOxE,CAAAA,MAAM,CAACqC,CAAAA,IAAKpE,KAAAA,EACxDuG,MAAOxE,CAAAA,MAAM,CAAC2E,CAAC,GAAG,CAACI,aAAcJ,CAAAA,CAAC,GAAGH,MAAAA,CAAOxE,MAAM,CAAC2E,CAAAA,IAAK1G,KAAAA,CAAAA;QAE1DuG,MAAOxE,CAAAA,MAAM,CAACuB,gBAAgB,EAAA;QAC9B,OAAOiD,MAAAA;AACT;AACF;;;;"}
@@ -191,11 +191,12 @@ import { Vector3 } from '@zephyr3d/base';
191
191
  * Updates collider position from its associated node
192
192
  *
193
193
  * @public
194
- */ function updateColliderFromNode(collider) {
195
- if (!collider.node || !collider.enabled) {
194
+ */ function updateColliderFromNode(collider, runtimeNode) {
195
+ const node = runtimeNode ?? collider.node;
196
+ if (!node || !collider.enabled) {
196
197
  return;
197
198
  }
198
- const worldMatrix = collider.node.worldMatrix;
199
+ const worldMatrix = node.worldMatrix;
199
200
  switch(collider.type){
200
201
  case 'sphere':
201
202
  {
@@ -1 +1 @@
1
- {"version":3,"file":"spring_collider.js","sources":["../../../src/animation/spring/spring_collider.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { Vector3 } from '@zephyr3d/base';\r\nimport type { SceneNode } from '../../scene/scene_node';\r\n\r\n/**\r\n * Base interface for spring collision shapes\r\n *\r\n * @public\r\n */\r\nexport interface SpringCollider {\r\n /** Type of collider */\r\n type: 'sphere' | 'capsule' | 'plane';\r\n /** Associated scene node (optional, for dynamic colliders) */\r\n node?: Nullable<SceneNode>;\r\n /** Whether this collider is enabled */\r\n enabled: boolean;\r\n}\r\n\r\n/**\r\n * Sphere collider for spring collision detection\r\n *\r\n * @public\r\n */\r\nexport interface SphereCollider extends SpringCollider {\r\n type: 'sphere';\r\n /** Center position in world space */\r\n center: Vector3;\r\n /** Radius of the sphere */\r\n radius: number;\r\n /** Authoring-space radius before node scaling (if node is set) */\r\n localRadius?: number;\r\n /** Baseline world scale captured at creation for backward compatibility */\r\n localRadiusScaleRef?: number;\r\n /** Local offset from node (if node is set) */\r\n localOffset?: Vector3;\r\n}\r\n\r\n/**\r\n * Capsule collider for spring collision detection\r\n *\r\n * @public\r\n */\r\nexport interface CapsuleCollider extends SpringCollider {\r\n type: 'capsule';\r\n /** Start point of the capsule axis in world space */\r\n start: Vector3;\r\n /** End point of the capsule axis in world space */\r\n end: Vector3;\r\n /** Radius of the capsule */\r\n radius: number;\r\n /** Authoring-space radius before node scaling (if node is set) */\r\n localRadius?: number;\r\n /** Baseline perpendicular scale captured at creation for backward compatibility */\r\n localRadiusScaleRef?: number;\r\n /** Local start offset from node (if node is set) */\r\n localStartOffset?: Vector3;\r\n /** Local end offset from node (if node is set) */\r\n localEndOffset?: Vector3;\r\n}\r\n\r\n/**\r\n * Plane collider for spring collision detection\r\n *\r\n * @public\r\n */\r\nexport interface PlaneCollider extends SpringCollider {\r\n type: 'plane';\r\n /** Point on the plane in world space */\r\n point: Vector3;\r\n /** Normal vector of the plane (should be normalized) */\r\n normal: Vector3;\r\n /** Local point offset from node (if node is set) */\r\n localPointOffset?: Vector3;\r\n /** Local normal direction (if node is set) */\r\n localNormal?: Vector3;\r\n}\r\n\r\n/**\r\n * Creates a sphere collider\r\n * @param centerOrOffset - Center position in world space, or local offset if node is provided\r\n * @param radius - Radius of the sphere\r\n * @param node - Optional scene node to attach to (if provided, centerOrOffset is treated as local offset)\r\n *\r\n * @public\r\n */\r\nexport function createSphereCollider(\r\n centerOrOffset: Vector3,\r\n radius: number,\r\n node?: SceneNode\r\n): SphereCollider {\r\n if (node) {\r\n // If node is provided, treat centerOrOffset as local offset\r\n const worldMatrix = node.worldMatrix;\r\n const worldCenter = worldMatrix.transformPointAffine(centerOrOffset, new Vector3());\r\n\r\n return {\r\n type: 'sphere',\r\n center: worldCenter,\r\n radius,\r\n localRadius: radius,\r\n localRadiusScaleRef: getUniformScale(worldMatrix),\r\n node,\r\n enabled: true,\r\n localOffset: centerOrOffset.clone()\r\n };\r\n } else {\r\n // No node, use as world position\r\n return {\r\n type: 'sphere',\r\n center: centerOrOffset.clone(),\r\n radius,\r\n node: null,\r\n enabled: true\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Creates a capsule collider\r\n * @param startOrOffset - Start point in world space, or local offset if node is provided\r\n * @param endOrOffset - End point in world space, or local offset if node is provided\r\n * @param radius - Radius of the capsule\r\n * @param node - Optional scene node to attach to (if provided, offsets are treated as local)\r\n *\r\n * @public\r\n */\r\nexport function createCapsuleCollider(\r\n startOrOffset: Vector3,\r\n endOrOffset: Vector3,\r\n radius: number,\r\n node?: SceneNode\r\n): CapsuleCollider {\r\n if (node) {\r\n // If node is provided, treat as local offsets\r\n const worldMatrix = node.worldMatrix;\r\n const worldStart = worldMatrix.transformPointAffine(startOrOffset, new Vector3());\r\n const worldEnd = worldMatrix.transformPointAffine(endOrOffset, new Vector3());\r\n\r\n return {\r\n type: 'capsule',\r\n start: worldStart,\r\n end: worldEnd,\r\n radius,\r\n localRadius: radius,\r\n localRadiusScaleRef: getPerpendicularScale(\r\n worldMatrix,\r\n Vector3.sub(endOrOffset, startOrOffset, new Vector3())\r\n ),\r\n node,\r\n enabled: true,\r\n localStartOffset: startOrOffset.clone(),\r\n localEndOffset: endOrOffset.clone()\r\n };\r\n } else {\r\n // No node, use as world positions\r\n return {\r\n type: 'capsule',\r\n start: startOrOffset.clone(),\r\n end: endOrOffset.clone(),\r\n radius,\r\n node: null,\r\n enabled: true\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Creates a plane collider\r\n * @param pointOrOffset - Point on plane in world space, or local offset if node is provided\r\n * @param normal - Normal vector (will be normalized)\r\n * @param node - Optional scene node to attach to (if provided, pointOrOffset is treated as local offset)\r\n *\r\n * @public\r\n */\r\nexport function createPlaneCollider(\r\n pointOrOffset: Vector3,\r\n normal: Vector3,\r\n node?: SceneNode\r\n): PlaneCollider {\r\n const normalizedNormal = new Vector3();\r\n Vector3.normalize(normal, normalizedNormal);\r\n\r\n if (node) {\r\n // If node is provided, treat as local offset\r\n const worldMatrix = node.worldMatrix;\r\n const worldPoint = worldMatrix.transformPointAffine(pointOrOffset, new Vector3());\r\n\r\n return {\r\n type: 'plane',\r\n point: worldPoint,\r\n normal: normalizedNormal.clone(),\r\n node,\r\n enabled: true,\r\n localPointOffset: pointOrOffset.clone(),\r\n localNormal: normalizedNormal.clone()\r\n };\r\n } else {\r\n // No node, use as world position\r\n return {\r\n type: 'plane',\r\n point: pointOrOffset.clone(),\r\n normal: normalizedNormal,\r\n node: null,\r\n enabled: true\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Resolves collision between a particle and a sphere collider\r\n * @returns true if collision occurred\r\n *\r\n * @public\r\n */\r\nexport function resolveSphereCollision(particlePos: Vector3, collider: SphereCollider): boolean {\r\n const toParticle = Vector3.sub(particlePos, collider.center, new Vector3());\r\n const distSq = toParticle.magnitudeSq;\r\n const radiusSq = collider.radius * collider.radius;\r\n\r\n if (distSq < radiusSq && distSq > 0.0001) {\r\n // Particle is inside sphere, push it out\r\n const dist = Math.sqrt(distSq);\r\n const penetration = collider.radius - dist;\r\n\r\n // Push particle to sphere surface\r\n Vector3.normalize(toParticle, toParticle);\r\n toParticle.scaleBy(penetration);\r\n Vector3.add(particlePos, toParticle, particlePos);\r\n\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Resolves collision between a particle and a capsule collider\r\n * @returns true if collision occurred\r\n *\r\n * @public\r\n */\r\nexport function resolveCapsuleCollision(particlePos: Vector3, collider: CapsuleCollider): boolean {\r\n // Find closest point on capsule axis\r\n const axis = Vector3.sub(collider.end, collider.start, new Vector3());\r\n const axisLength = axis.magnitude;\r\n\r\n if (axisLength < 0.0001) {\r\n // Degenerate capsule, treat as sphere\r\n const toParticle = Vector3.sub(particlePos, collider.start, new Vector3());\r\n const distSq = toParticle.magnitudeSq;\r\n const radiusSq = collider.radius * collider.radius;\r\n\r\n if (distSq < radiusSq && distSq > 0.0001) {\r\n const dist = Math.sqrt(distSq);\r\n const penetration = collider.radius - dist;\r\n Vector3.normalize(toParticle, toParticle);\r\n toParticle.scaleBy(penetration);\r\n Vector3.add(particlePos, toParticle, particlePos);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n Vector3.normalize(axis, axis);\r\n\r\n const toParticle = Vector3.sub(particlePos, collider.start, new Vector3());\r\n const projection = Vector3.dot(toParticle, axis);\r\n\r\n // Clamp projection to capsule length\r\n const t = Math.max(0, Math.min(axisLength, projection));\r\n\r\n // Closest point on capsule axis\r\n const closestPoint = Vector3.add(collider.start, Vector3.scale(axis, t, new Vector3()), new Vector3());\r\n\r\n // Check distance from closest point\r\n const toParticleFromAxis = Vector3.sub(particlePos, closestPoint, new Vector3());\r\n const distSq = toParticleFromAxis.magnitudeSq;\r\n const radiusSq = collider.radius * collider.radius;\r\n\r\n if (distSq < radiusSq && distSq > 0.0001) {\r\n const dist = Math.sqrt(distSq);\r\n const penetration = collider.radius - dist;\r\n Vector3.normalize(toParticleFromAxis, toParticleFromAxis);\r\n toParticleFromAxis.scaleBy(penetration);\r\n Vector3.add(particlePos, toParticleFromAxis, particlePos);\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Resolves collision between a particle and a plane collider\r\n * @returns true if collision occurred\r\n *\r\n * @public\r\n */\r\nexport function resolvePlaneCollision(particlePos: Vector3, collider: PlaneCollider): boolean {\r\n const toParticle = Vector3.sub(particlePos, collider.point, new Vector3());\r\n const distance = Vector3.dot(toParticle, collider.normal);\r\n\r\n if (distance < 0) {\r\n // Particle is below plane, push it up\r\n const correction = Vector3.scale(collider.normal, -distance, new Vector3());\r\n Vector3.add(particlePos, correction, particlePos);\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Updates collider position from its associated node\r\n *\r\n * @public\r\n */\r\nexport function updateColliderFromNode(collider: SpringCollider): void {\r\n if (!collider.node || !collider.enabled) {\r\n return;\r\n }\r\n\r\n const worldMatrix = collider.node.worldMatrix;\r\n\r\n switch (collider.type) {\r\n case 'sphere': {\r\n const sphere = collider as SphereCollider;\r\n if (sphere.localRadius !== undefined) {\r\n const currentScale = getUniformScale(worldMatrix);\r\n const refScale = Math.max(1e-6, sphere.localRadiusScaleRef ?? 1);\r\n sphere.radius = sphere.localRadius * (currentScale / refScale);\r\n }\r\n if (sphere.localOffset) {\r\n // Transform local offset to world space\r\n worldMatrix.transformPointAffine(sphere.localOffset, sphere.center);\r\n } else {\r\n // No local offset, just use node position\r\n sphere.center.x = worldMatrix.m03;\r\n sphere.center.y = worldMatrix.m13;\r\n sphere.center.z = worldMatrix.m23;\r\n }\r\n break;\r\n }\r\n\r\n case 'capsule': {\r\n const capsule = collider as CapsuleCollider;\r\n if (capsule.localRadius !== undefined) {\r\n const axisLocal =\r\n capsule.localStartOffset && capsule.localEndOffset\r\n ? Vector3.sub(capsule.localEndOffset, capsule.localStartOffset, new Vector3())\r\n : Vector3.axisPY();\r\n const currentScale = getPerpendicularScale(worldMatrix, axisLocal);\r\n const refScale = Math.max(1e-6, capsule.localRadiusScaleRef ?? 1);\r\n capsule.radius = capsule.localRadius * (currentScale / refScale);\r\n }\r\n if (capsule.localStartOffset && capsule.localEndOffset) {\r\n // Transform local offsets to world space\r\n worldMatrix.transformPointAffine(capsule.localStartOffset, capsule.start);\r\n worldMatrix.transformPointAffine(capsule.localEndOffset, capsule.end);\r\n } else {\r\n // No local offsets, just use node position for start\r\n capsule.start.x = worldMatrix.m03;\r\n capsule.start.y = worldMatrix.m13;\r\n capsule.start.z = worldMatrix.m23;\r\n }\r\n break;\r\n }\r\n\r\n case 'plane': {\r\n const plane = collider as PlaneCollider;\r\n if (plane.localPointOffset) {\r\n // Transform local offset to world space\r\n worldMatrix.transformPointAffine(plane.localPointOffset, plane.point);\r\n } else {\r\n // No local offset, just use node position\r\n plane.point.x = worldMatrix.m03;\r\n plane.point.y = worldMatrix.m13;\r\n plane.point.z = worldMatrix.m23;\r\n }\r\n\r\n if (plane.localNormal) {\r\n // Transform local normal to world space (rotation only)\r\n worldMatrix.transformVectorAffine(plane.localNormal, plane.normal).inplaceNormalize();\r\n }\r\n break;\r\n }\r\n }\r\n}\r\n\r\nfunction getUniformScale(worldMatrix: any): number {\r\n const sx = worldMatrix.transformVectorAffine(Vector3.axisPX(), new Vector3()).magnitude;\r\n const sy = worldMatrix.transformVectorAffine(Vector3.axisPY(), new Vector3()).magnitude;\r\n const sz = worldMatrix.transformVectorAffine(Vector3.axisPZ(), new Vector3()).magnitude;\r\n return Math.max(1e-6, (sx + sy + sz) / 3);\r\n}\r\n\r\nfunction getPerpendicularScale(worldMatrix: any, axisLocal: Vector3): number {\r\n const axis = axisLocal.magnitudeSq > 1e-8 ? axisLocal.clone().inplaceNormalize() : Vector3.axisPY();\r\n const helper = Math.abs(axis.y) < 0.99 ? Vector3.axisPY() : Vector3.axisPX();\r\n const u = Vector3.cross(axis, helper, new Vector3()).inplaceNormalize();\r\n const v = Vector3.cross(axis, u, new Vector3()).inplaceNormalize();\r\n const su = worldMatrix.transformVectorAffine(u, new Vector3()).magnitude;\r\n const sv = worldMatrix.transformVectorAffine(v, new Vector3()).magnitude;\r\n return Math.max(1e-6, (su + sv) * 0.5);\r\n}\r\n"],"names":["createSphereCollider","centerOrOffset","radius","node","worldMatrix","worldCenter","transformPointAffine","Vector3","type","center","localRadius","localRadiusScaleRef","getUniformScale","enabled","localOffset","clone","createCapsuleCollider","startOrOffset","endOrOffset","worldStart","worldEnd","start","end","getPerpendicularScale","sub","localStartOffset","localEndOffset","createPlaneCollider","pointOrOffset","normal","normalizedNormal","normalize","worldPoint","point","localPointOffset","localNormal","resolveSphereCollision","particlePos","collider","toParticle","distSq","magnitudeSq","radiusSq","dist","Math","sqrt","penetration","scaleBy","add","resolveCapsuleCollision","axis","axisLength","magnitude","projection","dot","t","max","min","closestPoint","scale","toParticleFromAxis","resolvePlaneCollision","distance","correction","updateColliderFromNode","sphere","undefined","currentScale","refScale","x","m03","y","m13","z","m23","capsule","axisLocal","axisPY","plane","transformVectorAffine","inplaceNormalize","sx","axisPX","sy","sz","axisPZ","helper","abs","u","cross","v","su","sv"],"mappings":"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"}
1
+ {"version":3,"file":"spring_collider.js","sources":["../../../src/animation/spring/spring_collider.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { Vector3 } from '@zephyr3d/base';\r\nimport type { SceneNode } from '../../scene/scene_node';\r\n\r\n/**\r\n * Base interface for spring collision shapes\r\n *\r\n * @public\r\n */\r\nexport interface SpringCollider {\r\n /** Type of collider */\r\n type: 'sphere' | 'capsule' | 'plane';\r\n /** Associated scene node (optional, for dynamic colliders) */\r\n node?: Nullable<SceneNode>;\r\n /** Whether this collider is enabled */\r\n enabled: boolean;\r\n}\r\n\r\n/**\r\n * Sphere collider for spring collision detection\r\n *\r\n * @public\r\n */\r\nexport interface SphereCollider extends SpringCollider {\r\n type: 'sphere';\r\n /** Center position in world space */\r\n center: Vector3;\r\n /** Radius of the sphere */\r\n radius: number;\r\n /** Authoring-space radius before node scaling (if node is set) */\r\n localRadius?: number;\r\n /** Baseline world scale captured at creation for backward compatibility */\r\n localRadiusScaleRef?: number;\r\n /** Local offset from node (if node is set) */\r\n localOffset?: Vector3;\r\n}\r\n\r\n/**\r\n * Capsule collider for spring collision detection\r\n *\r\n * @public\r\n */\r\nexport interface CapsuleCollider extends SpringCollider {\r\n type: 'capsule';\r\n /** Start point of the capsule axis in world space */\r\n start: Vector3;\r\n /** End point of the capsule axis in world space */\r\n end: Vector3;\r\n /** Radius of the capsule */\r\n radius: number;\r\n /** Authoring-space radius before node scaling (if node is set) */\r\n localRadius?: number;\r\n /** Baseline perpendicular scale captured at creation for backward compatibility */\r\n localRadiusScaleRef?: number;\r\n /** Local start offset from node (if node is set) */\r\n localStartOffset?: Vector3;\r\n /** Local end offset from node (if node is set) */\r\n localEndOffset?: Vector3;\r\n}\r\n\r\n/**\r\n * Plane collider for spring collision detection\r\n *\r\n * @public\r\n */\r\nexport interface PlaneCollider extends SpringCollider {\r\n type: 'plane';\r\n /** Point on the plane in world space */\r\n point: Vector3;\r\n /** Normal vector of the plane (should be normalized) */\r\n normal: Vector3;\r\n /** Local point offset from node (if node is set) */\r\n localPointOffset?: Vector3;\r\n /** Local normal direction (if node is set) */\r\n localNormal?: Vector3;\r\n}\r\n\r\n/**\r\n * Creates a sphere collider\r\n * @param centerOrOffset - Center position in world space, or local offset if node is provided\r\n * @param radius - Radius of the sphere\r\n * @param node - Optional scene node to attach to (if provided, centerOrOffset is treated as local offset)\r\n *\r\n * @public\r\n */\r\nexport function createSphereCollider(\r\n centerOrOffset: Vector3,\r\n radius: number,\r\n node?: SceneNode\r\n): SphereCollider {\r\n if (node) {\r\n // If node is provided, treat centerOrOffset as local offset\r\n const worldMatrix = node.worldMatrix;\r\n const worldCenter = worldMatrix.transformPointAffine(centerOrOffset, new Vector3());\r\n\r\n return {\r\n type: 'sphere',\r\n center: worldCenter,\r\n radius,\r\n localRadius: radius,\r\n localRadiusScaleRef: getUniformScale(worldMatrix),\r\n node,\r\n enabled: true,\r\n localOffset: centerOrOffset.clone()\r\n };\r\n } else {\r\n // No node, use as world position\r\n return {\r\n type: 'sphere',\r\n center: centerOrOffset.clone(),\r\n radius,\r\n node: null,\r\n enabled: true\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Creates a capsule collider\r\n * @param startOrOffset - Start point in world space, or local offset if node is provided\r\n * @param endOrOffset - End point in world space, or local offset if node is provided\r\n * @param radius - Radius of the capsule\r\n * @param node - Optional scene node to attach to (if provided, offsets are treated as local)\r\n *\r\n * @public\r\n */\r\nexport function createCapsuleCollider(\r\n startOrOffset: Vector3,\r\n endOrOffset: Vector3,\r\n radius: number,\r\n node?: SceneNode\r\n): CapsuleCollider {\r\n if (node) {\r\n // If node is provided, treat as local offsets\r\n const worldMatrix = node.worldMatrix;\r\n const worldStart = worldMatrix.transformPointAffine(startOrOffset, new Vector3());\r\n const worldEnd = worldMatrix.transformPointAffine(endOrOffset, new Vector3());\r\n\r\n return {\r\n type: 'capsule',\r\n start: worldStart,\r\n end: worldEnd,\r\n radius,\r\n localRadius: radius,\r\n localRadiusScaleRef: getPerpendicularScale(\r\n worldMatrix,\r\n Vector3.sub(endOrOffset, startOrOffset, new Vector3())\r\n ),\r\n node,\r\n enabled: true,\r\n localStartOffset: startOrOffset.clone(),\r\n localEndOffset: endOrOffset.clone()\r\n };\r\n } else {\r\n // No node, use as world positions\r\n return {\r\n type: 'capsule',\r\n start: startOrOffset.clone(),\r\n end: endOrOffset.clone(),\r\n radius,\r\n node: null,\r\n enabled: true\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Creates a plane collider\r\n * @param pointOrOffset - Point on plane in world space, or local offset if node is provided\r\n * @param normal - Normal vector (will be normalized)\r\n * @param node - Optional scene node to attach to (if provided, pointOrOffset is treated as local offset)\r\n *\r\n * @public\r\n */\r\nexport function createPlaneCollider(\r\n pointOrOffset: Vector3,\r\n normal: Vector3,\r\n node?: SceneNode\r\n): PlaneCollider {\r\n const normalizedNormal = new Vector3();\r\n Vector3.normalize(normal, normalizedNormal);\r\n\r\n if (node) {\r\n // If node is provided, treat as local offset\r\n const worldMatrix = node.worldMatrix;\r\n const worldPoint = worldMatrix.transformPointAffine(pointOrOffset, new Vector3());\r\n\r\n return {\r\n type: 'plane',\r\n point: worldPoint,\r\n normal: normalizedNormal.clone(),\r\n node,\r\n enabled: true,\r\n localPointOffset: pointOrOffset.clone(),\r\n localNormal: normalizedNormal.clone()\r\n };\r\n } else {\r\n // No node, use as world position\r\n return {\r\n type: 'plane',\r\n point: pointOrOffset.clone(),\r\n normal: normalizedNormal,\r\n node: null,\r\n enabled: true\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Resolves collision between a particle and a sphere collider\r\n * @returns true if collision occurred\r\n *\r\n * @public\r\n */\r\nexport function resolveSphereCollision(particlePos: Vector3, collider: SphereCollider): boolean {\r\n const toParticle = Vector3.sub(particlePos, collider.center, new Vector3());\r\n const distSq = toParticle.magnitudeSq;\r\n const radiusSq = collider.radius * collider.radius;\r\n\r\n if (distSq < radiusSq && distSq > 0.0001) {\r\n // Particle is inside sphere, push it out\r\n const dist = Math.sqrt(distSq);\r\n const penetration = collider.radius - dist;\r\n\r\n // Push particle to sphere surface\r\n Vector3.normalize(toParticle, toParticle);\r\n toParticle.scaleBy(penetration);\r\n Vector3.add(particlePos, toParticle, particlePos);\r\n\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Resolves collision between a particle and a capsule collider\r\n * @returns true if collision occurred\r\n *\r\n * @public\r\n */\r\nexport function resolveCapsuleCollision(particlePos: Vector3, collider: CapsuleCollider): boolean {\r\n // Find closest point on capsule axis\r\n const axis = Vector3.sub(collider.end, collider.start, new Vector3());\r\n const axisLength = axis.magnitude;\r\n\r\n if (axisLength < 0.0001) {\r\n // Degenerate capsule, treat as sphere\r\n const toParticle = Vector3.sub(particlePos, collider.start, new Vector3());\r\n const distSq = toParticle.magnitudeSq;\r\n const radiusSq = collider.radius * collider.radius;\r\n\r\n if (distSq < radiusSq && distSq > 0.0001) {\r\n const dist = Math.sqrt(distSq);\r\n const penetration = collider.radius - dist;\r\n Vector3.normalize(toParticle, toParticle);\r\n toParticle.scaleBy(penetration);\r\n Vector3.add(particlePos, toParticle, particlePos);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n Vector3.normalize(axis, axis);\r\n\r\n const toParticle = Vector3.sub(particlePos, collider.start, new Vector3());\r\n const projection = Vector3.dot(toParticle, axis);\r\n\r\n // Clamp projection to capsule length\r\n const t = Math.max(0, Math.min(axisLength, projection));\r\n\r\n // Closest point on capsule axis\r\n const closestPoint = Vector3.add(collider.start, Vector3.scale(axis, t, new Vector3()), new Vector3());\r\n\r\n // Check distance from closest point\r\n const toParticleFromAxis = Vector3.sub(particlePos, closestPoint, new Vector3());\r\n const distSq = toParticleFromAxis.magnitudeSq;\r\n const radiusSq = collider.radius * collider.radius;\r\n\r\n if (distSq < radiusSq && distSq > 0.0001) {\r\n const dist = Math.sqrt(distSq);\r\n const penetration = collider.radius - dist;\r\n Vector3.normalize(toParticleFromAxis, toParticleFromAxis);\r\n toParticleFromAxis.scaleBy(penetration);\r\n Vector3.add(particlePos, toParticleFromAxis, particlePos);\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Resolves collision between a particle and a plane collider\r\n * @returns true if collision occurred\r\n *\r\n * @public\r\n */\r\nexport function resolvePlaneCollision(particlePos: Vector3, collider: PlaneCollider): boolean {\r\n const toParticle = Vector3.sub(particlePos, collider.point, new Vector3());\r\n const distance = Vector3.dot(toParticle, collider.normal);\r\n\r\n if (distance < 0) {\r\n // Particle is below plane, push it up\r\n const correction = Vector3.scale(collider.normal, -distance, new Vector3());\r\n Vector3.add(particlePos, correction, particlePos);\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Updates collider position from its associated node\r\n *\r\n * @public\r\n */\r\nexport function updateColliderFromNode(collider: SpringCollider, runtimeNode?: Nullable<SceneNode>): void {\r\n const node = runtimeNode ?? collider.node;\r\n if (!node || !collider.enabled) {\r\n return;\r\n }\r\n\r\n const worldMatrix = node.worldMatrix;\r\n\r\n switch (collider.type) {\r\n case 'sphere': {\r\n const sphere = collider as SphereCollider;\r\n if (sphere.localRadius !== undefined) {\r\n const currentScale = getUniformScale(worldMatrix);\r\n const refScale = Math.max(1e-6, sphere.localRadiusScaleRef ?? 1);\r\n sphere.radius = sphere.localRadius * (currentScale / refScale);\r\n }\r\n if (sphere.localOffset) {\r\n // Transform local offset to world space\r\n worldMatrix.transformPointAffine(sphere.localOffset, sphere.center);\r\n } else {\r\n // No local offset, just use node position\r\n sphere.center.x = worldMatrix.m03;\r\n sphere.center.y = worldMatrix.m13;\r\n sphere.center.z = worldMatrix.m23;\r\n }\r\n break;\r\n }\r\n\r\n case 'capsule': {\r\n const capsule = collider as CapsuleCollider;\r\n if (capsule.localRadius !== undefined) {\r\n const axisLocal =\r\n capsule.localStartOffset && capsule.localEndOffset\r\n ? Vector3.sub(capsule.localEndOffset, capsule.localStartOffset, new Vector3())\r\n : Vector3.axisPY();\r\n const currentScale = getPerpendicularScale(worldMatrix, axisLocal);\r\n const refScale = Math.max(1e-6, capsule.localRadiusScaleRef ?? 1);\r\n capsule.radius = capsule.localRadius * (currentScale / refScale);\r\n }\r\n if (capsule.localStartOffset && capsule.localEndOffset) {\r\n // Transform local offsets to world space\r\n worldMatrix.transformPointAffine(capsule.localStartOffset, capsule.start);\r\n worldMatrix.transformPointAffine(capsule.localEndOffset, capsule.end);\r\n } else {\r\n // No local offsets, just use node position for start\r\n capsule.start.x = worldMatrix.m03;\r\n capsule.start.y = worldMatrix.m13;\r\n capsule.start.z = worldMatrix.m23;\r\n }\r\n break;\r\n }\r\n\r\n case 'plane': {\r\n const plane = collider as PlaneCollider;\r\n if (plane.localPointOffset) {\r\n // Transform local offset to world space\r\n worldMatrix.transformPointAffine(plane.localPointOffset, plane.point);\r\n } else {\r\n // No local offset, just use node position\r\n plane.point.x = worldMatrix.m03;\r\n plane.point.y = worldMatrix.m13;\r\n plane.point.z = worldMatrix.m23;\r\n }\r\n\r\n if (plane.localNormal) {\r\n // Transform local normal to world space (rotation only)\r\n worldMatrix.transformVectorAffine(plane.localNormal, plane.normal).inplaceNormalize();\r\n }\r\n break;\r\n }\r\n }\r\n}\r\n\r\nfunction getUniformScale(worldMatrix: any): number {\r\n const sx = worldMatrix.transformVectorAffine(Vector3.axisPX(), new Vector3()).magnitude;\r\n const sy = worldMatrix.transformVectorAffine(Vector3.axisPY(), new Vector3()).magnitude;\r\n const sz = worldMatrix.transformVectorAffine(Vector3.axisPZ(), new Vector3()).magnitude;\r\n return Math.max(1e-6, (sx + sy + sz) / 3);\r\n}\r\n\r\nfunction getPerpendicularScale(worldMatrix: any, axisLocal: Vector3): number {\r\n const axis = axisLocal.magnitudeSq > 1e-8 ? axisLocal.clone().inplaceNormalize() : Vector3.axisPY();\r\n const helper = Math.abs(axis.y) < 0.99 ? Vector3.axisPY() : Vector3.axisPX();\r\n const u = Vector3.cross(axis, helper, new Vector3()).inplaceNormalize();\r\n const v = Vector3.cross(axis, u, new Vector3()).inplaceNormalize();\r\n const su = worldMatrix.transformVectorAffine(u, new Vector3()).magnitude;\r\n const sv = worldMatrix.transformVectorAffine(v, new Vector3()).magnitude;\r\n return Math.max(1e-6, (su + sv) * 0.5);\r\n}\r\n"],"names":["createSphereCollider","centerOrOffset","radius","node","worldMatrix","worldCenter","transformPointAffine","Vector3","type","center","localRadius","localRadiusScaleRef","getUniformScale","enabled","localOffset","clone","createCapsuleCollider","startOrOffset","endOrOffset","worldStart","worldEnd","start","end","getPerpendicularScale","sub","localStartOffset","localEndOffset","createPlaneCollider","pointOrOffset","normal","normalizedNormal","normalize","worldPoint","point","localPointOffset","localNormal","resolveSphereCollision","particlePos","collider","toParticle","distSq","magnitudeSq","radiusSq","dist","Math","sqrt","penetration","scaleBy","add","resolveCapsuleCollision","axis","axisLength","magnitude","projection","dot","t","max","min","closestPoint","scale","toParticleFromAxis","resolvePlaneCollision","distance","correction","updateColliderFromNode","runtimeNode","sphere","undefined","currentScale","refScale","x","m03","y","m13","z","m23","capsule","axisLocal","axisPY","plane","transformVectorAffine","inplaceNormalize","sx","axisPX","sy","sz","axisPZ","helper","abs","u","cross","v","su","sv"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ const ROTATION_MATCH_EPSILON_SQ = 1e-10;
2
+ function rotationsMatch(a, b) {
3
+ const direct = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + (a.z - b.z) * (a.z - b.z) + (a.w - b.w) * (a.w - b.w);
4
+ const negated = (a.x + b.x) * (a.x + b.x) + (a.y + b.y) * (a.y + b.y) + (a.z + b.z) * (a.z + b.z) + (a.w + b.w) * (a.w + b.w);
5
+ return Math.min(direct, negated) <= ROTATION_MATCH_EPSILON_SQ;
6
+ }
7
+ /** Keeps spring output from becoming the next frame's unanimated input pose. */ class SpringNodePoseTracker {
8
+ _states = new Map();
9
+ restoreInputPose() {
10
+ for (const [node, state] of this._states){
11
+ if (rotationsMatch(node.rotation, state.appliedRotation)) {
12
+ node.rotation.set(state.inputRotation);
13
+ } else {
14
+ // Animation, mocap, IK or another upstream system supplied a new pose.
15
+ state.inputRotation.set(node.rotation);
16
+ }
17
+ }
18
+ }
19
+ recordAppliedRotation(node, inputRotation, appliedRotation) {
20
+ const state = this._states.get(node);
21
+ if (state) {
22
+ state.inputRotation.set(inputRotation);
23
+ state.appliedRotation.set(appliedRotation);
24
+ } else {
25
+ this._states.set(node, {
26
+ inputRotation: inputRotation.clone(),
27
+ appliedRotation: appliedRotation.clone()
28
+ });
29
+ }
30
+ }
31
+ clear(restoreInputPose) {
32
+ if (restoreInputPose) {
33
+ this.restoreInputPose();
34
+ }
35
+ this._states.clear();
36
+ }
37
+ }
38
+
39
+ export { SpringNodePoseTracker };
40
+ //# sourceMappingURL=spring_node_pose_tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spring_node_pose_tracker.js","sources":["../../../src/animation/spring/spring_node_pose_tracker.ts"],"sourcesContent":["import type { Quaternion } from '@zephyr3d/base';\r\nimport type { SceneNode } from '../../scene/scene_node';\r\n\r\ntype SpringNodePoseState = {\r\n inputRotation: Quaternion;\r\n appliedRotation: Quaternion;\r\n};\r\n\r\nconst ROTATION_MATCH_EPSILON_SQ = 1e-10;\r\n\r\nfunction rotationsMatch(a: Quaternion, b: Quaternion): boolean {\r\n const direct =\r\n (a.x - b.x) * (a.x - b.x) +\r\n (a.y - b.y) * (a.y - b.y) +\r\n (a.z - b.z) * (a.z - b.z) +\r\n (a.w - b.w) * (a.w - b.w);\r\n const negated =\r\n (a.x + b.x) * (a.x + b.x) +\r\n (a.y + b.y) * (a.y + b.y) +\r\n (a.z + b.z) * (a.z + b.z) +\r\n (a.w + b.w) * (a.w + b.w);\r\n return Math.min(direct, negated) <= ROTATION_MATCH_EPSILON_SQ;\r\n}\r\n\r\n/** Keeps spring output from becoming the next frame's unanimated input pose. */\r\nexport class SpringNodePoseTracker {\r\n private _states = new Map<SceneNode, SpringNodePoseState>();\r\n\r\n restoreInputPose(): void {\r\n for (const [node, state] of this._states) {\r\n if (rotationsMatch(node.rotation, state.appliedRotation)) {\r\n node.rotation.set(state.inputRotation);\r\n } else {\r\n // Animation, mocap, IK or another upstream system supplied a new pose.\r\n state.inputRotation.set(node.rotation);\r\n }\r\n }\r\n }\r\n\r\n recordAppliedRotation(node: SceneNode, inputRotation: Quaternion, appliedRotation: Quaternion): void {\r\n const state = this._states.get(node);\r\n if (state) {\r\n state.inputRotation.set(inputRotation);\r\n state.appliedRotation.set(appliedRotation);\r\n } else {\r\n this._states.set(node, {\r\n inputRotation: inputRotation.clone(),\r\n appliedRotation: appliedRotation.clone()\r\n });\r\n }\r\n }\r\n\r\n clear(restoreInputPose: boolean): void {\r\n if (restoreInputPose) {\r\n this.restoreInputPose();\r\n }\r\n this._states.clear();\r\n }\r\n}\r\n"],"names":["ROTATION_MATCH_EPSILON_SQ","rotationsMatch","a","b","direct","x","y","z","w","negated","Math","min","SpringNodePoseTracker","_states","Map","restoreInputPose","node","state","rotation","appliedRotation","set","inputRotation","recordAppliedRotation","get","clone","clear"],"mappings":"AAQA,MAAMA,yBAA4B,GAAA,KAAA;AAElC,SAASC,cAAAA,CAAeC,CAAa,EAAEC,CAAa,EAAA;AAClD,IAAA,MAAMC,MACJ,GAACF,CAAAA,CAAAA,CAAEG,CAAC,GAAGF,CAAEE,CAAAA,CAAC,KAAKH,CAAAA,CAAEG,CAAC,GAAGF,CAAAA,CAAEE,CAAAA,CACvB,GAACH,CAAAA,CAAAA,CAAEI,CAAC,GAAGH,CAAAA,CAAEG,CAAAA,KAAMJ,CAAEI,CAAAA,CAAC,GAAGH,CAAEG,CAAAA,CAAC,CAADA,GACvB,CAACJ,CAAEK,CAAAA,CAAC,GAAGJ,CAAEI,CAAAA,CAAC,KAAKL,CAAAA,CAAEK,CAAC,GAAGJ,EAAEI,CAAAA,CACvB,GAACL,CAAAA,CAAAA,CAAEM,CAAC,GAAGL,EAAEK,CAAAA,KAAMN,CAAEM,CAAAA,CAAC,GAAGL,CAAAA,CAAEK,CAAC,CAADA;AACzB,IAAA,MAAMC,OACJ,GAACP,CAAAA,CAAAA,CAAEG,CAAC,GAAGF,CAAEE,CAAAA,CAAC,KAAKH,CAAAA,CAAEG,CAAC,GAAGF,CAAAA,CAAEE,CAAAA,CACvB,GAACH,CAAAA,CAAAA,CAAEI,CAAC,GAAGH,CAAAA,CAAEG,CAAAA,KAAMJ,CAAEI,CAAAA,CAAC,GAAGH,CAAEG,CAAAA,CAAC,CAADA,GACvB,CAACJ,CAAEK,CAAAA,CAAC,GAAGJ,CAAEI,CAAAA,CAAC,KAAKL,CAAAA,CAAEK,CAAC,GAAGJ,EAAEI,CAAAA,CACvB,GAACL,CAAAA,CAAAA,CAAEM,CAAC,GAAGL,EAAEK,CAAAA,KAAMN,CAAEM,CAAAA,CAAC,GAAGL,CAAAA,CAAEK,CAAC,CAADA;AACzB,IAAA,OAAOE,IAAKC,CAAAA,GAAG,CAACP,MAAAA,EAAQK,OAAYT,CAAAA,IAAAA,yBAAAA;AACtC;AAEA,iFACO,MAAMY,qBAAAA,CAAAA;AACHC,IAAAA,OAAAA,GAAU,IAAIC,GAAsC,EAAA;IAE5DC,gBAAyB,GAAA;QACvB,KAAK,MAAM,CAACC,IAAMC,EAAAA,KAAAA,CAAM,IAAI,IAAI,CAACJ,OAAO,CAAE;AACxC,YAAA,IAAIZ,eAAee,IAAKE,CAAAA,QAAQ,EAAED,KAAAA,CAAME,eAAe,CAAG,EAAA;AACxDH,gBAAAA,IAAAA,CAAKE,QAAQ,CAACE,GAAG,CAACH,MAAMI,aAAa,CAAA;aAChC,MAAA;;AAELJ,gBAAAA,KAAAA,CAAMI,aAAa,CAACD,GAAG,CAACJ,KAAKE,QAAQ,CAAA;AACvC;AACF;AACF;AAEAI,IAAAA,qBAAAA,CAAsBN,IAAe,EAAEK,aAAyB,EAAEF,eAA2B,EAAQ;AACnG,QAAA,MAAMF,QAAQ,IAAI,CAACJ,OAAO,CAACU,GAAG,CAACP,IAAAA,CAAAA;AAC/B,QAAA,IAAIC,KAAO,EAAA;YACTA,KAAMI,CAAAA,aAAa,CAACD,GAAG,CAACC,aAAAA,CAAAA;YACxBJ,KAAME,CAAAA,eAAe,CAACC,GAAG,CAACD,eAAAA,CAAAA;SACrB,MAAA;AACL,YAAA,IAAI,CAACN,OAAO,CAACO,GAAG,CAACJ,IAAM,EAAA;AACrBK,gBAAAA,aAAAA,EAAeA,cAAcG,KAAK,EAAA;AAClCL,gBAAAA,eAAAA,EAAiBA,gBAAgBK,KAAK;AACxC,aAAA,CAAA;AACF;AACF;AAEAC,IAAAA,KAAAA,CAAMV,gBAAyB,EAAQ;AACrC,QAAA,IAAIA,gBAAkB,EAAA;AACpB,YAAA,IAAI,CAACA,gBAAgB,EAAA;AACvB;QACA,IAAI,CAACF,OAAO,CAACY,KAAK,EAAA;AACpB;AACF;;;;"}
@@ -13,6 +13,8 @@
13
13
  damping: options?.damping ?? 0.95,
14
14
  fixed: options?.fixed ?? false,
15
15
  node: options?.node ?? null,
16
+ anchorNode: options?.anchorNode ?? null,
17
+ anchorOffset: options?.anchorOffset?.clone() ?? null,
16
18
  lastFramePosition: position.clone()
17
19
  };
18
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"spring_particle.js","sources":["../../../src/animation/spring/spring_particle.ts"],"sourcesContent":["import type { Vector3, Quaternion, Nullable } from '@zephyr3d/base';\r\nimport type { SceneNode } from '../../scene/scene_node';\r\n\r\n/**\r\n * Represents a particle in the spring system\r\n *\r\n * @public\r\n */\r\nexport interface SpringParticle {\r\n /** Current position in world space */\r\n position: Vector3;\r\n /** Previous position for Verlet integration */\r\n prevPosition: Vector3;\r\n /** Original position for reset */\r\n originalPosition: Vector3;\r\n /** Animated (target) position for pose preservation */\r\n animPosition: Vector3;\r\n /** Original world rotation (for calculating rotation delta) */\r\n originalRotation: Quaternion | null;\r\n /** Mass of the particle (affects inertia) */\r\n mass: number;\r\n /** Damping coefficient [0-1] (0 = no damping, 1 = full damping) */\r\n damping: number;\r\n /** Whether this particle is fixed (anchor point) */\r\n fixed: boolean;\r\n /** Associated scene node (optional) */\r\n node: Nullable<SceneNode>;\r\n /** Previous frame position (used to calculate velocity for inertial forces) */\r\n lastFramePosition: Vector3;\r\n /** Position history for rotation center estimation (for fixed particles) */\r\n positionHistory?: Vector3[];\r\n}\r\n\r\n/**\r\n * Creates a new spring particle\r\n *\r\n * @public\r\n */\r\nexport function createSpringParticle(\r\n position: Vector3,\r\n options?: {\r\n mass?: number;\r\n damping?: number;\r\n fixed?: boolean;\r\n node?: SceneNode;\r\n originalRotation?: Quaternion;\r\n }\r\n): SpringParticle {\r\n return {\r\n position: position.clone(),\r\n prevPosition: position.clone(),\r\n originalPosition: position.clone(),\r\n animPosition: position.clone(),\r\n originalRotation: options?.originalRotation?.clone() ?? null,\r\n mass: options?.mass ?? 1.0,\r\n damping: options?.damping ?? 0.95,\r\n fixed: options?.fixed ?? false,\r\n node: options?.node ?? null,\r\n lastFramePosition: position.clone()\r\n };\r\n}\r\n"],"names":["createSpringParticle","position","options","clone","prevPosition","originalPosition","animPosition","originalRotation","mass","damping","fixed","node","lastFramePosition"],"mappings":"AAiCA;;;;AAIC,IACM,SAASA,oBACdC,CAAAA,QAAiB,EACjBC,OAMC,EAAA;IAED,OAAO;AACLD,QAAAA,QAAAA,EAAUA,SAASE,KAAK,EAAA;AACxBC,QAAAA,YAAAA,EAAcH,SAASE,KAAK,EAAA;AAC5BE,QAAAA,gBAAAA,EAAkBJ,SAASE,KAAK,EAAA;AAChCG,QAAAA,YAAAA,EAAcL,SAASE,KAAK,EAAA;QAC5BI,gBAAkBL,EAAAA,OAAAA,EAASK,kBAAkBJ,KAAW,EAAA,IAAA,IAAA;AACxDK,QAAAA,IAAAA,EAAMN,SAASM,IAAQ,IAAA,GAAA;AACvBC,QAAAA,OAAAA,EAASP,SAASO,OAAW,IAAA,IAAA;AAC7BC,QAAAA,KAAAA,EAAOR,SAASQ,KAAS,IAAA,KAAA;AACzBC,QAAAA,IAAAA,EAAMT,SAASS,IAAQ,IAAA,IAAA;AACvBC,QAAAA,iBAAAA,EAAmBX,SAASE,KAAK;AACnC,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"spring_particle.js","sources":["../../../src/animation/spring/spring_particle.ts"],"sourcesContent":["import type { Vector3, Quaternion, Nullable } from '@zephyr3d/base';\r\nimport type { SceneNode } from '../../scene/scene_node';\r\n\r\n/**\r\n * Represents a particle in the spring system\r\n *\r\n * @public\r\n */\r\nexport interface SpringParticle {\r\n /** Current position in world space */\r\n position: Vector3;\r\n /** Previous position for Verlet integration */\r\n prevPosition: Vector3;\r\n /** Original position for reset */\r\n originalPosition: Vector3;\r\n /** Animated (target) position for pose preservation */\r\n animPosition: Vector3;\r\n /** Original world rotation (for calculating rotation delta) */\r\n originalRotation: Quaternion | null;\r\n /** Mass of the particle (affects inertia) */\r\n mass: number;\r\n /** Damping coefficient [0-1] (0 = no damping, 1 = full damping) */\r\n damping: number;\r\n /** Whether this particle is fixed (anchor point) */\r\n fixed: boolean;\r\n /** Associated scene node (optional) */\r\n node: Nullable<SceneNode>;\r\n /** Optional alternate anchor node used as the fixed-position source */\r\n anchorNode?: Nullable<SceneNode>;\r\n /** Optional local-space offset evaluated from anchorNode */\r\n anchorOffset?: Nullable<Vector3>;\r\n /** Previous frame position (used to calculate velocity for inertial forces) */\r\n lastFramePosition: Vector3;\r\n /** Position history for rotation center estimation (for fixed particles) */\r\n positionHistory?: Vector3[];\r\n}\r\n\r\n/**\r\n * Creates a new spring particle\r\n *\r\n * @public\r\n */\r\nexport function createSpringParticle(\r\n position: Vector3,\r\n options?: {\r\n mass?: number;\r\n damping?: number;\r\n fixed?: boolean;\r\n node?: SceneNode;\r\n anchorNode?: SceneNode;\r\n anchorOffset?: Vector3;\r\n originalRotation?: Quaternion;\r\n }\r\n): SpringParticle {\r\n return {\r\n position: position.clone(),\r\n prevPosition: position.clone(),\r\n originalPosition: position.clone(),\r\n animPosition: position.clone(),\r\n originalRotation: options?.originalRotation?.clone() ?? null,\r\n mass: options?.mass ?? 1.0,\r\n damping: options?.damping ?? 0.95,\r\n fixed: options?.fixed ?? false,\r\n node: options?.node ?? null,\r\n anchorNode: options?.anchorNode ?? null,\r\n anchorOffset: options?.anchorOffset?.clone() ?? null,\r\n lastFramePosition: position.clone()\r\n };\r\n}\r\n"],"names":["createSpringParticle","position","options","clone","prevPosition","originalPosition","animPosition","originalRotation","mass","damping","fixed","node","anchorNode","anchorOffset","lastFramePosition"],"mappings":"AAqCA;;;;AAIC,IACM,SAASA,oBACdC,CAAAA,QAAiB,EACjBC,OAQC,EAAA;IAED,OAAO;AACLD,QAAAA,QAAAA,EAAUA,SAASE,KAAK,EAAA;AACxBC,QAAAA,YAAAA,EAAcH,SAASE,KAAK,EAAA;AAC5BE,QAAAA,gBAAAA,EAAkBJ,SAASE,KAAK,EAAA;AAChCG,QAAAA,YAAAA,EAAcL,SAASE,KAAK,EAAA;QAC5BI,gBAAkBL,EAAAA,OAAAA,EAASK,kBAAkBJ,KAAW,EAAA,IAAA,IAAA;AACxDK,QAAAA,IAAAA,EAAMN,SAASM,IAAQ,IAAA,GAAA;AACvBC,QAAAA,OAAAA,EAASP,SAASO,OAAW,IAAA,IAAA;AAC7BC,QAAAA,KAAAA,EAAOR,SAASQ,KAAS,IAAA,KAAA;AACzBC,QAAAA,IAAAA,EAAMT,SAASS,IAAQ,IAAA,IAAA;AACvBC,QAAAA,UAAAA,EAAYV,SAASU,UAAc,IAAA,IAAA;QACnCC,YAAcX,EAAAA,OAAAA,EAASW,cAAcV,KAAW,EAAA,IAAA,IAAA;AAChDW,QAAAA,iBAAAA,EAAmBb,SAASE,KAAK;AACnC,KAAA;AACF;;;;"}