@zephyr3d/scene 0.8.0 → 0.8.1
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/animationset.js +198 -1
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/ik/ccd_solver.js +3 -4
- package/dist/animation/ik/ccd_solver.js.map +1 -1
- package/dist/animation/ik/fabrik_solver.js +3 -4
- package/dist/animation/ik/fabrik_solver.js.map +1 -1
- package/dist/animation/ik/ik_pole_constraint.js +7 -2
- package/dist/animation/ik/ik_pole_constraint.js.map +1 -1
- package/dist/animation/ik/ik_utils.js +0 -79
- package/dist/animation/ik/ik_utils.js.map +1 -1
- package/dist/animation/ik/two_bone_ik_solver.js +3 -4
- package/dist/animation/ik/two_bone_ik_solver.js.map +1 -1
- package/dist/animation/spring/spring_bone.js +240 -0
- package/dist/animation/spring/spring_bone.js.map +1 -0
- package/dist/animation/spring/spring_bone_collider.js +198 -0
- package/dist/animation/spring/spring_bone_collider.js.map +1 -0
- package/dist/animation/spring/spring_bone_constraint.js +170 -0
- package/dist/animation/spring/spring_bone_constraint.js.map +1 -0
- package/dist/animation/spring/spring_bone_system.js +328 -0
- package/dist/animation/spring/spring_bone_system.js.map +1 -0
- package/dist/asset/model.js +2 -2
- package/dist/index.d.ts +15 -0
- package/dist/material/mixins/pbr/common.js +20 -17
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/render/gpu_picking.js +100 -0
- package/dist/render/gpu_picking.js.map +1 -0
- package/dist/render/rendergraph/device_pool_allocator.js +41 -0
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -0
- package/dist/render/rendergraph/executor.js +146 -0
- package/dist/render/rendergraph/executor.js.map +1 -0
- package/dist/render/rendergraph/forward_plus_builder.js +414 -0
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -0
- package/dist/render/rendergraph/rendergraph.js +306 -0
- package/dist/render/rendergraph/rendergraph.js.map +1 -0
- package/dist/render/rendergraph/types.js +57 -0
- package/dist/render/rendergraph/types.js.map +1 -0
- package/dist/render/sky_motion_vector.js +85 -0
- package/dist/render/sky_motion_vector.js.map +1 -0
- package/dist/utility/serialization/scene/animation.js +3 -3
- package/dist/utility/serialization/scene/node.js +1 -1
- package/package.json +2 -2
- package/dist/animation/ik/ik_chain_builder.js +0 -68
- package/dist/animation/ik/ik_chain_builder.js.map +0 -1
- package/dist/node_modules/@zephyr3d/runtime/dist/runtime/runtimemgr.js +0 -38
- package/dist/node_modules/@zephyr3d/runtime/dist/runtime/runtimemgr.js.map +0 -1
- package/dist/node_modules/@zephyr3d/runtime/dist/runtime/runtimescript.js +0 -10
- package/dist/node_modules/@zephyr3d/runtime/dist/runtime/runtimescript.js.map +0 -1
- package/dist/node_modules/@zephyr3d/runtime/dist/runtime/scriptingsystem.js +0 -127
- package/dist/node_modules/@zephyr3d/runtime/dist/runtime/scriptingsystem.js.map +0 -1
- package/dist/node_modules/@zephyr3d/runtime/dist/runtime/scriptregistry.js +0 -263
- package/dist/node_modules/@zephyr3d/runtime/dist/runtime/scriptregistry.js.map +0 -1
- package/dist/src/animation/animation.js +0 -127
- package/dist/src/animation/animation.js.map +0 -1
- package/dist/src/animation/animationset.js +0 -255
- package/dist/src/animation/animationset.js.map +0 -1
- package/dist/src/animation/animationtrack.js +0 -34
- package/dist/src/animation/animationtrack.js.map +0 -1
- package/dist/src/animation/eulerrotationtrack.js +0 -52
- package/dist/src/animation/eulerrotationtrack.js.map +0 -1
- package/dist/src/animation/morphtarget.js +0 -93
- package/dist/src/animation/morphtarget.js.map +0 -1
- package/dist/src/animation/morphtrack.js +0 -70
- package/dist/src/animation/morphtrack.js.map +0 -1
- package/dist/src/animation/proptrack.js +0 -161
- package/dist/src/animation/proptrack.js.map +0 -1
- package/dist/src/animation/rotationtrack.js +0 -51
- package/dist/src/animation/rotationtrack.js.map +0 -1
- package/dist/src/animation/scaletrack.js +0 -50
- package/dist/src/animation/scaletrack.js.map +0 -1
- package/dist/src/animation/skeleton.js +0 -204
- package/dist/src/animation/skeleton.js.map +0 -1
- package/dist/src/animation/translationtrack.js +0 -50
- package/dist/src/animation/translationtrack.js.map +0 -1
- package/dist/src/app/app.js +0 -129
- package/dist/src/app/app.js.map +0 -1
- package/dist/src/app/inputmgr.js +0 -267
- package/dist/src/app/inputmgr.js.map +0 -1
- package/dist/src/asset/assetmanager.js +0 -404
- package/dist/src/asset/assetmanager.js.map +0 -1
- package/dist/src/asset/builtin.js +0 -337
- package/dist/src/asset/builtin.js.map +0 -1
- package/dist/src/asset/loaders/dds/dds.js +0 -470
- package/dist/src/asset/loaders/dds/dds.js.map +0 -1
- package/dist/src/asset/loaders/dds/dds_loader.js +0 -28
- package/dist/src/asset/loaders/dds/dds_loader.js.map +0 -1
- package/dist/src/asset/loaders/gltf/gltf_loader.js +0 -1265
- package/dist/src/asset/loaders/gltf/gltf_loader.js.map +0 -1
- package/dist/src/asset/loaders/gltf/helpers.js +0 -327
- package/dist/src/asset/loaders/gltf/helpers.js.map +0 -1
- package/dist/src/asset/loaders/hdr/hdr.js +0 -180
- package/dist/src/asset/loaders/hdr/hdr.js.map +0 -1
- package/dist/src/asset/loaders/image/tga_Loader.js +0 -116
- package/dist/src/asset/loaders/image/tga_Loader.js.map +0 -1
- package/dist/src/asset/loaders/image/webimage_loader.js +0 -63
- package/dist/src/asset/loaders/image/webimage_loader.js.map +0 -1
- package/dist/src/asset/loaders/loader.js +0 -45
- package/dist/src/asset/loaders/loader.js.map +0 -1
- package/dist/src/asset/model.js +0 -414
- package/dist/src/asset/model.js.map +0 -1
- package/dist/src/blitter/bilateralblur.js +0 -221
- package/dist/src/blitter/bilateralblur.js.map +0 -1
- package/dist/src/blitter/blitter.js +0 -390
- package/dist/src/blitter/blitter.js.map +0 -1
- package/dist/src/blitter/box.js +0 -118
- package/dist/src/blitter/box.js.map +0 -1
- package/dist/src/blitter/copy.js +0 -22
- package/dist/src/blitter/copy.js.map +0 -1
- package/dist/src/blitter/gaussianblur.js +0 -228
- package/dist/src/blitter/gaussianblur.js.map +0 -1
- package/dist/src/camera/base.js +0 -92
- package/dist/src/camera/base.js.map +0 -1
- package/dist/src/camera/camera.js +0 -1005
- package/dist/src/camera/camera.js.map +0 -1
- package/dist/src/camera/fps.js +0 -238
- package/dist/src/camera/fps.js.map +0 -1
- package/dist/src/camera/orbit.js +0 -245
- package/dist/src/camera/orbit.js.map +0 -1
- package/dist/src/camera/orthocamera.js +0 -167
- package/dist/src/camera/orthocamera.js.map +0 -1
- package/dist/src/camera/perspectivecamera.js +0 -141
- package/dist/src/camera/perspectivecamera.js.map +0 -1
- package/dist/src/index.js +0 -120
- package/dist/src/index.js.map +0 -1
- package/dist/src/material/blinn.js +0 -81
- package/dist/src/material/blinn.js.map +0 -1
- package/dist/src/material/grassmaterial.js +0 -113
- package/dist/src/material/grassmaterial.js.map +0 -1
- package/dist/src/material/lambert.js +0 -92
- package/dist/src/material/lambert.js.map +0 -1
- package/dist/src/material/material.js +0 -301
- package/dist/src/material/material.js.map +0 -1
- package/dist/src/material/meshmaterial.js +0 -704
- package/dist/src/material/meshmaterial.js.map +0 -1
- package/dist/src/material/mixins/albedocolor.js +0 -76
- package/dist/src/material/mixins/albedocolor.js.map +0 -1
- package/dist/src/material/mixins/foliage.js +0 -47
- package/dist/src/material/mixins/foliage.js.map +0 -1
- package/dist/src/material/mixins/lightmodel/blinnphong.js +0 -112
- package/dist/src/material/mixins/lightmodel/blinnphong.js.map +0 -1
- package/dist/src/material/mixins/lightmodel/lambert.js +0 -58
- package/dist/src/material/mixins/lightmodel/lambert.js.map +0 -1
- package/dist/src/material/mixins/lightmodel/pbrmetallicroughness.js +0 -178
- package/dist/src/material/mixins/lightmodel/pbrmetallicroughness.js.map +0 -1
- package/dist/src/material/mixins/lightmodel/pbrspecularglossness.js +0 -139
- package/dist/src/material/mixins/lightmodel/pbrspecularglossness.js.map +0 -1
- package/dist/src/material/mixins/lit.js +0 -476
- package/dist/src/material/mixins/lit.js.map +0 -1
- package/dist/src/material/mixins/pbr/common.js +0 -918
- package/dist/src/material/mixins/pbr/common.js.map +0 -1
- package/dist/src/material/mixins/texture.js +0 -172
- package/dist/src/material/mixins/texture.js.map +0 -1
- package/dist/src/material/mixins/vertexcolor.js +0 -56
- package/dist/src/material/mixins/vertexcolor.js.map +0 -1
- package/dist/src/material/particle.js +0 -178
- package/dist/src/material/particle.js.map +0 -1
- package/dist/src/material/pbrmr.js +0 -97
- package/dist/src/material/pbrmr.js.map +0 -1
- package/dist/src/material/pbrsg.js +0 -97
- package/dist/src/material/pbrsg.js.map +0 -1
- package/dist/src/material/shader/helper.js +0 -1209
- package/dist/src/material/shader/helper.js.map +0 -1
- package/dist/src/material/terrain-cm.js +0 -606
- package/dist/src/material/terrain-cm.js.map +0 -1
- package/dist/src/material/terrainmaterial.js +0 -375
- package/dist/src/material/terrainmaterial.js.map +0 -1
- package/dist/src/material/unlit.js +0 -41
- package/dist/src/material/unlit.js.map +0 -1
- package/dist/src/material/water.js +0 -417
- package/dist/src/material/water.js.map +0 -1
- package/dist/src/posteffect/bloom.js +0 -361
- package/dist/src/posteffect/bloom.js.map +0 -1
- package/dist/src/posteffect/compositor.js +0 -226
- package/dist/src/posteffect/compositor.js.map +0 -1
- package/dist/src/posteffect/fxaa.js +0 -273
- package/dist/src/posteffect/fxaa.js.map +0 -1
- package/dist/src/posteffect/grayscale.js +0 -69
- package/dist/src/posteffect/grayscale.js.map +0 -1
- package/dist/src/posteffect/motionblur.js +0 -96
- package/dist/src/posteffect/motionblur.js.map +0 -1
- package/dist/src/posteffect/posteffect.js +0 -126
- package/dist/src/posteffect/posteffect.js.map +0 -1
- package/dist/src/posteffect/sao.js +0 -324
- package/dist/src/posteffect/sao.js.map +0 -1
- package/dist/src/posteffect/ssr.js +0 -489
- package/dist/src/posteffect/ssr.js.map +0 -1
- package/dist/src/posteffect/taa.js +0 -172
- package/dist/src/posteffect/taa.js.map +0 -1
- package/dist/src/posteffect/tonemap.js +0 -94
- package/dist/src/posteffect/tonemap.js.map +0 -1
- package/dist/src/render/abuffer_oit.js +0 -361
- package/dist/src/render/abuffer_oit.js.map +0 -1
- package/dist/src/render/clipmap.js +0 -851
- package/dist/src/render/clipmap.js.map +0 -1
- package/dist/src/render/cluster_light.js +0 -333
- package/dist/src/render/cluster_light.js.map +0 -1
- package/dist/src/render/cull_visitor.js +0 -187
- package/dist/src/render/cull_visitor.js.map +0 -1
- package/dist/src/render/depthpass.js +0 -68
- package/dist/src/render/depthpass.js.map +0 -1
- package/dist/src/render/drawable_mixin.js +0 -227
- package/dist/src/render/drawable_mixin.js.map +0 -1
- package/dist/src/render/envlight.js +0 -463
- package/dist/src/render/envlight.js.map +0 -1
- package/dist/src/render/fbm_wavegenerator.js +0 -251
- package/dist/src/render/fbm_wavegenerator.js.map +0 -1
- package/dist/src/render/fft_wavegenerator.js +0 -1006
- package/dist/src/render/fft_wavegenerator.js.map +0 -1
- package/dist/src/render/fullscreenquad.js +0 -38
- package/dist/src/render/fullscreenquad.js.map +0 -1
- package/dist/src/render/gerstner_wavegenerator.js +0 -314
- package/dist/src/render/gerstner_wavegenerator.js.map +0 -1
- package/dist/src/render/globalbindgroup_allocator.js +0 -60
- package/dist/src/render/globalbindgroup_allocator.js.map +0 -1
- package/dist/src/render/hzb.js +0 -273
- package/dist/src/render/hzb.js.map +0 -1
- package/dist/src/render/lightpass.js +0 -172
- package/dist/src/render/lightpass.js.map +0 -1
- package/dist/src/render/objectcolorpass.js +0 -51
- package/dist/src/render/objectcolorpass.js.map +0 -1
- package/dist/src/render/primitive.js +0 -364
- package/dist/src/render/primitive.js.map +0 -1
- package/dist/src/render/render_queue.js +0 -467
- package/dist/src/render/render_queue.js.map +0 -1
- package/dist/src/render/renderbundle_wrapper.js +0 -152
- package/dist/src/render/renderbundle_wrapper.js.map +0 -1
- package/dist/src/render/renderer.js +0 -455
- package/dist/src/render/renderer.js.map +0 -1
- package/dist/src/render/renderpass.js +0 -200
- package/dist/src/render/renderpass.js.map +0 -1
- package/dist/src/render/shadowmap_pass.js +0 -56
- package/dist/src/render/shadowmap_pass.js.map +0 -1
- package/dist/src/render/sky.js +0 -1103
- package/dist/src/render/sky.js.map +0 -1
- package/dist/src/render/weightedblended_oit.js +0 -168
- package/dist/src/render/weightedblended_oit.js.map +0 -1
- package/dist/src/scene/batchgroup.js +0 -162
- package/dist/src/scene/batchgroup.js.map +0 -1
- package/dist/src/scene/environment.js +0 -209
- package/dist/src/scene/environment.js.map +0 -1
- package/dist/src/scene/graph_node.js +0 -72
- package/dist/src/scene/graph_node.js.map +0 -1
- package/dist/src/scene/light.js +0 -416
- package/dist/src/scene/light.js.map +0 -1
- package/dist/src/scene/mesh.js +0 -341
- package/dist/src/scene/mesh.js.map +0 -1
- package/dist/src/scene/octree.js +0 -649
- package/dist/src/scene/octree.js.map +0 -1
- package/dist/src/scene/particlesys.js +0 -738
- package/dist/src/scene/particlesys.js.map +0 -1
- package/dist/src/scene/raycast_visitor.js +0 -103
- package/dist/src/scene/raycast_visitor.js.map +0 -1
- package/dist/src/scene/scene.js +0 -284
- package/dist/src/scene/scene.js.map +0 -1
- package/dist/src/scene/scene_node.js +0 -732
- package/dist/src/scene/scene_node.js.map +0 -1
- package/dist/src/scene/terrain/grass.js +0 -278
- package/dist/src/scene/terrain/grass.js.map +0 -1
- package/dist/src/scene/terrain/heightfield.js +0 -475
- package/dist/src/scene/terrain/heightfield.js.map +0 -1
- package/dist/src/scene/terrain/patch.js +0 -530
- package/dist/src/scene/terrain/patch.js.map +0 -1
- package/dist/src/scene/terrain/quadtree.js +0 -461
- package/dist/src/scene/terrain/quadtree.js.map +0 -1
- package/dist/src/scene/terrain/terrain.js +0 -246
- package/dist/src/scene/terrain/terrain.js.map +0 -1
- package/dist/src/scene/terrain-cm/grass.js +0 -594
- package/dist/src/scene/terrain-cm/grass.js.map +0 -1
- package/dist/src/scene/terrain-cm/grassmaterial.js +0 -159
- package/dist/src/scene/terrain-cm/grassmaterial.js.map +0 -1
- package/dist/src/scene/terrain-cm/terrain-cm.js +0 -538
- package/dist/src/scene/terrain-cm/terrain-cm.js.map +0 -1
- package/dist/src/scene/water.js +0 -374
- package/dist/src/scene/water.js.map +0 -1
- package/dist/src/shaders/atmosphere.js +0 -957
- package/dist/src/shaders/atmosphere.js.map +0 -1
- package/dist/src/shaders/fog.js +0 -112
- package/dist/src/shaders/fog.js.map +0 -1
- package/dist/src/shaders/misc.js +0 -266
- package/dist/src/shaders/misc.js.map +0 -1
- package/dist/src/shaders/noise.js +0 -222
- package/dist/src/shaders/noise.js.map +0 -1
- package/dist/src/shaders/pbr.js +0 -51
- package/dist/src/shaders/pbr.js.map +0 -1
- package/dist/src/shaders/shadow.js +0 -636
- package/dist/src/shaders/shadow.js.map +0 -1
- package/dist/src/shaders/ssr.js +0 -490
- package/dist/src/shaders/ssr.js.map +0 -1
- package/dist/src/shaders/temporal.js +0 -215
- package/dist/src/shaders/temporal.js.map +0 -1
- package/dist/src/shaders/water.js +0 -756
- package/dist/src/shaders/water.js.map +0 -1
- package/dist/src/shadow/esm.js +0 -237
- package/dist/src/shadow/esm.js.map +0 -1
- package/dist/src/shadow/pcf_opt.js +0 -181
- package/dist/src/shadow/pcf_opt.js.map +0 -1
- package/dist/src/shadow/pcf_pd.js +0 -189
- package/dist/src/shadow/pcf_pd.js.map +0 -1
- package/dist/src/shadow/shader.js +0 -37
- package/dist/src/shadow/shader.js.map +0 -1
- package/dist/src/shadow/shadow_impl.js +0 -15
- package/dist/src/shadow/shadow_impl.js.map +0 -1
- package/dist/src/shadow/shadowmapper.js +0 -790
- package/dist/src/shadow/shadowmapper.js.map +0 -1
- package/dist/src/shadow/ssm.js +0 -159
- package/dist/src/shadow/ssm.js.map +0 -1
- package/dist/src/shadow/vsm.js +0 -297
- package/dist/src/shadow/vsm.js.map +0 -1
- package/dist/src/shapes/box.js +0 -386
- package/dist/src/shapes/box.js.map +0 -1
- package/dist/src/shapes/cylinder.js +0 -125
- package/dist/src/shapes/cylinder.js.map +0 -1
- package/dist/src/shapes/plane.js +0 -88
- package/dist/src/shapes/plane.js.map +0 -1
- package/dist/src/shapes/shape.js +0 -87
- package/dist/src/shapes/shape.js.map +0 -1
- package/dist/src/shapes/sphere.js +0 -114
- package/dist/src/shapes/sphere.js.map +0 -1
- package/dist/src/shapes/tetrahedron.js +0 -188
- package/dist/src/shapes/tetrahedron.js.map +0 -1
- package/dist/src/shapes/torus.js +0 -111
- package/dist/src/shapes/torus.js.map +0 -1
- package/dist/src/utility/aabbtree.js +0 -400
- package/dist/src/utility/aabbtree.js.map +0 -1
- package/dist/src/utility/bounding_volume.js +0 -29
- package/dist/src/utility/bounding_volume.js.map +0 -1
- package/dist/src/utility/debug.js +0 -28
- package/dist/src/utility/debug.js.map +0 -1
- package/dist/src/utility/draco/decoder.js +0 -116
- package/dist/src/utility/draco/decoder.js.map +0 -1
- package/dist/src/utility/misc.js +0 -105
- package/dist/src/utility/misc.js.map +0 -1
- package/dist/src/utility/panorama.js +0 -163
- package/dist/src/utility/panorama.js.map +0 -1
- package/dist/src/utility/pmrem.js +0 -354
- package/dist/src/utility/pmrem.js.map +0 -1
- package/dist/src/utility/rendermipmap.js +0 -115
- package/dist/src/utility/rendermipmap.js.map +0 -1
- package/dist/src/utility/serialization/json.js +0 -402
- package/dist/src/utility/serialization/json.js.map +0 -1
- package/dist/src/utility/serialization/manager.js +0 -623
- package/dist/src/utility/serialization/manager.js.map +0 -1
- package/dist/src/utility/serialization/scene/animation.js +0 -248
- package/dist/src/utility/serialization/scene/animation.js.map +0 -1
- package/dist/src/utility/serialization/scene/batch.js +0 -59
- package/dist/src/utility/serialization/scene/batch.js.map +0 -1
- package/dist/src/utility/serialization/scene/camera.js +0 -790
- package/dist/src/utility/serialization/scene/camera.js.map +0 -1
- package/dist/src/utility/serialization/scene/common.js +0 -222
- package/dist/src/utility/serialization/scene/common.js.map +0 -1
- package/dist/src/utility/serialization/scene/light.js +0 -575
- package/dist/src/utility/serialization/scene/light.js.map +0 -1
- package/dist/src/utility/serialization/scene/material.js +0 -1111
- package/dist/src/utility/serialization/scene/material.js.map +0 -1
- package/dist/src/utility/serialization/scene/mesh.js +0 -148
- package/dist/src/utility/serialization/scene/mesh.js.map +0 -1
- package/dist/src/utility/serialization/scene/misc.js +0 -39
- package/dist/src/utility/serialization/scene/misc.js.map +0 -1
- package/dist/src/utility/serialization/scene/node.js +0 -451
- package/dist/src/utility/serialization/scene/node.js.map +0 -1
- package/dist/src/utility/serialization/scene/particle.js +0 -425
- package/dist/src/utility/serialization/scene/particle.js.map +0 -1
- package/dist/src/utility/serialization/scene/primitive.js +0 -692
- package/dist/src/utility/serialization/scene/primitive.js.map +0 -1
- package/dist/src/utility/serialization/scene/scene.js +0 -704
- package/dist/src/utility/serialization/scene/scene.js.map +0 -1
- package/dist/src/utility/serialization/scene/terrain.js +0 -488
- package/dist/src/utility/serialization/scene/terrain.js.map +0 -1
- package/dist/src/utility/serialization/scene/water.js +0 -465
- package/dist/src/utility/serialization/scene/water.js.map +0 -1
- package/dist/src/utility/shprojector.js +0 -297
- package/dist/src/utility/shprojector.js.map +0 -1
- package/dist/src/utility/textures/ggxlut.js +0 -213
- package/dist/src/utility/textures/ggxlut.js.map +0 -1
- package/dist/src/utility/textures/gradientnoise.js +0 -62
- package/dist/src/utility/textures/gradientnoise.js.map +0 -1
- package/dist/src/utility/textures/randomnoise.js +0 -41
- package/dist/src/utility/textures/randomnoise.js.map +0 -1
- package/dist/src/values.js +0 -162
- package/dist/src/values.js.map +0 -1
- package/dist/utility/blueprint/material/common.js +0 -7
- package/dist/utility/blueprint/material/common.js.map +0 -1
- package/dist/utility/serialization/blueprint/constants.js +0 -255
- package/dist/utility/serialization/blueprint/constants.js.map +0 -1
- package/dist/utility/serialization/blueprint/material/constants.js +0 -203
- package/dist/utility/serialization/blueprint/material/constants.js.map +0 -1
- package/dist/utility/serialization/blueprint/material/texture.js +0 -165
- package/dist/utility/serialization/blueprint/material/texture.js.map +0 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { Vector3 } from '@zephyr3d/base';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base class for spring bone constraints.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Constraints are applied after physics simulation to enforce
|
|
8
|
+
* additional rules between spring bones.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/ class SpringBoneConstraint {
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Distance constraint between two spring bones.
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* Maintains a distance range between two spring bones.
|
|
18
|
+
* Useful for preventing penetration and excessive stretching between
|
|
19
|
+
* adjacent chains (e.g., skirt panels).
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/ class DistanceConstraint extends SpringBoneConstraint {
|
|
23
|
+
/** First spring bone */ _bone1;
|
|
24
|
+
/** Second spring bone */ _bone2;
|
|
25
|
+
/** Minimum distance (prevents penetration) */ _minDistance;
|
|
26
|
+
/** Maximum distance (prevents excessive stretching) */ _maxDistance;
|
|
27
|
+
/** Constraint stiffness (0-1, how strongly to enforce) */ _stiffness;
|
|
28
|
+
/**
|
|
29
|
+
* Create a distance constraint.
|
|
30
|
+
*
|
|
31
|
+
* @param bone1 - First spring bone
|
|
32
|
+
* @param bone2 - Second spring bone
|
|
33
|
+
* @param minDistance - Minimum distance (default: 0.01)
|
|
34
|
+
* @param maxDistance - Maximum distance (default: 0.2)
|
|
35
|
+
* @param stiffness - Constraint stiffness (0-1, default: 0.5)
|
|
36
|
+
*/ constructor(bone1, bone2, minDistance = 0.01, maxDistance = 0.2, stiffness = 0.5){
|
|
37
|
+
super();
|
|
38
|
+
this._bone1 = bone1;
|
|
39
|
+
this._bone2 = bone2;
|
|
40
|
+
this._minDistance = Math.max(0, minDistance);
|
|
41
|
+
this._maxDistance = Math.max(this._minDistance, maxDistance);
|
|
42
|
+
this._stiffness = Math.max(0, Math.min(1, stiffness));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get/set minimum distance.
|
|
46
|
+
*/ get minDistance() {
|
|
47
|
+
return this._minDistance;
|
|
48
|
+
}
|
|
49
|
+
set minDistance(value) {
|
|
50
|
+
this._minDistance = Math.max(0, value);
|
|
51
|
+
this._maxDistance = Math.max(this._minDistance, this._maxDistance);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get/set maximum distance.
|
|
55
|
+
*/ get maxDistance() {
|
|
56
|
+
return this._maxDistance;
|
|
57
|
+
}
|
|
58
|
+
set maxDistance(value) {
|
|
59
|
+
this._maxDistance = Math.max(this._minDistance, value);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get/set stiffness.
|
|
63
|
+
*/ get stiffness() {
|
|
64
|
+
return this._stiffness;
|
|
65
|
+
}
|
|
66
|
+
set stiffness(value) {
|
|
67
|
+
this._stiffness = Math.max(0, Math.min(1, value));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Apply the distance constraint.
|
|
71
|
+
*/ apply() {
|
|
72
|
+
const pos1 = this._bone1.currentPosition;
|
|
73
|
+
const pos2 = this._bone2.currentPosition;
|
|
74
|
+
// Calculate current distance
|
|
75
|
+
const direction = Vector3.sub(pos2, pos1, new Vector3());
|
|
76
|
+
const distance = direction.magnitude;
|
|
77
|
+
if (distance < 0.000001) {
|
|
78
|
+
return; // Bones are at same position
|
|
79
|
+
}
|
|
80
|
+
const directionNorm = Vector3.scale(direction, 1 / distance, new Vector3());
|
|
81
|
+
let correction = 0;
|
|
82
|
+
if (distance < this._minDistance) {
|
|
83
|
+
// Too close, push apart
|
|
84
|
+
correction = (this._minDistance - distance) * 0.5 * this._stiffness;
|
|
85
|
+
} else if (distance > this._maxDistance) {
|
|
86
|
+
// Too far, pull together
|
|
87
|
+
correction = (this._maxDistance - distance) * 0.5 * this._stiffness;
|
|
88
|
+
} else {
|
|
89
|
+
// Within range, no correction needed
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// Apply correction to both bones (equal and opposite)
|
|
93
|
+
const offset = Vector3.scale(directionNorm, correction, new Vector3());
|
|
94
|
+
pos1.addBy(Vector3.scale(offset, -1, new Vector3()));
|
|
95
|
+
pos2.addBy(offset);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Circular constraint for skirt-like structures.
|
|
100
|
+
*
|
|
101
|
+
* @remarks
|
|
102
|
+
* Maintains distance constraints between adjacent bones in a circular arrangement.
|
|
103
|
+
* Automatically creates distance constraints between neighboring chains.
|
|
104
|
+
*
|
|
105
|
+
* @public
|
|
106
|
+
*/ class CircularConstraint extends SpringBoneConstraint {
|
|
107
|
+
/** Array of spring bone chains arranged in a circle */ _chains;
|
|
108
|
+
/** Distance constraints between adjacent chains */ _constraints;
|
|
109
|
+
/** Minimum distance between adjacent bones */ _minDistance;
|
|
110
|
+
/** Maximum distance between adjacent bones */ _maxDistance;
|
|
111
|
+
/** Constraint stiffness */ _stiffness;
|
|
112
|
+
/**
|
|
113
|
+
* Create a circular constraint.
|
|
114
|
+
*
|
|
115
|
+
* @param chains - Array of spring bone chains arranged in a circle
|
|
116
|
+
* @param minDistance - Minimum distance between adjacent bones (default: 0.05)
|
|
117
|
+
* @param maxDistance - Maximum distance between adjacent bones (default: 0.15)
|
|
118
|
+
* @param stiffness - Constraint stiffness (0-1, default: 0.5)
|
|
119
|
+
*/ constructor(chains, minDistance = 0.05, maxDistance = 0.15, stiffness = 0.5){
|
|
120
|
+
super();
|
|
121
|
+
this._chains = chains;
|
|
122
|
+
this._minDistance = minDistance;
|
|
123
|
+
this._maxDistance = maxDistance;
|
|
124
|
+
this._stiffness = stiffness;
|
|
125
|
+
this._constraints = [];
|
|
126
|
+
this._buildConstraints();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Build distance constraints between adjacent chains.
|
|
130
|
+
*/ _buildConstraints() {
|
|
131
|
+
this._constraints = [];
|
|
132
|
+
if (this._chains.length < 2) {
|
|
133
|
+
return; // Need at least 2 chains
|
|
134
|
+
}
|
|
135
|
+
// For each level (depth in the chain)
|
|
136
|
+
const maxDepth = Math.min(...this._chains.map((chain)=>chain.length));
|
|
137
|
+
for(let depth = 0; depth < maxDepth; depth++){
|
|
138
|
+
// Connect adjacent chains
|
|
139
|
+
for(let i = 0; i < this._chains.length; i++){
|
|
140
|
+
const nextIndex = (i + 1) % this._chains.length; // Wrap around
|
|
141
|
+
const bone1 = this._chains[i][depth];
|
|
142
|
+
const bone2 = this._chains[nextIndex][depth];
|
|
143
|
+
if (bone1 && bone2) {
|
|
144
|
+
const constraint = new DistanceConstraint(bone1, bone2, this._minDistance, this._maxDistance, this._stiffness);
|
|
145
|
+
this._constraints.push(constraint);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Rebuild constraints (call after modifying chains).
|
|
152
|
+
*/ rebuild() {
|
|
153
|
+
this._buildConstraints();
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Apply all distance constraints.
|
|
157
|
+
*/ apply() {
|
|
158
|
+
for (const constraint of this._constraints){
|
|
159
|
+
constraint.apply();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Get all distance constraints.
|
|
164
|
+
*/ get constraints() {
|
|
165
|
+
return this._constraints;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export { CircularConstraint, DistanceConstraint, SpringBoneConstraint };
|
|
170
|
+
//# sourceMappingURL=spring_bone_constraint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spring_bone_constraint.js","sources":["../../../src/animation/spring/spring_bone_constraint.ts"],"sourcesContent":["import { Vector3 } from '@zephyr3d/base';\r\nimport type { SpringBone } from './spring_bone';\r\n\r\n/**\r\n * Base class for spring bone constraints.\r\n *\r\n * @remarks\r\n * Constraints are applied after physics simulation to enforce\r\n * additional rules between spring bones.\r\n *\r\n * @public\r\n */\r\nexport abstract class SpringBoneConstraint {\r\n /**\r\n * Apply the constraint.\r\n *\r\n * @remarks\r\n * This method modifies the positions of spring bones to satisfy the constraint.\r\n */\r\n abstract apply(): void;\r\n}\r\n\r\n/**\r\n * Distance constraint between two spring bones.\r\n *\r\n * @remarks\r\n * Maintains a distance range between two spring bones.\r\n * Useful for preventing penetration and excessive stretching between\r\n * adjacent chains (e.g., skirt panels).\r\n *\r\n * @public\r\n */\r\nexport class DistanceConstraint extends SpringBoneConstraint {\r\n /** First spring bone */\r\n private _bone1: SpringBone;\r\n /** Second spring bone */\r\n private _bone2: SpringBone;\r\n /** Minimum distance (prevents penetration) */\r\n private _minDistance: number;\r\n /** Maximum distance (prevents excessive stretching) */\r\n private _maxDistance: number;\r\n /** Constraint stiffness (0-1, how strongly to enforce) */\r\n private _stiffness: number;\r\n\r\n /**\r\n * Create a distance constraint.\r\n *\r\n * @param bone1 - First spring bone\r\n * @param bone2 - Second spring bone\r\n * @param minDistance - Minimum distance (default: 0.01)\r\n * @param maxDistance - Maximum distance (default: 0.2)\r\n * @param stiffness - Constraint stiffness (0-1, default: 0.5)\r\n */\r\n constructor(\r\n bone1: SpringBone,\r\n bone2: SpringBone,\r\n minDistance = 0.01,\r\n maxDistance = 0.2,\r\n stiffness = 0.5\r\n ) {\r\n super();\r\n this._bone1 = bone1;\r\n this._bone2 = bone2;\r\n this._minDistance = Math.max(0, minDistance);\r\n this._maxDistance = Math.max(this._minDistance, maxDistance);\r\n this._stiffness = Math.max(0, Math.min(1, stiffness));\r\n }\r\n\r\n /**\r\n * Get/set minimum distance.\r\n */\r\n get minDistance(): number {\r\n return this._minDistance;\r\n }\r\n\r\n set minDistance(value: number) {\r\n this._minDistance = Math.max(0, value);\r\n this._maxDistance = Math.max(this._minDistance, this._maxDistance);\r\n }\r\n\r\n /**\r\n * Get/set maximum distance.\r\n */\r\n get maxDistance(): number {\r\n return this._maxDistance;\r\n }\r\n\r\n set maxDistance(value: number) {\r\n this._maxDistance = Math.max(this._minDistance, value);\r\n }\r\n\r\n /**\r\n * Get/set stiffness.\r\n */\r\n get stiffness(): number {\r\n return this._stiffness;\r\n }\r\n\r\n set stiffness(value: number) {\r\n this._stiffness = Math.max(0, Math.min(1, value));\r\n }\r\n\r\n /**\r\n * Apply the distance constraint.\r\n */\r\n apply(): void {\r\n const pos1 = this._bone1.currentPosition;\r\n const pos2 = this._bone2.currentPosition;\r\n\r\n // Calculate current distance\r\n const direction = Vector3.sub(pos2, pos1, new Vector3());\r\n const distance = direction.magnitude;\r\n\r\n if (distance < 0.000001) {\r\n return; // Bones are at same position\r\n }\r\n\r\n const directionNorm = Vector3.scale(direction, 1 / distance, new Vector3());\r\n\r\n let correction = 0;\r\n\r\n if (distance < this._minDistance) {\r\n // Too close, push apart\r\n correction = (this._minDistance - distance) * 0.5 * this._stiffness;\r\n } else if (distance > this._maxDistance) {\r\n // Too far, pull together\r\n correction = (this._maxDistance - distance) * 0.5 * this._stiffness;\r\n } else {\r\n // Within range, no correction needed\r\n return;\r\n }\r\n\r\n // Apply correction to both bones (equal and opposite)\r\n const offset = Vector3.scale(directionNorm, correction, new Vector3());\r\n pos1.addBy(Vector3.scale(offset, -1, new Vector3()));\r\n pos2.addBy(offset);\r\n }\r\n}\r\n\r\n/**\r\n * Circular constraint for skirt-like structures.\r\n *\r\n * @remarks\r\n * Maintains distance constraints between adjacent bones in a circular arrangement.\r\n * Automatically creates distance constraints between neighboring chains.\r\n *\r\n * @public\r\n */\r\nexport class CircularConstraint extends SpringBoneConstraint {\r\n /** Array of spring bone chains arranged in a circle */\r\n private _chains: SpringBone[][];\r\n /** Distance constraints between adjacent chains */\r\n private _constraints: DistanceConstraint[];\r\n /** Minimum distance between adjacent bones */\r\n private _minDistance: number;\r\n /** Maximum distance between adjacent bones */\r\n private _maxDistance: number;\r\n /** Constraint stiffness */\r\n private _stiffness: number;\r\n\r\n /**\r\n * Create a circular constraint.\r\n *\r\n * @param chains - Array of spring bone chains arranged in a circle\r\n * @param minDistance - Minimum distance between adjacent bones (default: 0.05)\r\n * @param maxDistance - Maximum distance between adjacent bones (default: 0.15)\r\n * @param stiffness - Constraint stiffness (0-1, default: 0.5)\r\n */\r\n constructor(\r\n chains: SpringBone[][],\r\n minDistance = 0.05,\r\n maxDistance = 0.15,\r\n stiffness = 0.5\r\n ) {\r\n super();\r\n this._chains = chains;\r\n this._minDistance = minDistance;\r\n this._maxDistance = maxDistance;\r\n this._stiffness = stiffness;\r\n this._constraints = [];\r\n\r\n this._buildConstraints();\r\n }\r\n\r\n /**\r\n * Build distance constraints between adjacent chains.\r\n */\r\n private _buildConstraints(): void {\r\n this._constraints = [];\r\n\r\n if (this._chains.length < 2) {\r\n return; // Need at least 2 chains\r\n }\r\n\r\n // For each level (depth in the chain)\r\n const maxDepth = Math.min(...this._chains.map(chain => chain.length));\r\n\r\n for (let depth = 0; depth < maxDepth; depth++) {\r\n // Connect adjacent chains\r\n for (let i = 0; i < this._chains.length; i++) {\r\n const nextIndex = (i + 1) % this._chains.length; // Wrap around\r\n\r\n const bone1 = this._chains[i][depth];\r\n const bone2 = this._chains[nextIndex][depth];\r\n\r\n if (bone1 && bone2) {\r\n const constraint = new DistanceConstraint(\r\n bone1,\r\n bone2,\r\n this._minDistance,\r\n this._maxDistance,\r\n this._stiffness\r\n );\r\n this._constraints.push(constraint);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Rebuild constraints (call after modifying chains).\r\n */\r\n rebuild(): void {\r\n this._buildConstraints();\r\n }\r\n\r\n /**\r\n * Apply all distance constraints.\r\n */\r\n apply(): void {\r\n for (const constraint of this._constraints) {\r\n constraint.apply();\r\n }\r\n }\r\n\r\n /**\r\n * Get all distance constraints.\r\n */\r\n get constraints(): readonly DistanceConstraint[] {\r\n return this._constraints;\r\n }\r\n}\r\n"],"names":["SpringBoneConstraint","DistanceConstraint","bone1","bone2","minDistance","maxDistance","stiffness","_bone1","_bone2","_minDistance","Math","max","_maxDistance","_stiffness","min","value","apply","pos1","currentPosition","pos2","direction","Vector3","sub","distance","magnitude","directionNorm","scale","correction","offset","addBy","CircularConstraint","chains","_chains","_constraints","_buildConstraints","length","maxDepth","map","chain","depth","i","nextIndex","constraint","push","rebuild","constraints"],"mappings":";;AAGA;;;;;;;;AAQC,IACM,MAAeA,oBAAAA,CAAAA;AAQtB;AAEA;;;;;;;;;IAUO,MAAMC,kBAA2BD,SAAAA,oBAAAA,CAAAA;6BAEtC,MAA2B;8BAE3B,MAA2B;mDAE3B,YAA6B;4DAE7B,YAA6B;+DAE7B,UAA2B;AAE3B;;;;;;;;AAQC,MACD,WACEE,CAAAA,KAAiB,EACjBC,KAAiB,EACjBC,WAAAA,GAAc,IAAI,EAClBC,WAAc,GAAA,GAAG,EACjBC,SAAAA,GAAY,GAAG,CACf;QACA,KAAK,EAAA;QACL,IAAI,CAACC,MAAM,GAAGL,KAAAA;QACd,IAAI,CAACM,MAAM,GAAGL,KAAAA;AACd,QAAA,IAAI,CAACM,YAAY,GAAGC,IAAKC,CAAAA,GAAG,CAAC,CAAGP,EAAAA,WAAAA,CAAAA;QAChC,IAAI,CAACQ,YAAY,GAAGF,IAAAA,CAAKC,GAAG,CAAC,IAAI,CAACF,YAAY,EAAEJ,WAAAA,CAAAA;QAChD,IAAI,CAACQ,UAAU,GAAGH,IAAKC,CAAAA,GAAG,CAAC,CAAGD,EAAAA,IAAAA,CAAKI,GAAG,CAAC,CAAGR,EAAAA,SAAAA,CAAAA,CAAAA;AAC5C;AAEA;;AAEC,MACD,IAAIF,WAAsB,GAAA;QACxB,OAAO,IAAI,CAACK,YAAY;AAC1B;IAEA,IAAIL,WAAAA,CAAYW,KAAa,EAAE;AAC7B,QAAA,IAAI,CAACN,YAAY,GAAGC,IAAKC,CAAAA,GAAG,CAAC,CAAGI,EAAAA,KAAAA,CAAAA;AAChC,QAAA,IAAI,CAACH,YAAY,GAAGF,IAAAA,CAAKC,GAAG,CAAC,IAAI,CAACF,YAAY,EAAE,IAAI,CAACG,YAAY,CAAA;AACnE;AAEA;;AAEC,MACD,IAAIP,WAAsB,GAAA;QACxB,OAAO,IAAI,CAACO,YAAY;AAC1B;IAEA,IAAIP,WAAAA,CAAYU,KAAa,EAAE;QAC7B,IAAI,CAACH,YAAY,GAAGF,IAAAA,CAAKC,GAAG,CAAC,IAAI,CAACF,YAAY,EAAEM,KAAAA,CAAAA;AAClD;AAEA;;AAEC,MACD,IAAIT,SAAoB,GAAA;QACtB,OAAO,IAAI,CAACO,UAAU;AACxB;IAEA,IAAIP,SAAAA,CAAUS,KAAa,EAAE;QAC3B,IAAI,CAACF,UAAU,GAAGH,IAAKC,CAAAA,GAAG,CAAC,CAAGD,EAAAA,IAAAA,CAAKI,GAAG,CAAC,CAAGC,EAAAA,KAAAA,CAAAA,CAAAA;AAC5C;AAEA;;AAEC,MACDC,KAAc,GAAA;AACZ,QAAA,MAAMC,IAAO,GAAA,IAAI,CAACV,MAAM,CAACW,eAAe;AACxC,QAAA,MAAMC,IAAO,GAAA,IAAI,CAACX,MAAM,CAACU,eAAe;;AAGxC,QAAA,MAAME,YAAYC,OAAQC,CAAAA,GAAG,CAACH,IAAAA,EAAMF,MAAM,IAAII,OAAAA,EAAAA,CAAAA;QAC9C,MAAME,QAAAA,GAAWH,UAAUI,SAAS;AAEpC,QAAA,IAAID,WAAW,QAAU,EAAA;AACvB,YAAA,OAAA;AACF;AAEA,QAAA,MAAME,gBAAgBJ,OAAQK,CAAAA,KAAK,CAACN,SAAW,EAAA,CAAA,GAAIG,UAAU,IAAIF,OAAAA,EAAAA,CAAAA;AAEjE,QAAA,IAAIM,UAAa,GAAA,CAAA;AAEjB,QAAA,IAAIJ,QAAW,GAAA,IAAI,CAACd,YAAY,EAAE;;YAEhCkB,UAAa,GAAC,CAAA,IAAI,CAAClB,YAAY,GAAGc,QAAO,IAAK,GAAA,GAAM,IAAI,CAACV,UAAU;AACrE,SAAA,MAAO,IAAIU,QAAAA,GAAW,IAAI,CAACX,YAAY,EAAE;;YAEvCe,UAAa,GAAC,CAAA,IAAI,CAACf,YAAY,GAAGW,QAAO,IAAK,GAAA,GAAM,IAAI,CAACV,UAAU;SAC9D,MAAA;;AAEL,YAAA;AACF;;AAGA,QAAA,MAAMe,SAASP,OAAQK,CAAAA,KAAK,CAACD,aAAAA,EAAeE,YAAY,IAAIN,OAAAA,EAAAA,CAAAA;QAC5DJ,IAAKY,CAAAA,KAAK,CAACR,OAAQK,CAAAA,KAAK,CAACE,MAAQ,EAAA,IAAI,IAAIP,OAAAA,EAAAA,CAAAA,CAAAA;AACzCF,QAAAA,IAAAA,CAAKU,KAAK,CAACD,MAAAA,CAAAA;AACb;AACF;AAEA;;;;;;;;IASO,MAAME,kBAA2B9B,SAAAA,oBAAAA,CAAAA;4DAEtC,OAAgC;wDAEhC,YAA2C;mDAE3C,YAA6B;mDAE7B,YAA6B;gCAE7B,UAA2B;AAE3B;;;;;;;MAQA,WAAA,CACE+B,MAAsB,EACtB3B,WAAc,GAAA,IAAI,EAClBC,WAAAA,GAAc,IAAI,EAClBC,SAAY,GAAA,GAAG,CACf;QACA,KAAK,EAAA;QACL,IAAI,CAAC0B,OAAO,GAAGD,MAAAA;QACf,IAAI,CAACtB,YAAY,GAAGL,WAAAA;QACpB,IAAI,CAACQ,YAAY,GAAGP,WAAAA;QACpB,IAAI,CAACQ,UAAU,GAAGP,SAAAA;QAClB,IAAI,CAAC2B,YAAY,GAAG,EAAE;AAEtB,QAAA,IAAI,CAACC,iBAAiB,EAAA;AACxB;AAEA;;AAEC,MACD,iBAAkC,GAAA;QAChC,IAAI,CAACD,YAAY,GAAG,EAAE;AAEtB,QAAA,IAAI,IAAI,CAACD,OAAO,CAACG,MAAM,GAAG,CAAG,EAAA;AAC3B,YAAA,OAAA;AACF;;AAGA,QAAA,MAAMC,QAAW1B,GAAAA,IAAAA,CAAKI,GAAG,CAAA,GAAI,IAAI,CAACkB,OAAO,CAACK,GAAG,CAACC,CAAAA,KAAAA,GAASA,MAAMH,MAAM,CAAA,CAAA;AAEnE,QAAA,IAAK,IAAII,KAAAA,GAAQ,CAAGA,EAAAA,KAAAA,GAAQH,UAAUG,KAAS,EAAA,CAAA;;YAE7C,IAAK,IAAIC,CAAI,GAAA,CAAA,EAAGA,CAAI,GAAA,IAAI,CAACR,OAAO,CAACG,MAAM,EAAEK,CAAK,EAAA,CAAA;AAC5C,gBAAA,MAAMC,SAAY,GAACD,CAAAA,CAAAA,GAAI,CAAA,IAAK,IAAI,CAACR,OAAO,CAACG,MAAM,CAAA;AAE/C,gBAAA,MAAMjC,QAAQ,IAAI,CAAC8B,OAAO,CAACQ,CAAAA,CAAE,CAACD,KAAM,CAAA;AACpC,gBAAA,MAAMpC,QAAQ,IAAI,CAAC6B,OAAO,CAACS,SAAAA,CAAU,CAACF,KAAM,CAAA;AAE5C,gBAAA,IAAIrC,SAASC,KAAO,EAAA;AAClB,oBAAA,MAAMuC,UAAa,GAAA,IAAIzC,kBACrBC,CAAAA,KAAAA,EACAC,OACA,IAAI,CAACM,YAAY,EACjB,IAAI,CAACG,YAAY,EACjB,IAAI,CAACC,UAAU,CAAA;AAEjB,oBAAA,IAAI,CAACoB,YAAY,CAACU,IAAI,CAACD,UAAAA,CAAAA;AACzB;AACF;AACF;AACF;AAEA;;AAEC,MACDE,OAAgB,GAAA;AACd,QAAA,IAAI,CAACV,iBAAiB,EAAA;AACxB;AAEA;;AAEC,MACDlB,KAAc,GAAA;AACZ,QAAA,KAAK,MAAM0B,UAAAA,IAAc,IAAI,CAACT,YAAY,CAAE;AAC1CS,YAAAA,UAAAA,CAAW1B,KAAK,EAAA;AAClB;AACF;AAEA;;AAEC,MACD,IAAI6B,WAA6C,GAAA;QAC/C,OAAO,IAAI,CAACZ,YAAY;AAC1B;AACF;;;;"}
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { Vector3, Quaternion } from '@zephyr3d/base';
|
|
2
|
+
import { SpringBone } from './spring_bone.js';
|
|
3
|
+
import { CircularConstraint } from './spring_bone_constraint.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Spring bone system manager.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* Manages multiple spring bones, colliders, and constraints.
|
|
10
|
+
* Updates physics simulation and applies results to bone nodes.
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
*/ class SpringBoneSystem {
|
|
14
|
+
/** All spring bones in the system */ _springBones;
|
|
15
|
+
/** All colliders in the system */ _colliders;
|
|
16
|
+
/** All constraints in the system */ _constraints;
|
|
17
|
+
/** Gravity vector in world space */ _gravity;
|
|
18
|
+
/** Wind force vector in world space */ _windForce;
|
|
19
|
+
/** Enable/disable the system */ _enabled;
|
|
20
|
+
/** Number of constraint iterations per update */ _constraintIterations;
|
|
21
|
+
/** Whether deltaTime is in milliseconds (true) or seconds (false) */ _deltaTimeInMilliseconds;
|
|
22
|
+
/**
|
|
23
|
+
* Create a spring bone system.
|
|
24
|
+
*
|
|
25
|
+
* @param deltaTimeInMilliseconds - Whether deltaTime is in milliseconds (default: false)
|
|
26
|
+
*/ constructor(deltaTimeInMilliseconds = false){
|
|
27
|
+
this._springBones = [];
|
|
28
|
+
this._colliders = [];
|
|
29
|
+
this._constraints = [];
|
|
30
|
+
this._gravity = new Vector3(0, -9.8, 0);
|
|
31
|
+
this._windForce = new Vector3(0, 0, 0);
|
|
32
|
+
this._enabled = true;
|
|
33
|
+
this._constraintIterations = 2;
|
|
34
|
+
this._deltaTimeInMilliseconds = deltaTimeInMilliseconds;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get/set gravity vector.
|
|
38
|
+
*/ get gravity() {
|
|
39
|
+
return this._gravity;
|
|
40
|
+
}
|
|
41
|
+
set gravity(value) {
|
|
42
|
+
this._gravity.set(value);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get/set wind force vector.
|
|
46
|
+
*/ get windForce() {
|
|
47
|
+
return this._windForce;
|
|
48
|
+
}
|
|
49
|
+
set windForce(value) {
|
|
50
|
+
this._windForce.set(value);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get/set enabled state.
|
|
54
|
+
*/ get enabled() {
|
|
55
|
+
return this._enabled;
|
|
56
|
+
}
|
|
57
|
+
set enabled(value) {
|
|
58
|
+
this._enabled = value;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Add a spring bone to the system.
|
|
62
|
+
*
|
|
63
|
+
* @param bone - The bone node to control
|
|
64
|
+
* @param stiffness - Spring stiffness (0-1, default: 0.1)
|
|
65
|
+
* @param damping - Damping factor (0-1, default: 0.5)
|
|
66
|
+
* @param mass - Mass of the bone (default: 1)
|
|
67
|
+
* @param gravityScale - Gravity scale (default: 1)
|
|
68
|
+
* @param radius - Collision radius (default: 0.05)
|
|
69
|
+
* @returns The created spring bone
|
|
70
|
+
*/ addSpringBone(bone, stiffness = 0.1, damping = 0.5, mass = 1, gravityScale = 1, radius = 0.05) {
|
|
71
|
+
const springBone = new SpringBone(bone, stiffness, damping, mass, gravityScale, radius);
|
|
72
|
+
this._springBones.push(springBone);
|
|
73
|
+
return springBone;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Add a spring bone chain to the system.
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* Adds multiple bones in a chain with the same parameters.
|
|
80
|
+
* The first bone (root) is typically fixed and not simulated.
|
|
81
|
+
*
|
|
82
|
+
* @param bones - Array of bone nodes from root to tip
|
|
83
|
+
* @param stiffness - Spring stiffness (0-1, default: 0.1)
|
|
84
|
+
* @param damping - Damping factor (0-1, default: 0.5)
|
|
85
|
+
* @param mass - Mass of each bone (default: 1)
|
|
86
|
+
* @param gravityScale - Gravity scale (default: 1)
|
|
87
|
+
* @param radius - Collision radius (default: 0.05)
|
|
88
|
+
* @param skipRoot - Skip the first bone (root) (default: true)
|
|
89
|
+
* @returns Array of created spring bones
|
|
90
|
+
*/ addSpringChain(bones, stiffness = 0.1, damping = 0.5, mass = 1, gravityScale = 1, radius = 0.05, skipRoot = true) {
|
|
91
|
+
const springBones = [];
|
|
92
|
+
const startIndex = skipRoot ? 1 : 0;
|
|
93
|
+
for(let i = startIndex; i < bones.length; i++){
|
|
94
|
+
const springBone = this.addSpringBone(bones[i], stiffness, damping, mass, gravityScale, radius);
|
|
95
|
+
springBones.push(springBone);
|
|
96
|
+
}
|
|
97
|
+
return springBones;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Remove a spring bone from the system.
|
|
101
|
+
*
|
|
102
|
+
* @param springBone - The spring bone to remove
|
|
103
|
+
* @returns True if removed, false if not found
|
|
104
|
+
*/ removeSpringBone(springBone) {
|
|
105
|
+
const index = this._springBones.indexOf(springBone);
|
|
106
|
+
if (index >= 0) {
|
|
107
|
+
this._springBones.splice(index, 1);
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Clear all spring bones.
|
|
114
|
+
*/ clearSpringBones() {
|
|
115
|
+
this._springBones = [];
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Add a collider to the system.
|
|
119
|
+
*
|
|
120
|
+
* @param collider - The collider to add
|
|
121
|
+
*/ addCollider(collider) {
|
|
122
|
+
this._colliders.push(collider);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Remove a collider from the system.
|
|
126
|
+
*
|
|
127
|
+
* @param collider - The collider to remove
|
|
128
|
+
* @returns True if removed, false if not found
|
|
129
|
+
*/ removeCollider(collider) {
|
|
130
|
+
const index = this._colliders.indexOf(collider);
|
|
131
|
+
if (index >= 0) {
|
|
132
|
+
this._colliders.splice(index, 1);
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Clear all colliders.
|
|
139
|
+
*/ clearColliders() {
|
|
140
|
+
this._colliders = [];
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Add a constraint to the system.
|
|
144
|
+
*
|
|
145
|
+
* @param constraint - The constraint to add
|
|
146
|
+
*/ addConstraint(constraint) {
|
|
147
|
+
this._constraints.push(constraint);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Remove a constraint from the system.
|
|
151
|
+
*
|
|
152
|
+
* @param constraint - The constraint to remove
|
|
153
|
+
* @returns True if removed, false if not found
|
|
154
|
+
*/ removeConstraint(constraint) {
|
|
155
|
+
const index = this._constraints.indexOf(constraint);
|
|
156
|
+
if (index >= 0) {
|
|
157
|
+
this._constraints.splice(index, 1);
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Clear all constraints.
|
|
164
|
+
*/ clearConstraints() {
|
|
165
|
+
this._constraints = [];
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Create circular constraints for skirt-like structures.
|
|
169
|
+
*
|
|
170
|
+
* @remarks
|
|
171
|
+
* This is a convenience method for creating distance constraints
|
|
172
|
+
* between adjacent chains arranged in a circle (e.g., skirt panels).
|
|
173
|
+
*
|
|
174
|
+
* @param chains - Array of spring bone chains arranged in a circle
|
|
175
|
+
* @param minDistance - Minimum distance between adjacent bones (default: 0.05)
|
|
176
|
+
* @param maxDistance - Maximum distance between adjacent bones (default: 0.15)
|
|
177
|
+
* @param stiffness - Constraint stiffness (0-1, default: 0.5)
|
|
178
|
+
* @returns The created circular constraint
|
|
179
|
+
*/ createCircularConstraints(chains, minDistance = 0.05, maxDistance = 0.15, stiffness = 0.5) {
|
|
180
|
+
const constraint = new CircularConstraint(chains, minDistance, maxDistance, stiffness);
|
|
181
|
+
this.addConstraint(constraint);
|
|
182
|
+
return constraint;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Get/set number of constraint iterations.
|
|
186
|
+
*
|
|
187
|
+
* @remarks
|
|
188
|
+
* Higher values give more accurate constraint solving but cost more performance.
|
|
189
|
+
* Typical values: 1-5
|
|
190
|
+
*/ get constraintIterations() {
|
|
191
|
+
return this._constraintIterations;
|
|
192
|
+
}
|
|
193
|
+
set constraintIterations(value) {
|
|
194
|
+
this._constraintIterations = Math.max(1, Math.floor(value));
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Reset all spring bones to their initial state.
|
|
198
|
+
*/ reset() {
|
|
199
|
+
for (const springBone of this._springBones){
|
|
200
|
+
springBone.reset();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Update parent bone rotation if parent is not in the spring system.
|
|
205
|
+
*
|
|
206
|
+
* @remarks
|
|
207
|
+
* When skipRoot=true, the parent bone is not in the spring system,
|
|
208
|
+
* but its rotation still needs to be updated to point toward the
|
|
209
|
+
* spring bone's simulated position.
|
|
210
|
+
*
|
|
211
|
+
* @param springBone - The spring bone whose parent should be updated
|
|
212
|
+
*/ _updateParentRotation(springBone) {
|
|
213
|
+
const bone = springBone.bone;
|
|
214
|
+
const parent = bone.parent;
|
|
215
|
+
if (!parent) {
|
|
216
|
+
return; // No parent to update
|
|
217
|
+
}
|
|
218
|
+
// Check if parent is in the spring system
|
|
219
|
+
const parentIsSpringBone = this._springBones.some((sb)=>sb.bone === parent);
|
|
220
|
+
if (parentIsSpringBone) {
|
|
221
|
+
return; // Parent is already being updated by the spring system
|
|
222
|
+
}
|
|
223
|
+
// Parent is not in the spring system, so we need to update its rotation
|
|
224
|
+
// to point toward the spring bone's simulated position
|
|
225
|
+
// Get parent's world position
|
|
226
|
+
const parentWorldPos = new Vector3();
|
|
227
|
+
parent.worldMatrix.decompose(null, null, parentWorldPos);
|
|
228
|
+
// Get simulated position
|
|
229
|
+
const simulatedPos = springBone.currentPosition;
|
|
230
|
+
// Calculate direction from parent to simulated position (in world space)
|
|
231
|
+
const currentDir = Vector3.sub(simulatedPos, parentWorldPos, new Vector3());
|
|
232
|
+
const currentLength = currentDir.magnitude;
|
|
233
|
+
if (currentLength < 0.000001) {
|
|
234
|
+
return; // Too close to parent
|
|
235
|
+
}
|
|
236
|
+
currentDir.scaleBy(1 / currentLength);
|
|
237
|
+
// Get grandparent (parent's parent) if it exists
|
|
238
|
+
const grandparent = parent.parent;
|
|
239
|
+
let grandparentWorldRot = new Quaternion().identity();
|
|
240
|
+
if (grandparent) {
|
|
241
|
+
grandparent.worldMatrix.decompose(null, grandparentWorldRot, null);
|
|
242
|
+
}
|
|
243
|
+
// Transform current direction to grandparent's local space
|
|
244
|
+
const grandparentInvRot = Quaternion.conjugate(grandparentWorldRot, new Quaternion());
|
|
245
|
+
const currentDirLocal = grandparentInvRot.transform(currentDir, new Vector3());
|
|
246
|
+
// Original direction in local space (normalized)
|
|
247
|
+
const originalDirLocal = Vector3.normalize(springBone.initialLocalPosition, new Vector3());
|
|
248
|
+
// Calculate local rotation from original to current
|
|
249
|
+
const localRotation = new Quaternion();
|
|
250
|
+
this._fromToRotation(originalDirLocal, currentDirLocal, localRotation);
|
|
251
|
+
// Apply to parent bone
|
|
252
|
+
parent.rotation = localRotation;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Calculate rotation from one direction to another.
|
|
256
|
+
*/ _fromToRotation(from, to, result) {
|
|
257
|
+
const dot = Vector3.dot(from, to);
|
|
258
|
+
if (dot >= 0.999999) {
|
|
259
|
+
return result.identity();
|
|
260
|
+
}
|
|
261
|
+
if (dot <= -0.999999) {
|
|
262
|
+
let axis = Vector3.cross(Vector3.axisPX(), from, new Vector3());
|
|
263
|
+
const lenSq = axis.x * axis.x + axis.y * axis.y + axis.z * axis.z;
|
|
264
|
+
if (lenSq < 0.000001) {
|
|
265
|
+
axis = Vector3.cross(Vector3.axisPY(), from, new Vector3());
|
|
266
|
+
}
|
|
267
|
+
axis.inplaceNormalize();
|
|
268
|
+
return result.fromAxisAngle(axis, Math.PI);
|
|
269
|
+
}
|
|
270
|
+
const axis = Vector3.cross(from, to).inplaceNormalize();
|
|
271
|
+
const angle = Math.acos(dot);
|
|
272
|
+
return result.fromAxisAngle(axis, angle);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Update the spring bone system.
|
|
276
|
+
*
|
|
277
|
+
* @param deltaTime - Time step (in seconds or milliseconds, depending on constructor parameter)
|
|
278
|
+
*/ update(deltaTime) {
|
|
279
|
+
if (!this._enabled || deltaTime <= 0) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
// Convert to seconds if needed
|
|
283
|
+
const deltaTimeSeconds = this._deltaTimeInMilliseconds ? deltaTime / 1000 : deltaTime;
|
|
284
|
+
// Clamp delta time to avoid instability
|
|
285
|
+
const clampedDeltaTime = Math.min(deltaTimeSeconds, 0.1);
|
|
286
|
+
// Update spring bones one by one (not in parallel)
|
|
287
|
+
// This ensures parent bones are updated before child bones
|
|
288
|
+
for (const springBone of this._springBones){
|
|
289
|
+
// Update physics
|
|
290
|
+
springBone.update(clampedDeltaTime, this._gravity, this._windForce);
|
|
291
|
+
// Apply collisions
|
|
292
|
+
const position = springBone.currentPosition;
|
|
293
|
+
const radius = springBone.radius;
|
|
294
|
+
for (const collider of this._colliders){
|
|
295
|
+
collider.collide(position, radius);
|
|
296
|
+
}
|
|
297
|
+
// Update parent bone rotation if parent is not in the spring system
|
|
298
|
+
this._updateParentRotation(springBone);
|
|
299
|
+
// Apply to bone node
|
|
300
|
+
springBone.applyToNode();
|
|
301
|
+
// Force update the bone's world matrix
|
|
302
|
+
// This ensures child bones see the updated parent transform
|
|
303
|
+
const bone = springBone.bone;
|
|
304
|
+
if (typeof bone.updateWorldMatrix === 'function') {
|
|
305
|
+
bone.updateWorldMatrix(true, false);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
// Apply constraints (multiple iterations for better convergence)
|
|
309
|
+
for(let i = 0; i < this._constraintIterations; i++){
|
|
310
|
+
for (const constraint of this._constraints){
|
|
311
|
+
constraint.apply();
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Get all spring bones.
|
|
317
|
+
*/ get springBones() {
|
|
318
|
+
return this._springBones;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Get all colliders.
|
|
322
|
+
*/ get colliders() {
|
|
323
|
+
return this._colliders;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export { SpringBoneSystem };
|
|
328
|
+
//# sourceMappingURL=spring_bone_system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spring_bone_system.js","sources":["../../../src/animation/spring/spring_bone_system.ts"],"sourcesContent":["import { Vector3, Quaternion } from '@zephyr3d/base';\r\nimport { SpringBone } from './spring_bone';\r\nimport type { SpringBoneCollider } from './spring_bone_collider';\r\nimport type { SpringBoneConstraint } from './spring_bone_constraint';\r\nimport { CircularConstraint } from './spring_bone_constraint';\r\nimport type { SceneNode } from '../../scene/scene_node';\r\n\r\n/**\r\n * Spring bone system manager.\r\n *\r\n * @remarks\r\n * Manages multiple spring bones, colliders, and constraints.\r\n * Updates physics simulation and applies results to bone nodes.\r\n *\r\n * @public\r\n */\r\nexport class SpringBoneSystem {\r\n /** All spring bones in the system */\r\n private _springBones: SpringBone[];\r\n /** All colliders in the system */\r\n private _colliders: SpringBoneCollider[];\r\n /** All constraints in the system */\r\n private _constraints: SpringBoneConstraint[];\r\n /** Gravity vector in world space */\r\n private _gravity: Vector3;\r\n /** Wind force vector in world space */\r\n private _windForce: Vector3;\r\n /** Enable/disable the system */\r\n private _enabled: boolean;\r\n /** Number of constraint iterations per update */\r\n private _constraintIterations: number;\r\n /** Whether deltaTime is in milliseconds (true) or seconds (false) */\r\n private _deltaTimeInMilliseconds: boolean;\r\n\r\n /**\r\n * Create a spring bone system.\r\n *\r\n * @param deltaTimeInMilliseconds - Whether deltaTime is in milliseconds (default: false)\r\n */\r\n constructor(deltaTimeInMilliseconds = false) {\r\n this._springBones = [];\r\n this._colliders = [];\r\n this._constraints = [];\r\n this._gravity = new Vector3(0, -9.8, 0);\r\n this._windForce = new Vector3(0, 0, 0);\r\n this._enabled = true;\r\n this._constraintIterations = 2;\r\n this._deltaTimeInMilliseconds = deltaTimeInMilliseconds;\r\n }\r\n\r\n /**\r\n * Get/set gravity vector.\r\n */\r\n get gravity(): Vector3 {\r\n return this._gravity;\r\n }\r\n\r\n set gravity(value: Vector3) {\r\n this._gravity.set(value);\r\n }\r\n\r\n /**\r\n * Get/set wind force vector.\r\n */\r\n get windForce(): Vector3 {\r\n return this._windForce;\r\n }\r\n\r\n set windForce(value: Vector3) {\r\n this._windForce.set(value);\r\n }\r\n\r\n /**\r\n * Get/set enabled state.\r\n */\r\n get enabled(): boolean {\r\n return this._enabled;\r\n }\r\n\r\n set enabled(value: boolean) {\r\n this._enabled = value;\r\n }\r\n\r\n /**\r\n * Add a spring bone to the system.\r\n *\r\n * @param bone - The bone node to control\r\n * @param stiffness - Spring stiffness (0-1, default: 0.1)\r\n * @param damping - Damping factor (0-1, default: 0.5)\r\n * @param mass - Mass of the bone (default: 1)\r\n * @param gravityScale - Gravity scale (default: 1)\r\n * @param radius - Collision radius (default: 0.05)\r\n * @returns The created spring bone\r\n */\r\n addSpringBone(\r\n bone: SceneNode,\r\n stiffness = 0.1,\r\n damping = 0.5,\r\n mass = 1,\r\n gravityScale = 1,\r\n radius = 0.05\r\n ): SpringBone {\r\n const springBone = new SpringBone(bone, stiffness, damping, mass, gravityScale, radius);\r\n this._springBones.push(springBone);\r\n return springBone;\r\n }\r\n\r\n /**\r\n * Add a spring bone chain to the system.\r\n *\r\n * @remarks\r\n * Adds multiple bones in a chain with the same parameters.\r\n * The first bone (root) is typically fixed and not simulated.\r\n *\r\n * @param bones - Array of bone nodes from root to tip\r\n * @param stiffness - Spring stiffness (0-1, default: 0.1)\r\n * @param damping - Damping factor (0-1, default: 0.5)\r\n * @param mass - Mass of each bone (default: 1)\r\n * @param gravityScale - Gravity scale (default: 1)\r\n * @param radius - Collision radius (default: 0.05)\r\n * @param skipRoot - Skip the first bone (root) (default: true)\r\n * @returns Array of created spring bones\r\n */\r\n addSpringChain(\r\n bones: SceneNode[],\r\n stiffness = 0.1,\r\n damping = 0.5,\r\n mass = 1,\r\n gravityScale = 1,\r\n radius = 0.05,\r\n skipRoot = true\r\n ): SpringBone[] {\r\n const springBones: SpringBone[] = [];\r\n const startIndex = skipRoot ? 1 : 0;\r\n\r\n for (let i = startIndex; i < bones.length; i++) {\r\n const springBone = this.addSpringBone(bones[i], stiffness, damping, mass, gravityScale, radius);\r\n springBones.push(springBone);\r\n }\r\n\r\n return springBones;\r\n }\r\n\r\n /**\r\n * Remove a spring bone from the system.\r\n *\r\n * @param springBone - The spring bone to remove\r\n * @returns True if removed, false if not found\r\n */\r\n removeSpringBone(springBone: SpringBone): boolean {\r\n const index = this._springBones.indexOf(springBone);\r\n if (index >= 0) {\r\n this._springBones.splice(index, 1);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Clear all spring bones.\r\n */\r\n clearSpringBones(): void {\r\n this._springBones = [];\r\n }\r\n\r\n /**\r\n * Add a collider to the system.\r\n *\r\n * @param collider - The collider to add\r\n */\r\n addCollider(collider: SpringBoneCollider): void {\r\n this._colliders.push(collider);\r\n }\r\n\r\n /**\r\n * Remove a collider from the system.\r\n *\r\n * @param collider - The collider to remove\r\n * @returns True if removed, false if not found\r\n */\r\n removeCollider(collider: SpringBoneCollider): boolean {\r\n const index = this._colliders.indexOf(collider);\r\n if (index >= 0) {\r\n this._colliders.splice(index, 1);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Clear all colliders.\r\n */\r\n clearColliders(): void {\r\n this._colliders = [];\r\n }\r\n\r\n /**\r\n * Add a constraint to the system.\r\n *\r\n * @param constraint - The constraint to add\r\n */\r\n addConstraint(constraint: SpringBoneConstraint): void {\r\n this._constraints.push(constraint);\r\n }\r\n\r\n /**\r\n * Remove a constraint from the system.\r\n *\r\n * @param constraint - The constraint to remove\r\n * @returns True if removed, false if not found\r\n */\r\n removeConstraint(constraint: SpringBoneConstraint): boolean {\r\n const index = this._constraints.indexOf(constraint);\r\n if (index >= 0) {\r\n this._constraints.splice(index, 1);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Clear all constraints.\r\n */\r\n clearConstraints(): void {\r\n this._constraints = [];\r\n }\r\n\r\n /**\r\n * Create circular constraints for skirt-like structures.\r\n *\r\n * @remarks\r\n * This is a convenience method for creating distance constraints\r\n * between adjacent chains arranged in a circle (e.g., skirt panels).\r\n *\r\n * @param chains - Array of spring bone chains arranged in a circle\r\n * @param minDistance - Minimum distance between adjacent bones (default: 0.05)\r\n * @param maxDistance - Maximum distance between adjacent bones (default: 0.15)\r\n * @param stiffness - Constraint stiffness (0-1, default: 0.5)\r\n * @returns The created circular constraint\r\n */\r\n createCircularConstraints(\r\n chains: SpringBone[][],\r\n minDistance = 0.05,\r\n maxDistance = 0.15,\r\n stiffness = 0.5\r\n ): CircularConstraint {\r\n const constraint = new CircularConstraint(chains, minDistance, maxDistance, stiffness);\r\n this.addConstraint(constraint);\r\n return constraint;\r\n }\r\n\r\n /**\r\n * Get/set number of constraint iterations.\r\n *\r\n * @remarks\r\n * Higher values give more accurate constraint solving but cost more performance.\r\n * Typical values: 1-5\r\n */\r\n get constraintIterations(): number {\r\n return this._constraintIterations;\r\n }\r\n\r\n set constraintIterations(value: number) {\r\n this._constraintIterations = Math.max(1, Math.floor(value));\r\n }\r\n\r\n /**\r\n * Reset all spring bones to their initial state.\r\n */\r\n reset(): void {\r\n for (const springBone of this._springBones) {\r\n springBone.reset();\r\n }\r\n }\r\n\r\n /**\r\n * Update parent bone rotation if parent is not in the spring system.\r\n *\r\n * @remarks\r\n * When skipRoot=true, the parent bone is not in the spring system,\r\n * but its rotation still needs to be updated to point toward the\r\n * spring bone's simulated position.\r\n *\r\n * @param springBone - The spring bone whose parent should be updated\r\n */\r\n private _updateParentRotation(springBone: SpringBone): void {\r\n const bone = springBone.bone;\r\n const parent = bone.parent;\r\n\r\n if (!parent) {\r\n return; // No parent to update\r\n }\r\n\r\n // Check if parent is in the spring system\r\n const parentIsSpringBone = this._springBones.some((sb) => sb.bone === parent);\r\n if (parentIsSpringBone) {\r\n return; // Parent is already being updated by the spring system\r\n }\r\n\r\n // Parent is not in the spring system, so we need to update its rotation\r\n // to point toward the spring bone's simulated position\r\n\r\n // Get parent's world position\r\n const parentWorldPos = new Vector3();\r\n parent.worldMatrix.decompose(null, null, parentWorldPos);\r\n\r\n // Get simulated position\r\n const simulatedPos = springBone.currentPosition;\r\n\r\n // Calculate direction from parent to simulated position (in world space)\r\n const currentDir = Vector3.sub(simulatedPos, parentWorldPos, new Vector3());\r\n const currentLength = currentDir.magnitude;\r\n\r\n if (currentLength < 0.000001) {\r\n return; // Too close to parent\r\n }\r\n\r\n currentDir.scaleBy(1 / currentLength);\r\n\r\n // Get grandparent (parent's parent) if it exists\r\n const grandparent = parent.parent;\r\n let grandparentWorldRot = new Quaternion().identity();\r\n\r\n if (grandparent) {\r\n grandparent.worldMatrix.decompose(null, grandparentWorldRot, null);\r\n }\r\n\r\n // Transform current direction to grandparent's local space\r\n const grandparentInvRot = Quaternion.conjugate(grandparentWorldRot, new Quaternion());\r\n const currentDirLocal = grandparentInvRot.transform(currentDir, new Vector3());\r\n\r\n // Original direction in local space (normalized)\r\n const originalDirLocal = Vector3.normalize(springBone.initialLocalPosition, new Vector3());\r\n\r\n // Calculate local rotation from original to current\r\n const localRotation = new Quaternion();\r\n this._fromToRotation(originalDirLocal, currentDirLocal, localRotation);\r\n\r\n // Apply to parent bone\r\n parent.rotation = localRotation;\r\n }\r\n\r\n /**\r\n * Calculate rotation from one direction to another.\r\n */\r\n private _fromToRotation(from: Vector3, to: Vector3, result: Quaternion): Quaternion {\r\n const dot = Vector3.dot(from, to);\r\n\r\n if (dot >= 0.999999) {\r\n return result.identity();\r\n }\r\n\r\n if (dot <= -0.999999) {\r\n let axis = Vector3.cross(Vector3.axisPX(), from, 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(), from, new Vector3());\r\n }\r\n axis.inplaceNormalize();\r\n return result.fromAxisAngle(axis, Math.PI);\r\n }\r\n\r\n const axis = Vector3.cross(from, to).inplaceNormalize();\r\n const angle = Math.acos(dot);\r\n return result.fromAxisAngle(axis, angle);\r\n }\r\n\r\n /**\r\n * Update the spring bone system.\r\n *\r\n * @param deltaTime - Time step (in seconds or milliseconds, depending on constructor parameter)\r\n */\r\n update(deltaTime: number): void {\r\n if (!this._enabled || deltaTime <= 0) {\r\n return;\r\n }\r\n\r\n // Convert to seconds if needed\r\n const deltaTimeSeconds = this._deltaTimeInMilliseconds ? deltaTime / 1000 : deltaTime;\r\n\r\n // Clamp delta time to avoid instability\r\n const clampedDeltaTime = Math.min(deltaTimeSeconds, 0.1);\r\n\r\n // Update spring bones one by one (not in parallel)\r\n // This ensures parent bones are updated before child bones\r\n for (const springBone of this._springBones) {\r\n // Update physics\r\n springBone.update(clampedDeltaTime, this._gravity, this._windForce);\r\n\r\n // Apply collisions\r\n const position = springBone.currentPosition;\r\n const radius = springBone.radius;\r\n\r\n for (const collider of this._colliders) {\r\n collider.collide(position, radius);\r\n }\r\n\r\n // Update parent bone rotation if parent is not in the spring system\r\n this._updateParentRotation(springBone);\r\n\r\n // Apply to bone node\r\n springBone.applyToNode();\r\n\r\n // Force update the bone's world matrix\r\n // This ensures child bones see the updated parent transform\r\n const bone = springBone.bone;\r\n if (typeof (bone as any).updateWorldMatrix === 'function') {\r\n (bone as any).updateWorldMatrix(true, false);\r\n }\r\n }\r\n\r\n // Apply constraints (multiple iterations for better convergence)\r\n for (let i = 0; i < this._constraintIterations; i++) {\r\n for (const constraint of this._constraints) {\r\n constraint.apply();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get all spring bones.\r\n */\r\n get springBones(): readonly SpringBone[] {\r\n return this._springBones;\r\n }\r\n\r\n /**\r\n * Get all colliders.\r\n */\r\n get colliders(): readonly SpringBoneCollider[] {\r\n return this._colliders;\r\n }\r\n}\r\n"],"names":["SpringBoneSystem","deltaTimeInMilliseconds","_springBones","_colliders","_constraints","_gravity","Vector3","_windForce","_enabled","_constraintIterations","_deltaTimeInMilliseconds","gravity","value","set","windForce","enabled","addSpringBone","bone","stiffness","damping","mass","gravityScale","radius","springBone","SpringBone","push","addSpringChain","bones","skipRoot","springBones","startIndex","i","length","removeSpringBone","index","indexOf","splice","clearSpringBones","addCollider","collider","removeCollider","clearColliders","addConstraint","constraint","removeConstraint","clearConstraints","createCircularConstraints","chains","minDistance","maxDistance","CircularConstraint","constraintIterations","Math","max","floor","reset","_updateParentRotation","parent","parentIsSpringBone","some","sb","parentWorldPos","worldMatrix","decompose","simulatedPos","currentPosition","currentDir","sub","currentLength","magnitude","scaleBy","grandparent","grandparentWorldRot","Quaternion","identity","grandparentInvRot","conjugate","currentDirLocal","transform","originalDirLocal","normalize","initialLocalPosition","localRotation","_fromToRotation","rotation","from","to","result","dot","axis","cross","axisPX","lenSq","x","y","z","axisPY","inplaceNormalize","fromAxisAngle","PI","angle","acos","update","deltaTime","deltaTimeSeconds","clampedDeltaTime","min","position","collide","applyToNode","updateWorldMatrix","apply","colliders"],"mappings":"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"}
|
package/dist/asset/model.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Vector3, Quaternion, Matrix4x4, Disposable, DRef } from '@zephyr3d/base';
|
|
2
2
|
import { Mesh } from '../scene/mesh.js';
|
|
3
3
|
import { SceneNode } from '../scene/scene_node.js';
|
|
4
|
-
import { NodeTranslationTrack } from '../animation/translationtrack.js';
|
|
5
4
|
import { NodeRotationTrack } from '../animation/rotationtrack.js';
|
|
6
5
|
import '../animation/eulerrotationtrack.js';
|
|
6
|
+
import { NodeTranslationTrack } from '../animation/translationtrack.js';
|
|
7
7
|
import { NodeScaleTrack } from '../animation/scaletrack.js';
|
|
8
|
-
import { MorphTargetTrack } from '../animation/morphtrack.js';
|
|
9
8
|
import { Skeleton } from '../animation/skeleton.js';
|
|
9
|
+
import { MorphTargetTrack } from '../animation/morphtrack.js';
|
|
10
10
|
import { processMorphData } from '../animation/morphtarget.js';
|
|
11
11
|
import { MAX_MORPH_TARGETS } from '../values.js';
|
|
12
12
|
|
package/dist/index.d.ts
CHANGED
|
@@ -12449,6 +12449,21 @@ declare class AnimationSet extends Disposable implements IDisposable {
|
|
|
12449
12449
|
* @param options - Optional fade-out configuration.
|
|
12450
12450
|
*/
|
|
12451
12451
|
stopAnimation(name: string, options?: StopAnimationOptions): void;
|
|
12452
|
+
/**
|
|
12453
|
+
* Copy an animation clip from another AnimationSet into this one.
|
|
12454
|
+
*
|
|
12455
|
+
* Prerequisites:
|
|
12456
|
+
* - Both sets must reference skeletons with identical joint names and counts.
|
|
12457
|
+
* - The source clip must exist in `sourceSet`.
|
|
12458
|
+
*
|
|
12459
|
+
* @param sourceSet - The AnimationSet to copy from.
|
|
12460
|
+
* @param animationName - Name of the clip to copy.
|
|
12461
|
+
* @param targetName - Name for the new clip in this set. Defaults to `animationName`.
|
|
12462
|
+
* @param excludeJoint - Optional predicate; joints whose name returns true are excluded from
|
|
12463
|
+
* skeleton structure matching.
|
|
12464
|
+
* @returns The newly created AnimationClip, or null on failure.
|
|
12465
|
+
*/
|
|
12466
|
+
copyAnimationFrom(sourceSet: AnimationSet, animationName: string, targetName?: string, excludeJoint?: (jointName: string) => boolean): AnimationClip | null;
|
|
12452
12467
|
/**
|
|
12453
12468
|
* Dispose the animation set and release owned resources.
|
|
12454
12469
|
*
|