@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 @@
1
+ {"version":3,"file":"ik_track.js","sources":["../../../src/animation/ik/ik_track.ts"],"sourcesContent":["import { Quaternion } from '@zephyr3d/base';\r\nimport { AnimationTrack } from '../animationtrack';\r\nimport type { FABRIKSolver } from './fabrik_solver';\r\n\r\n/**\r\n * IK animation track state.\r\n *\r\n * Represents the rotations of all joints in an IK chain at a specific time.\r\n */\r\ninterface IKState {\r\n /** Array of joint rotations (one per joint, excluding end effector) */\r\n rotations: Quaternion[];\r\n}\r\n\r\n/**\r\n * Animation track that applies IK solving.\r\n *\r\n * @remarks\r\n * This track integrates IK solving into the animation system, allowing\r\n * IK to be blended with other animations. The track solves the IK chain\r\n * each frame and produces joint rotations that can be mixed with other\r\n * animation tracks.\r\n *\r\n * @public\r\n */\r\nexport class IKTrack extends AnimationTrack<IKState> {\r\n /** The IK solver */\r\n private _solver: FABRIKSolver;\r\n /** Cached state for reuse */\r\n private _state: IKState;\r\n /** Duration of the track (can be infinite for procedural IK) */\r\n private _duration: number;\r\n\r\n /**\r\n * Create an IK animation track.\r\n *\r\n * @param solver - The FABRIK solver to use\r\n * @param duration - Duration of the track in seconds (default: Infinity for procedural)\r\n */\r\n constructor(solver: FABRIKSolver, duration = Infinity) {\r\n super(false);\r\n this._solver = solver;\r\n this._duration = duration;\r\n\r\n // Initialize state with identity rotations\r\n const numJoints = solver.chain.joints.length - 1; // Exclude end effector\r\n this._state = {\r\n rotations: Array.from({ length: numJoints }, () => new Quaternion())\r\n };\r\n }\r\n\r\n /**\r\n * Get the IK solver.\r\n */\r\n get solver(): FABRIKSolver {\r\n return this._solver;\r\n }\r\n\r\n /**\r\n * Set the duration of the track.\r\n */\r\n setDuration(duration: number): void {\r\n this._duration = Math.max(0, duration);\r\n }\r\n\r\n /**\r\n * Calculate IK state at the given time.\r\n *\r\n * @remarks\r\n * For procedural IK, the time parameter is typically ignored.\r\n * The solver uses the current target position set externally.\r\n */\r\n calculateState(_target: object, _currentTime: number): IKState {\r\n const joints = this._solver.chain.joints;\r\n\r\n // Store current rotations as the calculated state\r\n for (let i = 0; i < joints.length - 1; i++) {\r\n this._state.rotations[i].set(joints[i].rotation);\r\n }\r\n\r\n return this._state;\r\n }\r\n\r\n /**\r\n * Apply IK state to the target scene nodes.\r\n */\r\n applyState(_target: object, state: IKState): void {\r\n const joints = this._solver.chain.joints;\r\n\r\n // Apply rotations to scene nodes\r\n for (let i = 0; i < state.rotations.length && i < joints.length - 1; i++) {\r\n joints[i].node.rotation = state.rotations[i];\r\n }\r\n }\r\n\r\n /**\r\n * Mix two IK states using spherical interpolation.\r\n */\r\n mixState(a: IKState, b: IKState, t: number): IKState {\r\n const result: IKState = {\r\n rotations: []\r\n };\r\n\r\n const count = Math.min(a.rotations.length, b.rotations.length);\r\n for (let i = 0; i < count; i++) {\r\n result.rotations.push(Quaternion.slerp(a.rotations[i], b.rotations[i], t));\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Get the blend identifier for this track.\r\n *\r\n * IK tracks with the same root joint can be blended together.\r\n */\r\n getBlendId(): string {\r\n const rootNode = this._solver.chain.root.node;\r\n return `ik-chain-${rootNode.runtimeId}`;\r\n }\r\n\r\n /**\r\n * Get the duration of this track.\r\n */\r\n getDuration(): number {\r\n return this._duration;\r\n }\r\n}\r\n"],"names":["IKTrack","AnimationTrack","solver","duration","Infinity","_solver","_duration","numJoints","chain","joints","length","_state","rotations","Array","from","Quaternion","setDuration","Math","max","calculateState","_target","_currentTime","i","set","rotation","applyState","state","node","mixState","a","b","t","result","count","min","push","slerp","getBlendId","rootNode","root","runtimeId","getDuration"],"mappings":"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"}
@@ -0,0 +1,270 @@
1
+ import { Vector3, Quaternion } from '@zephyr3d/base';
2
+
3
+ /**
4
+ * Utility functions for IK calculations.
5
+ *
6
+ * @internal
7
+ */ class IKUtils {
8
+ /**
9
+ * Calculate the rotation needed to align 'from' direction to 'to' direction.
10
+ *
11
+ * @param from - Starting direction vector
12
+ * @param to - Target direction vector
13
+ * @param result - Output quaternion
14
+ * @returns The rotation quaternion
15
+ */ static fromToRotation(from, to, result) {
16
+ const fromNorm = Vector3.normalize(from, new Vector3());
17
+ const toNorm = Vector3.normalize(to, new Vector3());
18
+ const dot = Vector3.dot(fromNorm, toNorm);
19
+ // Vectors are parallel
20
+ if (dot >= 0.999999) {
21
+ return result.identity();
22
+ }
23
+ // Vectors are opposite
24
+ if (dot <= -0.999999) {
25
+ // Find an orthogonal axis
26
+ let axis = Vector3.cross(Vector3.axisPX(), fromNorm, new Vector3());
27
+ const lenSq = axis.x * axis.x + axis.y * axis.y + axis.z * axis.z;
28
+ if (lenSq < 0.000001) {
29
+ axis = Vector3.cross(Vector3.axisPY(), fromNorm, new Vector3());
30
+ }
31
+ axis.inplaceNormalize();
32
+ return result.fromAxisAngle(axis, Math.PI);
33
+ }
34
+ // General case
35
+ const axis = Vector3.cross(fromNorm, toNorm).inplaceNormalize();
36
+ const angle = Math.acos(dot);
37
+ return result.fromAxisAngle(axis, angle);
38
+ }
39
+ /**
40
+ * Calculate bone length between two positions.
41
+ *
42
+ * @param start - Start position
43
+ * @param end - End position
44
+ * @returns Distance between positions
45
+ */ static calculateBoneLength(start, end) {
46
+ return Vector3.distance(start, end);
47
+ }
48
+ /**
49
+ * Decompose a quaternion into swing and twist components around a given axis.
50
+ *
51
+ * @remarks
52
+ * Given a rotation Q and an axis A, decompose Q into:
53
+ * - Twist: rotation around A
54
+ * - Swing: rotation perpendicular to A
55
+ * Such that Q = Twist * Swing
56
+ *
57
+ * Algorithm:
58
+ * 1. Project Q's imaginary part onto axis to get twist component
59
+ * 2. Normalize to get pure twist rotation
60
+ * 3. Calculate swing = twist^-1 * Q
61
+ *
62
+ * @param q - The quaternion to decompose
63
+ * @param axis - The twist axis (must be normalized)
64
+ * @param outSwing - Output swing rotation
65
+ * @param outTwist - Output twist rotation
66
+ */ static decomposeSwingTwist(q, axis, outSwing, outTwist) {
67
+ // Project quaternion's imaginary part (xyz) onto twist axis
68
+ // twist quaternion = (w, (xyz · axis) * axis)
69
+ const dot = q.x * axis.x + q.y * axis.y + q.z * axis.z;
70
+ outTwist.x = axis.x * dot;
71
+ outTwist.y = axis.y * dot;
72
+ outTwist.z = axis.z * dot;
73
+ outTwist.w = q.w;
74
+ // Normalize twist quaternion
75
+ const twistLen = Math.sqrt(outTwist.x * outTwist.x + outTwist.y * outTwist.y + outTwist.z * outTwist.z + outTwist.w * outTwist.w);
76
+ if (twistLen < 0.000001) {
77
+ // No rotation or rotation perpendicular to axis
78
+ outTwist.identity();
79
+ outSwing.set(q);
80
+ return;
81
+ }
82
+ outTwist.x /= twistLen;
83
+ outTwist.y /= twistLen;
84
+ outTwist.z /= twistLen;
85
+ outTwist.w /= twistLen;
86
+ // Calculate swing: Q = Twist * Swing => Swing = Twist^-1 * Q
87
+ const twistInv = Quaternion.conjugate(outTwist, new Quaternion());
88
+ Quaternion.multiply(twistInv, q, outSwing);
89
+ }
90
+ /**
91
+ * Get the twist angle (in radians) from a twist quaternion around an axis.
92
+ *
93
+ * @param twist - The twist quaternion
94
+ * @param axis - The twist axis (must be normalized)
95
+ * @returns Twist angle in radians, range [-PI, PI]
96
+ */ static getTwistAngle(twist, axis) {
97
+ // For a twist quaternion around axis: twist = (cos(θ/2), sin(θ/2) * axis)
98
+ // We can extract the angle from the quaternion components
99
+ // Ensure twist is normalized
100
+ const len = Math.sqrt(twist.x * twist.x + twist.y * twist.y + twist.z * twist.z + twist.w * twist.w);
101
+ if (len < 0.000001) {
102
+ return 0;
103
+ }
104
+ const w = twist.w / len;
105
+ const halfAngle = Math.acos(Math.max(-1, Math.min(1, w)));
106
+ // Determine sign based on axis direction
107
+ const dot = twist.x * axis.x + twist.y * axis.y + twist.z * axis.z;
108
+ const sign = dot >= 0 ? 1 : -1;
109
+ return sign * 2 * halfAngle;
110
+ }
111
+ /**
112
+ * Create a twist quaternion from an angle and axis.
113
+ *
114
+ * @param angle - Twist angle in radians
115
+ * @param axis - The twist axis (must be normalized)
116
+ * @param result - Output quaternion
117
+ * @returns The twist quaternion
118
+ */ static createTwist(angle, axis, result) {
119
+ const halfAngle = angle * 0.5;
120
+ const s = Math.sin(halfAngle);
121
+ result.x = axis.x * s;
122
+ result.y = axis.y * s;
123
+ result.z = axis.z * s;
124
+ result.w = Math.cos(halfAngle);
125
+ return result;
126
+ }
127
+ /**
128
+ * Clamp twist angle and optionally smooth with previous twist.
129
+ *
130
+ * @param currentTwist - Current twist angle in radians
131
+ * @param previousTwist - Previous frame's twist angle in radians (optional)
132
+ * @param minTwist - Minimum allowed twist angle in radians
133
+ * @param maxTwist - Maximum allowed twist angle in radians
134
+ * @param smoothFactor - Smoothing factor [0-1], 0 = no smoothing, 1 = full smoothing
135
+ * @returns Clamped and smoothed twist angle
136
+ */ static clampAndSmoothTwist(currentTwist, previousTwist, minTwist, maxTwist, smoothFactor = 0.5) {
137
+ // Clamp to range
138
+ let clampedTwist = Math.max(minTwist, Math.min(maxTwist, currentTwist));
139
+ // Smooth with previous frame if available
140
+ if (previousTwist !== undefined && smoothFactor > 0.001) {
141
+ // Normalize angle difference to [-PI, PI]
142
+ let diff = clampedTwist - previousTwist;
143
+ while(diff > Math.PI){
144
+ diff -= 2 * Math.PI;
145
+ }
146
+ while(diff < -Math.PI){
147
+ diff += 2 * Math.PI;
148
+ }
149
+ // Lerp
150
+ clampedTwist = previousTwist + diff * (1 - smoothFactor);
151
+ }
152
+ return clampedTwist;
153
+ }
154
+ /**
155
+ * Calculate a look-at rotation with twist constraint using a pole vector.
156
+ *
157
+ * @remarks
158
+ * This creates a rotation that:
159
+ * 1. Aligns 'forward' direction to 'targetDir'
160
+ * 2. Keeps the perpendicular plane aligned with 'poleDir'
161
+ *
162
+ * This prevents unwanted twist around the bone axis by using an external
163
+ * reference direction (pole vector) rather than relying on previous rotations.
164
+ *
165
+ * @param forward - Current forward direction (will be aligned to targetDir)
166
+ * @param targetDir - Desired forward direction
167
+ * @param poleDir - Direction that should be in the "up" hemisphere (from joint position)
168
+ * @param result - Output quaternion
169
+ * @returns The rotation quaternion
170
+ */ static lookAtRotationWithPole(forward, targetDir, poleDir, result) {
171
+ const forwardNorm = Vector3.normalize(forward, new Vector3());
172
+ const targetDirNorm = Vector3.normalize(targetDir, new Vector3());
173
+ const poleDirNorm = Vector3.normalize(poleDir, new Vector3());
174
+ // First, align forward to targetDir (swing rotation)
175
+ const swingRotation = new Quaternion();
176
+ this.fromToRotation(forwardNorm, targetDirNorm, swingRotation);
177
+ // Calculate the "right" vector perpendicular to targetDir and poleDir
178
+ // This defines the plane that the bone should bend in
179
+ const right = Vector3.cross(targetDirNorm, poleDirNorm, new Vector3());
180
+ const rightLenSq = right.x * right.x + right.y * right.y + right.z * right.z;
181
+ // If pole is parallel to target direction, no twist correction possible
182
+ if (rightLenSq < 0.000001) {
183
+ result.set(swingRotation);
184
+ return result;
185
+ }
186
+ right.scaleBy(1 / Math.sqrt(rightLenSq));
187
+ // Calculate the "up" vector perpendicular to targetDir in the pole plane
188
+ const up = Vector3.cross(right, targetDirNorm, new Vector3()).inplaceNormalize();
189
+ // Now we need to find the twist rotation around targetDir
190
+ // We want the local "up" axis to align with the calculated "up" vector
191
+ // Get a perpendicular vector to forward in the original space
192
+ let originalUp = Vector3.cross(forwardNorm, Vector3.axisPY(), new Vector3());
193
+ const originalUpLenSq = originalUp.x * originalUp.x + originalUp.y * originalUp.y + originalUp.z * originalUp.z;
194
+ if (originalUpLenSq < 0.000001) {
195
+ originalUp = Vector3.cross(forwardNorm, Vector3.axisPX(), new Vector3());
196
+ }
197
+ originalUp.inplaceNormalize();
198
+ // Rotate originalUp by swing rotation to see where it ends up
199
+ const rotatedUp = swingRotation.transform(originalUp, new Vector3());
200
+ // Project rotatedUp onto the plane perpendicular to targetDir
201
+ const rotatedUpDot = Vector3.dot(rotatedUp, targetDirNorm);
202
+ const rotatedUpProj = Vector3.scale(targetDirNorm, rotatedUpDot, new Vector3());
203
+ const rotatedUpPerp = Vector3.sub(rotatedUp, rotatedUpProj, new Vector3());
204
+ const rotatedUpPerpLen = rotatedUpPerp.magnitude;
205
+ if (rotatedUpPerpLen < 0.000001) {
206
+ result.set(swingRotation);
207
+ return result;
208
+ }
209
+ rotatedUpPerp.scaleBy(1 / rotatedUpPerpLen);
210
+ // Calculate twist rotation to align rotatedUpPerp with up
211
+ const twistRotation = new Quaternion();
212
+ this.fromToRotation(rotatedUpPerp, up, twistRotation);
213
+ // Combine swing and twist
214
+ return Quaternion.multiply(twistRotation, swingRotation, result);
215
+ }
216
+ /**
217
+ * Calculate a look-at rotation with twist constraint.
218
+ *
219
+ * @remarks
220
+ * This creates a rotation that:
221
+ * 1. Aligns 'forward' direction to 'targetDir'
222
+ * 2. Keeps 'up' direction as close as possible to 'targetUp'
223
+ *
224
+ * This prevents unwanted twist around the bone axis.
225
+ *
226
+ * @param forward - Current forward direction (will be aligned to targetDir)
227
+ * @param targetDir - Desired forward direction
228
+ * @param up - Current up direction (perpendicular to forward)
229
+ * @param targetUp - Desired up direction (will be projected perpendicular to targetDir)
230
+ * @param result - Output quaternion
231
+ * @returns The rotation quaternion
232
+ */ static lookAtRotation(forward, targetDir, up, targetUp, result) {
233
+ const forwardNorm = Vector3.normalize(forward, new Vector3());
234
+ const targetDirNorm = Vector3.normalize(targetDir, new Vector3());
235
+ // First, align forward to targetDir (swing rotation)
236
+ const swingRotation = new Quaternion();
237
+ this.fromToRotation(forwardNorm, targetDirNorm, swingRotation);
238
+ // Rotate the up vector by swing rotation
239
+ const rotatedUp = swingRotation.transform(up, new Vector3());
240
+ // Project targetUp onto plane perpendicular to targetDir
241
+ const dot = Vector3.dot(targetUp, targetDirNorm);
242
+ const projection = Vector3.scale(targetDirNorm, dot, new Vector3());
243
+ const targetUpPerp = Vector3.sub(targetUp, projection, new Vector3());
244
+ const targetUpPerpLen = targetUpPerp.magnitude;
245
+ // If targetUp is parallel to targetDir, no twist correction needed
246
+ if (targetUpPerpLen < 0.000001) {
247
+ result.set(swingRotation);
248
+ return result;
249
+ }
250
+ targetUpPerp.scaleBy(1 / targetUpPerpLen);
251
+ // Project rotatedUp onto the same plane
252
+ const rotatedUpDot = Vector3.dot(rotatedUp, targetDirNorm);
253
+ const rotatedUpProj = Vector3.scale(targetDirNorm, rotatedUpDot, new Vector3());
254
+ const rotatedUpPerp = Vector3.sub(rotatedUp, rotatedUpProj, new Vector3());
255
+ const rotatedUpPerpLen = rotatedUpPerp.magnitude;
256
+ if (rotatedUpPerpLen < 0.000001) {
257
+ result.set(swingRotation);
258
+ return result;
259
+ }
260
+ rotatedUpPerp.scaleBy(1 / rotatedUpPerpLen);
261
+ // Calculate twist rotation around targetDir
262
+ const twistRotation = new Quaternion();
263
+ this.fromToRotation(rotatedUpPerp, targetUpPerp, twistRotation);
264
+ // Combine swing and twist
265
+ return Quaternion.multiply(twistRotation, swingRotation, result);
266
+ }
267
+ }
268
+
269
+ export { IKUtils };
270
+ //# sourceMappingURL=ik_utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ik_utils.js","sources":["../../../src/animation/ik/ik_utils.ts"],"sourcesContent":["import { Vector3, Quaternion } from '@zephyr3d/base';\r\n\r\n/**\r\n * Utility functions for IK calculations.\r\n *\r\n * @internal\r\n */\r\nexport class IKUtils {\r\n /**\r\n * Calculate the rotation needed to align 'from' direction to 'to' direction.\r\n *\r\n * @param from - Starting direction vector\r\n * @param to - Target direction vector\r\n * @param result - Output quaternion\r\n * @returns The rotation quaternion\r\n */\r\n static fromToRotation(from: Vector3, to: Vector3, result: Quaternion): Quaternion {\r\n const fromNorm = Vector3.normalize(from, new Vector3());\r\n const toNorm = Vector3.normalize(to, new Vector3());\r\n\r\n const dot = Vector3.dot(fromNorm, toNorm);\r\n\r\n // Vectors are parallel\r\n if (dot >= 0.999999) {\r\n return result.identity();\r\n }\r\n\r\n // Vectors are opposite\r\n if (dot <= -0.999999) {\r\n // Find an orthogonal axis\r\n let axis = Vector3.cross(Vector3.axisPX(), fromNorm, new Vector3());\r\n const lenSq = axis.x * axis.x + axis.y * axis.y + axis.z * axis.z;\r\n if (lenSq < 0.000001) {\r\n axis = Vector3.cross(Vector3.axisPY(), fromNorm, new Vector3());\r\n }\r\n axis.inplaceNormalize();\r\n return result.fromAxisAngle(axis, Math.PI);\r\n }\r\n\r\n // General case\r\n const axis = Vector3.cross(fromNorm, toNorm).inplaceNormalize();\r\n const angle = Math.acos(dot);\r\n return result.fromAxisAngle(axis, angle);\r\n }\r\n\r\n /**\r\n * Calculate bone length between two positions.\r\n *\r\n * @param start - Start position\r\n * @param end - End position\r\n * @returns Distance between positions\r\n */\r\n static calculateBoneLength(start: Vector3, end: Vector3): number {\r\n return Vector3.distance(start, end);\r\n }\r\n\r\n /**\r\n * Decompose a quaternion into swing and twist components around a given axis.\r\n *\r\n * @remarks\r\n * Given a rotation Q and an axis A, decompose Q into:\r\n * - Twist: rotation around A\r\n * - Swing: rotation perpendicular to A\r\n * Such that Q = Twist * Swing\r\n *\r\n * Algorithm:\r\n * 1. Project Q's imaginary part onto axis to get twist component\r\n * 2. Normalize to get pure twist rotation\r\n * 3. Calculate swing = twist^-1 * Q\r\n *\r\n * @param q - The quaternion to decompose\r\n * @param axis - The twist axis (must be normalized)\r\n * @param outSwing - Output swing rotation\r\n * @param outTwist - Output twist rotation\r\n */\r\n static decomposeSwingTwist(q: Quaternion, axis: Vector3, outSwing: Quaternion, outTwist: Quaternion): void {\r\n // Project quaternion's imaginary part (xyz) onto twist axis\r\n // twist quaternion = (w, (xyz · axis) * axis)\r\n const dot = q.x * axis.x + q.y * axis.y + q.z * axis.z;\r\n\r\n outTwist.x = axis.x * dot;\r\n outTwist.y = axis.y * dot;\r\n outTwist.z = axis.z * dot;\r\n outTwist.w = q.w;\r\n\r\n // Normalize twist quaternion\r\n const twistLen = Math.sqrt(\r\n outTwist.x * outTwist.x + outTwist.y * outTwist.y + outTwist.z * outTwist.z + outTwist.w * outTwist.w\r\n );\r\n\r\n if (twistLen < 0.000001) {\r\n // No rotation or rotation perpendicular to axis\r\n outTwist.identity();\r\n outSwing.set(q);\r\n return;\r\n }\r\n\r\n outTwist.x /= twistLen;\r\n outTwist.y /= twistLen;\r\n outTwist.z /= twistLen;\r\n outTwist.w /= twistLen;\r\n\r\n // Calculate swing: Q = Twist * Swing => Swing = Twist^-1 * Q\r\n const twistInv = Quaternion.conjugate(outTwist, new Quaternion());\r\n Quaternion.multiply(twistInv, q, outSwing);\r\n }\r\n\r\n /**\r\n * Get the twist angle (in radians) from a twist quaternion around an axis.\r\n *\r\n * @param twist - The twist quaternion\r\n * @param axis - The twist axis (must be normalized)\r\n * @returns Twist angle in radians, range [-PI, PI]\r\n */\r\n static getTwistAngle(twist: Quaternion, axis: Vector3): number {\r\n // For a twist quaternion around axis: twist = (cos(θ/2), sin(θ/2) * axis)\r\n // We can extract the angle from the quaternion components\r\n\r\n // Ensure twist is normalized\r\n const len = Math.sqrt(twist.x * twist.x + twist.y * twist.y + twist.z * twist.z + twist.w * twist.w);\r\n if (len < 0.000001) {\r\n return 0;\r\n }\r\n\r\n const w = twist.w / len;\r\n const halfAngle = Math.acos(Math.max(-1, Math.min(1, w)));\r\n\r\n // Determine sign based on axis direction\r\n const dot = twist.x * axis.x + twist.y * axis.y + twist.z * axis.z;\r\n const sign = dot >= 0 ? 1 : -1;\r\n\r\n return sign * 2 * halfAngle;\r\n }\r\n\r\n /**\r\n * Create a twist quaternion from an angle and axis.\r\n *\r\n * @param angle - Twist angle in radians\r\n * @param axis - The twist axis (must be normalized)\r\n * @param result - Output quaternion\r\n * @returns The twist quaternion\r\n */\r\n static createTwist(angle: number, axis: Vector3, result: Quaternion): Quaternion {\r\n const halfAngle = angle * 0.5;\r\n const s = Math.sin(halfAngle);\r\n result.x = axis.x * s;\r\n result.y = axis.y * s;\r\n result.z = axis.z * s;\r\n result.w = Math.cos(halfAngle);\r\n return result;\r\n }\r\n\r\n /**\r\n * Clamp twist angle and optionally smooth with previous twist.\r\n *\r\n * @param currentTwist - Current twist angle in radians\r\n * @param previousTwist - Previous frame's twist angle in radians (optional)\r\n * @param minTwist - Minimum allowed twist angle in radians\r\n * @param maxTwist - Maximum allowed twist angle in radians\r\n * @param smoothFactor - Smoothing factor [0-1], 0 = no smoothing, 1 = full smoothing\r\n * @returns Clamped and smoothed twist angle\r\n */\r\n static clampAndSmoothTwist(\r\n currentTwist: number,\r\n previousTwist: number | undefined,\r\n minTwist: number,\r\n maxTwist: number,\r\n smoothFactor: number = 0.5\r\n ): number {\r\n // Clamp to range\r\n let clampedTwist = Math.max(minTwist, Math.min(maxTwist, currentTwist));\r\n\r\n // Smooth with previous frame if available\r\n if (previousTwist !== undefined && smoothFactor > 0.001) {\r\n // Normalize angle difference to [-PI, PI]\r\n let diff = clampedTwist - previousTwist;\r\n while (diff > Math.PI) {\r\n diff -= 2 * Math.PI;\r\n }\r\n while (diff < -Math.PI) {\r\n diff += 2 * Math.PI;\r\n }\r\n\r\n // Lerp\r\n clampedTwist = previousTwist + diff * (1 - smoothFactor);\r\n }\r\n\r\n return clampedTwist;\r\n }\r\n\r\n /**\r\n * Calculate a look-at rotation with twist constraint using a pole vector.\r\n *\r\n * @remarks\r\n * This creates a rotation that:\r\n * 1. Aligns 'forward' direction to 'targetDir'\r\n * 2. Keeps the perpendicular plane aligned with 'poleDir'\r\n *\r\n * This prevents unwanted twist around the bone axis by using an external\r\n * reference direction (pole vector) rather than relying on previous rotations.\r\n *\r\n * @param forward - Current forward direction (will be aligned to targetDir)\r\n * @param targetDir - Desired forward direction\r\n * @param poleDir - Direction that should be in the \"up\" hemisphere (from joint position)\r\n * @param result - Output quaternion\r\n * @returns The rotation quaternion\r\n */\r\n static lookAtRotationWithPole(\r\n forward: Vector3,\r\n targetDir: Vector3,\r\n poleDir: Vector3,\r\n result: Quaternion\r\n ): Quaternion {\r\n const forwardNorm = Vector3.normalize(forward, new Vector3());\r\n const targetDirNorm = Vector3.normalize(targetDir, new Vector3());\r\n const poleDirNorm = Vector3.normalize(poleDir, new Vector3());\r\n\r\n // First, align forward to targetDir (swing rotation)\r\n const swingRotation = new Quaternion();\r\n this.fromToRotation(forwardNorm, targetDirNorm, swingRotation);\r\n\r\n // Calculate the \"right\" vector perpendicular to targetDir and poleDir\r\n // This defines the plane that the bone should bend in\r\n const right = Vector3.cross(targetDirNorm, poleDirNorm, new Vector3());\r\n const rightLenSq = right.x * right.x + right.y * right.y + right.z * right.z;\r\n\r\n // If pole is parallel to target direction, no twist correction possible\r\n if (rightLenSq < 0.000001) {\r\n result.set(swingRotation);\r\n return result;\r\n }\r\n\r\n right.scaleBy(1 / Math.sqrt(rightLenSq));\r\n\r\n // Calculate the \"up\" vector perpendicular to targetDir in the pole plane\r\n const up = Vector3.cross(right, targetDirNorm, new Vector3()).inplaceNormalize();\r\n\r\n // Now we need to find the twist rotation around targetDir\r\n // We want the local \"up\" axis to align with the calculated \"up\" vector\r\n\r\n // Get a perpendicular vector to forward in the original space\r\n let originalUp = Vector3.cross(forwardNorm, Vector3.axisPY(), new Vector3());\r\n const originalUpLenSq =\r\n originalUp.x * originalUp.x + originalUp.y * originalUp.y + originalUp.z * originalUp.z;\r\n if (originalUpLenSq < 0.000001) {\r\n originalUp = Vector3.cross(forwardNorm, Vector3.axisPX(), new Vector3());\r\n }\r\n originalUp.inplaceNormalize();\r\n\r\n // Rotate originalUp by swing rotation to see where it ends up\r\n const rotatedUp = swingRotation.transform(originalUp, new Vector3());\r\n\r\n // Project rotatedUp onto the plane perpendicular to targetDir\r\n const rotatedUpDot = Vector3.dot(rotatedUp, targetDirNorm);\r\n const rotatedUpProj = Vector3.scale(targetDirNorm, rotatedUpDot, new Vector3());\r\n const rotatedUpPerp = Vector3.sub(rotatedUp, rotatedUpProj, new Vector3());\r\n const rotatedUpPerpLen = rotatedUpPerp.magnitude;\r\n\r\n if (rotatedUpPerpLen < 0.000001) {\r\n result.set(swingRotation);\r\n return result;\r\n }\r\n\r\n rotatedUpPerp.scaleBy(1 / rotatedUpPerpLen);\r\n\r\n // Calculate twist rotation to align rotatedUpPerp with up\r\n const twistRotation = new Quaternion();\r\n this.fromToRotation(rotatedUpPerp, up, twistRotation);\r\n\r\n // Combine swing and twist\r\n return Quaternion.multiply(twistRotation, swingRotation, result);\r\n }\r\n\r\n /**\r\n * Calculate a look-at rotation with twist constraint.\r\n *\r\n * @remarks\r\n * This creates a rotation that:\r\n * 1. Aligns 'forward' direction to 'targetDir'\r\n * 2. Keeps 'up' direction as close as possible to 'targetUp'\r\n *\r\n * This prevents unwanted twist around the bone axis.\r\n *\r\n * @param forward - Current forward direction (will be aligned to targetDir)\r\n * @param targetDir - Desired forward direction\r\n * @param up - Current up direction (perpendicular to forward)\r\n * @param targetUp - Desired up direction (will be projected perpendicular to targetDir)\r\n * @param result - Output quaternion\r\n * @returns The rotation quaternion\r\n */\r\n static lookAtRotation(\r\n forward: Vector3,\r\n targetDir: Vector3,\r\n up: Vector3,\r\n targetUp: Vector3,\r\n result: Quaternion\r\n ): Quaternion {\r\n const forwardNorm = Vector3.normalize(forward, new Vector3());\r\n const targetDirNorm = Vector3.normalize(targetDir, new Vector3());\r\n\r\n // First, align forward to targetDir (swing rotation)\r\n const swingRotation = new Quaternion();\r\n this.fromToRotation(forwardNorm, targetDirNorm, swingRotation);\r\n\r\n // Rotate the up vector by swing rotation\r\n const rotatedUp = swingRotation.transform(up, new Vector3());\r\n\r\n // Project targetUp onto plane perpendicular to targetDir\r\n const dot = Vector3.dot(targetUp, targetDirNorm);\r\n const projection = Vector3.scale(targetDirNorm, dot, new Vector3());\r\n const targetUpPerp = Vector3.sub(targetUp, projection, new Vector3());\r\n const targetUpPerpLen = targetUpPerp.magnitude;\r\n\r\n // If targetUp is parallel to targetDir, no twist correction needed\r\n if (targetUpPerpLen < 0.000001) {\r\n result.set(swingRotation);\r\n return result;\r\n }\r\n\r\n targetUpPerp.scaleBy(1 / targetUpPerpLen);\r\n\r\n // Project rotatedUp onto the same plane\r\n const rotatedUpDot = Vector3.dot(rotatedUp, targetDirNorm);\r\n const rotatedUpProj = Vector3.scale(targetDirNorm, rotatedUpDot, new Vector3());\r\n const rotatedUpPerp = Vector3.sub(rotatedUp, rotatedUpProj, new Vector3());\r\n const rotatedUpPerpLen = rotatedUpPerp.magnitude;\r\n\r\n if (rotatedUpPerpLen < 0.000001) {\r\n result.set(swingRotation);\r\n return result;\r\n }\r\n\r\n rotatedUpPerp.scaleBy(1 / rotatedUpPerpLen);\r\n\r\n // Calculate twist rotation around targetDir\r\n const twistRotation = new Quaternion();\r\n this.fromToRotation(rotatedUpPerp, targetUpPerp, twistRotation);\r\n\r\n // Combine swing and twist\r\n return Quaternion.multiply(twistRotation, swingRotation, result);\r\n }\r\n}\r\n"],"names":["IKUtils","fromToRotation","from","to","result","fromNorm","Vector3","normalize","toNorm","dot","identity","axis","cross","axisPX","lenSq","x","y","z","axisPY","inplaceNormalize","fromAxisAngle","Math","PI","angle","acos","calculateBoneLength","start","end","distance","decomposeSwingTwist","q","outSwing","outTwist","w","twistLen","sqrt","set","twistInv","Quaternion","conjugate","multiply","getTwistAngle","twist","len","halfAngle","max","min","sign","createTwist","s","sin","cos","clampAndSmoothTwist","currentTwist","previousTwist","minTwist","maxTwist","smoothFactor","clampedTwist","undefined","diff","lookAtRotationWithPole","forward","targetDir","poleDir","forwardNorm","targetDirNorm","poleDirNorm","swingRotation","right","rightLenSq","scaleBy","up","originalUp","originalUpLenSq","rotatedUp","transform","rotatedUpDot","rotatedUpProj","scale","rotatedUpPerp","sub","rotatedUpPerpLen","magnitude","twistRotation","lookAtRotation","targetUp","projection","targetUpPerp","targetUpPerpLen"],"mappings":"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"}