@zephyr3d/scene 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. package/dist/animation/animation.js +4 -33
  2. package/dist/animation/animation.js.map +1 -1
  3. package/dist/animation/animationset.js +24 -11
  4. package/dist/animation/animationset.js.map +1 -1
  5. package/dist/animation/animationtrack.js +1 -0
  6. package/dist/animation/animationtrack.js.map +1 -1
  7. package/dist/animation/eulerrotationtrack.js +0 -1
  8. package/dist/animation/eulerrotationtrack.js.map +1 -1
  9. package/dist/animation/ik/ccd_solver.js +372 -0
  10. package/dist/animation/ik/ccd_solver.js.map +1 -0
  11. package/dist/animation/ik/fabrik_solver.js +399 -0
  12. package/dist/animation/ik/fabrik_solver.js.map +1 -0
  13. package/dist/animation/ik/ik_angle_constraint.js +181 -0
  14. package/dist/animation/ik/ik_angle_constraint.js.map +1 -0
  15. package/dist/animation/ik/ik_chain.js +163 -0
  16. package/dist/animation/ik/ik_chain.js.map +1 -0
  17. package/dist/animation/ik/ik_chain_builder.js +68 -0
  18. package/dist/animation/ik/ik_chain_builder.js.map +1 -0
  19. package/dist/animation/ik/ik_constraint.js +25 -0
  20. package/dist/animation/ik/ik_constraint.js.map +1 -0
  21. package/dist/animation/ik/ik_pole_constraint.js +123 -0
  22. package/dist/animation/ik/ik_pole_constraint.js.map +1 -0
  23. package/dist/animation/ik/ik_solver.js +48 -0
  24. package/dist/animation/ik/ik_solver.js.map +1 -0
  25. package/dist/animation/ik/ik_track.js +96 -0
  26. package/dist/animation/ik/ik_track.js.map +1 -0
  27. package/dist/animation/ik/ik_utils.js +270 -0
  28. package/dist/animation/ik/ik_utils.js.map +1 -0
  29. package/dist/animation/ik/two_bone_ik_solver.js +332 -0
  30. package/dist/animation/ik/two_bone_ik_solver.js.map +1 -0
  31. package/dist/animation/ik_modifier.js +61 -0
  32. package/dist/animation/ik_modifier.js.map +1 -0
  33. package/dist/animation/ik_postprocessor.js +71 -0
  34. package/dist/animation/ik_postprocessor.js.map +1 -0
  35. package/dist/animation/manual_transform_processor.js +156 -0
  36. package/dist/animation/manual_transform_processor.js.map +1 -0
  37. package/dist/animation/morphtarget.js +7 -1
  38. package/dist/animation/morphtarget.js.map +1 -1
  39. package/dist/animation/morphtrack.js +3 -3
  40. package/dist/animation/morphtrack.js.map +1 -1
  41. package/dist/animation/proptrack.js +37 -41
  42. package/dist/animation/proptrack.js.map +1 -1
  43. package/dist/animation/rotationtrack.js +0 -1
  44. package/dist/animation/rotationtrack.js.map +1 -1
  45. package/dist/animation/scaletrack.js +0 -1
  46. package/dist/animation/scaletrack.js.map +1 -1
  47. package/dist/animation/skeleton.js +57 -60
  48. package/dist/animation/skeleton.js.map +1 -1
  49. package/dist/animation/skeleton_modifier.js +38 -0
  50. package/dist/animation/skeleton_modifier.js.map +1 -0
  51. package/dist/animation/skeleton_postprocessor.js +50 -0
  52. package/dist/animation/skeleton_postprocessor.js.map +1 -0
  53. package/dist/animation/spring/multi_chain_spring_system.js +503 -0
  54. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -0
  55. package/dist/animation/spring/spring_chain.js +103 -0
  56. package/dist/animation/spring/spring_chain.js.map +1 -0
  57. package/dist/animation/spring/spring_collider.js +247 -0
  58. package/dist/animation/spring/spring_collider.js.map +1 -0
  59. package/dist/animation/spring/spring_constraint.js +21 -0
  60. package/dist/animation/spring/spring_constraint.js.map +1 -0
  61. package/dist/animation/spring/spring_particle.js +20 -0
  62. package/dist/animation/spring/spring_particle.js.map +1 -0
  63. package/dist/animation/spring/spring_system.js +526 -0
  64. package/dist/animation/spring/spring_system.js.map +1 -0
  65. package/dist/animation/spring_modifier.js +45 -0
  66. package/dist/animation/spring_modifier.js.map +1 -0
  67. package/dist/animation/spring_postprocessor.js +54 -0
  68. package/dist/animation/spring_postprocessor.js.map +1 -0
  69. package/dist/animation/translationtrack.js +0 -1
  70. package/dist/animation/translationtrack.js.map +1 -1
  71. package/dist/app/api.js +13 -4
  72. package/dist/app/api.js.map +1 -1
  73. package/dist/app/app.js +13 -1
  74. package/dist/app/app.js.map +1 -1
  75. package/dist/app/engine.js +33 -45
  76. package/dist/app/engine.js.map +1 -1
  77. package/dist/app/inputmgr.js.map +1 -1
  78. package/dist/app/runtimescript.js.map +1 -1
  79. package/dist/app/screen.js +318 -0
  80. package/dist/app/screen.js.map +1 -0
  81. package/dist/app/scriptingsystem.js +10 -6
  82. package/dist/app/scriptingsystem.js.map +1 -1
  83. package/dist/app/scriptregistry.js +11 -22
  84. package/dist/app/scriptregistry.js.map +1 -1
  85. package/dist/asset/assetmanager.js +79 -58
  86. package/dist/asset/assetmanager.js.map +1 -1
  87. package/dist/asset/builtin.js +5 -5
  88. package/dist/asset/builtin.js.map +1 -1
  89. package/dist/asset/loaders/dds/dds.js +6 -2
  90. package/dist/asset/loaders/dds/dds.js.map +1 -1
  91. package/dist/asset/loaders/dds/dds_loader.js +1 -1
  92. package/dist/asset/loaders/dds/dds_loader.js.map +1 -1
  93. package/dist/asset/loaders/gltf/gltf_loader.js +14 -6
  94. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  95. package/dist/asset/loaders/gltf/helpers.js +6 -2
  96. package/dist/asset/loaders/gltf/helpers.js.map +1 -1
  97. package/dist/asset/loaders/hdr/hdr.js +22 -15
  98. package/dist/asset/loaders/hdr/hdr.js.map +1 -1
  99. package/dist/asset/loaders/image/tga_Loader.js +2 -1
  100. package/dist/asset/loaders/image/tga_Loader.js.map +1 -1
  101. package/dist/asset/loaders/image/webimage_loader.js.map +1 -1
  102. package/dist/asset/loaders/loader.js +2 -2
  103. package/dist/asset/loaders/loader.js.map +1 -1
  104. package/dist/asset/model.js +9 -5
  105. package/dist/asset/model.js.map +1 -1
  106. package/dist/blitter/bilateralblur.js.map +1 -1
  107. package/dist/blitter/blitter.js +9 -11
  108. package/dist/blitter/blitter.js.map +1 -1
  109. package/dist/blitter/box.js +0 -1
  110. package/dist/blitter/box.js.map +1 -1
  111. package/dist/blitter/copy.js.map +1 -1
  112. package/dist/blitter/gaussianblur.js.map +1 -1
  113. package/dist/camera/base.js +1 -3
  114. package/dist/camera/base.js.map +1 -1
  115. package/dist/camera/camera.js +121 -37
  116. package/dist/camera/camera.js.map +1 -1
  117. package/dist/camera/fps.js +19 -17
  118. package/dist/camera/fps.js.map +1 -1
  119. package/dist/camera/orbit.js +45 -43
  120. package/dist/camera/orbit.js.map +1 -1
  121. package/dist/camera/orthocamera.js +27 -21
  122. package/dist/camera/orthocamera.js.map +1 -1
  123. package/dist/camera/perspectivecamera.js +28 -19
  124. package/dist/camera/perspectivecamera.js.map +1 -1
  125. package/dist/index.d.ts +15802 -15577
  126. package/dist/index.js +33 -11
  127. package/dist/index.js.map +1 -1
  128. package/dist/material/blinn.js.map +1 -1
  129. package/dist/material/grassmaterial.js.map +1 -1
  130. package/dist/material/lambert.js.map +1 -1
  131. package/dist/material/material.js +11 -5
  132. package/dist/material/material.js.map +1 -1
  133. package/dist/material/meshmaterial.js +10 -9
  134. package/dist/material/meshmaterial.js.map +1 -1
  135. package/dist/material/mixins/albedocolor.js.map +1 -1
  136. package/dist/material/mixins/foliage.js.map +1 -1
  137. package/dist/material/mixins/lightmodel/blinnphong.js +66 -4
  138. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  139. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  140. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +7 -0
  141. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  142. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  143. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  144. package/dist/material/mixins/lit.js +3 -3
  145. package/dist/material/mixins/lit.js.map +1 -1
  146. package/dist/material/mixins/pbr/brdf.js.map +1 -1
  147. package/dist/material/mixins/pbr/common.js.map +1 -1
  148. package/dist/material/mixins/texture.js +3 -0
  149. package/dist/material/mixins/texture.js.map +1 -1
  150. package/dist/material/mixins/vertexcolor.js.map +1 -1
  151. package/dist/material/particle.js.map +1 -1
  152. package/dist/material/pbrblueprint.js +180 -22
  153. package/dist/material/pbrblueprint.js.map +1 -1
  154. package/dist/material/pbrmr.js.map +1 -1
  155. package/dist/material/pbrsg.js.map +1 -1
  156. package/dist/material/shader/helper.js +41 -56
  157. package/dist/material/shader/helper.js.map +1 -1
  158. package/dist/material/sprite.js +301 -0
  159. package/dist/material/sprite.js.map +1 -0
  160. package/dist/material/sprite3d.js +301 -0
  161. package/dist/material/sprite3d.js.map +1 -0
  162. package/dist/material/sprite3d_std.js +116 -0
  163. package/dist/material/sprite3d_std.js.map +1 -0
  164. package/dist/material/sprite3dblueprint.js +235 -0
  165. package/dist/material/sprite3dblueprint.js.map +1 -0
  166. package/dist/material/sprite_std.js +116 -0
  167. package/dist/material/sprite_std.js.map +1 -0
  168. package/dist/material/spriteblueprint.js +235 -0
  169. package/dist/material/spriteblueprint.js.map +1 -0
  170. package/dist/material/terrain-cm.js +0 -1
  171. package/dist/material/terrain-cm.js.map +1 -1
  172. package/dist/material/unlit.js.map +1 -1
  173. package/dist/material/water.js.map +1 -1
  174. package/dist/posteffect/bloom.js.map +1 -1
  175. package/dist/posteffect/compositor.js.map +1 -1
  176. package/dist/posteffect/fxaa.js.map +1 -1
  177. package/dist/posteffect/grayscale.js.map +1 -1
  178. package/dist/posteffect/motionblur.js.map +1 -1
  179. package/dist/posteffect/posteffect.js.map +1 -1
  180. package/dist/posteffect/sao.js.map +1 -1
  181. package/dist/posteffect/ssr.js +7 -5
  182. package/dist/posteffect/ssr.js.map +1 -1
  183. package/dist/posteffect/taa.js.map +1 -1
  184. package/dist/posteffect/tonemap.js.map +1 -1
  185. package/dist/render/abuffer_oit.js +8 -6
  186. package/dist/render/abuffer_oit.js.map +1 -1
  187. package/dist/render/clipmap.js +0 -10
  188. package/dist/render/clipmap.js.map +1 -1
  189. package/dist/render/cluster_light.js +4 -4
  190. package/dist/render/cluster_light.js.map +1 -1
  191. package/dist/render/cull_visitor.js +15 -17
  192. package/dist/render/cull_visitor.js.map +1 -1
  193. package/dist/render/depthpass.js +3 -4
  194. package/dist/render/depthpass.js.map +1 -1
  195. package/dist/render/drawable.js +15 -0
  196. package/dist/render/drawable.js.map +1 -0
  197. package/dist/render/drawable_mixin.js +8 -4
  198. package/dist/render/drawable_mixin.js.map +1 -1
  199. package/dist/render/envlight.js.map +1 -1
  200. package/dist/render/fbm_wavegenerator.js +3 -1
  201. package/dist/render/fbm_wavegenerator.js.map +1 -1
  202. package/dist/render/fft_wavegenerator.js +67 -64
  203. package/dist/render/fft_wavegenerator.js.map +1 -1
  204. package/dist/render/fullscreenquad.js.map +1 -1
  205. package/dist/render/gerstner_wavegenerator.js +3 -1
  206. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  207. package/dist/render/globalbindgroup_allocator.js +3 -1
  208. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  209. package/dist/render/hzb.js +1 -2
  210. package/dist/render/hzb.js.map +1 -1
  211. package/dist/render/lightpass.js +13 -13
  212. package/dist/render/lightpass.js.map +1 -1
  213. package/dist/render/objectcolorpass.js +4 -7
  214. package/dist/render/objectcolorpass.js.map +1 -1
  215. package/dist/render/primitive.js +4 -5
  216. package/dist/render/primitive.js.map +1 -1
  217. package/dist/render/render_queue.js +10 -5
  218. package/dist/render/render_queue.js.map +1 -1
  219. package/dist/render/renderer.js +16 -22
  220. package/dist/render/renderer.js.map +1 -1
  221. package/dist/render/renderpass.js +27 -52
  222. package/dist/render/renderpass.js.map +1 -1
  223. package/dist/render/rendertarget.js +5 -0
  224. package/dist/render/rendertarget.js.map +1 -0
  225. package/dist/render/screenrendertarget.js +56 -0
  226. package/dist/render/screenrendertarget.js.map +1 -0
  227. package/dist/render/shadowmap_pass.js +4 -5
  228. package/dist/render/shadowmap_pass.js.map +1 -1
  229. package/dist/render/sky.js +16 -14
  230. package/dist/render/sky.js.map +1 -1
  231. package/dist/render/weightedblended_oit.js.map +1 -1
  232. package/dist/scene/basesprite.js +296 -0
  233. package/dist/scene/basesprite.js.map +1 -0
  234. package/dist/scene/batchgroup.js +4 -2
  235. package/dist/scene/batchgroup.js.map +1 -1
  236. package/dist/scene/environment.js +9 -10
  237. package/dist/scene/environment.js.map +1 -1
  238. package/dist/scene/graph_node.js.map +1 -1
  239. package/dist/scene/light.js +22 -4
  240. package/dist/scene/light.js.map +1 -1
  241. package/dist/scene/mesh.js +96 -26
  242. package/dist/scene/mesh.js.map +1 -1
  243. package/dist/scene/octree.js.map +1 -1
  244. package/dist/scene/particlesys.js +25 -22
  245. package/dist/scene/particlesys.js.map +1 -1
  246. package/dist/scene/raycast_visitor.js +0 -16
  247. package/dist/scene/raycast_visitor.js.map +1 -1
  248. package/dist/scene/scene.js +7 -4
  249. package/dist/scene/scene.js.map +1 -1
  250. package/dist/scene/scene_node.js +20 -35
  251. package/dist/scene/scene_node.js.map +1 -1
  252. package/dist/scene/sprite.js +18 -0
  253. package/dist/scene/sprite.js.map +1 -0
  254. package/dist/scene/sprite3d.js +18 -0
  255. package/dist/scene/sprite3d.js.map +1 -0
  256. package/dist/scene/terrain-cm/grass.js +5 -4
  257. package/dist/scene/terrain-cm/grass.js.map +1 -1
  258. package/dist/scene/terrain-cm/grassmaterial.js +3 -1
  259. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  260. package/dist/scene/terrain-cm/terrain-cm.js +65 -48
  261. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  262. package/dist/scene/water.js +35 -30
  263. package/dist/scene/water.js.map +1 -1
  264. package/dist/shaders/atmosphere.js +17 -29
  265. package/dist/shaders/atmosphere.js.map +1 -1
  266. package/dist/shaders/fog.js.map +1 -1
  267. package/dist/shaders/misc.js.map +1 -1
  268. package/dist/shaders/noise.js.map +1 -1
  269. package/dist/shaders/pbr.js.map +1 -1
  270. package/dist/shaders/shadow.js.map +1 -1
  271. package/dist/shaders/ssr.js.map +1 -1
  272. package/dist/shaders/temporal.js.map +1 -1
  273. package/dist/shaders/water.js.map +1 -1
  274. package/dist/shadow/esm.js +1 -1
  275. package/dist/shadow/esm.js.map +1 -1
  276. package/dist/shadow/pcf_opt.js.map +1 -1
  277. package/dist/shadow/pcf_pd.js.map +1 -1
  278. package/dist/shadow/shader.js +3 -1
  279. package/dist/shadow/shader.js.map +1 -1
  280. package/dist/shadow/shadow_impl.js.map +1 -1
  281. package/dist/shadow/shadowmapper.js +6 -18
  282. package/dist/shadow/shadowmapper.js.map +1 -1
  283. package/dist/shadow/ssm.js.map +1 -1
  284. package/dist/shadow/vsm.js.map +1 -1
  285. package/dist/shapes/box.js +9 -3
  286. package/dist/shapes/box.js.map +1 -1
  287. package/dist/shapes/cylinder.js +2 -2
  288. package/dist/shapes/cylinder.js.map +1 -1
  289. package/dist/shapes/plane.js +2 -2
  290. package/dist/shapes/plane.js.map +1 -1
  291. package/dist/shapes/shape.js +2 -1
  292. package/dist/shapes/shape.js.map +1 -1
  293. package/dist/shapes/sphere.js +2 -2
  294. package/dist/shapes/sphere.js.map +1 -1
  295. package/dist/shapes/tetrahedron.js +5 -6
  296. package/dist/shapes/tetrahedron.js.map +1 -1
  297. package/dist/shapes/torus.js +2 -2
  298. package/dist/shapes/torus.js.map +1 -1
  299. package/dist/utility/aabbtree.js +1 -1
  300. package/dist/utility/aabbtree.js.map +1 -1
  301. package/dist/utility/blueprint/common/constants.js +578 -104
  302. package/dist/utility/blueprint/common/constants.js.map +1 -1
  303. package/dist/utility/blueprint/common/math.js +471 -9
  304. package/dist/utility/blueprint/common/math.js.map +1 -1
  305. package/dist/utility/blueprint/common.js +1 -1
  306. package/dist/utility/blueprint/common.js.map +1 -1
  307. package/dist/utility/blueprint/material/func.js +9 -5
  308. package/dist/utility/blueprint/material/func.js.map +1 -1
  309. package/dist/utility/blueprint/material/inputs.js.map +1 -1
  310. package/dist/utility/blueprint/material/ir.js +288 -80
  311. package/dist/utility/blueprint/material/ir.js.map +1 -1
  312. package/dist/utility/blueprint/material/pbr.js +92 -4
  313. package/dist/utility/blueprint/material/pbr.js.map +1 -1
  314. package/dist/utility/blueprint/material/texture.js +62 -45
  315. package/dist/utility/blueprint/material/texture.js.map +1 -1
  316. package/dist/utility/blueprint/node.js +28 -1
  317. package/dist/utility/blueprint/node.js.map +1 -1
  318. package/dist/utility/bounding_volume.js.map +1 -1
  319. package/dist/utility/debug.js.map +1 -1
  320. package/dist/utility/draco/decoder.js.map +1 -1
  321. package/dist/utility/misc.js +1 -1
  322. package/dist/utility/misc.js.map +1 -1
  323. package/dist/utility/panorama.js.map +1 -1
  324. package/dist/utility/pmrem.js.map +1 -1
  325. package/dist/utility/rendermipmap.js.map +1 -1
  326. package/dist/utility/serialization/json.js +19 -15
  327. package/dist/utility/serialization/json.js.map +1 -1
  328. package/dist/utility/serialization/manager.js +89 -22
  329. package/dist/utility/serialization/manager.js.map +1 -1
  330. package/dist/utility/serialization/scene/animation.js +44 -41
  331. package/dist/utility/serialization/scene/animation.js.map +1 -1
  332. package/dist/utility/serialization/scene/batch.js +4 -3
  333. package/dist/utility/serialization/scene/batch.js.map +1 -1
  334. package/dist/utility/serialization/scene/camera.js +97 -9
  335. package/dist/utility/serialization/scene/camera.js.map +1 -1
  336. package/dist/utility/serialization/scene/common.js +102 -28
  337. package/dist/utility/serialization/scene/common.js.map +1 -1
  338. package/dist/utility/serialization/scene/light.js +14 -12
  339. package/dist/utility/serialization/scene/light.js.map +1 -1
  340. package/dist/utility/serialization/scene/material.js +216 -26
  341. package/dist/utility/serialization/scene/material.js.map +1 -1
  342. package/dist/utility/serialization/scene/mesh.js +71 -100
  343. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  344. package/dist/utility/serialization/scene/misc.js +3 -2
  345. package/dist/utility/serialization/scene/misc.js.map +1 -1
  346. package/dist/utility/serialization/scene/node.js +42 -9
  347. package/dist/utility/serialization/scene/node.js.map +1 -1
  348. package/dist/utility/serialization/scene/particle.js +7 -5
  349. package/dist/utility/serialization/scene/particle.js.map +1 -1
  350. package/dist/utility/serialization/scene/primitive.js +18 -15
  351. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  352. package/dist/utility/serialization/scene/scene.js +3 -2
  353. package/dist/utility/serialization/scene/scene.js.map +1 -1
  354. package/dist/utility/serialization/scene/sprite.js +164 -0
  355. package/dist/utility/serialization/scene/sprite.js.map +1 -0
  356. package/dist/utility/serialization/scene/terrain.js +8 -6
  357. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  358. package/dist/utility/serialization/scene/water.js +11 -9
  359. package/dist/utility/serialization/scene/water.js.map +1 -1
  360. package/dist/utility/serialization/types.js +6 -0
  361. package/dist/utility/serialization/types.js.map +1 -0
  362. package/dist/utility/shprojector.js.map +1 -1
  363. package/dist/utility/textures/ggxlut.js.map +1 -1
  364. package/dist/utility/textures/gradientnoise.js.map +1 -1
  365. package/dist/utility/textures/randomnoise.js.map +1 -1
  366. package/dist/values.js +14 -14
  367. package/dist/values.js.map +1 -1
  368. package/package.json +80 -80
@@ -0,0 +1,503 @@
1
+ import { Vector3, Quaternion } from '@zephyr3d/base';
2
+ import { IKUtils } from '../ik/ik_utils.js';
3
+
4
+ /**
5
+ * Physics engine for multiple spring chains with inter-chain constraints
6
+ * Suitable for cloth, skirts, capes, and other multi-chain simulations
7
+ *
8
+ * @public
9
+ */ class MultiChainSpringSystem {
10
+ _chains;
11
+ _interChainConstraints;
12
+ _iterations;
13
+ _gravity;
14
+ _wind;
15
+ _enableInertialForces;
16
+ _centrifugalScale;
17
+ _coriolisScale;
18
+ _solver;
19
+ constructor(options){
20
+ this._chains = [];
21
+ this._interChainConstraints = [];
22
+ this._iterations = options?.iterations ?? 5;
23
+ this._gravity = options?.gravity?.clone() ?? new Vector3(0, -9.8, 0);
24
+ this._wind = options?.wind?.clone() ?? new Vector3(0, 0, 0);
25
+ this._enableInertialForces = options?.enableInertialForces ?? true;
26
+ this._centrifugalScale = options?.centrifugalScale ?? 1.0;
27
+ this._coriolisScale = options?.coriolisScale ?? 1.0;
28
+ this._solver = options?.solver ?? 'verlet';
29
+ }
30
+ /**
31
+ * Adds a spring chain to the system
32
+ * @param chain - The chain to add
33
+ * @returns The index of the added chain
34
+ */ addChain(chain) {
35
+ this._chains.push(chain);
36
+ return this._chains.length - 1;
37
+ }
38
+ /**
39
+ * Adds an inter-chain constraint
40
+ * @param constraint - The constraint to add
41
+ */ addInterChainConstraint(constraint) {
42
+ this._interChainConstraints.push(constraint);
43
+ }
44
+ /**
45
+ * Creates radial constraints between adjacent chains
46
+ * Useful for skirts, capes, and other radial multi-chain structures
47
+ * @param options - Configuration options
48
+ */ createRadialConstraints(options) {
49
+ const skipRows = options.skipRows ?? 0;
50
+ const connectDistance = options.connectDistance ?? 1;
51
+ const compliance = options.compliance ?? 0;
52
+ for(let i = 0; i < this._chains.length; i++){
53
+ for(let offset = 1; offset <= connectDistance; offset++){
54
+ const j = (i + offset) % this._chains.length;
55
+ const chainA = this._chains[i];
56
+ const chainB = this._chains[j];
57
+ const minLength = Math.min(chainA.particles.length, chainB.particles.length);
58
+ for(let row = skipRows; row < minLength; row++){
59
+ const pA = chainA.particles[row];
60
+ const pB = chainB.particles[row];
61
+ const distance = Vector3.distance(pA.position, pB.position);
62
+ if (distance <= options.maxDistance) {
63
+ this.addInterChainConstraint({
64
+ chainAIndex: i,
65
+ chainBIndex: j,
66
+ particleAIndex: row,
67
+ particleBIndex: row,
68
+ restLength: distance,
69
+ stiffness: options.stiffness,
70
+ compliance,
71
+ lambda: 0
72
+ });
73
+ }
74
+ }
75
+ }
76
+ }
77
+ }
78
+ /**
79
+ * Updates the physics simulation for all chains
80
+ * @param deltaTime - Time step in seconds
81
+ */ update(deltaTime) {
82
+ const dt = Math.min(deltaTime, 0.033);
83
+ // Save all particle positions before updating
84
+ if (this._enableInertialForces) {
85
+ for (const chain of this._chains){
86
+ for (const p of chain.particles){
87
+ p.lastFramePosition.set(p.position);
88
+ }
89
+ }
90
+ }
91
+ this.updateFixedParticles();
92
+ // Calculate global rotation parameters
93
+ let rotationCenter = null;
94
+ let angularVelocity = null;
95
+ if (this._enableInertialForces && dt > 0.0001) {
96
+ const result = this.calculateGlobalRotation(dt);
97
+ rotationCenter = result.center;
98
+ angularVelocity = result.omega;
99
+ }
100
+ for (const chain of this._chains){
101
+ for (const particle of chain.particles){
102
+ if (particle.fixed) {
103
+ continue;
104
+ }
105
+ const velocity = Vector3.sub(particle.position, particle.prevPosition, new Vector3());
106
+ velocity.scaleBy(particle.damping);
107
+ const acceleration = Vector3.add(this._gravity, this._wind, new Vector3());
108
+ // Apply inertial forces
109
+ if (this._enableInertialForces && rotationCenter && angularVelocity) {
110
+ const inertialAccel = this.calculateInertialAcceleration(particle, rotationCenter, angularVelocity, velocity, this._centrifugalScale, this._coriolisScale);
111
+ Vector3.add(acceleration, inertialAccel, acceleration);
112
+ }
113
+ const positionDelta = Vector3.scale(acceleration, dt * dt, new Vector3());
114
+ Vector3.add(velocity, positionDelta, velocity);
115
+ particle.prevPosition.set(particle.position);
116
+ Vector3.add(particle.position, velocity, particle.position);
117
+ }
118
+ }
119
+ if (this._solver === 'xpbd') {
120
+ for (const chain of this._chains){
121
+ for (const c of chain.constraints){
122
+ c.lambda = 0;
123
+ }
124
+ }
125
+ for (const c of this._interChainConstraints){
126
+ c.lambda = 0;
127
+ }
128
+ }
129
+ for(let iter = 0; iter < this._iterations; iter++){
130
+ for (const chain of this._chains){
131
+ for (const constraint of chain.constraints){
132
+ if (this._solver === 'xpbd') {
133
+ this.solveConstraintXPBD(chain, constraint, dt);
134
+ } else {
135
+ this.solveConstraint(chain, constraint);
136
+ }
137
+ }
138
+ }
139
+ for (const constraint of this._interChainConstraints){
140
+ if (this._solver === 'xpbd') {
141
+ this.solveInterChainConstraintXPBD(constraint, dt);
142
+ } else {
143
+ this.solveInterChainConstraint(constraint);
144
+ }
145
+ }
146
+ }
147
+ }
148
+ updateFixedParticles() {
149
+ for (const chain of this._chains){
150
+ for (const particle of chain.particles){
151
+ if (particle.fixed && particle.node) {
152
+ const worldPos = new Vector3(particle.node.worldMatrix.m03, particle.node.worldMatrix.m13, particle.node.worldMatrix.m23);
153
+ particle.position.set(worldPos);
154
+ particle.prevPosition.set(worldPos);
155
+ // Maintain position history
156
+ if (this._enableInertialForces) {
157
+ if (!particle.positionHistory) {
158
+ particle.positionHistory = [];
159
+ }
160
+ particle.positionHistory.push(worldPos.clone());
161
+ if (particle.positionHistory.length > 5) {
162
+ particle.positionHistory.shift();
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+ calculateGlobalRotation(dt) {
170
+ const fixedParticles = [];
171
+ const velocities = [];
172
+ for (const chain of this._chains){
173
+ for (const p of chain.particles){
174
+ if (!p.fixed) {
175
+ continue;
176
+ }
177
+ const velocity = Vector3.sub(p.position, p.lastFramePosition, new Vector3());
178
+ velocity.scaleBy(1.0 / dt);
179
+ if (velocity.magnitudeSq > 0.001) {
180
+ fixedParticles.push(p);
181
+ velocities.push(velocity);
182
+ }
183
+ }
184
+ }
185
+ if (fixedParticles.length === 0) {
186
+ return {
187
+ center: new Vector3(0, 0, 0),
188
+ omega: new Vector3(0, 0, 0)
189
+ };
190
+ }
191
+ // Estimate rotation center
192
+ let center;
193
+ if (fixedParticles.length === 1) {
194
+ center = this.estimateRotationCenterFromHistory(fixedParticles[0], velocities[0]);
195
+ } else {
196
+ center = new Vector3(0, 0, 0);
197
+ for (const p of fixedParticles){
198
+ Vector3.add(center, p.position, center);
199
+ }
200
+ center.scaleBy(1.0 / fixedParticles.length);
201
+ }
202
+ // Estimate angular velocity
203
+ let sumOmega = new Vector3(0, 0, 0);
204
+ let count = 0;
205
+ for(let i = 0; i < fixedParticles.length; i++){
206
+ const r = Vector3.sub(fixedParticles[i].position, center, new Vector3());
207
+ const v = velocities[i];
208
+ const rLengthSq = r.magnitudeSq;
209
+ if (rLengthSq > 0.0001) {
210
+ const omega = Vector3.cross(r, v, new Vector3());
211
+ omega.scaleBy(1.0 / rLengthSq);
212
+ Vector3.add(sumOmega, omega, sumOmega);
213
+ count++;
214
+ }
215
+ }
216
+ if (count > 0) {
217
+ sumOmega.scaleBy(1.0 / count);
218
+ }
219
+ return {
220
+ center,
221
+ omega: sumOmega
222
+ };
223
+ }
224
+ estimateRotationCenterFromHistory(particle, currentVelocity) {
225
+ const history = particle.positionHistory;
226
+ if (!history || history.length < 3) {
227
+ const speed = currentVelocity.magnitude;
228
+ if (speed < 0.001) {
229
+ return particle.position.clone();
230
+ }
231
+ const estimatedRadius = Math.max(0.5, speed * 0.5);
232
+ const up = new Vector3(0, 1, 0);
233
+ const perpDir = Vector3.cross(currentVelocity, up, new Vector3());
234
+ if (perpDir.magnitudeSq < 0.0001) {
235
+ perpDir.set(new Vector3(1, 0, 0));
236
+ } else {
237
+ Vector3.normalize(perpDir, perpDir);
238
+ }
239
+ const center = Vector3.add(particle.position, Vector3.scale(perpDir, estimatedRadius, new Vector3()), new Vector3());
240
+ return center;
241
+ }
242
+ const p1 = history[0];
243
+ const p2 = history[Math.floor(history.length / 2)];
244
+ const p3 = history[history.length - 1];
245
+ const center = this.calculateCircleCenter(p1, p2, p3);
246
+ return center;
247
+ }
248
+ calculateCircleCenter(p1, p2, p3) {
249
+ const mid12 = Vector3.scale(Vector3.add(p1, p2, new Vector3()), 0.5, new Vector3());
250
+ const mid23 = Vector3.scale(Vector3.add(p2, p3, new Vector3()), 0.5, new Vector3());
251
+ const dir12 = Vector3.sub(p2, p1, new Vector3());
252
+ const dir23 = Vector3.sub(p3, p2, new Vector3());
253
+ const normal = Vector3.cross(dir12, dir23, new Vector3());
254
+ if (normal.magnitudeSq < 0.0001) {
255
+ return Vector3.scale(Vector3.add(Vector3.add(p1, p2, new Vector3()), p3, new Vector3()), 1.0 / 3.0, new Vector3());
256
+ }
257
+ Vector3.normalize(normal, normal);
258
+ const perp12 = Vector3.cross(dir12, normal, new Vector3());
259
+ Vector3.normalize(perp12, perp12);
260
+ const perp23 = Vector3.cross(dir23, normal, new Vector3());
261
+ Vector3.normalize(perp23, perp23);
262
+ const diff = Vector3.sub(mid23, mid12, new Vector3());
263
+ const det = perp12.x * perp23.y - perp12.y * perp23.x;
264
+ if (Math.abs(det) > 0.0001) {
265
+ const t = (diff.x * perp23.y - diff.y * perp23.x) / det;
266
+ const center = Vector3.add(mid12, Vector3.scale(perp12, t, new Vector3()), new Vector3());
267
+ return center;
268
+ }
269
+ return Vector3.scale(Vector3.add(Vector3.add(p1, p2, new Vector3()), p3, new Vector3()), 1.0 / 3.0, new Vector3());
270
+ }
271
+ calculateInertialAcceleration(particle, rotationCenter, angularVelocity, particleVelocity, centrifugalScale, coriolisScale) {
272
+ const r = Vector3.sub(particle.position, rotationCenter, new Vector3());
273
+ const omegaCrossR = Vector3.cross(angularVelocity, r, new Vector3());
274
+ const centrifugalAccel = Vector3.cross(angularVelocity, omegaCrossR, new Vector3());
275
+ centrifugalAccel.scaleBy(centrifugalScale);
276
+ const coriolisAccel = Vector3.cross(angularVelocity, particleVelocity, new Vector3());
277
+ coriolisAccel.scaleBy(-2 * coriolisScale);
278
+ const totalAccel = Vector3.add(centrifugalAccel, coriolisAccel, new Vector3());
279
+ return totalAccel;
280
+ }
281
+ solveConstraint(chain, constraint) {
282
+ const pA = chain.particles[constraint.particleA];
283
+ const pB = chain.particles[constraint.particleB];
284
+ const delta = Vector3.sub(pB.position, pA.position, new Vector3());
285
+ const currentLength = delta.magnitude;
286
+ if (currentLength < 0.0001) {
287
+ return;
288
+ }
289
+ const diff = (currentLength - constraint.restLength) / currentLength;
290
+ const correction = Vector3.scale(delta, diff * constraint.stiffness * 0.5, new Vector3());
291
+ if (!pA.fixed) {
292
+ Vector3.add(pA.position, correction, pA.position);
293
+ }
294
+ if (!pB.fixed) {
295
+ Vector3.sub(pB.position, correction, pB.position);
296
+ }
297
+ }
298
+ solveInterChainConstraint(constraint) {
299
+ const chainA = this._chains[constraint.chainAIndex];
300
+ const chainB = this._chains[constraint.chainBIndex];
301
+ const pA = chainA.particles[constraint.particleAIndex];
302
+ const pB = chainB.particles[constraint.particleBIndex];
303
+ const delta = Vector3.sub(pB.position, pA.position, new Vector3());
304
+ const currentLength = delta.magnitude;
305
+ if (currentLength < 0.0001) {
306
+ return;
307
+ }
308
+ const diff = (currentLength - constraint.restLength) / currentLength;
309
+ const correction = Vector3.scale(delta, diff * constraint.stiffness * 0.5, new Vector3());
310
+ if (!pA.fixed) {
311
+ Vector3.add(pA.position, correction, pA.position);
312
+ }
313
+ if (!pB.fixed) {
314
+ Vector3.sub(pB.position, correction, pB.position);
315
+ }
316
+ }
317
+ solveConstraintXPBD(chain, constraint, dt) {
318
+ const pA = chain.particles[constraint.particleA];
319
+ const pB = chain.particles[constraint.particleB];
320
+ const wA = pA.fixed ? 0 : 1.0 / pA.mass;
321
+ const wB = pB.fixed ? 0 : 1.0 / pB.mass;
322
+ const wSum = wA + wB;
323
+ if (wSum < 1e-10) {
324
+ return;
325
+ }
326
+ const delta = Vector3.sub(pB.position, pA.position, new Vector3());
327
+ const currentLength = delta.magnitude;
328
+ if (currentLength < 0.0001) {
329
+ return;
330
+ }
331
+ const C = currentLength - constraint.restLength;
332
+ const alphaTilde = constraint.compliance / (dt * dt);
333
+ const deltaLambda = (-C - alphaTilde * constraint.lambda) / (wSum + alphaTilde);
334
+ constraint.lambda += deltaLambda;
335
+ const n = Vector3.scale(delta, 1.0 / currentLength, new Vector3());
336
+ if (!pA.fixed) {
337
+ Vector3.add(pA.position, Vector3.scale(n, -wA * deltaLambda, new Vector3()), pA.position);
338
+ }
339
+ if (!pB.fixed) {
340
+ Vector3.add(pB.position, Vector3.scale(n, wB * deltaLambda, new Vector3()), pB.position);
341
+ }
342
+ }
343
+ solveInterChainConstraintXPBD(constraint, dt) {
344
+ const chainA = this._chains[constraint.chainAIndex];
345
+ const chainB = this._chains[constraint.chainBIndex];
346
+ const pA = chainA.particles[constraint.particleAIndex];
347
+ const pB = chainB.particles[constraint.particleBIndex];
348
+ const wA = pA.fixed ? 0 : 1.0 / pA.mass;
349
+ const wB = pB.fixed ? 0 : 1.0 / pB.mass;
350
+ const wSum = wA + wB;
351
+ if (wSum < 1e-10) {
352
+ return;
353
+ }
354
+ const delta = Vector3.sub(pB.position, pA.position, new Vector3());
355
+ const currentLength = delta.magnitude;
356
+ if (currentLength < 0.0001) {
357
+ return;
358
+ }
359
+ const C = currentLength - constraint.restLength;
360
+ const alphaTilde = constraint.compliance / (dt * dt);
361
+ const deltaLambda = (-C - alphaTilde * constraint.lambda) / (wSum + alphaTilde);
362
+ constraint.lambda += deltaLambda;
363
+ const n = Vector3.scale(delta, 1.0 / currentLength, new Vector3());
364
+ if (!pA.fixed) {
365
+ Vector3.add(pA.position, Vector3.scale(n, -wA * deltaLambda, new Vector3()), pA.position);
366
+ }
367
+ if (!pB.fixed) {
368
+ Vector3.add(pB.position, Vector3.scale(n, wB * deltaLambda, new Vector3()), pB.position);
369
+ }
370
+ }
371
+ /**
372
+ * Applies simulation results to scene nodes
373
+ * @param weight - Blend weight [0-1] (default: 1.0)
374
+ */ applyToNodes(weight = 1.0) {
375
+ for (const chain of this._chains){
376
+ this.applyChainToNodes(chain, weight);
377
+ }
378
+ }
379
+ applyChainToNodes(chain, weight) {
380
+ for(let i = 0; i < chain.particles.length - 1; i++){
381
+ const particle = chain.particles[i];
382
+ const nextParticle = chain.particles[i + 1];
383
+ if (!particle.node) {
384
+ continue;
385
+ }
386
+ // Get current bone direction from node's world matrix (before physics)
387
+ const currentBonePos = new Vector3(particle.node.worldMatrix.m03, particle.node.worldMatrix.m13, particle.node.worldMatrix.m23);
388
+ const nextNode = nextParticle.node;
389
+ if (!nextNode) {
390
+ continue;
391
+ }
392
+ const nextBonePos = new Vector3(nextNode.worldMatrix.m03, nextNode.worldMatrix.m13, nextNode.worldMatrix.m23);
393
+ const originalDir = Vector3.sub(nextBonePos, currentBonePos, new Vector3());
394
+ // Get current bone rotation from node's world matrix
395
+ const currentBoneRotation = new Quaternion();
396
+ particle.node.worldMatrix.decompose(null, currentBoneRotation, null);
397
+ // Calculate new direction from physics simulation
398
+ const newDir = Vector3.sub(nextParticle.position, particle.position, new Vector3());
399
+ const deltaRotation = new Quaternion();
400
+ IKUtils.fromToRotation(originalDir, newDir, deltaRotation);
401
+ let worldRotation = Quaternion.multiply(deltaRotation, currentBoneRotation, new Quaternion());
402
+ if (weight < 1) {
403
+ Quaternion.slerp(currentBoneRotation, worldRotation, weight, worldRotation);
404
+ }
405
+ const parent = particle.node.parent;
406
+ if (parent) {
407
+ const parentWorldRotation = new Quaternion();
408
+ parent.worldMatrix.decompose(null, parentWorldRotation, null);
409
+ const parentInvRotation = Quaternion.conjugate(parentWorldRotation, new Quaternion());
410
+ const localRotation = Quaternion.multiply(parentInvRotation, worldRotation, new Quaternion());
411
+ particle.node.rotation = localRotation;
412
+ } else {
413
+ particle.node.rotation = worldRotation;
414
+ }
415
+ }
416
+ }
417
+ /**
418
+ * Resets the simulation to initial state
419
+ */ reset() {
420
+ for (const chain of this._chains){
421
+ chain.reset();
422
+ }
423
+ }
424
+ /**
425
+ * Gets the spring chains
426
+ */ get chains() {
427
+ return this._chains;
428
+ }
429
+ /**
430
+ * Gets the inter-chain constraints
431
+ */ get interChainConstraints() {
432
+ return this._interChainConstraints;
433
+ }
434
+ /**
435
+ * Gets the current gravity
436
+ */ get gravity() {
437
+ return this._gravity;
438
+ }
439
+ set gravity(gravity) {
440
+ this._gravity.set(gravity);
441
+ }
442
+ /**
443
+ * Gets the current wind
444
+ */ get wind() {
445
+ return this._wind;
446
+ }
447
+ set wind(wind) {
448
+ this._wind.set(wind);
449
+ }
450
+ /**
451
+ * Gets the number of iterations
452
+ */ get iterations() {
453
+ return this._iterations;
454
+ }
455
+ set iterations(count) {
456
+ this._iterations = Math.max(1, count);
457
+ }
458
+ /**
459
+ * Gets whether inertial forces are enabled
460
+ */ get enableInertialForces() {
461
+ return this._enableInertialForces;
462
+ }
463
+ set enableInertialForces(enabled) {
464
+ this._enableInertialForces = enabled;
465
+ }
466
+ /**
467
+ * Gets the centrifugal force scale
468
+ */ get centrifugalScale() {
469
+ return this._centrifugalScale;
470
+ }
471
+ set centrifugalScale(scale) {
472
+ this._centrifugalScale = Math.max(0, scale);
473
+ }
474
+ /**
475
+ * Gets the Coriolis force scale
476
+ */ get coriolisScale() {
477
+ return this._coriolisScale;
478
+ }
479
+ set coriolisScale(scale) {
480
+ this._coriolisScale = Math.max(0, scale);
481
+ }
482
+ get solver() {
483
+ return this._solver;
484
+ }
485
+ set solver(type) {
486
+ if (this._solver !== type) {
487
+ this._solver = type;
488
+ if (type === 'xpbd') {
489
+ for (const chain of this._chains){
490
+ for (const c of chain.constraints){
491
+ c.lambda = 0;
492
+ }
493
+ }
494
+ for (const c of this._interChainConstraints){
495
+ c.lambda = 0;
496
+ }
497
+ }
498
+ }
499
+ }
500
+ }
501
+
502
+ export { MultiChainSpringSystem };
503
+ //# sourceMappingURL=multi_chain_spring_system.js.map
@@ -0,0 +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 * @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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"}