@zephyr3d/scene 0.9.27 → 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 +54 -0
- 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 +279 -55
- 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 +171 -1
- 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 +104 -178
- 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 +25436 -15990
- package/dist/index.js +65 -11
- 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/lambert.js +4 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +66 -4
- 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 +191 -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 +333 -191
- 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 +1261 -1438
- 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 +106 -106
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/postsss.js +572 -0
- package/dist/posteffect/postsss.js.map +1 -0
- package/dist/posteffect/sao.js +2 -6
- 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 +4 -13
- 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 +3 -2
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +179 -64
- 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 +25 -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 +5 -5
- 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 +5 -10
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +247 -157
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +16 -38
- 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/instance_culling.js +499 -0
- package/dist/render/instance_culling.js.map +1 -0
- package/dist/render/lightpass.js +19 -8
- 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/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 +162 -11
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +10 -7
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +14 -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 +272 -55
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_graph_context.js +41 -0
- package/dist/render/rendergraph/frame_graph_context.js.map +1 -0
- 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 +58 -158
- package/dist/render/underwater.js.map +1 -1
- 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 +134 -319
- package/dist/render/water_caustics.js.map +1 -1
- 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 +3 -3
- 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 +633 -268
- 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/ssgi.js +63 -0
- package/dist/shaders/ssgi.js.map +1 -0
- package/dist/shaders/ssgi_reprojection.js +118 -0
- package/dist/shaders/ssgi_reprojection.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 +32 -82
- package/dist/shaders/water.js.map +1 -1
- package/dist/shaders/water_medium.js +7 -21
- package/dist/shaders/water_medium.js.map +1 -1
- 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 +40 -2
- 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 +34 -6
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +46 -5
- 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 +87 -254
- 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 +1543 -264
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +10 -22
- 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
- package/dist/animation/joint_dynamics/convex_collider.js +0 -320
- package/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { Quaternion, Vector3 } from '@zephyr3d/base';
|
|
2
|
+
import { BaseCameraController } from './base.js';
|
|
3
|
+
|
|
4
|
+
const defaultOptions = ()=>({
|
|
5
|
+
mode: 'free',
|
|
6
|
+
pivotOffset: new Vector3(0, 1.5, 0),
|
|
7
|
+
armLength: 4,
|
|
8
|
+
minArmLength: 1.5,
|
|
9
|
+
maxArmLength: 12,
|
|
10
|
+
minPitch: -1,
|
|
11
|
+
maxPitch: 1.3,
|
|
12
|
+
positionLag: 10,
|
|
13
|
+
forwardAxis: new Vector3(0, 0, 1),
|
|
14
|
+
chasePitch: 0.3,
|
|
15
|
+
chaseStiffness: 3,
|
|
16
|
+
recenterDelay: 1.5,
|
|
17
|
+
recenterMinSpeed: 1,
|
|
18
|
+
probeRadius: 0.15,
|
|
19
|
+
collisionMask: -1,
|
|
20
|
+
exclude: null,
|
|
21
|
+
zoomOutSpeed: 4,
|
|
22
|
+
mouseSensitivity: 0.005,
|
|
23
|
+
mouseButtons: [
|
|
24
|
+
0,
|
|
25
|
+
2
|
|
26
|
+
],
|
|
27
|
+
fovBoost: null
|
|
28
|
+
});
|
|
29
|
+
const identity = Quaternion.identity();
|
|
30
|
+
/** Closest the camera comes to the pivot */ const MIN_DISTANCE = 0.05;
|
|
31
|
+
/** A sweep hit closer than this started inside something */ const START_OVERLAP = 1e-3;
|
|
32
|
+
/** Above this, a near plane is warned about as too far from the eye */ const LARGE_NEAR_RADIUS = 0.5;
|
|
33
|
+
/**
|
|
34
|
+
* Third-person camera on a spring arm.
|
|
35
|
+
*
|
|
36
|
+
* The camera orbits a pivot above its target at `armLength`, turned by look
|
|
37
|
+
* input. A sphere is swept from the pivot to the camera through the scene's
|
|
38
|
+
* physics world: an obstacle pulls the camera in at once, and it eases back out
|
|
39
|
+
* once clear. In `'chase'` mode it swings back behind a moving target when the
|
|
40
|
+
* player stops turning it, as driving games do.
|
|
41
|
+
*
|
|
42
|
+
* Its {@link FollowCameraController.updatePhase} is `'late'`: it is updated after
|
|
43
|
+
* physics, so it follows the pose of the target rendered this frame. Feed it look
|
|
44
|
+
* input from an action map, or let it read mouse drags through `camera.handleEvent`.
|
|
45
|
+
*
|
|
46
|
+
* The camera should have no parent; it is placed in world space.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const follow = new FollowCameraController(car, { mode: 'chase', armLength: 7 });
|
|
51
|
+
* camera.controller = follow;
|
|
52
|
+
* myApp.on('tick', () => {
|
|
53
|
+
* const look = driving.vector2('look');
|
|
54
|
+
* follow.addLookInput(look.x, look.y);
|
|
55
|
+
* });
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @public
|
|
59
|
+
*/ class FollowCameraController extends BaseCameraController {
|
|
60
|
+
/** Options; may be changed at any time. */ options;
|
|
61
|
+
_target;
|
|
62
|
+
_yaw;
|
|
63
|
+
_pitch;
|
|
64
|
+
_pivot;
|
|
65
|
+
_lastTargetPos;
|
|
66
|
+
_distance;
|
|
67
|
+
_idleTime;
|
|
68
|
+
_speed;
|
|
69
|
+
_baseFovY;
|
|
70
|
+
_snap;
|
|
71
|
+
_blendTime;
|
|
72
|
+
_blendElapsed;
|
|
73
|
+
_blendEye;
|
|
74
|
+
_blendLookAt;
|
|
75
|
+
_eye;
|
|
76
|
+
_lookAt;
|
|
77
|
+
_dragging;
|
|
78
|
+
_lastX;
|
|
79
|
+
_lastY;
|
|
80
|
+
_warnedNear = false;
|
|
81
|
+
/**
|
|
82
|
+
* @param target - Node to follow.
|
|
83
|
+
* @param options - Options; unspecified ones take their defaults.
|
|
84
|
+
*/ constructor(target, options){
|
|
85
|
+
super();
|
|
86
|
+
this.options = {
|
|
87
|
+
...defaultOptions(),
|
|
88
|
+
...options
|
|
89
|
+
};
|
|
90
|
+
this._target = target;
|
|
91
|
+
this._yaw = 0;
|
|
92
|
+
this._pitch = this.options.chasePitch;
|
|
93
|
+
this._pivot = new Vector3();
|
|
94
|
+
this._lastTargetPos = new Vector3();
|
|
95
|
+
this._distance = this.options.armLength;
|
|
96
|
+
this._idleTime = 0;
|
|
97
|
+
this._speed = 0;
|
|
98
|
+
this._baseFovY = 0;
|
|
99
|
+
this._snap = true;
|
|
100
|
+
this._blendTime = 0;
|
|
101
|
+
this._blendElapsed = 0;
|
|
102
|
+
this._blendEye = new Vector3();
|
|
103
|
+
this._blendLookAt = new Vector3();
|
|
104
|
+
this._eye = new Vector3();
|
|
105
|
+
this._lookAt = new Vector3();
|
|
106
|
+
this._dragging = false;
|
|
107
|
+
this._lastX = 0;
|
|
108
|
+
this._lastY = 0;
|
|
109
|
+
}
|
|
110
|
+
/** @override */ get updatePhase() {
|
|
111
|
+
return 'late';
|
|
112
|
+
}
|
|
113
|
+
/** The node being followed. */ get target() {
|
|
114
|
+
return this._target;
|
|
115
|
+
}
|
|
116
|
+
/** Horizontal angle of the arm. 0 puts the camera on the pivot's +Z side. */ get yaw() {
|
|
117
|
+
return this._yaw;
|
|
118
|
+
}
|
|
119
|
+
set yaw(val) {
|
|
120
|
+
this._yaw = val;
|
|
121
|
+
}
|
|
122
|
+
/** Vertical angle of the arm, clamped to the pitch limits. */ get pitch() {
|
|
123
|
+
return this._pitch;
|
|
124
|
+
}
|
|
125
|
+
set pitch(val) {
|
|
126
|
+
this._pitch = Math.min(Math.max(val, this.options.minPitch), this.options.maxPitch);
|
|
127
|
+
}
|
|
128
|
+
/** Current camera distance from the pivot, after collision. */ get distance() {
|
|
129
|
+
return this._distance;
|
|
130
|
+
}
|
|
131
|
+
/** Speed of the target in units per second, estimated from its movement. */ get targetSpeed() {
|
|
132
|
+
return this._speed;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Switches to another target, e.g. when the player gets into a vehicle.
|
|
136
|
+
*
|
|
137
|
+
* @param target - Node to follow.
|
|
138
|
+
* @param options - `blendTime`: seconds to ease from the current view to the new
|
|
139
|
+
* one, 0 to cut. `options`: options to change at the same time.
|
|
140
|
+
*/ setTarget(target, options) {
|
|
141
|
+
const camera = this._getCamera();
|
|
142
|
+
this._blendTime = options?.blendTime ?? 0;
|
|
143
|
+
this._blendElapsed = 0;
|
|
144
|
+
if (camera && this._blendTime > 0 && !this._snap) {
|
|
145
|
+
this._blendEye.set(this._eye);
|
|
146
|
+
this._blendLookAt.set(this._lookAt);
|
|
147
|
+
} else {
|
|
148
|
+
this._blendTime = 0;
|
|
149
|
+
}
|
|
150
|
+
Object.assign(this.options, options?.options ?? {});
|
|
151
|
+
this._target = target;
|
|
152
|
+
this._snap = true;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Turns the camera. Call every frame with the frame's look input, such as the
|
|
156
|
+
* value of a look action.
|
|
157
|
+
*
|
|
158
|
+
* @param x - Radians to turn right.
|
|
159
|
+
* @param y - Radians to turn up.
|
|
160
|
+
*/ addLookInput(x, y) {
|
|
161
|
+
if (x !== 0 || y !== 0) {
|
|
162
|
+
this._yaw -= x;
|
|
163
|
+
this.pitch = this._pitch - y;
|
|
164
|
+
this._idleTime = 0;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Zooms the camera. The arm length is scaled by `exp(amount)`: positive moves
|
|
169
|
+
* the camera out.
|
|
170
|
+
*
|
|
171
|
+
* @param amount - Zoom amount.
|
|
172
|
+
*/ addZoomInput(amount) {
|
|
173
|
+
const o = this.options;
|
|
174
|
+
o.armLength = Math.min(Math.max(o.armLength * Math.exp(amount), o.minArmLength), o.maxArmLength);
|
|
175
|
+
}
|
|
176
|
+
/** Jumps to the wanted view on the next update, without lag or easing. */ snap() {
|
|
177
|
+
this._snap = true;
|
|
178
|
+
this._blendTime = 0;
|
|
179
|
+
}
|
|
180
|
+
/** @override */ reset() {
|
|
181
|
+
this._snap = true;
|
|
182
|
+
this._blendTime = 0;
|
|
183
|
+
}
|
|
184
|
+
/** @override */ _onMouseDown(evt) {
|
|
185
|
+
if (this.options.mouseButtons.includes(evt.button)) {
|
|
186
|
+
this._dragging = true;
|
|
187
|
+
this._lastX = evt.offsetX;
|
|
188
|
+
this._lastY = evt.offsetY;
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
/** @override */ _onMouseUp(evt) {
|
|
194
|
+
if (this._dragging && this.options.mouseButtons.includes(evt.button)) {
|
|
195
|
+
this._dragging = false;
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
/** @override */ _onMouseMove(evt) {
|
|
201
|
+
if (this._dragging) {
|
|
202
|
+
const s = this.options.mouseSensitivity;
|
|
203
|
+
this.addLookInput((evt.offsetX - this._lastX) * s, -(evt.offsetY - this._lastY) * s);
|
|
204
|
+
this._lastX = evt.offsetX;
|
|
205
|
+
this._lastY = evt.offsetY;
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
/** @override */ _onMouseWheel(evt) {
|
|
211
|
+
this.addZoomInput(evt.deltaY * 0.001);
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
/** @override */ _onUpdate(dt) {
|
|
215
|
+
const camera = this._getCamera();
|
|
216
|
+
const target = this._target;
|
|
217
|
+
if (!camera || !target) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const o = this.options;
|
|
221
|
+
const targetPos = target.getWorldPosition();
|
|
222
|
+
const wantedPivot = Vector3.add(targetPos, o.pivotOffset);
|
|
223
|
+
if (this._snap) {
|
|
224
|
+
this._pivot.set(wantedPivot);
|
|
225
|
+
this._lastTargetPos.set(targetPos);
|
|
226
|
+
this._speed = 0;
|
|
227
|
+
this._idleTime = o.recenterDelay;
|
|
228
|
+
if (o.mode === 'chase') {
|
|
229
|
+
this._yaw = this._chaseYaw(target);
|
|
230
|
+
this.pitch = o.chasePitch;
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
// Exponential approach: frame-rate independent
|
|
234
|
+
const t = o.positionLag > 0 ? 1 - Math.exp(-o.positionLag * dt) : 1;
|
|
235
|
+
this._pivot.combineBy(wantedPivot, 1 - t, t);
|
|
236
|
+
if (dt > 0) {
|
|
237
|
+
const speed = Vector3.distance(targetPos, this._lastTargetPos) / dt;
|
|
238
|
+
this._speed += (speed - this._speed) * (1 - Math.exp(-8 * dt));
|
|
239
|
+
}
|
|
240
|
+
this._lastTargetPos.set(targetPos);
|
|
241
|
+
this._idleTime += dt;
|
|
242
|
+
if (o.mode === 'chase' && this._idleTime >= o.recenterDelay && this._speed >= o.recenterMinSpeed) {
|
|
243
|
+
const t = 1 - Math.exp(-o.chaseStiffness * dt);
|
|
244
|
+
let diff = this._chaseYaw(target) - this._yaw;
|
|
245
|
+
// Shortest way round
|
|
246
|
+
diff = Math.atan2(Math.sin(diff), Math.cos(diff));
|
|
247
|
+
this._yaw += diff * t;
|
|
248
|
+
this.pitch = this._pitch + (o.chasePitch - this._pitch) * t;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// Spring arm: sweep from the pivot back along the view direction
|
|
252
|
+
const cosPitch = Math.cos(this._pitch);
|
|
253
|
+
const back = new Vector3(Math.sin(this._yaw) * cosPitch, Math.sin(this._pitch), Math.cos(this._yaw) * cosPitch);
|
|
254
|
+
const free = this._sweep(back, o.armLength);
|
|
255
|
+
if (this._snap || free < this._distance) {
|
|
256
|
+
this._distance = free;
|
|
257
|
+
} else {
|
|
258
|
+
this._distance = Math.min(free, this._distance + o.zoomOutSpeed * dt);
|
|
259
|
+
}
|
|
260
|
+
// Never on the pivot itself: looking at the point the eye is on has no direction
|
|
261
|
+
this._distance = Math.max(this._distance, MIN_DISTANCE);
|
|
262
|
+
this._lookAt.set(this._pivot);
|
|
263
|
+
Vector3.combine(this._pivot, back, 1, this._distance, this._eye);
|
|
264
|
+
let eye = this._eye;
|
|
265
|
+
let lookAt = this._lookAt;
|
|
266
|
+
if (this._blendTime > 0) {
|
|
267
|
+
this._blendElapsed += dt;
|
|
268
|
+
const x = Math.min(this._blendElapsed / this._blendTime, 1);
|
|
269
|
+
const s = x * x * (3 - 2 * x);
|
|
270
|
+
eye = Vector3.combine(this._blendEye, this._eye, 1 - s, s);
|
|
271
|
+
lookAt = Vector3.combine(this._blendLookAt, this._lookAt, 1 - s, s);
|
|
272
|
+
if (x >= 1) {
|
|
273
|
+
this._blendTime = 0;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
camera.lookAt(eye, lookAt, Vector3.axisPY());
|
|
277
|
+
if (camera.isPerspective()) {
|
|
278
|
+
const perspective = camera;
|
|
279
|
+
if (o.fovBoost) {
|
|
280
|
+
// The field of view without boost is taken when boosting starts
|
|
281
|
+
if (!this._baseFovY) {
|
|
282
|
+
this._baseFovY = perspective.fovY;
|
|
283
|
+
}
|
|
284
|
+
const k = Math.min(this._speed / o.fovBoost.maxSpeed, 1);
|
|
285
|
+
perspective.fovY = this._baseFovY + o.fovBoost.maxBoost * k;
|
|
286
|
+
} else if (this._baseFovY) {
|
|
287
|
+
// Boost was turned off: restore once, then leave the field of view alone
|
|
288
|
+
perspective.fovY = this._baseFovY;
|
|
289
|
+
this._baseFovY = 0;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
this._snap = false;
|
|
293
|
+
}
|
|
294
|
+
/** Yaw that puts the camera behind the target */ _chaseYaw(target) {
|
|
295
|
+
const fwd = target.worldMatrix.transformVectorAffine(this.options.forwardAxis, new Vector3());
|
|
296
|
+
if (fwd.x === 0 && fwd.z === 0) {
|
|
297
|
+
return this._yaw;
|
|
298
|
+
}
|
|
299
|
+
return Math.atan2(-fwd.x, -fwd.z);
|
|
300
|
+
}
|
|
301
|
+
/** How far the camera can go back from the pivot along `dir`, up to `length` */ _sweep(dir, length) {
|
|
302
|
+
const camera = this._getCamera();
|
|
303
|
+
const world = camera?.scene?.physicsWorld;
|
|
304
|
+
if (!world || length <= 0) {
|
|
305
|
+
return length;
|
|
306
|
+
}
|
|
307
|
+
const o = this.options;
|
|
308
|
+
let radius = o.probeRadius;
|
|
309
|
+
if (camera.isPerspective()) {
|
|
310
|
+
// The near plane's corners are this far from the eye: a smaller sphere
|
|
311
|
+
// lets them into a wall the sphere itself stopped short of
|
|
312
|
+
const p = camera;
|
|
313
|
+
const halfHeight = p.near * Math.tan(p.fovY / 2);
|
|
314
|
+
const nearRadius = Math.hypot(p.near, halfHeight, halfHeight * p.aspect);
|
|
315
|
+
if (nearRadius > LARGE_NEAR_RADIUS && !this._warnedNear) {
|
|
316
|
+
this._warnedNear = true;
|
|
317
|
+
console.warn(`FollowCameraController: the camera's near plane (${p.near}) is far from the eye, so ` + `the camera keeps ${nearRadius.toFixed(2)} away from walls and is pushed in close in ` + 'narrow places; set the near plane to about 0.1');
|
|
318
|
+
}
|
|
319
|
+
radius = Math.max(radius, nearRadius);
|
|
320
|
+
}
|
|
321
|
+
const options = {
|
|
322
|
+
layerMask: o.collisionMask,
|
|
323
|
+
exclude: o.exclude ?? this._target?.physics ?? null
|
|
324
|
+
};
|
|
325
|
+
let hit = world.shapeCast({
|
|
326
|
+
type: 'sphere',
|
|
327
|
+
radius
|
|
328
|
+
}, this._pivot, identity, dir, length, options);
|
|
329
|
+
if (hit && hit.distance <= START_OVERLAP && radius > o.probeRadius) {
|
|
330
|
+
// The sphere is already in a wall at the pivot: there is no room for the
|
|
331
|
+
// near plane anyway, so fall back to the small probe rather than the pivot
|
|
332
|
+
hit = world.shapeCast({
|
|
333
|
+
type: 'sphere',
|
|
334
|
+
radius: o.probeRadius
|
|
335
|
+
}, this._pivot, identity, dir, length, options);
|
|
336
|
+
}
|
|
337
|
+
return hit ? hit.distance : length;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export { FollowCameraController };
|
|
342
|
+
//# sourceMappingURL=follow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"follow.js","sources":["../../src/camera/follow.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { Quaternion, Vector3 } from '@zephyr3d/base';\r\nimport type { IControllerMouseEvent, IControllerWheelEvent, CameraControllerUpdatePhase } from './base';\r\nimport { BaseCameraController } from './base';\r\nimport type { SceneNode } from '../scene/scene_node';\r\nimport type { NodePhysics } from '../physics/node_physics';\r\n\r\n/**\r\n * Options of {@link FollowCameraController}. Angles are in radians, distances in\r\n * world units, rates in 1/s.\r\n *\r\n * @public\r\n */\r\nexport interface FollowCameraOptions {\r\n /**\r\n * `'free'`: the player turns the camera; it stays where it was turned.\r\n * `'chase'`: as free, but after `recenterDelay` seconds without look input the\r\n * camera swings back behind the target while the target moves.\r\n */\r\n mode: 'free' | 'chase';\r\n /** World-space offset from the target's origin to the point the camera orbits and looks at. */\r\n pivotOffset: Vector3;\r\n /** Wanted distance from the pivot. Changed by zoom input within the limits below. */\r\n armLength: number;\r\n minArmLength: number;\r\n maxArmLength: number;\r\n /** Lowest and highest pitch. Positive pitch puts the camera above the pivot, looking down. */\r\n minPitch: number;\r\n maxPitch: number;\r\n /** How fast the pivot catches up with the target; 0 follows rigidly. */\r\n positionLag: number;\r\n /** Chase mode: the target's local forward axis. */\r\n forwardAxis: Vector3;\r\n /** Chase mode: pitch the camera returns to. */\r\n chasePitch: number;\r\n /** Chase mode: how fast the camera swings back behind the target. */\r\n chaseStiffness: number;\r\n /** Chase mode: seconds without look input before swinging back. */\r\n recenterDelay: number;\r\n /** Chase mode: the target must move at least this fast for the camera to swing back. */\r\n recenterMinSpeed: number;\r\n /**\r\n * Least radius of the sphere swept from the pivot to the camera. For a\r\n * perspective camera the sweep uses at least the distance from the eye to the\r\n * near plane's corners, or the near plane would cut into walls; keep the near\r\n * plane small (around 0.1) so that this stays small too.\r\n */\r\n probeRadius: number;\r\n /** Collider layers that block the camera, as bits `1 << layer`. */\r\n collisionMask: number;\r\n /** Physics object the sweep ignores. Defaults to the target's own `physics`. */\r\n exclude: Nullable<NodePhysics>;\r\n /** How fast the camera moves back out after an obstacle clears. Moving in is immediate. */\r\n zoomOutSpeed: number;\r\n /** Radians per pixel of mouse drag, for input through `camera.handleEvent`. */\r\n mouseSensitivity: number;\r\n /** Mouse buttons (as `MouseEvent.button`) that rotate the camera when dragged; empty for none. */\r\n mouseButtons: number[];\r\n /**\r\n * Widen the field of view with the target's speed: by `maxBoost` at `maxSpeed`\r\n * and above. Perspective cameras only; null disables it.\r\n */\r\n fovBoost: Nullable<{ maxBoost: number; maxSpeed: number }>;\r\n}\r\n\r\nconst defaultOptions = (): FollowCameraOptions => ({\r\n mode: 'free',\r\n pivotOffset: new Vector3(0, 1.5, 0),\r\n armLength: 4,\r\n minArmLength: 1.5,\r\n maxArmLength: 12,\r\n minPitch: -1.0,\r\n maxPitch: 1.3,\r\n positionLag: 10,\r\n forwardAxis: new Vector3(0, 0, 1),\r\n chasePitch: 0.3,\r\n chaseStiffness: 3,\r\n recenterDelay: 1.5,\r\n recenterMinSpeed: 1,\r\n probeRadius: 0.15,\r\n collisionMask: ~0,\r\n exclude: null,\r\n zoomOutSpeed: 4,\r\n mouseSensitivity: 0.005,\r\n mouseButtons: [0, 2],\r\n fovBoost: null\r\n});\r\n\r\nconst identity = Quaternion.identity();\r\n/** Closest the camera comes to the pivot */\r\nconst MIN_DISTANCE = 0.05;\r\n/** A sweep hit closer than this started inside something */\r\nconst START_OVERLAP = 1e-3;\r\n/** Above this, a near plane is warned about as too far from the eye */\r\nconst LARGE_NEAR_RADIUS = 0.5;\r\n\r\n/**\r\n * Third-person camera on a spring arm.\r\n *\r\n * The camera orbits a pivot above its target at `armLength`, turned by look\r\n * input. A sphere is swept from the pivot to the camera through the scene's\r\n * physics world: an obstacle pulls the camera in at once, and it eases back out\r\n * once clear. In `'chase'` mode it swings back behind a moving target when the\r\n * player stops turning it, as driving games do.\r\n *\r\n * Its {@link FollowCameraController.updatePhase} is `'late'`: it is updated after\r\n * physics, so it follows the pose of the target rendered this frame. Feed it look\r\n * input from an action map, or let it read mouse drags through `camera.handleEvent`.\r\n *\r\n * The camera should have no parent; it is placed in world space.\r\n *\r\n * @example\r\n * ```ts\r\n * const follow = new FollowCameraController(car, { mode: 'chase', armLength: 7 });\r\n * camera.controller = follow;\r\n * myApp.on('tick', () => {\r\n * const look = driving.vector2('look');\r\n * follow.addLookInput(look.x, look.y);\r\n * });\r\n * ```\r\n *\r\n * @public\r\n */\r\nexport class FollowCameraController extends BaseCameraController {\r\n /** Options; may be changed at any time. */\r\n readonly options: FollowCameraOptions;\r\n private _target: Nullable<SceneNode>;\r\n private _yaw: number;\r\n private _pitch: number;\r\n private readonly _pivot: Vector3;\r\n private readonly _lastTargetPos: Vector3;\r\n private _distance: number;\r\n private _idleTime: number;\r\n private _speed: number;\r\n private _baseFovY: number;\r\n private _snap: boolean;\r\n private _blendTime: number;\r\n private _blendElapsed: number;\r\n private readonly _blendEye: Vector3;\r\n private readonly _blendLookAt: Vector3;\r\n private readonly _eye: Vector3;\r\n private readonly _lookAt: Vector3;\r\n private _dragging: boolean;\r\n private _lastX: number;\r\n private _lastY: number;\r\n private _warnedNear = false;\r\n /**\r\n * @param target - Node to follow.\r\n * @param options - Options; unspecified ones take their defaults.\r\n */\r\n constructor(target: Nullable<SceneNode>, options?: Partial<FollowCameraOptions>) {\r\n super();\r\n this.options = { ...defaultOptions(), ...options };\r\n this._target = target;\r\n this._yaw = 0;\r\n this._pitch = this.options.chasePitch;\r\n this._pivot = new Vector3();\r\n this._lastTargetPos = new Vector3();\r\n this._distance = this.options.armLength;\r\n this._idleTime = 0;\r\n this._speed = 0;\r\n this._baseFovY = 0;\r\n this._snap = true;\r\n this._blendTime = 0;\r\n this._blendElapsed = 0;\r\n this._blendEye = new Vector3();\r\n this._blendLookAt = new Vector3();\r\n this._eye = new Vector3();\r\n this._lookAt = new Vector3();\r\n this._dragging = false;\r\n this._lastX = 0;\r\n this._lastY = 0;\r\n }\r\n /** @override */\r\n get updatePhase(): CameraControllerUpdatePhase {\r\n return 'late';\r\n }\r\n /** The node being followed. */\r\n get target() {\r\n return this._target;\r\n }\r\n /** Horizontal angle of the arm. 0 puts the camera on the pivot's +Z side. */\r\n get yaw() {\r\n return this._yaw;\r\n }\r\n set yaw(val: number) {\r\n this._yaw = val;\r\n }\r\n /** Vertical angle of the arm, clamped to the pitch limits. */\r\n get pitch() {\r\n return this._pitch;\r\n }\r\n set pitch(val: number) {\r\n this._pitch = Math.min(Math.max(val, this.options.minPitch), this.options.maxPitch);\r\n }\r\n /** Current camera distance from the pivot, after collision. */\r\n get distance() {\r\n return this._distance;\r\n }\r\n /** Speed of the target in units per second, estimated from its movement. */\r\n get targetSpeed() {\r\n return this._speed;\r\n }\r\n /**\r\n * Switches to another target, e.g. when the player gets into a vehicle.\r\n *\r\n * @param target - Node to follow.\r\n * @param options - `blendTime`: seconds to ease from the current view to the new\r\n * one, 0 to cut. `options`: options to change at the same time.\r\n */\r\n setTarget(\r\n target: Nullable<SceneNode>,\r\n options?: { blendTime?: number; options?: Partial<FollowCameraOptions> }\r\n ) {\r\n const camera = this._getCamera();\r\n this._blendTime = options?.blendTime ?? 0;\r\n this._blendElapsed = 0;\r\n if (camera && this._blendTime > 0 && !this._snap) {\r\n this._blendEye.set(this._eye);\r\n this._blendLookAt.set(this._lookAt);\r\n } else {\r\n this._blendTime = 0;\r\n }\r\n Object.assign(this.options, options?.options ?? {});\r\n this._target = target;\r\n this._snap = true;\r\n }\r\n /**\r\n * Turns the camera. Call every frame with the frame's look input, such as the\r\n * value of a look action.\r\n *\r\n * @param x - Radians to turn right.\r\n * @param y - Radians to turn up.\r\n */\r\n addLookInput(x: number, y: number) {\r\n if (x !== 0 || y !== 0) {\r\n this._yaw -= x;\r\n this.pitch = this._pitch - y;\r\n this._idleTime = 0;\r\n }\r\n }\r\n /**\r\n * Zooms the camera. The arm length is scaled by `exp(amount)`: positive moves\r\n * the camera out.\r\n *\r\n * @param amount - Zoom amount.\r\n */\r\n addZoomInput(amount: number) {\r\n const o = this.options;\r\n o.armLength = Math.min(Math.max(o.armLength * Math.exp(amount), o.minArmLength), o.maxArmLength);\r\n }\r\n /** Jumps to the wanted view on the next update, without lag or easing. */\r\n snap() {\r\n this._snap = true;\r\n this._blendTime = 0;\r\n }\r\n /** @override */\r\n reset() {\r\n this._snap = true;\r\n this._blendTime = 0;\r\n }\r\n /** @override */\r\n protected _onMouseDown(evt: IControllerMouseEvent): boolean {\r\n if (this.options.mouseButtons.includes(evt.button)) {\r\n this._dragging = true;\r\n this._lastX = evt.offsetX;\r\n this._lastY = evt.offsetY;\r\n return true;\r\n }\r\n return false;\r\n }\r\n /** @override */\r\n protected _onMouseUp(evt: IControllerMouseEvent): boolean {\r\n if (this._dragging && this.options.mouseButtons.includes(evt.button)) {\r\n this._dragging = false;\r\n return true;\r\n }\r\n return false;\r\n }\r\n /** @override */\r\n protected _onMouseMove(evt: IControllerMouseEvent): boolean {\r\n if (this._dragging) {\r\n const s = this.options.mouseSensitivity;\r\n this.addLookInput((evt.offsetX - this._lastX) * s, -(evt.offsetY - this._lastY) * s);\r\n this._lastX = evt.offsetX;\r\n this._lastY = evt.offsetY;\r\n return true;\r\n }\r\n return false;\r\n }\r\n /** @override */\r\n protected _onMouseWheel(evt: IControllerWheelEvent): boolean {\r\n this.addZoomInput(evt.deltaY * 0.001);\r\n return true;\r\n }\r\n /** @override */\r\n protected _onUpdate(dt: number) {\r\n const camera = this._getCamera();\r\n const target = this._target;\r\n if (!camera || !target) {\r\n return;\r\n }\r\n const o = this.options;\r\n const targetPos = target.getWorldPosition();\r\n const wantedPivot = Vector3.add(targetPos, o.pivotOffset);\r\n if (this._snap) {\r\n this._pivot.set(wantedPivot);\r\n this._lastTargetPos.set(targetPos);\r\n this._speed = 0;\r\n this._idleTime = o.recenterDelay;\r\n if (o.mode === 'chase') {\r\n this._yaw = this._chaseYaw(target);\r\n this.pitch = o.chasePitch;\r\n }\r\n } else {\r\n // Exponential approach: frame-rate independent\r\n const t = o.positionLag > 0 ? 1 - Math.exp(-o.positionLag * dt) : 1;\r\n this._pivot.combineBy(wantedPivot, 1 - t, t);\r\n if (dt > 0) {\r\n const speed = Vector3.distance(targetPos, this._lastTargetPos) / dt;\r\n this._speed += (speed - this._speed) * (1 - Math.exp(-8 * dt));\r\n }\r\n this._lastTargetPos.set(targetPos);\r\n this._idleTime += dt;\r\n if (o.mode === 'chase' && this._idleTime >= o.recenterDelay && this._speed >= o.recenterMinSpeed) {\r\n const t = 1 - Math.exp(-o.chaseStiffness * dt);\r\n let diff = this._chaseYaw(target) - this._yaw;\r\n // Shortest way round\r\n diff = Math.atan2(Math.sin(diff), Math.cos(diff));\r\n this._yaw += diff * t;\r\n this.pitch = this._pitch + (o.chasePitch - this._pitch) * t;\r\n }\r\n }\r\n // Spring arm: sweep from the pivot back along the view direction\r\n const cosPitch = Math.cos(this._pitch);\r\n const back = new Vector3(\r\n Math.sin(this._yaw) * cosPitch,\r\n Math.sin(this._pitch),\r\n Math.cos(this._yaw) * cosPitch\r\n );\r\n const free = this._sweep(back, o.armLength);\r\n if (this._snap || free < this._distance) {\r\n this._distance = free;\r\n } else {\r\n this._distance = Math.min(free, this._distance + o.zoomOutSpeed * dt);\r\n }\r\n // Never on the pivot itself: looking at the point the eye is on has no direction\r\n this._distance = Math.max(this._distance, MIN_DISTANCE);\r\n this._lookAt.set(this._pivot);\r\n Vector3.combine(this._pivot, back, 1, this._distance, this._eye);\r\n let eye = this._eye;\r\n let lookAt = this._lookAt;\r\n if (this._blendTime > 0) {\r\n this._blendElapsed += dt;\r\n const x = Math.min(this._blendElapsed / this._blendTime, 1);\r\n const s = x * x * (3 - 2 * x);\r\n eye = Vector3.combine(this._blendEye, this._eye, 1 - s, s);\r\n lookAt = Vector3.combine(this._blendLookAt, this._lookAt, 1 - s, s);\r\n if (x >= 1) {\r\n this._blendTime = 0;\r\n }\r\n }\r\n camera.lookAt(eye, lookAt, Vector3.axisPY());\r\n if (camera.isPerspective()) {\r\n const perspective = camera as unknown as { fovY: number };\r\n if (o.fovBoost) {\r\n // The field of view without boost is taken when boosting starts\r\n if (!this._baseFovY) {\r\n this._baseFovY = perspective.fovY;\r\n }\r\n const k = Math.min(this._speed / o.fovBoost.maxSpeed, 1);\r\n perspective.fovY = this._baseFovY + o.fovBoost.maxBoost * k;\r\n } else if (this._baseFovY) {\r\n // Boost was turned off: restore once, then leave the field of view alone\r\n perspective.fovY = this._baseFovY;\r\n this._baseFovY = 0;\r\n }\r\n }\r\n this._snap = false;\r\n }\r\n /** Yaw that puts the camera behind the target */\r\n private _chaseYaw(target: SceneNode) {\r\n const fwd = target.worldMatrix.transformVectorAffine(this.options.forwardAxis, new Vector3());\r\n if (fwd.x === 0 && fwd.z === 0) {\r\n return this._yaw;\r\n }\r\n return Math.atan2(-fwd.x, -fwd.z);\r\n }\r\n /** How far the camera can go back from the pivot along `dir`, up to `length` */\r\n private _sweep(dir: Vector3, length: number) {\r\n const camera = this._getCamera();\r\n const world = camera?.scene?.physicsWorld;\r\n if (!world || length <= 0) {\r\n return length;\r\n }\r\n const o = this.options;\r\n let radius = o.probeRadius;\r\n if (camera!.isPerspective()) {\r\n // The near plane's corners are this far from the eye: a smaller sphere\r\n // lets them into a wall the sphere itself stopped short of\r\n const p = camera as unknown as { near: number; fovY: number; aspect: number };\r\n const halfHeight = p.near * Math.tan(p.fovY / 2);\r\n const nearRadius = Math.hypot(p.near, halfHeight, halfHeight * p.aspect);\r\n if (nearRadius > LARGE_NEAR_RADIUS && !this._warnedNear) {\r\n this._warnedNear = true;\r\n console.warn(\r\n `FollowCameraController: the camera's near plane (${p.near}) is far from the eye, so ` +\r\n `the camera keeps ${nearRadius.toFixed(2)} away from walls and is pushed in close in ` +\r\n 'narrow places; set the near plane to about 0.1'\r\n );\r\n }\r\n radius = Math.max(radius, nearRadius);\r\n }\r\n const options = { layerMask: o.collisionMask, exclude: o.exclude ?? this._target?.physics ?? null };\r\n let hit = world.shapeCast({ type: 'sphere', radius }, this._pivot, identity, dir, length, options);\r\n if (hit && hit.distance <= START_OVERLAP && radius > o.probeRadius) {\r\n // The sphere is already in a wall at the pivot: there is no room for the\r\n // near plane anyway, so fall back to the small probe rather than the pivot\r\n hit = world.shapeCast(\r\n { type: 'sphere', radius: o.probeRadius },\r\n this._pivot,\r\n identity,\r\n dir,\r\n length,\r\n options\r\n );\r\n }\r\n return hit ? hit.distance : length;\r\n }\r\n}\r\n"],"names":["defaultOptions","mode","pivotOffset","Vector3","armLength","minArmLength","maxArmLength","minPitch","maxPitch","positionLag","forwardAxis","chasePitch","chaseStiffness","recenterDelay","recenterMinSpeed","probeRadius","collisionMask","exclude","zoomOutSpeed","mouseSensitivity","mouseButtons","fovBoost","identity","Quaternion","MIN_DISTANCE","START_OVERLAP","LARGE_NEAR_RADIUS","FollowCameraController","BaseCameraController","_target","_yaw","_pitch","_pivot","_lastTargetPos","_distance","_idleTime","_speed","_baseFovY","_snap","_blendTime","_blendElapsed","_blendEye","_blendLookAt","_eye","_lookAt","_dragging","_lastX","_lastY","_warnedNear","target","options","updatePhase","yaw","val","pitch","Math","min","max","distance","targetSpeed","setTarget","camera","_getCamera","blendTime","set","Object","assign","addLookInput","x","y","addZoomInput","amount","o","exp","snap","reset","_onMouseDown","evt","includes","button","offsetX","offsetY","_onMouseUp","_onMouseMove","s","_onMouseWheel","deltaY","_onUpdate","dt","targetPos","getWorldPosition","wantedPivot","add","_chaseYaw","t","combineBy","speed","diff","atan2","sin","cos","cosPitch","back","free","_sweep","combine","eye","lookAt","axisPY","isPerspective","perspective","fovY","k","maxSpeed","maxBoost","fwd","worldMatrix","transformVectorAffine","z","dir","length","world","scene","physicsWorld","radius","p","halfHeight","near","tan","nearRadius","hypot","aspect","console","warn","toFixed","layerMask","physics","hit","shapeCast","type"],"mappings":"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"}
|
package/dist/camera/fps.js
CHANGED
|
@@ -184,8 +184,10 @@ import { BaseCameraController } from './base.js';
|
|
|
184
184
|
/**
|
|
185
185
|
* {@inheritDoc BaseCameraController._onUpdate}
|
|
186
186
|
* @override
|
|
187
|
-
*/ _onUpdate() {
|
|
187
|
+
*/ _onUpdate(deltaTime) {
|
|
188
188
|
const camera = this._getCamera();
|
|
189
|
+
// moveSpeed is per 60 Hz frame
|
|
190
|
+
const step = this.options.moveSpeed * deltaTime * 60;
|
|
189
191
|
const x = camera.worldMatrix.getRow(0).xyz();
|
|
190
192
|
x.y = 0;
|
|
191
193
|
x.inplaceNormalize();
|
|
@@ -194,27 +196,27 @@ import { BaseCameraController } from './base.js';
|
|
|
194
196
|
let changed = false;
|
|
195
197
|
if (this.keyForward) {
|
|
196
198
|
changed = true;
|
|
197
|
-
move.subBy(Vector3.scale(z,
|
|
199
|
+
move.subBy(Vector3.scale(z, step));
|
|
198
200
|
}
|
|
199
201
|
if (this.keyBackward) {
|
|
200
202
|
changed = true;
|
|
201
|
-
move.addBy(Vector3.scale(z,
|
|
203
|
+
move.addBy(Vector3.scale(z, step));
|
|
202
204
|
}
|
|
203
205
|
if (this.keyUp) {
|
|
204
206
|
changed = true;
|
|
205
|
-
move.y +=
|
|
207
|
+
move.y += step;
|
|
206
208
|
}
|
|
207
209
|
if (this.keyDown) {
|
|
208
210
|
changed = true;
|
|
209
|
-
move.y -=
|
|
211
|
+
move.y -= step;
|
|
210
212
|
}
|
|
211
213
|
if (this.keyLeft) {
|
|
212
214
|
changed = true;
|
|
213
|
-
move.subBy(Vector3.scale(x,
|
|
215
|
+
move.subBy(Vector3.scale(x, step));
|
|
214
216
|
}
|
|
215
217
|
if (this.keyRight) {
|
|
216
218
|
changed = true;
|
|
217
|
-
move.addBy(Vector3.scale(x,
|
|
219
|
+
move.addBy(Vector3.scale(x, step));
|
|
218
220
|
}
|
|
219
221
|
if (changed) {
|
|
220
222
|
if (camera.parent) {
|
package/dist/camera/fps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fps.js","sources":["../../src/camera/fps.ts"],"sourcesContent":["import type { RequireOptionals } from '@zephyr3d/base';\r\nimport { Vector3, Quaternion, Matrix3x3, Matrix4x4 } from '@zephyr3d/base';\r\nimport type {\r\n IControllerKeydownEvent,\r\n IControllerKeyupEvent,\r\n IControllerPointerDownEvent,\r\n IControllerPointerMoveEvent,\r\n IControllerPointerUpEvent\r\n} from './base';\r\nimport { BaseCameraController } from './base';\r\n\r\n/**\r\n * Creation options for FPSCameraController\r\n * @public\r\n */\r\nexport interface FPSCameraControllerOptions {\r\n /** The control keys */\r\n controlKeys?: {\r\n up: string;\r\n down: string;\r\n forward: string;\r\n backward: string;\r\n left: string;\r\n right: string;\r\n };\r\n /** Moving speed */\r\n moveSpeed?: number;\r\n /** Rotating speed */\r\n rotateSpeed?: number;\r\n}\r\n\r\n/**\r\n * FPS camera controller\r\n * @public\r\n */\r\nexport class FPSCameraController extends BaseCameraController {\r\n /** @internal */\r\n private readonly options: RequireOptionals<FPSCameraControllerOptions>;\r\n /** @internal */\r\n private mouseDown!: boolean;\r\n /** @internal */\r\n private lastMouseX!: number;\r\n /** @internal */\r\n private lastMouseY!: number;\r\n /** @internal */\r\n private keyUp!: boolean;\r\n /** @internal */\r\n private keyDown!: boolean;\r\n /** @internal */\r\n private keyLeft!: boolean;\r\n /** @internal */\r\n private keyRight!: boolean;\r\n /** @internal */\r\n private keyForward!: boolean;\r\n /** @internal */\r\n private keyBackward!: boolean;\r\n /**\r\n * Creates an instance of FPSCameraController\r\n * @param options - The creation options\r\n */\r\n constructor(options?: FPSCameraControllerOptions) {\r\n super();\r\n this.options = Object.assign(\r\n {\r\n controlKeys: {\r\n up: 'KeyQ',\r\n down: 'KeyE',\r\n forward: 'KeyW',\r\n backward: 'KeyS',\r\n left: 'KeyA',\r\n right: 'KeyD'\r\n },\r\n moveSpeed: 0.2,\r\n rotateSpeed: 0.01\r\n },\r\n options || {}\r\n );\r\n this.reset();\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController.reset}\r\n * @override\r\n */\r\n reset() {\r\n this.mouseDown = false;\r\n this.lastMouseX = 0;\r\n this.lastMouseY = 0;\r\n this.keyUp = false;\r\n this.keyDown = false;\r\n this.keyLeft = false;\r\n this.keyRight = false;\r\n this.keyForward = false;\r\n this.keyBackward = false;\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onMouseDown}\r\n * @override\r\n */\r\n protected _onMouseDown(evt: IControllerPointerDownEvent) {\r\n if (evt.button === 0) {\r\n this.mouseDown = true;\r\n this.lastMouseX = evt.offsetX;\r\n this.lastMouseY = evt.offsetY;\r\n return true;\r\n }\r\n return false;\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onMouseUp}\r\n * @override\r\n */\r\n protected _onMouseUp(evt: IControllerPointerUpEvent) {\r\n if (evt.button === 0 && this.mouseDown) {\r\n this.mouseDown = false;\r\n return true;\r\n }\r\n return false;\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onMouseMove}\r\n * @override\r\n */\r\n protected _onMouseMove(evt: IControllerPointerMoveEvent) {\r\n const camera = this._getCamera()!;\r\n if (this.mouseDown) {\r\n const dx = evt.offsetX - this.lastMouseX;\r\n const dy = evt.offsetY - this.lastMouseY;\r\n this.lastMouseX = evt.offsetX;\r\n this.lastMouseY = evt.offsetY;\r\n const zAxis = camera.worldMatrix.getRow(2).xyz();\r\n const alpha = Math.atan2(zAxis.z, zAxis.x) + dx * this.options.rotateSpeed;\r\n const beta = Math.min(\r\n Math.PI / 2.1,\r\n Math.max(-Math.PI / 2.1, Math.asin(zAxis.y) + dy * this.options.rotateSpeed)\r\n );\r\n const newY = Math.sin(beta);\r\n const r = Math.sqrt(Math.max(0, 1 - newY * newY));\r\n const newZ = Math.sin(alpha) * r;\r\n const newX = Math.cos(alpha) * r;\r\n zAxis.setXYZ(newX, newY, newZ).inplaceNormalize();\r\n const XAxis = Vector3.cross(Vector3.axisPY(), zAxis).inplaceNormalize();\r\n const YAxis = Vector3.cross(zAxis, XAxis).inplaceNormalize();\r\n const rotation = Quaternion.fromRotationMatrix(\r\n new Matrix3x3([XAxis.x, XAxis.y, XAxis.z, YAxis.x, YAxis.y, YAxis.z, zAxis.x, zAxis.y, zAxis.z])\r\n );\r\n if (!camera.parent) {\r\n camera.rotation.set(rotation);\r\n } else {\r\n const pos = new Vector3();\r\n const scale = new Vector3();\r\n camera.worldMatrix.decompose(scale, null, pos);\r\n const newWorldMatrix = Matrix4x4.scaling(scale).rotateLeft(rotation).translateLeft(pos);\r\n const newLocalMatrix = camera.parent\r\n ? newWorldMatrix.multiplyLeftAffine(Matrix4x4.invertAffine(camera.parent.worldMatrix))\r\n : newWorldMatrix;\r\n newLocalMatrix.decompose(scale, rotation, pos);\r\n camera.position.set(pos);\r\n camera.scale.set(scale);\r\n camera.rotation.set(rotation);\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onKeyDown}\r\n * @override\r\n */\r\n protected _onKeyDown(evt: IControllerKeydownEvent) {\r\n switch (evt.code) {\r\n case this.options.controlKeys.up:\r\n this.keyUp = true;\r\n break;\r\n case this.options.controlKeys.down:\r\n this.keyDown = true;\r\n break;\r\n case this.options.controlKeys.left:\r\n this.keyLeft = true;\r\n break;\r\n case this.options.controlKeys.right:\r\n this.keyRight = true;\r\n break;\r\n case this.options.controlKeys.forward:\r\n this.keyForward = true;\r\n break;\r\n case this.options.controlKeys.backward:\r\n this.keyBackward = true;\r\n break;\r\n default:\r\n return false;\r\n }\r\n return true;\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onKeyUp}\r\n * @override\r\n */\r\n protected _onKeyUp(evt: IControllerKeyupEvent) {\r\n switch (evt.code) {\r\n case this.options.controlKeys.up:\r\n this.keyUp = false;\r\n break;\r\n case this.options.controlKeys.down:\r\n this.keyDown = false;\r\n break;\r\n case this.options.controlKeys.left:\r\n this.keyLeft = false;\r\n break;\r\n case this.options.controlKeys.right:\r\n this.keyRight = false;\r\n break;\r\n case this.options.controlKeys.forward:\r\n this.keyForward = false;\r\n break;\r\n case this.options.controlKeys.backward:\r\n this.keyBackward = false;\r\n break;\r\n default:\r\n return false;\r\n }\r\n return true;\r\n }\r\n /**\r\n * Set options\r\n * @param opt - options\r\n */\r\n setOptions(opt?: FPSCameraControllerOptions) {\r\n Object.assign(this.options, opt ?? {});\r\n this.reset();\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onUpdate}\r\n * @override\r\n */\r\n protected _onUpdate() {\r\n const camera = this._getCamera()!;\r\n const x = camera.worldMatrix.getRow(0).xyz();\r\n x.y = 0;\r\n x.inplaceNormalize();\r\n const z = camera.worldMatrix.getRow(2).xyz().inplaceNormalize();\r\n const move = new Vector3(0, 0, 0);\r\n let changed = false;\r\n if (this.keyForward) {\r\n changed = true;\r\n move.subBy(Vector3.scale(z, this.options.moveSpeed));\r\n }\r\n if (this.keyBackward) {\r\n changed = true;\r\n move.addBy(Vector3.scale(z, this.options.moveSpeed));\r\n }\r\n if (this.keyUp) {\r\n changed = true;\r\n move.y += this.options.moveSpeed;\r\n }\r\n if (this.keyDown) {\r\n changed = true;\r\n move.y -= this.options.moveSpeed;\r\n }\r\n if (this.keyLeft) {\r\n changed = true;\r\n move.subBy(Vector3.scale(x, this.options.moveSpeed));\r\n }\r\n if (this.keyRight) {\r\n changed = true;\r\n move.addBy(Vector3.scale(x, this.options.moveSpeed));\r\n }\r\n if (changed) {\r\n if (camera.parent) {\r\n const pos = new Vector3();\r\n const scale = new Vector3();\r\n const rotation = new Quaternion();\r\n camera.worldMatrix.decompose(scale, rotation, pos);\r\n pos.addBy(move);\r\n const newWorldMatrix = Matrix4x4.scaling(scale).rotateLeft(rotation).translateLeft(pos);\r\n const newLocalMatrix = newWorldMatrix.multiplyLeftAffine(\r\n Matrix4x4.invertAffine(camera.parent.worldMatrix)\r\n );\r\n newLocalMatrix.decompose(scale, rotation, pos);\r\n camera.position.set(pos);\r\n camera.scale.set(scale);\r\n camera.rotation.set(rotation);\r\n } else {\r\n camera.moveBy(move);\r\n }\r\n }\r\n }\r\n}\r\n"],"names":["FPSCameraController","BaseCameraController","options","Object","assign","controlKeys","up","down","forward","backward","left","right","moveSpeed","rotateSpeed","reset","mouseDown","lastMouseX","lastMouseY","keyUp","keyDown","keyLeft","keyRight","keyForward","keyBackward","_onMouseDown","evt","button","offsetX","offsetY","_onMouseUp","_onMouseMove","camera","_getCamera","dx","dy","zAxis","worldMatrix","getRow","xyz","alpha","Math","atan2","z","x","beta","min","PI","max","asin","y","newY","sin","r","sqrt","newZ","newX","cos","setXYZ","inplaceNormalize","XAxis","Vector3","cross","axisPY","YAxis","rotation","Quaternion","fromRotationMatrix","Matrix3x3","parent","set","pos","scale","decompose","newWorldMatrix","Matrix4x4","scaling","rotateLeft","translateLeft","newLocalMatrix","multiplyLeftAffine","invertAffine","position","_onKeyDown","code","_onKeyUp","setOptions","opt","move","changed","subBy","addBy","moveBy"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fps.js","sources":["../../src/camera/fps.ts"],"sourcesContent":["import type { RequireOptionals } from '@zephyr3d/base';\r\nimport { Vector3, Quaternion, Matrix3x3, Matrix4x4 } from '@zephyr3d/base';\r\nimport type { IControllerKeyboardEvent, IControllerMouseEvent } from './base';\r\nimport { BaseCameraController } from './base';\r\n\r\n/**\r\n * Creation options for FPSCameraController\r\n * @public\r\n */\r\nexport interface FPSCameraControllerOptions {\r\n /** The control keys */\r\n controlKeys?: {\r\n up: string;\r\n down: string;\r\n forward: string;\r\n backward: string;\r\n left: string;\r\n right: string;\r\n };\r\n /** Moving speed: world units per 1/60 s, independent of the actual frame rate. */\r\n moveSpeed?: number;\r\n /** Rotating speed */\r\n rotateSpeed?: number;\r\n}\r\n\r\n/**\r\n * FPS camera controller\r\n * @public\r\n */\r\nexport class FPSCameraController extends BaseCameraController {\r\n /** @internal */\r\n private readonly options: RequireOptionals<FPSCameraControllerOptions>;\r\n /** @internal */\r\n private mouseDown!: boolean;\r\n /** @internal */\r\n private lastMouseX!: number;\r\n /** @internal */\r\n private lastMouseY!: number;\r\n /** @internal */\r\n private keyUp!: boolean;\r\n /** @internal */\r\n private keyDown!: boolean;\r\n /** @internal */\r\n private keyLeft!: boolean;\r\n /** @internal */\r\n private keyRight!: boolean;\r\n /** @internal */\r\n private keyForward!: boolean;\r\n /** @internal */\r\n private keyBackward!: boolean;\r\n /**\r\n * Creates an instance of FPSCameraController\r\n * @param options - The creation options\r\n */\r\n constructor(options?: FPSCameraControllerOptions) {\r\n super();\r\n this.options = Object.assign(\r\n {\r\n controlKeys: {\r\n up: 'KeyQ',\r\n down: 'KeyE',\r\n forward: 'KeyW',\r\n backward: 'KeyS',\r\n left: 'KeyA',\r\n right: 'KeyD'\r\n },\r\n moveSpeed: 0.2,\r\n rotateSpeed: 0.01\r\n },\r\n options || {}\r\n );\r\n this.reset();\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController.reset}\r\n * @override\r\n */\r\n reset() {\r\n this.mouseDown = false;\r\n this.lastMouseX = 0;\r\n this.lastMouseY = 0;\r\n this.keyUp = false;\r\n this.keyDown = false;\r\n this.keyLeft = false;\r\n this.keyRight = false;\r\n this.keyForward = false;\r\n this.keyBackward = false;\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onMouseDown}\r\n * @override\r\n */\r\n protected _onMouseDown(evt: IControllerMouseEvent) {\r\n if (evt.button === 0) {\r\n this.mouseDown = true;\r\n this.lastMouseX = evt.offsetX;\r\n this.lastMouseY = evt.offsetY;\r\n return true;\r\n }\r\n return false;\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onMouseUp}\r\n * @override\r\n */\r\n protected _onMouseUp(evt: IControllerMouseEvent) {\r\n if (evt.button === 0 && this.mouseDown) {\r\n this.mouseDown = false;\r\n return true;\r\n }\r\n return false;\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onMouseMove}\r\n * @override\r\n */\r\n protected _onMouseMove(evt: IControllerMouseEvent) {\r\n const camera = this._getCamera()!;\r\n if (this.mouseDown) {\r\n const dx = evt.offsetX - this.lastMouseX;\r\n const dy = evt.offsetY - this.lastMouseY;\r\n this.lastMouseX = evt.offsetX;\r\n this.lastMouseY = evt.offsetY;\r\n const zAxis = camera.worldMatrix.getRow(2).xyz();\r\n const alpha = Math.atan2(zAxis.z, zAxis.x) + dx * this.options.rotateSpeed;\r\n const beta = Math.min(\r\n Math.PI / 2.1,\r\n Math.max(-Math.PI / 2.1, Math.asin(zAxis.y) + dy * this.options.rotateSpeed)\r\n );\r\n const newY = Math.sin(beta);\r\n const r = Math.sqrt(Math.max(0, 1 - newY * newY));\r\n const newZ = Math.sin(alpha) * r;\r\n const newX = Math.cos(alpha) * r;\r\n zAxis.setXYZ(newX, newY, newZ).inplaceNormalize();\r\n const XAxis = Vector3.cross(Vector3.axisPY(), zAxis).inplaceNormalize();\r\n const YAxis = Vector3.cross(zAxis, XAxis).inplaceNormalize();\r\n const rotation = Quaternion.fromRotationMatrix(\r\n new Matrix3x3([XAxis.x, XAxis.y, XAxis.z, YAxis.x, YAxis.y, YAxis.z, zAxis.x, zAxis.y, zAxis.z])\r\n );\r\n if (!camera.parent) {\r\n camera.rotation.set(rotation);\r\n } else {\r\n const pos = new Vector3();\r\n const scale = new Vector3();\r\n camera.worldMatrix.decompose(scale, null, pos);\r\n const newWorldMatrix = Matrix4x4.scaling(scale).rotateLeft(rotation).translateLeft(pos);\r\n const newLocalMatrix = camera.parent\r\n ? newWorldMatrix.multiplyLeftAffine(Matrix4x4.invertAffine(camera.parent.worldMatrix))\r\n : newWorldMatrix;\r\n newLocalMatrix.decompose(scale, rotation, pos);\r\n camera.position.set(pos);\r\n camera.scale.set(scale);\r\n camera.rotation.set(rotation);\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onKeyDown}\r\n * @override\r\n */\r\n protected _onKeyDown(evt: IControllerKeyboardEvent) {\r\n switch (evt.code) {\r\n case this.options.controlKeys.up:\r\n this.keyUp = true;\r\n break;\r\n case this.options.controlKeys.down:\r\n this.keyDown = true;\r\n break;\r\n case this.options.controlKeys.left:\r\n this.keyLeft = true;\r\n break;\r\n case this.options.controlKeys.right:\r\n this.keyRight = true;\r\n break;\r\n case this.options.controlKeys.forward:\r\n this.keyForward = true;\r\n break;\r\n case this.options.controlKeys.backward:\r\n this.keyBackward = true;\r\n break;\r\n default:\r\n return false;\r\n }\r\n return true;\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onKeyUp}\r\n * @override\r\n */\r\n protected _onKeyUp(evt: IControllerKeyboardEvent) {\r\n switch (evt.code) {\r\n case this.options.controlKeys.up:\r\n this.keyUp = false;\r\n break;\r\n case this.options.controlKeys.down:\r\n this.keyDown = false;\r\n break;\r\n case this.options.controlKeys.left:\r\n this.keyLeft = false;\r\n break;\r\n case this.options.controlKeys.right:\r\n this.keyRight = false;\r\n break;\r\n case this.options.controlKeys.forward:\r\n this.keyForward = false;\r\n break;\r\n case this.options.controlKeys.backward:\r\n this.keyBackward = false;\r\n break;\r\n default:\r\n return false;\r\n }\r\n return true;\r\n }\r\n /**\r\n * Set options\r\n * @param opt - options\r\n */\r\n setOptions(opt?: FPSCameraControllerOptions) {\r\n Object.assign(this.options, opt ?? {});\r\n this.reset();\r\n }\r\n /**\r\n * {@inheritDoc BaseCameraController._onUpdate}\r\n * @override\r\n */\r\n protected _onUpdate(deltaTime: number) {\r\n const camera = this._getCamera()!;\r\n // moveSpeed is per 60 Hz frame\r\n const step = this.options.moveSpeed * deltaTime * 60;\r\n const x = camera.worldMatrix.getRow(0).xyz();\r\n x.y = 0;\r\n x.inplaceNormalize();\r\n const z = camera.worldMatrix.getRow(2).xyz().inplaceNormalize();\r\n const move = new Vector3(0, 0, 0);\r\n let changed = false;\r\n if (this.keyForward) {\r\n changed = true;\r\n move.subBy(Vector3.scale(z, step));\r\n }\r\n if (this.keyBackward) {\r\n changed = true;\r\n move.addBy(Vector3.scale(z, step));\r\n }\r\n if (this.keyUp) {\r\n changed = true;\r\n move.y += step;\r\n }\r\n if (this.keyDown) {\r\n changed = true;\r\n move.y -= step;\r\n }\r\n if (this.keyLeft) {\r\n changed = true;\r\n move.subBy(Vector3.scale(x, step));\r\n }\r\n if (this.keyRight) {\r\n changed = true;\r\n move.addBy(Vector3.scale(x, step));\r\n }\r\n if (changed) {\r\n if (camera.parent) {\r\n const pos = new Vector3();\r\n const scale = new Vector3();\r\n const rotation = new Quaternion();\r\n camera.worldMatrix.decompose(scale, rotation, pos);\r\n pos.addBy(move);\r\n const newWorldMatrix = Matrix4x4.scaling(scale).rotateLeft(rotation).translateLeft(pos);\r\n const newLocalMatrix = newWorldMatrix.multiplyLeftAffine(\r\n Matrix4x4.invertAffine(camera.parent.worldMatrix)\r\n );\r\n newLocalMatrix.decompose(scale, rotation, pos);\r\n camera.position.set(pos);\r\n camera.scale.set(scale);\r\n camera.rotation.set(rotation);\r\n } else {\r\n camera.moveBy(move);\r\n }\r\n }\r\n }\r\n}\r\n"],"names":["FPSCameraController","BaseCameraController","options","Object","assign","controlKeys","up","down","forward","backward","left","right","moveSpeed","rotateSpeed","reset","mouseDown","lastMouseX","lastMouseY","keyUp","keyDown","keyLeft","keyRight","keyForward","keyBackward","_onMouseDown","evt","button","offsetX","offsetY","_onMouseUp","_onMouseMove","camera","_getCamera","dx","dy","zAxis","worldMatrix","getRow","xyz","alpha","Math","atan2","z","x","beta","min","PI","max","asin","y","newY","sin","r","sqrt","newZ","newX","cos","setXYZ","inplaceNormalize","XAxis","Vector3","cross","axisPY","YAxis","rotation","Quaternion","fromRotationMatrix","Matrix3x3","parent","set","pos","scale","decompose","newWorldMatrix","Matrix4x4","scaling","rotateLeft","translateLeft","newLocalMatrix","multiplyLeftAffine","invertAffine","position","_onKeyDown","code","_onKeyUp","setOptions","opt","_onUpdate","deltaTime","step","move","changed","subBy","addBy","moveBy"],"mappings":"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"}
|
package/dist/camera/orbit.js
CHANGED
|
@@ -28,7 +28,7 @@ import { BaseCameraController } from './base.js';
|
|
|
28
28
|
damping: 1,
|
|
29
29
|
rotateSpeed: 1,
|
|
30
30
|
panSpeed: 1,
|
|
31
|
-
zoomSpeed:
|
|
31
|
+
zoomSpeed: 5,
|
|
32
32
|
controls: {
|
|
33
33
|
rotate: {
|
|
34
34
|
button: 0,
|
|
@@ -139,7 +139,20 @@ import { BaseCameraController } from './base.js';
|
|
|
139
139
|
* {@inheritDoc BaseCameraController._onMouseWheel}
|
|
140
140
|
* @override
|
|
141
141
|
*/ _onMouseWheel(evt) {
|
|
142
|
-
|
|
142
|
+
// Same scroll handling as the editor camera (EditorCameraController._onMouseWheel)
|
|
143
|
+
let px = evt.deltaY;
|
|
144
|
+
if (evt.deltaMode === 1) {
|
|
145
|
+
px *= 16;
|
|
146
|
+
} else if (evt.deltaMode === 2) {
|
|
147
|
+
px *= window.innerHeight;
|
|
148
|
+
}
|
|
149
|
+
if (evt.ctrlKey) {
|
|
150
|
+
px *= 10;
|
|
151
|
+
}
|
|
152
|
+
if (evt.shiftKey) {
|
|
153
|
+
px *= 0.1;
|
|
154
|
+
}
|
|
155
|
+
this.zoom(Math.max(-100, Math.min(100, px)));
|
|
143
156
|
return true;
|
|
144
157
|
}
|
|
145
158
|
/**
|
|
@@ -164,12 +177,18 @@ import { BaseCameraController } from './base.js';
|
|
|
164
177
|
}
|
|
165
178
|
return false;
|
|
166
179
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Moves the eye along the view direction by zoomSpeed per 100 pixels, away from the center for
|
|
182
|
+
* positive values; it stops short of the center instead of passing through it
|
|
183
|
+
*/ zoom(px) {
|
|
184
|
+
const center = this.options.center;
|
|
185
|
+
const distance = Vector3.distance(this.eyePos, center);
|
|
186
|
+
if (distance < 1e-6 || px === 0) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const newDistance = Math.max(0.01, distance + this.options.zoomSpeed * px * 0.01);
|
|
190
|
+
if (newDistance !== distance) {
|
|
191
|
+
this.eyePos.combineBy(center, newDistance / distance, 1 - newDistance / distance);
|
|
173
192
|
}
|
|
174
193
|
}
|
|
175
194
|
matchesControl(evt, control) {
|
|
@@ -204,18 +223,26 @@ import { BaseCameraController } from './base.js';
|
|
|
204
223
|
/**
|
|
205
224
|
* {@inheritDoc BaseCameraController._onUpdate}
|
|
206
225
|
* @override
|
|
207
|
-
*/ _onUpdate() {
|
|
226
|
+
*/ _onUpdate(deltaTime) {
|
|
208
227
|
const camera = this._getCamera();
|
|
209
228
|
const center = this.options.center;
|
|
229
|
+
// Velocities are per 60 Hz frame and decay by `damping` per frame. For `frames`
|
|
230
|
+
// such frames the velocity decays by `decay`, and the distance covered is the
|
|
231
|
+
// sum of the geometric series, `travel` times the current velocity. At 60 fps
|
|
232
|
+
// this is exactly one frame: travel 1, decay 1 - damping.
|
|
233
|
+
const frames = deltaTime * 60;
|
|
234
|
+
const damping = this.options.damping;
|
|
235
|
+
const decay = Math.pow(1 - damping, frames);
|
|
236
|
+
const travel = damping > 0 ? (1 - decay) / damping : frames;
|
|
210
237
|
if (Math.abs(this.panVelocityX) > 0.0001 || Math.abs(this.panVelocityY) > 0.0001) {
|
|
211
238
|
const right = this.xVector;
|
|
212
239
|
const up = this.upVector;
|
|
213
|
-
center.combineBy(right, 1, this.panVelocityX);
|
|
214
|
-
center.combineBy(up, 1, this.panVelocityY);
|
|
215
|
-
this.eyePos.combineBy(right, 1, this.panVelocityX);
|
|
216
|
-
this.eyePos.combineBy(up, 1, this.panVelocityY);
|
|
217
|
-
this.panVelocityX *=
|
|
218
|
-
this.panVelocityY *=
|
|
240
|
+
center.combineBy(right, 1, this.panVelocityX * travel);
|
|
241
|
+
center.combineBy(up, 1, this.panVelocityY * travel);
|
|
242
|
+
this.eyePos.combineBy(right, 1, this.panVelocityX * travel);
|
|
243
|
+
this.eyePos.combineBy(up, 1, this.panVelocityY * travel);
|
|
244
|
+
this.panVelocityX *= decay;
|
|
245
|
+
this.panVelocityY *= decay;
|
|
219
246
|
if (Math.abs(this.panVelocityX) < 0.0001) {
|
|
220
247
|
this.panVelocityX = 0;
|
|
221
248
|
}
|
|
@@ -224,16 +251,16 @@ import { BaseCameraController } from './base.js';
|
|
|
224
251
|
}
|
|
225
252
|
}
|
|
226
253
|
if (Math.abs(this.rotateX) > 0.0001 || Math.abs(this.rotateY) > 0.0001) {
|
|
227
|
-
Quaternion.fromAxisAngle(this.xVector, this.rotateX, this.quat);
|
|
254
|
+
Quaternion.fromAxisAngle(this.xVector, this.rotateX * travel, this.quat);
|
|
228
255
|
this.quat.transform(this.eyePos.subBy(center), this.eyePos);
|
|
229
|
-
Quaternion.fromEulerAngle(0, this.rotateY, 0, 'ZYX', this.quat);
|
|
256
|
+
Quaternion.fromEulerAngle(0, this.rotateY * travel, 0, 'ZYX', this.quat);
|
|
230
257
|
this.quat.transform(this.eyePos, this.eyePos);
|
|
231
258
|
this.quat.transform(this.xVector, this.xVector).inplaceNormalize();
|
|
232
259
|
Vector3.normalize(this.eyePos, this.direction).inplaceNormalize();
|
|
233
260
|
Vector3.cross(this.direction, this.xVector, this.upVector).inplaceNormalize();
|
|
234
261
|
this.eyePos.addBy(center);
|
|
235
|
-
this.rotateX *=
|
|
236
|
-
this.rotateY *=
|
|
262
|
+
this.rotateX *= decay;
|
|
263
|
+
this.rotateY *= decay;
|
|
237
264
|
if (Math.abs(this.rotateX) < 0.0001) {
|
|
238
265
|
this.rotateX = 0;
|
|
239
266
|
}
|