@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.
- package/dist/animation/animation.js +4 -33
- package/dist/animation/animation.js.map +1 -1
- package/dist/animation/animationset.js +24 -11
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/animationtrack.js +1 -0
- package/dist/animation/animationtrack.js.map +1 -1
- package/dist/animation/eulerrotationtrack.js +0 -1
- package/dist/animation/eulerrotationtrack.js.map +1 -1
- package/dist/animation/ik/ccd_solver.js +372 -0
- package/dist/animation/ik/ccd_solver.js.map +1 -0
- package/dist/animation/ik/fabrik_solver.js +399 -0
- package/dist/animation/ik/fabrik_solver.js.map +1 -0
- package/dist/animation/ik/ik_angle_constraint.js +181 -0
- package/dist/animation/ik/ik_angle_constraint.js.map +1 -0
- package/dist/animation/ik/ik_chain.js +163 -0
- package/dist/animation/ik/ik_chain.js.map +1 -0
- package/dist/animation/ik/ik_chain_builder.js +68 -0
- package/dist/animation/ik/ik_chain_builder.js.map +1 -0
- package/dist/animation/ik/ik_constraint.js +25 -0
- package/dist/animation/ik/ik_constraint.js.map +1 -0
- package/dist/animation/ik/ik_pole_constraint.js +123 -0
- package/dist/animation/ik/ik_pole_constraint.js.map +1 -0
- package/dist/animation/ik/ik_solver.js +48 -0
- package/dist/animation/ik/ik_solver.js.map +1 -0
- package/dist/animation/ik/ik_track.js +96 -0
- package/dist/animation/ik/ik_track.js.map +1 -0
- package/dist/animation/ik/ik_utils.js +270 -0
- package/dist/animation/ik/ik_utils.js.map +1 -0
- package/dist/animation/ik/two_bone_ik_solver.js +332 -0
- package/dist/animation/ik/two_bone_ik_solver.js.map +1 -0
- package/dist/animation/ik_modifier.js +61 -0
- package/dist/animation/ik_modifier.js.map +1 -0
- package/dist/animation/ik_postprocessor.js +71 -0
- package/dist/animation/ik_postprocessor.js.map +1 -0
- package/dist/animation/manual_transform_processor.js +156 -0
- package/dist/animation/manual_transform_processor.js.map +1 -0
- package/dist/animation/morphtarget.js +7 -1
- package/dist/animation/morphtarget.js.map +1 -1
- package/dist/animation/morphtrack.js +3 -3
- package/dist/animation/morphtrack.js.map +1 -1
- package/dist/animation/proptrack.js +37 -41
- package/dist/animation/proptrack.js.map +1 -1
- package/dist/animation/rotationtrack.js +0 -1
- package/dist/animation/rotationtrack.js.map +1 -1
- package/dist/animation/scaletrack.js +0 -1
- package/dist/animation/scaletrack.js.map +1 -1
- package/dist/animation/skeleton.js +57 -60
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skeleton_modifier.js +38 -0
- package/dist/animation/skeleton_modifier.js.map +1 -0
- package/dist/animation/skeleton_postprocessor.js +50 -0
- package/dist/animation/skeleton_postprocessor.js.map +1 -0
- package/dist/animation/spring/multi_chain_spring_system.js +503 -0
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -0
- package/dist/animation/spring/spring_chain.js +103 -0
- package/dist/animation/spring/spring_chain.js.map +1 -0
- package/dist/animation/spring/spring_collider.js +247 -0
- package/dist/animation/spring/spring_collider.js.map +1 -0
- package/dist/animation/spring/spring_constraint.js +21 -0
- package/dist/animation/spring/spring_constraint.js.map +1 -0
- package/dist/animation/spring/spring_particle.js +20 -0
- package/dist/animation/spring/spring_particle.js.map +1 -0
- package/dist/animation/spring/spring_system.js +526 -0
- package/dist/animation/spring/spring_system.js.map +1 -0
- package/dist/animation/spring_modifier.js +45 -0
- package/dist/animation/spring_modifier.js.map +1 -0
- package/dist/animation/spring_postprocessor.js +54 -0
- package/dist/animation/spring_postprocessor.js.map +1 -0
- package/dist/animation/translationtrack.js +0 -1
- package/dist/animation/translationtrack.js.map +1 -1
- package/dist/app/api.js +13 -4
- package/dist/app/api.js.map +1 -1
- package/dist/app/app.js +13 -1
- package/dist/app/app.js.map +1 -1
- package/dist/app/engine.js +33 -45
- package/dist/app/engine.js.map +1 -1
- package/dist/app/inputmgr.js.map +1 -1
- package/dist/app/runtimescript.js.map +1 -1
- package/dist/app/screen.js +318 -0
- package/dist/app/screen.js.map +1 -0
- package/dist/app/scriptingsystem.js +10 -6
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +11 -22
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +79 -58
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/builtin.js +5 -5
- package/dist/asset/builtin.js.map +1 -1
- package/dist/asset/loaders/dds/dds.js +6 -2
- package/dist/asset/loaders/dds/dds.js.map +1 -1
- package/dist/asset/loaders/dds/dds_loader.js +1 -1
- package/dist/asset/loaders/dds/dds_loader.js.map +1 -1
- package/dist/asset/loaders/gltf/gltf_loader.js +14 -6
- package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
- package/dist/asset/loaders/gltf/helpers.js +6 -2
- package/dist/asset/loaders/gltf/helpers.js.map +1 -1
- package/dist/asset/loaders/hdr/hdr.js +22 -15
- package/dist/asset/loaders/hdr/hdr.js.map +1 -1
- package/dist/asset/loaders/image/tga_Loader.js +2 -1
- package/dist/asset/loaders/image/tga_Loader.js.map +1 -1
- package/dist/asset/loaders/image/webimage_loader.js.map +1 -1
- package/dist/asset/loaders/loader.js +2 -2
- package/dist/asset/loaders/loader.js.map +1 -1
- package/dist/asset/model.js +9 -5
- package/dist/asset/model.js.map +1 -1
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/blitter.js +9 -11
- package/dist/blitter/blitter.js.map +1 -1
- package/dist/blitter/box.js +0 -1
- package/dist/blitter/box.js.map +1 -1
- package/dist/blitter/copy.js.map +1 -1
- package/dist/blitter/gaussianblur.js.map +1 -1
- package/dist/camera/base.js +1 -3
- package/dist/camera/base.js.map +1 -1
- package/dist/camera/camera.js +121 -37
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/fps.js +19 -17
- package/dist/camera/fps.js.map +1 -1
- package/dist/camera/orbit.js +45 -43
- package/dist/camera/orbit.js.map +1 -1
- package/dist/camera/orthocamera.js +27 -21
- package/dist/camera/orthocamera.js.map +1 -1
- package/dist/camera/perspectivecamera.js +28 -19
- package/dist/camera/perspectivecamera.js.map +1 -1
- package/dist/index.d.ts +15802 -15577
- package/dist/index.js +33 -11
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/grassmaterial.js.map +1 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +11 -5
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +10 -9
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/albedocolor.js.map +1 -1
- package/dist/material/mixins/foliage.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +66 -4
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +7 -0
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +3 -3
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/brdf.js.map +1 -1
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mixins/texture.js +3 -0
- package/dist/material/mixins/texture.js.map +1 -1
- package/dist/material/mixins/vertexcolor.js.map +1 -1
- package/dist/material/particle.js.map +1 -1
- package/dist/material/pbrblueprint.js +180 -22
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/shader/helper.js +41 -56
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/sprite.js +301 -0
- package/dist/material/sprite.js.map +1 -0
- package/dist/material/sprite3d.js +301 -0
- package/dist/material/sprite3d.js.map +1 -0
- package/dist/material/sprite3d_std.js +116 -0
- package/dist/material/sprite3d_std.js.map +1 -0
- package/dist/material/sprite3dblueprint.js +235 -0
- package/dist/material/sprite3dblueprint.js.map +1 -0
- package/dist/material/sprite_std.js +116 -0
- package/dist/material/sprite_std.js.map +1 -0
- package/dist/material/spriteblueprint.js +235 -0
- package/dist/material/spriteblueprint.js.map +1 -0
- package/dist/material/terrain-cm.js +0 -1
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/unlit.js.map +1 -1
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/fxaa.js.map +1 -1
- package/dist/posteffect/grayscale.js.map +1 -1
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/ssr.js +7 -5
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +8 -6
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +0 -10
- package/dist/render/clipmap.js.map +1 -1
- package/dist/render/cluster_light.js +4 -4
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/cull_visitor.js +15 -17
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/depthpass.js +3 -4
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable.js +15 -0
- package/dist/render/drawable.js.map +1 -0
- package/dist/render/drawable_mixin.js +8 -4
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +3 -1
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +67 -64
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/fullscreenquad.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +3 -1
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +3 -1
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/hzb.js +1 -2
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/lightpass.js +13 -13
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/objectcolorpass.js +4 -7
- package/dist/render/objectcolorpass.js.map +1 -1
- package/dist/render/primitive.js +4 -5
- package/dist/render/primitive.js.map +1 -1
- package/dist/render/render_queue.js +10 -5
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +16 -22
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/renderpass.js +27 -52
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/rendertarget.js +5 -0
- package/dist/render/rendertarget.js.map +1 -0
- package/dist/render/screenrendertarget.js +56 -0
- package/dist/render/screenrendertarget.js.map +1 -0
- package/dist/render/shadowmap_pass.js +4 -5
- package/dist/render/shadowmap_pass.js.map +1 -1
- package/dist/render/sky.js +16 -14
- package/dist/render/sky.js.map +1 -1
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +296 -0
- package/dist/scene/basesprite.js.map +1 -0
- package/dist/scene/batchgroup.js +4 -2
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +9 -10
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/graph_node.js.map +1 -1
- package/dist/scene/light.js +22 -4
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +96 -26
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/octree.js.map +1 -1
- package/dist/scene/particlesys.js +25 -22
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/raycast_visitor.js +0 -16
- package/dist/scene/raycast_visitor.js.map +1 -1
- package/dist/scene/scene.js +7 -4
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +20 -35
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/sprite.js +18 -0
- package/dist/scene/sprite.js.map +1 -0
- package/dist/scene/sprite3d.js +18 -0
- package/dist/scene/sprite3d.js.map +1 -0
- package/dist/scene/terrain-cm/grass.js +5 -4
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grassmaterial.js +3 -1
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +65 -48
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/water.js +35 -30
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/atmosphere.js +17 -29
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/misc.js.map +1 -1
- package/dist/shaders/noise.js.map +1 -1
- package/dist/shaders/pbr.js.map +1 -1
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shaders/water.js.map +1 -1
- package/dist/shadow/esm.js +1 -1
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/shader.js +3 -1
- package/dist/shadow/shader.js.map +1 -1
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadowmapper.js +6 -18
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/shapes/box.js +9 -3
- package/dist/shapes/box.js.map +1 -1
- package/dist/shapes/cylinder.js +2 -2
- package/dist/shapes/cylinder.js.map +1 -1
- package/dist/shapes/plane.js +2 -2
- package/dist/shapes/plane.js.map +1 -1
- package/dist/shapes/shape.js +2 -1
- package/dist/shapes/shape.js.map +1 -1
- package/dist/shapes/sphere.js +2 -2
- package/dist/shapes/sphere.js.map +1 -1
- package/dist/shapes/tetrahedron.js +5 -6
- package/dist/shapes/tetrahedron.js.map +1 -1
- package/dist/shapes/torus.js +2 -2
- package/dist/shapes/torus.js.map +1 -1
- package/dist/utility/aabbtree.js +1 -1
- package/dist/utility/aabbtree.js.map +1 -1
- package/dist/utility/blueprint/common/constants.js +578 -104
- package/dist/utility/blueprint/common/constants.js.map +1 -1
- package/dist/utility/blueprint/common/math.js +471 -9
- package/dist/utility/blueprint/common/math.js.map +1 -1
- package/dist/utility/blueprint/common.js +1 -1
- package/dist/utility/blueprint/common.js.map +1 -1
- package/dist/utility/blueprint/material/func.js +9 -5
- package/dist/utility/blueprint/material/func.js.map +1 -1
- package/dist/utility/blueprint/material/inputs.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +288 -80
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/blueprint/material/pbr.js +92 -4
- package/dist/utility/blueprint/material/pbr.js.map +1 -1
- package/dist/utility/blueprint/material/texture.js +62 -45
- package/dist/utility/blueprint/material/texture.js.map +1 -1
- package/dist/utility/blueprint/node.js +28 -1
- package/dist/utility/blueprint/node.js.map +1 -1
- package/dist/utility/bounding_volume.js.map +1 -1
- package/dist/utility/debug.js.map +1 -1
- package/dist/utility/draco/decoder.js.map +1 -1
- package/dist/utility/misc.js +1 -1
- package/dist/utility/misc.js.map +1 -1
- package/dist/utility/panorama.js.map +1 -1
- package/dist/utility/pmrem.js.map +1 -1
- package/dist/utility/rendermipmap.js.map +1 -1
- package/dist/utility/serialization/json.js +19 -15
- package/dist/utility/serialization/json.js.map +1 -1
- package/dist/utility/serialization/manager.js +89 -22
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +44 -41
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +4 -3
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +97 -9
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/common.js +102 -28
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +14 -12
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +216 -26
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +71 -100
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/misc.js +3 -2
- package/dist/utility/serialization/scene/misc.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +42 -9
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +7 -5
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +18 -15
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +3 -2
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +164 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -0
- package/dist/utility/serialization/scene/terrain.js +8 -6
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +11 -9
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js +6 -0
- package/dist/utility/serialization/types.js.map +1 -0
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/utility/textures/ggxlut.js.map +1 -1
- package/dist/utility/textures/gradientnoise.js.map +1 -1
- package/dist/utility/textures/randomnoise.js.map +1 -1
- package/dist/values.js +14 -14
- package/dist/values.js.map +1 -1
- 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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"}
|