@zephyr3d/scene 0.9.26 → 0.10.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/README.md +60 -27
- package/dist/animation/animation_bank.js +634 -0
- package/dist/animation/animation_bank.js.map +1 -0
- package/dist/animation/animation_bank_gpu.js +256 -0
- package/dist/animation/animation_bank_gpu.js.map +1 -0
- package/dist/animation/animationset.js +146 -30
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/cloth/gpu_cloth_component.js +406 -0
- package/dist/animation/cloth/gpu_cloth_component.js.map +1 -0
- package/dist/animation/cloth/gpu_cloth_system.js +332 -202
- package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
- package/dist/animation/gpu_animation_driver.js +289 -0
- package/dist/animation/gpu_animation_driver.js.map +1 -0
- package/dist/animation/joint_dynamics/collision.js +112 -1
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +6 -0
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +11 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +50 -12
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/animation/skeleton.js +300 -56
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skin_palette_atlas.js +252 -0
- package/dist/animation/skin_palette_atlas.js.map +1 -0
- package/dist/animation/spring/multi_chain_spring_system.js +298 -38
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_chain.js +2 -0
- package/dist/animation/spring/spring_chain.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +159 -21
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_particle.js +1 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_solver.js +173 -0
- package/dist/animation/spring/spring_solver.js.map +1 -0
- package/dist/animation/spring/spring_system.js +249 -24
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring_modifier.js +32 -1
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/app.js +26 -0
- package/dist/app/app.js.map +1 -1
- package/dist/app/engine.js +86 -15
- package/dist/app/engine.js.map +1 -1
- package/dist/app/gamepad.js +191 -0
- package/dist/app/gamepad.js.map +1 -0
- package/dist/app/inputactions.js +271 -0
- package/dist/app/inputactions.js.map +1 -0
- package/dist/app/inputmgr.js +331 -22
- package/dist/app/inputmgr.js.map +1 -1
- package/dist/app/loading.js +138 -0
- package/dist/app/loading.js.map +1 -0
- package/dist/app/pipelinecache.js +209 -0
- package/dist/app/pipelinecache.js.map +1 -0
- package/dist/app/runtimescript.js +25 -0
- package/dist/app/runtimescript.js.map +1 -1
- package/dist/app/scriptingsystem.js +54 -0
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +7 -2
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/asset_manifest.js +59 -0
- package/dist/asset/asset_manifest.js.map +1 -0
- package/dist/asset/asset_preload.js +258 -0
- package/dist/asset/asset_preload.js.map +1 -0
- package/dist/asset/assetmanager.js +117 -65
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- package/dist/asset/loaders/ktx2/basis_location.js +17 -0
- package/dist/asset/loaders/ktx2/basis_location.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js +88 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js +118 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js.map +1 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js +259 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js.map +1 -0
- package/dist/asset/mesh_lod_builder.js +104 -0
- package/dist/asset/mesh_lod_builder.js.map +1 -0
- package/dist/asset/mesh_settings.js +111 -0
- package/dist/asset/mesh_settings.js.map +1 -0
- package/dist/asset/meshopt_decoder.js +18 -0
- package/dist/asset/meshopt_decoder.js.map +1 -0
- package/dist/asset/meshopt_simplifier.js +26 -0
- package/dist/asset/meshopt_simplifier.js.map +1 -0
- package/dist/asset/model.js +177 -3
- package/dist/asset/model.js.map +1 -1
- package/dist/asset/texture_settings.js +231 -0
- package/dist/asset/texture_settings.js.map +1 -0
- package/dist/asset/zmsh_binary.js +131 -0
- package/dist/asset/zmsh_binary.js.map +1 -0
- package/dist/asset/zsdf_binary.js +111 -0
- package/dist/asset/zsdf_binary.js.map +1 -0
- package/dist/blitter/bilateralblur.js +1 -2
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/gaussianblur.js +1 -6
- package/dist/blitter/gaussianblur.js.map +1 -1
- package/dist/camera/base.js +31 -10
- package/dist/camera/base.js.map +1 -1
- package/dist/camera/camera.js +178 -200
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/follow.js +342 -0
- package/dist/camera/follow.js.map +1 -0
- package/dist/camera/fps.js +9 -7
- package/dist/camera/fps.js.map +1 -1
- package/dist/camera/orbit.js +46 -19
- package/dist/camera/orbit.js.map +1 -1
- package/dist/index.d.ts +30475 -19865
- package/dist/index.js +67 -12
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +3 -0
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/eye.js +1 -1
- package/dist/material/eye.js.map +1 -1
- package/dist/material/hair.js +2 -3
- package/dist/material/hair.js.map +1 -1
- package/dist/material/hairstrand.js +235 -235
- package/dist/material/hairstrand.js.map +1 -1
- package/dist/material/lambert.js +4 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +362 -300
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +118 -45
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +1 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +34 -61
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -2
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +2 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +223 -83
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +31 -206
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mtoon.js +1 -1
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrmr.js +3 -0
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +3 -0
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/sdf_debug.js +78 -0
- package/dist/material/sdf_debug.js.map +1 -0
- package/dist/material/shader/helper.js +733 -190
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/shader/terrain_blend.js +204 -43
- package/dist/material/shader/terrain_blend.js.map +1 -1
- package/dist/material/skin.js +331 -297
- package/dist/material/skin.js.map +1 -1
- package/dist/material/skinprofile.js +1058 -0
- package/dist/material/skinprofile.js.map +1 -0
- package/dist/material/sss.js +353 -0
- package/dist/material/sss.js.map +1 -0
- package/dist/material/sss_kernel.js +265 -0
- package/dist/material/sss_kernel.js.map +1 -0
- package/dist/material/sssprofile.js +879 -0
- package/dist/material/sssprofile.js.map +1 -0
- package/dist/material/subsurfaceprofile.js +4 -8
- package/dist/material/subsurfaceprofile.js.map +1 -1
- package/dist/material/terrain-cm.js +464 -188
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/unlit.js +3 -0
- package/dist/material/unlit.js.map +1 -1
- package/dist/material/water.js +2009 -201
- package/dist/material/water.js.map +1 -1
- package/dist/node_modules/meshoptimizer/LICENSE +21 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js +197 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js.map +1 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js +677 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js.map +1 -0
- package/dist/physics/character.js +226 -0
- package/dist/physics/character.js.map +1 -0
- package/dist/physics/collider.js +209 -0
- package/dist/physics/collider.js.map +1 -0
- package/dist/physics/events.js +79 -0
- package/dist/physics/events.js.map +1 -0
- package/dist/physics/joint.js +272 -0
- package/dist/physics/joint.js.map +1 -0
- package/dist/physics/node_physics.js +234 -0
- package/dist/physics/node_physics.js.map +1 -0
- package/dist/physics/part.js +91 -0
- package/dist/physics/part.js.map +1 -0
- package/dist/physics/rigid_body.js +379 -0
- package/dist/physics/rigid_body.js.map +1 -0
- package/dist/physics/vehicle.js +335 -0
- package/dist/physics/vehicle.js.map +1 -0
- package/dist/physics/world.js +25 -0
- package/dist/physics/world.js.map +1 -0
- package/dist/posteffect/bloom.js +49 -14
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/motionblur.js +668 -63
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js +12 -1
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/postsss.js +572 -0
- package/dist/posteffect/postsss.js.map +1 -0
- package/dist/posteffect/sao.js +48 -50
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +605 -355
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +91 -162
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +3 -11
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +34 -15
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js +1 -0
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/render/abuffer_oit.js +40 -39
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +328 -62
- package/dist/render/clipmap.js.map +1 -1
- package/dist/render/cluster_light.js +958 -224
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/cull_visitor.js +26 -5
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/debug_views.js +37 -0
- package/dist/render/debug_views.js.map +1 -0
- package/dist/render/depthpass.js +5 -1
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +53 -6
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +53 -53
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +196 -113
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +8 -13
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +268 -136
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +113 -28
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/gi/probe_volume.js +1334 -0
- package/dist/render/gi/probe_volume.js.map +1 -0
- package/dist/render/gi/scene_gi.js +282 -0
- package/dist/render/gi/scene_gi.js.map +1 -0
- package/dist/render/gi/voxel_atlas.js +198 -0
- package/dist/render/gi/voxel_atlas.js.map +1 -0
- package/dist/render/gi/voxel_lighting.js +652 -0
- package/dist/render/gi/voxel_lighting.js.map +1 -0
- package/dist/render/gi/voxel_scene.js +642 -0
- package/dist/render/gi/voxel_scene.js.map +1 -0
- package/dist/render/gi/voxelize_pass.js +223 -0
- package/dist/render/gi/voxelize_pass.js.map +1 -0
- package/dist/render/globalbindgroup_allocator.js +3 -2
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/gpu_picking.js +9 -36
- package/dist/render/gpu_picking.js.map +1 -1
- package/dist/render/hzb.js +80 -22
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/instance_culling.js +499 -0
- package/dist/render/instance_culling.js.map +1 -0
- package/dist/render/lightpass.js +23 -9
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/lod.js +46 -0
- package/dist/render/lod.js.map +1 -0
- package/dist/render/oit.js +11 -11
- package/dist/render/oit.js.map +1 -1
- package/dist/render/primitive.js +301 -9
- package/dist/render/primitive.js.map +1 -1
- package/dist/render/primitive_readback.js +209 -0
- package/dist/render/primitive_readback.js.map +1 -0
- package/dist/render/render_queue.js +198 -11
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +14 -7
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +15 -1
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/executor.js +136 -0
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +585 -59
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
- package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +8 -1
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/scene_render_context.js +31 -2
- package/dist/render/rendergraph/scene_render_context.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +28 -5
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/sdf/box_allocator.js +98 -0
- package/dist/render/sdf/box_allocator.js.map +1 -0
- package/dist/render/sdf/global_sdf.js +865 -0
- package/dist/render/sdf/global_sdf.js.map +1 -0
- package/dist/render/sdf/scene_sdf.js +562 -0
- package/dist/render/sdf/scene_sdf.js.map +1 -0
- package/dist/render/sdf/sdf_atlas.js +227 -0
- package/dist/render/sdf/sdf_atlas.js.map +1 -0
- package/dist/render/sdf/sdf_programs.js +42 -0
- package/dist/render/sdf/sdf_programs.js.map +1 -0
- package/dist/render/sdf/sdf_view.js +199 -0
- package/dist/render/sdf/sdf_view.js.map +1 -0
- package/dist/render/sdf/waterline.js +610 -0
- package/dist/render/sdf/waterline.js.map +1 -0
- package/dist/render/shadow_mask_pass.js +142 -25
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/shore_wave_generator.js +1193 -0
- package/dist/render/shore_wave_generator.js.map +1 -0
- package/dist/render/sky.js +516 -86
- package/dist/render/sky.js.map +1 -1
- package/dist/render/transmission_thickness_pass.js +477 -0
- package/dist/render/transmission_thickness_pass.js.map +1 -0
- package/dist/render/underwater.js +524 -0
- package/dist/render/underwater.js.map +1 -0
- package/dist/render/virtualtexture/virtual_texture.js +1214 -0
- package/dist/render/virtualtexture/virtual_texture.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_common.js +472 -0
- package/dist/render/volumetric_cloud/cloud_common.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_noise.js +189 -0
- package/dist/render/volumetric_cloud/cloud_noise.js.map +1 -0
- package/dist/render/volumetric_cloud/debug_view.js +131 -0
- package/dist/render/volumetric_cloud/debug_view.js.map +1 -0
- package/dist/render/volumetric_cloud/resources.js +380 -0
- package/dist/render/volumetric_cloud/resources.js.map +1 -0
- package/dist/render/volumetric_cloud/sky_cache.js +380 -0
- package/dist/render/volumetric_cloud/sky_cache.js.map +1 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js +318 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js.map +1 -0
- package/dist/render/water_caustics.js +1195 -0
- package/dist/render/water_caustics.js.map +1 -0
- package/dist/render/water_foam.js +627 -0
- package/dist/render/water_foam.js.map +1 -0
- package/dist/render/water_interaction.js +1795 -0
- package/dist/render/water_interaction.js.map +1 -0
- package/dist/render/weightedblended_oit.js +36 -36
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +9 -4
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +108 -12
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +28 -7
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/foliage.js +1020 -0
- package/dist/scene/foliage.js.map +1 -0
- package/dist/scene/foliage_buckets.js +147 -0
- package/dist/scene/foliage_buckets.js.map +1 -0
- package/dist/scene/foliage_mask.js +358 -0
- package/dist/scene/foliage_mask.js.map +1 -0
- package/dist/scene/hair.js +15 -4
- package/dist/scene/hair.js.map +1 -1
- package/dist/scene/light.js +179 -13
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +327 -45
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +6 -0
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +9 -3
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +9 -3
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +8 -2
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/physics_settings.js +157 -0
- package/dist/scene/physics_settings.js.map +1 -0
- package/dist/scene/scene.js +190 -44
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +147 -6
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain-cm/bladegrassmaterial.js +735 -0
- package/dist/scene/terrain-cm/bladegrassmaterial.js.map +1 -0
- package/dist/scene/terrain-cm/grass.js +881 -42
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grass_gpu.js +929 -0
- package/dist/scene/terrain-cm/grass_gpu.js.map +1 -0
- package/dist/scene/terrain-cm/grassmaterial.js +180 -9
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +465 -36
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/terrain-cm/terrain_gi_albedo.js +257 -0
- package/dist/scene/terrain-cm/terrain_gi_albedo.js.map +1 -0
- package/dist/scene/terrain-cm/terrain_rvt.js +395 -0
- package/dist/scene/terrain-cm/terrain_rvt.js.map +1 -0
- package/dist/scene/update_queue.js +54 -0
- package/dist/scene/update_queue.js.map +1 -0
- package/dist/scene/water.js +997 -96
- package/dist/scene/water.js.map +1 -1
- package/dist/scene/water_surface_sampler.js +324 -0
- package/dist/scene/water_surface_sampler.js.map +1 -0
- package/dist/scene/wind.js +317 -0
- package/dist/scene/wind.js.map +1 -0
- package/dist/shaders/atmosphere.js +388 -166
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js +100 -32
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/gi.js +365 -0
- package/dist/shaders/gi.js.map +1 -0
- package/dist/shaders/ltc_rect.js +202 -0
- package/dist/shaders/ltc_rect.js.map +1 -0
- package/dist/shaders/misc.js +1 -10
- package/dist/shaders/misc.js.map +1 -1
- package/dist/shaders/noise.js +5 -1
- package/dist/shaders/noise.js.map +1 -1
- package/dist/shaders/probes.js +309 -0
- package/dist/shaders/probes.js.map +1 -0
- package/dist/shaders/sdf.js +537 -0
- package/dist/shaders/sdf.js.map +1 -0
- package/dist/shaders/shadow.js +104 -70
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/skin_brdf.js +243 -0
- package/dist/shaders/skin_brdf.js.map +1 -0
- package/dist/shaders/ssr.js +6 -159
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shaders/temporal.js +38 -27
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shaders/water.js +40 -87
- package/dist/shaders/water.js.map +1 -1
- package/dist/shaders/water_medium.js +42 -0
- package/dist/shaders/water_medium.js.map +1 -0
- package/dist/shadow/dom.js +110 -19
- package/dist/shadow/dom.js.map +1 -1
- package/dist/shadow/esm.js +3 -3
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +15 -48
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +15 -53
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +34 -9
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js +3 -8
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +87 -49
- package/dist/shadow/shadow_region.js.map +1 -1
- package/dist/shadow/shadowmapper.js +93 -53
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +18 -72
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +3 -3
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/shapes/shape.js +44 -1
- package/dist/shapes/shape.js.map +1 -1
- package/dist/utility/buoyancy.js +287 -0
- package/dist/utility/buoyancy.js.map +1 -0
- package/dist/utility/physical.js +10 -1
- package/dist/utility/physical.js.map +1 -1
- package/dist/utility/pmrem.js +17 -43
- package/dist/utility/pmrem.js.map +1 -1
- package/dist/utility/sdf/bake.js +435 -0
- package/dist/utility/sdf/bake.js.map +1 -0
- package/dist/utility/sdf/bvh.js +576 -0
- package/dist/utility/sdf/bvh.js.map +1 -0
- package/dist/utility/serialization/manager.js +36 -6
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +77 -7
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +11 -4
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +140 -279
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/cloth.js +25 -0
- package/dist/utility/serialization/scene/cloth.js.map +1 -0
- package/dist/utility/serialization/scene/common.js +14 -6
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/foliage.js +821 -0
- package/dist/utility/serialization/scene/foliage.js.map +1 -0
- package/dist/utility/serialization/scene/hair.js +11 -4
- package/dist/utility/serialization/scene/hair.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +115 -7
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +388 -220
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +69 -4
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +140 -5
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/node_physics.js +1318 -0
- package/dist/utility/serialization/scene/node_physics.js.map +1 -0
- package/dist/utility/serialization/scene/particle.js +11 -4
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/physics.js +120 -0
- package/dist/utility/serialization/scene/physics.js.map +1 -0
- package/dist/utility/serialization/scene/primitive.js +124 -10
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +1687 -51
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +11 -4
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +163 -33
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +11 -4
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +2473 -114
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +97 -109
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/utility/textures/foam.js +170 -0
- package/dist/utility/textures/foam.js.map +1 -0
- package/dist/utility/textures/ggxlut.js +17 -43
- package/dist/utility/textures/ggxlut.js.map +1 -1
- package/dist/utility/textures/ltcdata.js +4 -4
- package/dist/utility/textures/ltcdata.js.map +1 -1
- package/dist/utility/textures/ltclut.js +16 -6
- package/dist/utility/textures/ltclut.js.map +1 -1
- package/dist/utility/unsupported.js +24 -0
- package/dist/utility/unsupported.js.map +1 -0
- package/dist/values.js +13 -1
- package/dist/values.js.map +1 -1
- package/package.json +25 -12
- package/src/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- package/src/asset/meshoptimizer/LICENSE +21 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { Vector3 } from '@zephyr3d/base';
|
|
2
|
+
import { PhysicsPart } from './part.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Makes its node a car, truck or other wheeled vehicle, driven by
|
|
6
|
+
* {@link Vehicle.throttle}, {@link Vehicle.brake} and {@link Vehicle.steering}.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* The node needs a dynamic {@link RigidBody}, and colliders for the body. The
|
|
10
|
+
* wheels are the {@link NodePhysics.wheel} of nodes below it, with no other rigid
|
|
11
|
+
* body in between; each wheel node is placed where the wheel's centre is with
|
|
12
|
+
* the suspension at rest. While simulating, the wheel nodes are moved up and
|
|
13
|
+
* down with the suspension, turned with the steering and rolled with the
|
|
14
|
+
* vehicle's motion.
|
|
15
|
+
*
|
|
16
|
+
* Up is the node's +Y; the front is {@link Vehicle.forward}. Wheels are rays
|
|
17
|
+
* cast down from the body, as in Bullet's ray cast vehicle:
|
|
18
|
+
* they find the ground, but do not collide - the body's colliders do.
|
|
19
|
+
*
|
|
20
|
+
* Inputs stay in effect until changed, and are applied every simulation step.
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
*/ class Vehicle extends PhysicsPart {
|
|
24
|
+
_maxEngineForce;
|
|
25
|
+
_maxBrakeForce;
|
|
26
|
+
_maxHandbrakeForce;
|
|
27
|
+
_maxSteerAngle;
|
|
28
|
+
_forward;
|
|
29
|
+
_layer;
|
|
30
|
+
_throttle;
|
|
31
|
+
_brake;
|
|
32
|
+
_handbrake;
|
|
33
|
+
_steering;
|
|
34
|
+
_error;
|
|
35
|
+
constructor(){
|
|
36
|
+
super();
|
|
37
|
+
this._maxEngineForce = 4000;
|
|
38
|
+
this._maxBrakeForce = 3000;
|
|
39
|
+
this._maxHandbrakeForce = 6000;
|
|
40
|
+
this._maxSteerAngle = 30;
|
|
41
|
+
this._forward = '+z';
|
|
42
|
+
this._layer = 0;
|
|
43
|
+
this._throttle = 0;
|
|
44
|
+
this._brake = 0;
|
|
45
|
+
this._handbrake = false;
|
|
46
|
+
this._steering = 0;
|
|
47
|
+
this._error = '';
|
|
48
|
+
}
|
|
49
|
+
/** Total driving force at full throttle, in newtons, shared out by {@link Wheel.drive}. Default 4000. */ get maxEngineForce() {
|
|
50
|
+
return this._maxEngineForce;
|
|
51
|
+
}
|
|
52
|
+
set maxEngineForce(value) {
|
|
53
|
+
this._maxEngineForce = Math.max(0, value);
|
|
54
|
+
}
|
|
55
|
+
/** Braking force of a wheel at full brake, in newtons, scaled by {@link Wheel.brake}. Default 3000. */ get maxBrakeForce() {
|
|
56
|
+
return this._maxBrakeForce;
|
|
57
|
+
}
|
|
58
|
+
set maxBrakeForce(value) {
|
|
59
|
+
this._maxBrakeForce = Math.max(0, value);
|
|
60
|
+
}
|
|
61
|
+
/** Braking force of a wheel with the handbrake on, in newtons, scaled by {@link Wheel.handbrake}. Default 6000. */ get maxHandbrakeForce() {
|
|
62
|
+
return this._maxHandbrakeForce;
|
|
63
|
+
}
|
|
64
|
+
set maxHandbrakeForce(value) {
|
|
65
|
+
this._maxHandbrakeForce = Math.max(0, value);
|
|
66
|
+
}
|
|
67
|
+
/** Steering angle at full lock, in degrees, scaled by {@link Wheel.steer}. Default 30. */ get maxSteerAngle() {
|
|
68
|
+
return this._maxSteerAngle;
|
|
69
|
+
}
|
|
70
|
+
set maxSteerAngle(value) {
|
|
71
|
+
this._maxSteerAngle = value;
|
|
72
|
+
}
|
|
73
|
+
/** Which way the front faces in the node's space. Default `'+z'`. */ get forward() {
|
|
74
|
+
return this._forward;
|
|
75
|
+
}
|
|
76
|
+
set forward(value) {
|
|
77
|
+
if (value !== this._forward) {
|
|
78
|
+
this._forward = value;
|
|
79
|
+
this._rebuild();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Collision layer of the wheels: they find ground on the layers this one collides with. Default 0. */ get layer() {
|
|
83
|
+
return this._layer;
|
|
84
|
+
}
|
|
85
|
+
set layer(value) {
|
|
86
|
+
this._layer = Math.min(15, Math.max(0, Math.floor(value)));
|
|
87
|
+
}
|
|
88
|
+
/** Accelerator, -1 to 1; below 0 drives backwards. Overrides the brake on driven wheels. */ get throttle() {
|
|
89
|
+
return this._throttle;
|
|
90
|
+
}
|
|
91
|
+
set throttle(value) {
|
|
92
|
+
this._throttle = Math.min(1, Math.max(-1, value));
|
|
93
|
+
}
|
|
94
|
+
/** Brake pedal, 0 to 1. */ get brake() {
|
|
95
|
+
return this._brake;
|
|
96
|
+
}
|
|
97
|
+
set brake(value) {
|
|
98
|
+
this._brake = Math.min(1, Math.max(0, value));
|
|
99
|
+
}
|
|
100
|
+
/** Whether the handbrake is on. */ get handbrake() {
|
|
101
|
+
return this._handbrake;
|
|
102
|
+
}
|
|
103
|
+
set handbrake(value) {
|
|
104
|
+
this._handbrake = !!value;
|
|
105
|
+
}
|
|
106
|
+
/** Steering wheel, -1 to 1; above 0 turns left. */ get steering() {
|
|
107
|
+
return this._steering;
|
|
108
|
+
}
|
|
109
|
+
set steering(value) {
|
|
110
|
+
this._steering = Math.min(1, Math.max(-1, value));
|
|
111
|
+
}
|
|
112
|
+
/** Speed along the front direction in m/s; negative when going backwards. */ get speed() {
|
|
113
|
+
return this.world?._vehicleSpeed(this) ?? 0;
|
|
114
|
+
}
|
|
115
|
+
/** The wheels, in scene order, while the vehicle is in a simulation. */ get wheels() {
|
|
116
|
+
return this.world?._vehicleWheels(this) ?? [];
|
|
117
|
+
}
|
|
118
|
+
/** Why the vehicle could not be built, or an empty string. */ get error() {
|
|
119
|
+
return this._error;
|
|
120
|
+
}
|
|
121
|
+
/** The front direction in node space. */ _forwardVector(out = new Vector3()) {
|
|
122
|
+
switch(this._forward){
|
|
123
|
+
case '-z':
|
|
124
|
+
return out.setXYZ(0, 0, -1);
|
|
125
|
+
case '+x':
|
|
126
|
+
return out.setXYZ(1, 0, 0);
|
|
127
|
+
case '-x':
|
|
128
|
+
return out.setXYZ(-1, 0, 0);
|
|
129
|
+
default:
|
|
130
|
+
return out.setXYZ(0, 0, 1);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** Whether any input asks the vehicle to move. */ _hasInput() {
|
|
134
|
+
return this._throttle !== 0 || this._brake !== 0 || this._handbrake || this._steering !== 0;
|
|
135
|
+
}
|
|
136
|
+
_setError(error) {
|
|
137
|
+
this._error = error;
|
|
138
|
+
}
|
|
139
|
+
_rebuild() {
|
|
140
|
+
this.world?._markVehiclesDirty();
|
|
141
|
+
}
|
|
142
|
+
_join(world) {
|
|
143
|
+
world._registerVehicle(this);
|
|
144
|
+
}
|
|
145
|
+
_leave(world) {
|
|
146
|
+
world._unregisterVehicle(this);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* A wheel of the {@link Vehicle} above its node.
|
|
151
|
+
*
|
|
152
|
+
* @remarks
|
|
153
|
+
* Place the node where the wheel's centre is with the suspension at rest. The
|
|
154
|
+
* suspension runs along the vehicle's down direction, the axle along its
|
|
155
|
+
* sideways direction. While simulating, the node's local position and rotation
|
|
156
|
+
* are set from the suspension, steering and roll; they go back to where they
|
|
157
|
+
* were when the vehicle leaves the simulation.
|
|
158
|
+
*
|
|
159
|
+
* Suspension stiffness and damping are per kilogram of the vehicle, so they
|
|
160
|
+
* feel the same on a light car and a heavy truck: with four wheels resting, the
|
|
161
|
+
* suspension sinks by 9.81 / (4 × stiffness) metres.
|
|
162
|
+
*
|
|
163
|
+
* @public
|
|
164
|
+
*/ class Wheel extends PhysicsPart {
|
|
165
|
+
_radius;
|
|
166
|
+
_suspensionRestLength;
|
|
167
|
+
_suspensionStiffness;
|
|
168
|
+
_suspensionCompression;
|
|
169
|
+
_suspensionRelaxation;
|
|
170
|
+
_maxSuspensionTravel;
|
|
171
|
+
_maxSuspensionForce;
|
|
172
|
+
_frictionSlip;
|
|
173
|
+
_sideFriction;
|
|
174
|
+
_steer;
|
|
175
|
+
_drive;
|
|
176
|
+
_brake;
|
|
177
|
+
_handbrake;
|
|
178
|
+
/** Added to what the vehicle's inputs give this wheel. */ engineForce;
|
|
179
|
+
brakeForce;
|
|
180
|
+
steerAngle;
|
|
181
|
+
/** State after the last simulation step. */ _state;
|
|
182
|
+
/** The node's local transform before the vehicle took it over. */ _rest;
|
|
183
|
+
/** The node the vehicle last wrote to, to give the rest pose back to. */ _restNode;
|
|
184
|
+
_error;
|
|
185
|
+
constructor(){
|
|
186
|
+
super();
|
|
187
|
+
this._radius = 0.4;
|
|
188
|
+
this._suspensionRestLength = 0.3;
|
|
189
|
+
this._suspensionStiffness = 30;
|
|
190
|
+
this._suspensionCompression = 2.2;
|
|
191
|
+
this._suspensionRelaxation = 3.3;
|
|
192
|
+
this._maxSuspensionTravel = 0.3;
|
|
193
|
+
this._maxSuspensionForce = 1e6;
|
|
194
|
+
this._frictionSlip = 1.5;
|
|
195
|
+
this._sideFriction = 1;
|
|
196
|
+
this._steer = 0;
|
|
197
|
+
this._drive = 0;
|
|
198
|
+
this._brake = 1;
|
|
199
|
+
this._handbrake = 0;
|
|
200
|
+
this.engineForce = 0;
|
|
201
|
+
this.brakeForce = 0;
|
|
202
|
+
this.steerAngle = 0;
|
|
203
|
+
this._state = {
|
|
204
|
+
suspensionLength: 0,
|
|
205
|
+
rotation: 0,
|
|
206
|
+
steering: 0,
|
|
207
|
+
inContact: false,
|
|
208
|
+
contactPoint: new Vector3(),
|
|
209
|
+
contactNormal: new Vector3(),
|
|
210
|
+
groundKey: -1,
|
|
211
|
+
suspensionForce: 0
|
|
212
|
+
};
|
|
213
|
+
this._rest = null;
|
|
214
|
+
this._restNode = null;
|
|
215
|
+
this._error = '';
|
|
216
|
+
}
|
|
217
|
+
/** Wheel radius in metres. Default 0.4. */ get radius() {
|
|
218
|
+
return this._radius;
|
|
219
|
+
}
|
|
220
|
+
set radius(value) {
|
|
221
|
+
this._set('_radius', Math.max(0.01, value));
|
|
222
|
+
}
|
|
223
|
+
/** Suspension length at rest, from where it is attached to the wheel's centre, in metres. Default 0.3. */ get suspensionRestLength() {
|
|
224
|
+
return this._suspensionRestLength;
|
|
225
|
+
}
|
|
226
|
+
set suspensionRestLength(value) {
|
|
227
|
+
this._set('_suspensionRestLength', Math.max(0, value));
|
|
228
|
+
}
|
|
229
|
+
/** Spring strength per kilogram of vehicle; higher is firmer and sinks less. Default 30. */ get suspensionStiffness() {
|
|
230
|
+
return this._suspensionStiffness;
|
|
231
|
+
}
|
|
232
|
+
set suspensionStiffness(value) {
|
|
233
|
+
this._set('_suspensionStiffness', Math.max(0, value));
|
|
234
|
+
}
|
|
235
|
+
/** Damping while the suspension compresses, per kilogram of vehicle. Default 2.2. */ get suspensionCompression() {
|
|
236
|
+
return this._suspensionCompression;
|
|
237
|
+
}
|
|
238
|
+
set suspensionCompression(value) {
|
|
239
|
+
this._set('_suspensionCompression', Math.max(0, value));
|
|
240
|
+
}
|
|
241
|
+
/** Damping while the suspension extends, per kilogram of vehicle. Default 3.3. */ get suspensionRelaxation() {
|
|
242
|
+
return this._suspensionRelaxation;
|
|
243
|
+
}
|
|
244
|
+
set suspensionRelaxation(value) {
|
|
245
|
+
this._set('_suspensionRelaxation', Math.max(0, value));
|
|
246
|
+
}
|
|
247
|
+
/** How far the suspension compresses or extends from rest, in metres. Default 0.3. */ get maxSuspensionTravel() {
|
|
248
|
+
return this._maxSuspensionTravel;
|
|
249
|
+
}
|
|
250
|
+
set maxSuspensionTravel(value) {
|
|
251
|
+
this._set('_maxSuspensionTravel', Math.max(0, value));
|
|
252
|
+
}
|
|
253
|
+
/** Most force the suspension pushes with, in newtons. Default 1000000. */ get maxSuspensionForce() {
|
|
254
|
+
return this._maxSuspensionForce;
|
|
255
|
+
}
|
|
256
|
+
set maxSuspensionForce(value) {
|
|
257
|
+
this._set('_maxSuspensionForce', Math.max(0, value));
|
|
258
|
+
}
|
|
259
|
+
/** Grip: the most sideways force per unit of load, like a friction coefficient. Default 1.5. */ get frictionSlip() {
|
|
260
|
+
return this._frictionSlip;
|
|
261
|
+
}
|
|
262
|
+
set frictionSlip(value) {
|
|
263
|
+
this._set('_frictionSlip', Math.max(0, value));
|
|
264
|
+
}
|
|
265
|
+
/** Scales the sideways grip; lower lets the wheel slide out. Default 1. */ get sideFriction() {
|
|
266
|
+
return this._sideFriction;
|
|
267
|
+
}
|
|
268
|
+
set sideFriction(value) {
|
|
269
|
+
this._set('_sideFriction', Math.max(0, value));
|
|
270
|
+
}
|
|
271
|
+
/** Share of the steering: 1 turns with the wheel, -1 against it (rear steer), 0 not at all. Default 0. */ get steer() {
|
|
272
|
+
return this._steer;
|
|
273
|
+
}
|
|
274
|
+
set steer(value) {
|
|
275
|
+
this._steer = value;
|
|
276
|
+
}
|
|
277
|
+
/** Share of the engine force, e.g. 0.5 for each front wheel of a front wheel drive car. Default 0. */ get drive() {
|
|
278
|
+
return this._drive;
|
|
279
|
+
}
|
|
280
|
+
set drive(value) {
|
|
281
|
+
this._drive = value;
|
|
282
|
+
}
|
|
283
|
+
/** Share of the brake. Default 1. */ get brake() {
|
|
284
|
+
return this._brake;
|
|
285
|
+
}
|
|
286
|
+
set brake(value) {
|
|
287
|
+
this._brake = Math.max(0, value);
|
|
288
|
+
}
|
|
289
|
+
/** Share of the handbrake, usually 1 on rear wheels. Default 0. */ get handbrake() {
|
|
290
|
+
return this._handbrake;
|
|
291
|
+
}
|
|
292
|
+
set handbrake(value) {
|
|
293
|
+
this._handbrake = Math.max(0, value);
|
|
294
|
+
}
|
|
295
|
+
/** Whether the wheel touched ground at the last step. */ get inContact() {
|
|
296
|
+
return this._state.inContact;
|
|
297
|
+
}
|
|
298
|
+
/** Where the wheel touches the ground, world space; valid when {@link Wheel.inContact}. */ get contactPoint() {
|
|
299
|
+
return this._state.contactPoint;
|
|
300
|
+
}
|
|
301
|
+
/** Direction of the ground under the wheel, world space; valid when {@link Wheel.inContact}. */ get contactNormal() {
|
|
302
|
+
return this._state.contactNormal;
|
|
303
|
+
}
|
|
304
|
+
/** The node of the ground under the wheel, or null. */ get groundNode() {
|
|
305
|
+
return this.world?._colliderNodeByKey(this._state.groundKey) ?? null;
|
|
306
|
+
}
|
|
307
|
+
/** Current suspension length in metres. */ get suspensionLength() {
|
|
308
|
+
return this._state.suspensionLength;
|
|
309
|
+
}
|
|
310
|
+
/** Force the suspension pushes with, in newtons. */ get suspensionForce() {
|
|
311
|
+
return this._state.suspensionForce;
|
|
312
|
+
}
|
|
313
|
+
/** Why the wheel is not part of a vehicle, or an empty string. */ get error() {
|
|
314
|
+
return this._error;
|
|
315
|
+
}
|
|
316
|
+
_setError(error) {
|
|
317
|
+
this._error = error;
|
|
318
|
+
}
|
|
319
|
+
_set(key, value) {
|
|
320
|
+
const self = this;
|
|
321
|
+
if (self[key] !== value) {
|
|
322
|
+
self[key] = value;
|
|
323
|
+
this.world?._markVehiclesDirty();
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
_join(world) {
|
|
327
|
+
world._registerWheel(this);
|
|
328
|
+
}
|
|
329
|
+
_leave(world) {
|
|
330
|
+
world._unregisterWheel(this);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
export { Vehicle, Wheel };
|
|
335
|
+
//# sourceMappingURL=vehicle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vehicle.js","sources":["../../src/physics/vehicle.ts"],"sourcesContent":["import type { Quaternion } from '@zephyr3d/base';\r\nimport { Vector3 } from '@zephyr3d/base';\r\nimport type { SceneNode } from '../scene/scene_node';\r\nimport { PhysicsPart } from './part';\r\nimport type { PhysicsWorld } from './world';\r\n\r\n/**\r\n * Which way the front of a {@link Vehicle} faces, in its node's space.\r\n *\r\n * @public\r\n */\r\nexport type VehicleForward = '+z' | '-z' | '+x' | '-x';\r\n\r\n/**\r\n * Makes its node a car, truck or other wheeled vehicle, driven by\r\n * {@link Vehicle.throttle}, {@link Vehicle.brake} and {@link Vehicle.steering}.\r\n *\r\n * @remarks\r\n * The node needs a dynamic {@link RigidBody}, and colliders for the body. The\r\n * wheels are the {@link NodePhysics.wheel} of nodes below it, with no other rigid\r\n * body in between; each wheel node is placed where the wheel's centre is with\r\n * the suspension at rest. While simulating, the wheel nodes are moved up and\r\n * down with the suspension, turned with the steering and rolled with the\r\n * vehicle's motion.\r\n *\r\n * Up is the node's +Y; the front is {@link Vehicle.forward}. Wheels are rays\r\n * cast down from the body, as in Bullet's ray cast vehicle:\r\n * they find the ground, but do not collide - the body's colliders do.\r\n *\r\n * Inputs stay in effect until changed, and are applied every simulation step.\r\n *\r\n * @public\r\n */\r\nexport class Vehicle extends PhysicsPart {\r\n private _maxEngineForce: number;\r\n private _maxBrakeForce: number;\r\n private _maxHandbrakeForce: number;\r\n private _maxSteerAngle: number;\r\n private _forward: VehicleForward;\r\n private _layer: number;\r\n private _throttle: number;\r\n private _brake: number;\r\n private _handbrake: boolean;\r\n private _steering: number;\r\n private _error: string;\r\n\r\n constructor() {\r\n super();\r\n this._maxEngineForce = 4000;\r\n this._maxBrakeForce = 3000;\r\n this._maxHandbrakeForce = 6000;\r\n this._maxSteerAngle = 30;\r\n this._forward = '+z';\r\n this._layer = 0;\r\n this._throttle = 0;\r\n this._brake = 0;\r\n this._handbrake = false;\r\n this._steering = 0;\r\n this._error = '';\r\n }\r\n\r\n /** Total driving force at full throttle, in newtons, shared out by {@link Wheel.drive}. Default 4000. */\r\n get maxEngineForce() {\r\n return this._maxEngineForce;\r\n }\r\n set maxEngineForce(value: number) {\r\n this._maxEngineForce = Math.max(0, value);\r\n }\r\n /** Braking force of a wheel at full brake, in newtons, scaled by {@link Wheel.brake}. Default 3000. */\r\n get maxBrakeForce() {\r\n return this._maxBrakeForce;\r\n }\r\n set maxBrakeForce(value: number) {\r\n this._maxBrakeForce = Math.max(0, value);\r\n }\r\n /** Braking force of a wheel with the handbrake on, in newtons, scaled by {@link Wheel.handbrake}. Default 6000. */\r\n get maxHandbrakeForce() {\r\n return this._maxHandbrakeForce;\r\n }\r\n set maxHandbrakeForce(value: number) {\r\n this._maxHandbrakeForce = Math.max(0, value);\r\n }\r\n /** Steering angle at full lock, in degrees, scaled by {@link Wheel.steer}. Default 30. */\r\n get maxSteerAngle() {\r\n return this._maxSteerAngle;\r\n }\r\n set maxSteerAngle(value: number) {\r\n this._maxSteerAngle = value;\r\n }\r\n /** Which way the front faces in the node's space. Default `'+z'`. */\r\n get forward() {\r\n return this._forward;\r\n }\r\n set forward(value: VehicleForward) {\r\n if (value !== this._forward) {\r\n this._forward = value;\r\n this._rebuild();\r\n }\r\n }\r\n /** Collision layer of the wheels: they find ground on the layers this one collides with. Default 0. */\r\n get layer() {\r\n return this._layer;\r\n }\r\n set layer(value: number) {\r\n this._layer = Math.min(15, Math.max(0, Math.floor(value)));\r\n }\r\n\r\n /** Accelerator, -1 to 1; below 0 drives backwards. Overrides the brake on driven wheels. */\r\n get throttle() {\r\n return this._throttle;\r\n }\r\n set throttle(value: number) {\r\n this._throttle = Math.min(1, Math.max(-1, value));\r\n }\r\n /** Brake pedal, 0 to 1. */\r\n get brake() {\r\n return this._brake;\r\n }\r\n set brake(value: number) {\r\n this._brake = Math.min(1, Math.max(0, value));\r\n }\r\n /** Whether the handbrake is on. */\r\n get handbrake() {\r\n return this._handbrake;\r\n }\r\n set handbrake(value: boolean) {\r\n this._handbrake = !!value;\r\n }\r\n /** Steering wheel, -1 to 1; above 0 turns left. */\r\n get steering() {\r\n return this._steering;\r\n }\r\n set steering(value: number) {\r\n this._steering = Math.min(1, Math.max(-1, value));\r\n }\r\n\r\n /** Speed along the front direction in m/s; negative when going backwards. */\r\n get speed() {\r\n return this.world?._vehicleSpeed(this) ?? 0;\r\n }\r\n /** The wheels, in scene order, while the vehicle is in a simulation. */\r\n get wheels(): readonly Wheel[] {\r\n return this.world?._vehicleWheels(this) ?? [];\r\n }\r\n /** Why the vehicle could not be built, or an empty string. */\r\n get error() {\r\n return this._error;\r\n }\r\n\r\n /** The front direction in node space. */\r\n _forwardVector(out = new Vector3()) {\r\n switch (this._forward) {\r\n case '-z':\r\n return out.setXYZ(0, 0, -1);\r\n case '+x':\r\n return out.setXYZ(1, 0, 0);\r\n case '-x':\r\n return out.setXYZ(-1, 0, 0);\r\n default:\r\n return out.setXYZ(0, 0, 1);\r\n }\r\n }\r\n /** Whether any input asks the vehicle to move. */\r\n _hasInput() {\r\n return this._throttle !== 0 || this._brake !== 0 || this._handbrake || this._steering !== 0;\r\n }\r\n _setError(error: string) {\r\n this._error = error;\r\n }\r\n private _rebuild() {\r\n this.world?._markVehiclesDirty();\r\n }\r\n protected _join(world: PhysicsWorld) {\r\n world._registerVehicle(this);\r\n }\r\n protected _leave(world: PhysicsWorld) {\r\n world._unregisterVehicle(this);\r\n }\r\n}\r\n\r\n/**\r\n * A wheel of the {@link Vehicle} above its node.\r\n *\r\n * @remarks\r\n * Place the node where the wheel's centre is with the suspension at rest. The\r\n * suspension runs along the vehicle's down direction, the axle along its\r\n * sideways direction. While simulating, the node's local position and rotation\r\n * are set from the suspension, steering and roll; they go back to where they\r\n * were when the vehicle leaves the simulation.\r\n *\r\n * Suspension stiffness and damping are per kilogram of the vehicle, so they\r\n * feel the same on a light car and a heavy truck: with four wheels resting, the\r\n * suspension sinks by 9.81 / (4 × stiffness) metres.\r\n *\r\n * @public\r\n */\r\nexport class Wheel extends PhysicsPart {\r\n private _radius: number;\r\n private _suspensionRestLength: number;\r\n private _suspensionStiffness: number;\r\n private _suspensionCompression: number;\r\n private _suspensionRelaxation: number;\r\n private _maxSuspensionTravel: number;\r\n private _maxSuspensionForce: number;\r\n private _frictionSlip: number;\r\n private _sideFriction: number;\r\n private _steer: number;\r\n private _drive: number;\r\n private _brake: number;\r\n private _handbrake: number;\r\n /** Added to what the vehicle's inputs give this wheel. */\r\n engineForce: number;\r\n brakeForce: number;\r\n steerAngle: number;\r\n /** State after the last simulation step. */\r\n readonly _state: {\r\n suspensionLength: number;\r\n rotation: number;\r\n steering: number;\r\n inContact: boolean;\r\n contactPoint: Vector3;\r\n contactNormal: Vector3;\r\n groundKey: number;\r\n suspensionForce: number;\r\n };\r\n /** The node's local transform before the vehicle took it over. */\r\n _rest: { position: Vector3; rotation: Quaternion } | null;\r\n /** The node the vehicle last wrote to, to give the rest pose back to. */\r\n _restNode: SceneNode | null;\r\n private _error: string;\r\n\r\n constructor() {\r\n super();\r\n this._radius = 0.4;\r\n this._suspensionRestLength = 0.3;\r\n this._suspensionStiffness = 30;\r\n this._suspensionCompression = 2.2;\r\n this._suspensionRelaxation = 3.3;\r\n this._maxSuspensionTravel = 0.3;\r\n this._maxSuspensionForce = 1e6;\r\n this._frictionSlip = 1.5;\r\n this._sideFriction = 1;\r\n this._steer = 0;\r\n this._drive = 0;\r\n this._brake = 1;\r\n this._handbrake = 0;\r\n this.engineForce = 0;\r\n this.brakeForce = 0;\r\n this.steerAngle = 0;\r\n this._state = {\r\n suspensionLength: 0,\r\n rotation: 0,\r\n steering: 0,\r\n inContact: false,\r\n contactPoint: new Vector3(),\r\n contactNormal: new Vector3(),\r\n groundKey: -1,\r\n suspensionForce: 0\r\n };\r\n this._rest = null;\r\n this._restNode = null;\r\n this._error = '';\r\n }\r\n\r\n /** Wheel radius in metres. Default 0.4. */\r\n get radius() {\r\n return this._radius;\r\n }\r\n set radius(value: number) {\r\n this._set('_radius', Math.max(0.01, value));\r\n }\r\n /** Suspension length at rest, from where it is attached to the wheel's centre, in metres. Default 0.3. */\r\n get suspensionRestLength() {\r\n return this._suspensionRestLength;\r\n }\r\n set suspensionRestLength(value: number) {\r\n this._set('_suspensionRestLength', Math.max(0, value));\r\n }\r\n /** Spring strength per kilogram of vehicle; higher is firmer and sinks less. Default 30. */\r\n get suspensionStiffness() {\r\n return this._suspensionStiffness;\r\n }\r\n set suspensionStiffness(value: number) {\r\n this._set('_suspensionStiffness', Math.max(0, value));\r\n }\r\n /** Damping while the suspension compresses, per kilogram of vehicle. Default 2.2. */\r\n get suspensionCompression() {\r\n return this._suspensionCompression;\r\n }\r\n set suspensionCompression(value: number) {\r\n this._set('_suspensionCompression', Math.max(0, value));\r\n }\r\n /** Damping while the suspension extends, per kilogram of vehicle. Default 3.3. */\r\n get suspensionRelaxation() {\r\n return this._suspensionRelaxation;\r\n }\r\n set suspensionRelaxation(value: number) {\r\n this._set('_suspensionRelaxation', Math.max(0, value));\r\n }\r\n /** How far the suspension compresses or extends from rest, in metres. Default 0.3. */\r\n get maxSuspensionTravel() {\r\n return this._maxSuspensionTravel;\r\n }\r\n set maxSuspensionTravel(value: number) {\r\n this._set('_maxSuspensionTravel', Math.max(0, value));\r\n }\r\n /** Most force the suspension pushes with, in newtons. Default 1000000. */\r\n get maxSuspensionForce() {\r\n return this._maxSuspensionForce;\r\n }\r\n set maxSuspensionForce(value: number) {\r\n this._set('_maxSuspensionForce', Math.max(0, value));\r\n }\r\n /** Grip: the most sideways force per unit of load, like a friction coefficient. Default 1.5. */\r\n get frictionSlip() {\r\n return this._frictionSlip;\r\n }\r\n set frictionSlip(value: number) {\r\n this._set('_frictionSlip', Math.max(0, value));\r\n }\r\n /** Scales the sideways grip; lower lets the wheel slide out. Default 1. */\r\n get sideFriction() {\r\n return this._sideFriction;\r\n }\r\n set sideFriction(value: number) {\r\n this._set('_sideFriction', Math.max(0, value));\r\n }\r\n /** Share of the steering: 1 turns with the wheel, -1 against it (rear steer), 0 not at all. Default 0. */\r\n get steer() {\r\n return this._steer;\r\n }\r\n set steer(value: number) {\r\n this._steer = value;\r\n }\r\n /** Share of the engine force, e.g. 0.5 for each front wheel of a front wheel drive car. Default 0. */\r\n get drive() {\r\n return this._drive;\r\n }\r\n set drive(value: number) {\r\n this._drive = value;\r\n }\r\n /** Share of the brake. Default 1. */\r\n get brake() {\r\n return this._brake;\r\n }\r\n set brake(value: number) {\r\n this._brake = Math.max(0, value);\r\n }\r\n /** Share of the handbrake, usually 1 on rear wheels. Default 0. */\r\n get handbrake() {\r\n return this._handbrake;\r\n }\r\n set handbrake(value: number) {\r\n this._handbrake = Math.max(0, value);\r\n }\r\n\r\n /** Whether the wheel touched ground at the last step. */\r\n get inContact() {\r\n return this._state.inContact;\r\n }\r\n /** Where the wheel touches the ground, world space; valid when {@link Wheel.inContact}. */\r\n get contactPoint(): Vector3 {\r\n return this._state.contactPoint;\r\n }\r\n /** Direction of the ground under the wheel, world space; valid when {@link Wheel.inContact}. */\r\n get contactNormal(): Vector3 {\r\n return this._state.contactNormal;\r\n }\r\n /** The node of the ground under the wheel, or null. */\r\n get groundNode(): SceneNode | null {\r\n return this.world?._colliderNodeByKey(this._state.groundKey) ?? null;\r\n }\r\n /** Current suspension length in metres. */\r\n get suspensionLength() {\r\n return this._state.suspensionLength;\r\n }\r\n /** Force the suspension pushes with, in newtons. */\r\n get suspensionForce() {\r\n return this._state.suspensionForce;\r\n }\r\n /** Why the wheel is not part of a vehicle, or an empty string. */\r\n get error() {\r\n return this._error;\r\n }\r\n\r\n _setError(error: string) {\r\n this._error = error;\r\n }\r\n private _set(key: string, value: number) {\r\n const self = this as unknown as Record<string, number>;\r\n if (self[key] !== value) {\r\n self[key] = value;\r\n this.world?._markVehiclesDirty();\r\n }\r\n }\r\n protected _join(world: PhysicsWorld) {\r\n world._registerWheel(this);\r\n }\r\n protected _leave(world: PhysicsWorld) {\r\n world._unregisterWheel(this);\r\n }\r\n}\r\n"],"names":["Vehicle","PhysicsPart","_maxEngineForce","_maxBrakeForce","_maxHandbrakeForce","_maxSteerAngle","_forward","_layer","_throttle","_brake","_handbrake","_steering","_error","maxEngineForce","value","Math","max","maxBrakeForce","maxHandbrakeForce","maxSteerAngle","forward","_rebuild","layer","min","floor","throttle","brake","handbrake","steering","speed","world","_vehicleSpeed","wheels","_vehicleWheels","error","_forwardVector","out","Vector3","setXYZ","_hasInput","_setError","_markVehiclesDirty","_join","_registerVehicle","_leave","_unregisterVehicle","Wheel","_radius","_suspensionRestLength","_suspensionStiffness","_suspensionCompression","_suspensionRelaxation","_maxSuspensionTravel","_maxSuspensionForce","_frictionSlip","_sideFriction","_steer","_drive","engineForce","brakeForce","steerAngle","_rest","_restNode","_state","suspensionLength","rotation","inContact","contactPoint","contactNormal","groundKey","suspensionForce","radius","_set","suspensionRestLength","suspensionStiffness","suspensionCompression","suspensionRelaxation","maxSuspensionTravel","maxSuspensionForce","frictionSlip","sideFriction","steer","drive","groundNode","_colliderNodeByKey","key","self","_registerWheel","_unregisterWheel"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
let worldFactory = null;
|
|
2
|
+
/**
|
|
3
|
+
* Sets how scenes get their physics world.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Called by a physics implementation when it is loaded (`initPhysics` of
|
|
7
|
+
* `@zephyr3d/physics`), not usually by applications. Scenes create their world
|
|
8
|
+
* from it the first time they need one; scenes that already have a world keep
|
|
9
|
+
* it. Without a factory, scenes have no world: physics data on nodes is kept,
|
|
10
|
+
* saved and loaded, but not simulated.
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
*/ function setPhysicsWorldFactory(factory) {
|
|
14
|
+
worldFactory = factory;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The factory set with {@link setPhysicsWorldFactory}, or null.
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/ function getPhysicsWorldFactory() {
|
|
21
|
+
return worldFactory;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { getPhysicsWorldFactory, setPhysicsWorldFactory };
|
|
25
|
+
//# sourceMappingURL=world.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"world.js","sources":["../../src/physics/world.ts"],"sourcesContent":["import type { IEventTarget, Nullable, Quaternion, Vector3 } from '@zephyr3d/base';\r\nimport type { Scene } from '../scene/scene';\r\nimport type { SceneNode } from '../scene/scene_node';\r\nimport type {\r\n CharacterMoveResult,\r\n ColliderOutline,\r\n PhysicsQueryHit,\r\n PhysicsQueryOptions,\r\n PhysicsShape,\r\n PhysicsWorldEventMap\r\n} from './types';\r\nimport type { RigidBody } from './rigid_body';\r\nimport type { Collider } from './collider';\r\nimport type { Joint } from './joint';\r\nimport type { CharacterController } from './character';\r\nimport type { Vehicle, Wheel } from './vehicle';\r\n\r\n/**\r\n * A simulated rigid body, as a physics implementation exposes it to\r\n * {@link RigidBody}. Application code uses {@link RigidBody} instead.\r\n *\r\n * @public\r\n */\r\nexport interface PhysicsBodyHandle {\r\n setMass(mass: number): void;\r\n setDamping(linear: number, angular: number): void;\r\n setGravityScale(scale: number): void;\r\n setCcd(enabled: boolean): void;\r\n setEnabledAxes(translation: [boolean, boolean, boolean], rotation: [boolean, boolean, boolean]): void;\r\n getPosition(out: Vector3): Vector3;\r\n getRotation(out: Quaternion): Quaternion;\r\n getLinearVelocity(out: Vector3): Vector3;\r\n setLinearVelocity(v: Vector3): void;\r\n getAngularVelocity(out: Vector3): Vector3;\r\n setAngularVelocity(v: Vector3): void;\r\n /** Sets the force and torque applied during the following steps, replacing earlier ones. */\r\n setForce(force: Vector3, torque: Vector3): void;\r\n applyImpulse(impulse: Vector3, torqueImpulse: Vector3): void;\r\n isSleeping(): boolean;\r\n wakeUp(): void;\r\n}\r\n\r\n/**\r\n * A simulated joint, as a physics implementation exposes it to {@link Joint}.\r\n *\r\n * @public\r\n */\r\nexport interface PhysicsJointHandle {\r\n setContactsEnabled(enabled: boolean): void;\r\n}\r\n\r\n/**\r\n * The physics simulation of one scene: steps the physics data on its nodes\r\n * ({@link SceneNode.physics}) and answers queries.\r\n *\r\n * @remarks\r\n * Scenes get one from the physics implementation an application loads, as\r\n * `scene.physicsWorld`; see {@link setPhysicsWorldFactory}. The members whose\r\n * names start with an underscore are how physics data talks to the\r\n * implementation; application code does not call them.\r\n *\r\n * @public\r\n */\r\nexport interface PhysicsWorld extends IEventTarget<PhysicsWorldEventMap> {\r\n /** The scene this world simulates. */\r\n readonly scene: Scene;\r\n /** Whether the world has been disposed. */\r\n readonly disposed: boolean;\r\n /** Gravity in m/s². Default (0, -9.81, 0). */\r\n gravity: Vector3;\r\n /** Length of one simulation step, in seconds. Default 1/60. */\r\n fixedTimeStep: number;\r\n /** Most simulation steps taken in one frame. Default 8: real time down to 7.5 frames per second at the default step. */\r\n maxSubSteps: number;\r\n /** Whether moving bodies are drawn between their last two simulated poses. Default true. */\r\n interpolation: boolean;\r\n /** Whether this world steps on its own each frame. Default true. */\r\n enabled: boolean;\r\n /** Whether the simulation waits to start until mesh and terrain colliders have their geometry. Default true. */\r\n waitForCollidersOnStart: boolean;\r\n /** Display names of the 16 collider layers. */\r\n readonly layerNames: readonly string[];\r\n /** Whether colliders on layers `a` and `b` collide. */\r\n getLayerCollision(a: number, b: number): boolean;\r\n /** Sets whether colliders on layers `a` and `b` collide; applies to both orders. */\r\n setLayerCollision(a: number, b: number, enabled: boolean): void;\r\n /** Advances the simulation by `dt` seconds of frame time; called each frame while enabled. */\r\n update(dt: number): void;\r\n /** Resolves once every collider waiting for its geometry has it, or failed to. */\r\n whenReady(): Promise<void>;\r\n /**\r\n * Brings the world up to date with the scene without stepping it: physics data added,\r\n * removed or changed, and nodes moved, since the last step. For tools querying a world that\r\n * is not simulated, such as the editor's; queries otherwise see the world as of the last step.\r\n *\r\n * @remarks\r\n * Moves no body. Colliders that come to touch through it start touching without a contact\r\n * event, so do not call it on a world being simulated if contact events matter.\r\n */\r\n syncWithScene(): void;\r\n /** The nearest collider along a ray. */\r\n raycast(\r\n origin: Vector3,\r\n direction: Vector3,\r\n maxDistance?: number,\r\n options?: PhysicsQueryOptions\r\n ): Nullable<PhysicsQueryHit>;\r\n /** Every collider along a ray, nearest first. */\r\n raycastAll(\r\n origin: Vector3,\r\n direction: Vector3,\r\n maxDistance?: number,\r\n options?: PhysicsQueryOptions\r\n ): PhysicsQueryHit[];\r\n /** The first collider a shape moved along a direction would touch. */\r\n shapeCast(\r\n shape: PhysicsShape,\r\n position: Vector3,\r\n rotation: Quaternion,\r\n direction: Vector3,\r\n maxDistance?: number,\r\n options?: PhysicsQueryOptions\r\n ): Nullable<PhysicsQueryHit>;\r\n /** Colliders overlapping a shape. */\r\n overlap(\r\n shape: PhysicsShape,\r\n position: Vector3,\r\n rotation: Quaternion,\r\n options?: PhysicsQueryOptions\r\n ): Collider[];\r\n /** Colliders containing a point. */\r\n overlapPoint(point: Vector3, options?: PhysicsQueryOptions): Collider[];\r\n /**\r\n * Traces a collider's shape (or a character controller's capsule) as lines,\r\n * exactly as the simulation builds it; for tools.\r\n */\r\n getColliderOutline(target: Collider | CharacterController): Promise<Nullable<ColliderOutline>>;\r\n /** A key that changes whenever {@link PhysicsWorld.getColliderOutline} would give a different outline. */\r\n getColliderOutlineKey(target: Collider | CharacterController): string;\r\n /** Releases the world. */\r\n dispose(): void;\r\n\r\n /** Whether a fixed update is running, so forces act on one step only. */\r\n readonly _inFixedUpdate: boolean;\r\n _registerBody(body: RigidBody): void;\r\n _unregisterBody(body: RigidBody): void;\r\n _markBodyDirty(body: RigidBody): void;\r\n _getBodyHandle(body: RigidBody): Nullable<PhysicsBodyHandle>;\r\n _registerCollider(collider: Collider): void;\r\n _unregisterCollider(collider: Collider): void;\r\n _markColliderDirty(collider: Collider): void;\r\n _updateColliderGroups(collider: Collider): void;\r\n _registerJoint(joint: Joint): void;\r\n _unregisterJoint(joint: Joint): void;\r\n _markJointDirty(joint: Joint): void;\r\n _getJointHandle(joint: Joint): Nullable<PhysicsJointHandle>;\r\n _applyJointLimits(joint: Joint): void;\r\n _applyJointMotor(joint: Joint): void;\r\n _jointValue(joint: Joint): number;\r\n _registerCharacter(character: CharacterController): void;\r\n _unregisterCharacter(character: CharacterController): void;\r\n _configureCharacter(character: CharacterController): void;\r\n _moveCharacter(character: CharacterController, displacement: Vector3): Nullable<CharacterMoveResult>;\r\n _registerVehicle(vehicle: Vehicle): void;\r\n _unregisterVehicle(vehicle: Vehicle): void;\r\n _registerWheel(wheel: Wheel): void;\r\n _unregisterWheel(wheel: Wheel): void;\r\n _markVehiclesDirty(): void;\r\n _vehicleSpeed(vehicle: Vehicle): number;\r\n _vehicleWheels(vehicle: Vehicle): readonly Wheel[];\r\n _colliderNodeByKey(key: number): Nullable<SceneNode>;\r\n}\r\n\r\n/**\r\n * Creates the physics world of a scene.\r\n *\r\n * @public\r\n */\r\nexport type PhysicsWorldFactory = (scene: Scene) => PhysicsWorld;\r\n\r\nlet worldFactory: Nullable<PhysicsWorldFactory> = null;\r\n\r\n/**\r\n * Sets how scenes get their physics world.\r\n *\r\n * @remarks\r\n * Called by a physics implementation when it is loaded (`initPhysics` of\r\n * `@zephyr3d/physics`), not usually by applications. Scenes create their world\r\n * from it the first time they need one; scenes that already have a world keep\r\n * it. Without a factory, scenes have no world: physics data on nodes is kept,\r\n * saved and loaded, but not simulated.\r\n *\r\n * @public\r\n */\r\nexport function setPhysicsWorldFactory(factory: Nullable<PhysicsWorldFactory>) {\r\n worldFactory = factory;\r\n}\r\n\r\n/**\r\n * The factory set with {@link setPhysicsWorldFactory}, or null.\r\n *\r\n * @public\r\n */\r\nexport function getPhysicsWorldFactory() {\r\n return worldFactory;\r\n}\r\n"],"names":["worldFactory","setPhysicsWorldFactory","factory","getPhysicsWorldFactory"],"mappings":"AAoLA,IAAIA,YAA8C,GAAA,IAAA;AAElD;;;;;;;;;;;IAYO,SAASC,sBAAAA,CAAuBC,OAAsC,EAAA;IAC3EF,YAAeE,GAAAA,OAAAA;AACjB;AAEA;;;;AAIC,IACM,SAASC,sBAAAA,GAAAA;IACd,OAAOH,YAAAA;AACT;;;;"}
|
package/dist/posteffect/bloom.js
CHANGED
|
@@ -8,6 +8,13 @@ import { Vector4, Vector2 } from '@zephyr3d/base';
|
|
|
8
8
|
*/ class Bloom extends AbstractPostEffect {
|
|
9
9
|
static className = 'Bloom';
|
|
10
10
|
/** Largest finite IEEE-754 half-float value used by the HDR post-effect chain. */ static HALF_FLOAT_MAX = 65504;
|
|
11
|
+
static PHYSICAL_LEVEL_WEIGHTS = [
|
|
12
|
+
0.3465 + 0.138,
|
|
13
|
+
0.1176,
|
|
14
|
+
0.066,
|
|
15
|
+
0.066,
|
|
16
|
+
0.061
|
|
17
|
+
].map((w)=>w * 0.675);
|
|
11
18
|
static _programDownsampleH = null;
|
|
12
19
|
static _programDownsampleV = null;
|
|
13
20
|
static _programUpsample = null;
|
|
@@ -117,12 +124,36 @@ import { Vector4, Vector2 } from '@zephyr3d/base';
|
|
|
117
124
|
* NdotL ~ 1 changes frame to frame. The trade is a slightly dimmer, slightly tighter halo,
|
|
118
125
|
* because the weighting deliberately holds the brightest samples back. Turn it off for a static
|
|
119
126
|
* scene that wants maximum reach and has no high-frequency speculars to stabilize.
|
|
127
|
+
*
|
|
128
|
+
* Only applies under legacy lighting. With physical lighting, bloom downsample is a
|
|
129
|
+
* plain linear average and leaves fireflies to TAA (bloom reads the TAA-resolved frame).
|
|
120
130
|
*/ get karisAverage() {
|
|
121
131
|
return this._karisAverage;
|
|
122
132
|
}
|
|
123
133
|
set karisAverage(val) {
|
|
124
134
|
this._karisAverage = !!val;
|
|
125
135
|
}
|
|
136
|
+
static _levelWeights(ctx, count) {
|
|
137
|
+
const physical = ctx.scene?.lightingMode === 'physical';
|
|
138
|
+
const weights = [];
|
|
139
|
+
for(let i = 0; i < count; i++){
|
|
140
|
+
weights.push(physical ? Bloom.PHYSICAL_LEVEL_WEIGHTS[i] ?? 0 : 1);
|
|
141
|
+
}
|
|
142
|
+
return weights;
|
|
143
|
+
}
|
|
144
|
+
/** Whether the prefilter uses the Karis average, see {@link Bloom.karisAverage}. */ _useKarisAverage(ctx) {
|
|
145
|
+
return this._karisAverage && ctx.scene?.lightingMode !== 'physical';
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Upsample source scale for level `i + 1` into level `i`.
|
|
149
|
+
*
|
|
150
|
+
* @remarks
|
|
151
|
+
* The chain accumulates acc[i] = L[i] + (w[i+1] / w[i]) * up(acc[i+1]), which equals
|
|
152
|
+
* sum(w[k] * L[k]) / w[i]; the final compose multiplies by w[0]. This weights every level with a
|
|
153
|
+
* single scalar per pass.
|
|
154
|
+
*/ static _upsampleScale(weights, i) {
|
|
155
|
+
return weights[i] > 0 ? weights[i + 1] / weights[i] : 0;
|
|
156
|
+
}
|
|
126
157
|
/** {@inheritDoc AbstractPostEffect.requireLinearDepthTexture} */ requireLinearDepthTexture() {
|
|
127
158
|
return false;
|
|
128
159
|
}
|
|
@@ -161,6 +192,7 @@ import { Vector4, Vector2 } from '@zephyr3d/base';
|
|
|
161
192
|
// Degenerate viewport: no pyramid possible, bloom contributes nothing.
|
|
162
193
|
return s.input;
|
|
163
194
|
}
|
|
195
|
+
const weights = Bloom._levelWeights(ctx, levels.length);
|
|
164
196
|
// 1. Prefilter (threshold/knee) at half resolution.
|
|
165
197
|
const prefilterHandle = graph.addPass('Bloom:Prefilter', (builder)=>{
|
|
166
198
|
builder.read(s.input);
|
|
@@ -180,7 +212,7 @@ import { Vector4, Vector2 } from '@zephyr3d/base';
|
|
|
180
212
|
this._prepare(device, inputTexture);
|
|
181
213
|
device.pushDeviceStates();
|
|
182
214
|
try {
|
|
183
|
-
this.prefilter(device, inputTexture, rg.getTexture(out));
|
|
215
|
+
this.prefilter(device, inputTexture, rg.getTexture(out), this._useKarisAverage(ctx));
|
|
184
216
|
} finally{
|
|
185
217
|
device.popDeviceStates();
|
|
186
218
|
}
|
|
@@ -240,7 +272,7 @@ import { Vector4, Vector2 } from '@zephyr3d/base';
|
|
|
240
272
|
device.pushDeviceStates();
|
|
241
273
|
try {
|
|
242
274
|
this._prepare(device, rg.getTexture(src));
|
|
243
|
-
this.upsampleInto(device, rg.getTexture(src), rg.getTexture(out));
|
|
275
|
+
this.upsampleInto(device, rg.getTexture(src), rg.getTexture(out), Bloom._upsampleScale(weights, i));
|
|
244
276
|
} finally{
|
|
245
277
|
device.popDeviceStates();
|
|
246
278
|
}
|
|
@@ -264,7 +296,7 @@ import { Vector4, Vector2 } from '@zephyr3d/base';
|
|
|
264
296
|
device.setFramebuffer(output.framebuffer ? rg.getFramebuffer(output.framebuffer) : null);
|
|
265
297
|
device.setViewport(null);
|
|
266
298
|
device.setScissor(null);
|
|
267
|
-
this.finalCompose(device, rg.getTexture(s.input), rg.getTexture(bloomHandle), output.srgbOutput);
|
|
299
|
+
this.finalCompose(device, rg.getTexture(s.input), rg.getTexture(bloomHandle), output.srgbOutput, weights[0]);
|
|
268
300
|
} finally{
|
|
269
301
|
device.popDeviceStates();
|
|
270
302
|
}
|
|
@@ -280,17 +312,18 @@ import { Vector4, Vector2 } from '@zephyr3d/base';
|
|
|
280
312
|
const w = Math.max(inputColorTexture.width >> 1, 1);
|
|
281
313
|
const h = Math.max(inputColorTexture.height >> 1, 1);
|
|
282
314
|
const colorTex = device.pool.fetchTemporalTexture2D(false, inputColorTexture.format, w, h, false);
|
|
283
|
-
this.prefilter(device, inputColorTexture, colorTex);
|
|
315
|
+
this.prefilter(device, inputColorTexture, colorTex, this._useKarisAverage(ctx));
|
|
284
316
|
this.downsample(device, colorTex, downsampleTextures);
|
|
285
|
-
|
|
317
|
+
const weights = Bloom._levelWeights(ctx, downsampleTextures.length);
|
|
318
|
+
this.upsample(device, downsampleTextures, weights);
|
|
286
319
|
device.popDeviceStates();
|
|
287
|
-
this.finalCompose(device, inputColorTexture, downsampleTextures[0], srgbOutput);
|
|
320
|
+
this.finalCompose(device, inputColorTexture, downsampleTextures[0], srgbOutput, weights[0]);
|
|
288
321
|
for (const tex of downsampleTextures){
|
|
289
322
|
device.pool.releaseTexture(tex);
|
|
290
323
|
}
|
|
291
324
|
device.pool.releaseTexture(colorTex);
|
|
292
325
|
}
|
|
293
|
-
/** @internal */ prefilter(device, srcTexture, rt) {
|
|
326
|
+
/** @internal */ prefilter(device, srcTexture, rt, karis = this._karisAverage) {
|
|
294
327
|
this._thresholdValue.x = this._threshold * this._threshold;
|
|
295
328
|
this._thresholdValue.y = this._thresholdValue.x * this._thresholdKnee;
|
|
296
329
|
this._thresholdValue.z = 2 * this._thresholdValue.y;
|
|
@@ -309,15 +342,15 @@ import { Vector4, Vector2 } from '@zephyr3d/base';
|
|
|
309
342
|
// Half-texel diagonals of the *source*, so each fetch lands on a 2x2 group boundary.
|
|
310
343
|
this._invTexSize.setXY(1 / srcTexture.width, 1 / srcTexture.height);
|
|
311
344
|
Bloom._bindgroupPrefilter.setValue('invTexSize', this._invTexSize);
|
|
312
|
-
Bloom._bindgroupPrefilter.setValue('karis',
|
|
345
|
+
Bloom._bindgroupPrefilter.setValue('karis', karis ? 1 : 0);
|
|
313
346
|
this.drawFullscreenQuad();
|
|
314
347
|
}
|
|
315
|
-
/** @internal */ finalCompose(device, srcTexture, bloomTexture, srgbOutput) {
|
|
348
|
+
/** @internal */ finalCompose(device, srcTexture, bloomTexture, srgbOutput, levelWeight = 1) {
|
|
316
349
|
device.setProgram(Bloom._programFinalCompose);
|
|
317
350
|
device.setBindGroup(0, Bloom._bindgroupFinalCompose);
|
|
318
351
|
Bloom._bindgroupFinalCompose.setTexture('srcTex', srcTexture);
|
|
319
352
|
Bloom._bindgroupFinalCompose.setTexture('bloomTex', bloomTexture);
|
|
320
|
-
Bloom._bindgroupFinalCompose.setValue('intensity', this._intensity);
|
|
353
|
+
Bloom._bindgroupFinalCompose.setValue('intensity', this._intensity * levelWeight);
|
|
321
354
|
// Legacy lighting puts Bloom last in the chain (see Camera.syncPostProcessingMode), so this
|
|
322
355
|
// pass may be the one writing the sRGB screen. Without this the whole frame is handed to the
|
|
323
356
|
// display scene-linear and everything darkens the moment bloom is switched on.
|
|
@@ -325,14 +358,15 @@ import { Vector4, Vector2 } from '@zephyr3d/base';
|
|
|
325
358
|
Bloom._bindgroupFinalCompose.setValue('flip', device.type === 'webgpu' && device.getFramebuffer() ? 1 : 0);
|
|
326
359
|
this.drawFullscreenQuad();
|
|
327
360
|
}
|
|
328
|
-
/** @internal */ upsample(device, textures) {
|
|
361
|
+
/** @internal */ upsample(device, textures, weights) {
|
|
329
362
|
for(let i = textures.length - 2; i >= 0; i--){
|
|
330
|
-
this.upsampleInto(device, textures[i + 1], textures[i]);
|
|
363
|
+
this.upsampleInto(device, textures[i + 1], textures[i], weights ? Bloom._upsampleScale(weights, i) : 1);
|
|
331
364
|
}
|
|
332
365
|
}
|
|
333
|
-
/** @internal */ upsampleInto(device, srcTexture, dstTexture) {
|
|
366
|
+
/** @internal */ upsampleInto(device, srcTexture, dstTexture, scale = 1) {
|
|
334
367
|
device.setProgram(Bloom._programUpsample);
|
|
335
368
|
device.setBindGroup(0, Bloom._bindgroupUpsample);
|
|
369
|
+
Bloom._bindgroupUpsample.setValue('scale', scale);
|
|
336
370
|
Bloom._bindgroupUpsample.setValue('flip', device.type === 'webgpu' ? 1 : 0);
|
|
337
371
|
Bloom._bindgroupUpsample.setTexture('tex', srcTexture);
|
|
338
372
|
// Tent offsets are in source-texel units, so the filter widens with the level it reads
|
|
@@ -545,6 +579,7 @@ import { Vector4, Vector2 } from '@zephyr3d/base';
|
|
|
545
579
|
this.tex = pb.tex2D().uniform(0);
|
|
546
580
|
this.invTexSize = pb.vec2().uniform(0);
|
|
547
581
|
this.radius = pb.float().uniform(0);
|
|
582
|
+
this.scale = pb.float().uniform(0);
|
|
548
583
|
this.$outputs.outColor = pb.vec4();
|
|
549
584
|
pb.main(function() {
|
|
550
585
|
// 3x3 tent filter, the upsample kernel from "Next Generation Post Processing in
|
|
@@ -604,7 +639,7 @@ import { Vector4, Vector2 } from '@zephyr3d/base';
|
|
|
604
639
|
for (const [dx, dy, w] of taps){
|
|
605
640
|
this.sum = pb.add(this.sum, pb.mul(pb.textureSampleLevel(this.tex, pb.add(this.$inputs.uv, pb.mul(this.o, pb.vec2(dx, dy))), 0).rgb, w / 16));
|
|
606
641
|
}
|
|
607
|
-
this.$outputs.outColor = pb.vec4(this.sum, 1);
|
|
642
|
+
this.$outputs.outColor = pb.vec4(pb.mul(this.sum, this.scale), 1);
|
|
608
643
|
});
|
|
609
644
|
}
|
|
610
645
|
});
|