@woosh/meep-engine 3.60.4 → 3.60.5
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/CHANGELOG.md +2602 -0
- package/CONTRIBUTING.md +7 -0
- package/MIGRATION_2_TO_3.md +136 -0
- package/SECURITY.md +4 -0
- package/editor/EditorCameraNavigation.d.ts +2 -1
- package/editor/EditorCameraNavigation.d.ts.map +1 -1
- package/editor/EditorCameraNavigation.js +51 -57
- package/package.json +6 -2
- package/src/engine/EngineHarness.d.ts +3 -9
- package/src/engine/EngineHarness.d.ts.map +1 -1
- package/src/engine/EngineHarness.js +6 -8
- package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
- package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
- package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
- package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
- package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
- package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
- package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
- package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
- package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
- package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
- package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/Water.js +8 -0
- package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/WaterSystem.js +731 -734
- package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
- package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
- package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
- package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
- package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
- package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
- package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
- package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
- package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
- package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
- package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
- package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
- package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
- package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
- package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
- package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
- package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
- package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
- package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
- package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
- package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
- package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
- package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
- package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/playground/water_refraction/README.md +5 -6
- package/src/shade/playground/water_refraction/index.html +1 -1
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +7 -5
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
- package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
- package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
- package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +2 -2
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +2 -2
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +2 -1
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +18 -1
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +5 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +10 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
- package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
- package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
- package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
- package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
- package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
- package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
- package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
- package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
- package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
- package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
- package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
- package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/material/GPUMaterialManager.d.ts +7 -0
- package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
- package/src/shade/renderer/material/GPUMaterialManager.js +11 -0
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
- package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
- package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
- package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
- package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
- package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water.js +22 -13
- package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water_avboit.js +7 -7
- package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
- package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
- package/editor/REWORK_PLAN_2026_08.md +0 -692
- package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
- package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
- package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
- package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
- package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
- package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
- package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
- package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
- package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
- package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
- package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
- package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
- package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
- package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
- package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
- package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
- package/src/REVIEW_2026_08_06/adv-core.md +0 -511
- package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
- package/src/REVIEW_2026_08_06/adv-view.md +0 -446
- package/src/REVIEW_2026_08_06/api-core.md +0 -296
- package/src/REVIEW_2026_08_06/api-engine.md +0 -195
- package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
- package/src/REVIEW_2026_08_06/core-binary.md +0 -348
- package/src/REVIEW_2026_08_06/core-collection.md +0 -376
- package/src/REVIEW_2026_08_06/core-math.md +0 -221
- package/src/REVIEW_2026_08_06/core-process.md +0 -266
- package/src/REVIEW_2026_08_06/core-science.md +0 -223
- package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
- package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
- package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
- package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
- package/src/REVIEW_2026_08_06/engine-input.md +0 -197
- package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
- package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
- package/src/REVIEW_2026_08_06/generation.md +0 -176
- package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
- package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
- package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
- package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
- package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
- package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
- package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
- package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
- package/src/REVIEW_2026_08_06/view.md +0 -667
- package/src/REVIEW_2026_08_06.md +0 -610
- package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
- package/src/core/bvh2/bvh3/NOTES.md +0 -2
- package/src/core/bvh8/NOTES.md +0 -63
- package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
- package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
- package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
- package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
- package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
- package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
- package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
- package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
- package/src/core/geom/3d/gjk/NOTES.md +0 -8
- package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
- package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
- package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
- package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
- package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
- package/src/engine/REVIEW_2026_07_03.md +0 -211
- package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
- package/src/engine/control/first-person/DESIGN.md +0 -658
- package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
- package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
- package/src/engine/control/first-person/TODO.md +0 -160
- package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
- package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
- package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
- package/src/engine/ecs/ik/PLAN.md +0 -179
- package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
- package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
- package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
- package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
- package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
- package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
- package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
- package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
- package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
- package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
- package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
- package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
- package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
- package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
- package/src/engine/network/CONGESTION_CONTROL.md +0 -87
- package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
- package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
- package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
- package/src/engine/physics/cloth/PLAN.md +0 -3056
- package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
- package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
- package/src/engine/physics/fluid/solver/NOTES.md +0 -46
- package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
- package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
- package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
- package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
- package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
- package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
- package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
- package/src/format/image/avif/DECISIONS.md +0 -545
- package/src/format/image/jpeg/NOTES.md +0 -3
- package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
- package/src/generation/COORDINATES.md +0 -54
- package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
- package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
- package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
- package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
- package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
- package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
- package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
- package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
- package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
- package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
- package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
- package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
- package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
- package/src/shade/RENDERER_CONTRACT.md +0 -697
- package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
- package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
- package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
- package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
- package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
- package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
- package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
- package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
- package/src/shade/renderer/NOTES.md +0 -78
- package/src/shade/renderer/PLAN.md +0 -8
- package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
- package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
- package/src/shade/renderer/atmosphere/NOTES.md +0 -6
- package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
- package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
- package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
- package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
- package/src/shade/renderer/camera/orbital/README.md +0 -81
- package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
- package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/index.js +0 -9
- package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
- package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
- package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
- package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
- package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
- package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
- package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
- package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
- package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
- package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
- package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
- package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
- package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
- package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
- package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
- package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
- package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
- package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
- package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
- package/src/shade/renderer/hiz/NOTES.md +0 -3
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
- package/src/shade/renderer/light/cluster/NOTES.md +0 -11
- package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
- package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
- package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
- package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
- package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
- package/src/shade/renderer/particles/DESIGN.md +0 -1011
- package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
- package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
- package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
- package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
- package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
- package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
- package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
- package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
- package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
- package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
- package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
- package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
- package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
- package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
- package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
- package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
- package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
- package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
- package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
- package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
- package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
- package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
- package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
- package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
- package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
- package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
- package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
- package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
- package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
- package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
- package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
- package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
- package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
- package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
- package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
- package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
- package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
- package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
- package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
- package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
- package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
- package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
- package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
- package/src/shade/wgsl/NOTES.md +0 -4
|
@@ -1,109 +1,82 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { assert } from "../../../core/assert.js";
|
|
2
|
+
import Vector3 from "../../../core/geom/Vector3.js";
|
|
3
|
+
import Script from "../../ecs/components/Script.js";
|
|
2
4
|
import Entity from "../../ecs/Entity.js";
|
|
3
|
-
import {
|
|
5
|
+
import { MouseEventButtons } from "../../input/devices/mouse/MouseEventButtons.js";
|
|
4
6
|
import InputController from "../../input/ecs/components/InputController.js";
|
|
5
7
|
import { Camera } from "../ecs/camera/Camera.js";
|
|
6
|
-
import TopDownCameraController
|
|
8
|
+
import TopDownCameraController from "../ecs/camera/topdown/TopDownCameraController.js";
|
|
9
|
+
import { OrbitalCameraRig } from "./orbital/OrbitalCameraRig.js";
|
|
7
10
|
|
|
8
11
|
/**
|
|
12
|
+
* Pointer navigation for a camera entity's {@link TopDownCameraController}: drag with the primary
|
|
13
|
+
* button (or a touch) to orbit, with the secondary to pan, the wheel to zoom. A drag moves the camera
|
|
14
|
+
* as it happens and throws on release; see {@link OrbitalCameraRig}.
|
|
15
|
+
*
|
|
16
|
+
* The orbit swings all the way round, under the target included, short of turning over at the poles.
|
|
9
17
|
*
|
|
10
18
|
* @param {Object} options
|
|
11
|
-
* @param {number} options.camera_entity
|
|
19
|
+
* @param {number} options.camera_entity carries the {@link TopDownCameraController} and {@link Camera}
|
|
12
20
|
* @param {EntityComponentDataset} options.ecd
|
|
13
|
-
* @param {HTMLElement} options.dom_element
|
|
14
|
-
* @
|
|
15
|
-
* @return {Entity}
|
|
21
|
+
* @param {HTMLElement} options.dom_element the viewport, measured for its height
|
|
22
|
+
* @return {Entity} transient, to be built into the dataset
|
|
16
23
|
*/
|
|
17
24
|
export function makeOrbitalCameraController({
|
|
18
25
|
camera_entity,
|
|
19
26
|
ecd,
|
|
20
27
|
dom_element,
|
|
21
|
-
sensitivity = 1
|
|
22
28
|
}) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
* @returns {TopDownCameraController}
|
|
26
|
-
*/
|
|
27
|
-
function getCameraController() {
|
|
28
|
-
return ecd.getComponent(camera_entity, TopDownCameraController)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function getCamera() {
|
|
32
|
-
return ecd.getComponent(camera_entity, Camera)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
37
|
-
* @param {Vector2} delta
|
|
38
|
-
*/
|
|
39
|
-
function orbit(delta) {
|
|
40
|
-
|
|
41
|
-
const cameraController = getCameraController();
|
|
42
|
-
|
|
43
|
-
const scale = sensitivity * 2 * Math.PI / dom_element.clientHeight;
|
|
44
|
-
|
|
45
|
-
rotate_from_view(delta.x * scale, delta.y * scale, cameraController, cameraController);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
*
|
|
50
|
-
* @param {Vector2} delta
|
|
51
|
-
*/
|
|
52
|
-
function pan(delta) {
|
|
53
|
-
|
|
54
|
-
const cameraController = getCameraController();
|
|
55
|
-
const camera = getCamera();
|
|
56
|
-
|
|
57
|
-
TopDownCameraController.pan(delta, cameraController, dom_element.clientHeight, camera.fov.getValue());
|
|
29
|
+
const controller = ecd.getComponent(camera_entity, TopDownCameraController);
|
|
30
|
+
const camera = ecd.getComponent(camera_entity, Camera);
|
|
58
31
|
|
|
59
|
-
|
|
32
|
+
assert.defined(controller, 'controller');
|
|
33
|
+
assert.defined(camera, 'camera');
|
|
60
34
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
35
|
+
const rig = new OrbitalCameraRig(controller, {
|
|
36
|
+
orbit_buttons: MouseEventButtons.primary,
|
|
37
|
+
pan_buttons: MouseEventButtons.secondary,
|
|
38
|
+
pitch_min: -Math.PI / 2,
|
|
39
|
+
pitch_max: Math.PI / 2,
|
|
40
|
+
pan_axes: Vector3.one
|
|
41
|
+
});
|
|
67
42
|
|
|
68
43
|
const inputController = new InputController([
|
|
69
44
|
{
|
|
70
|
-
path: 'pointer/on/
|
|
71
|
-
listener(
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
path: 'pointer/on/down',
|
|
77
|
-
listener(position, event) {
|
|
78
|
-
// event.preventDefault();
|
|
45
|
+
path: 'pointer/on/dragStart',
|
|
46
|
+
listener(origin, event) {
|
|
47
|
+
rig.begin(event.buttons);
|
|
79
48
|
}
|
|
80
49
|
},
|
|
81
50
|
{
|
|
82
51
|
path: 'pointer/on/drag',
|
|
83
|
-
listener
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
} else {
|
|
91
|
-
orbit(delta);
|
|
92
|
-
}
|
|
52
|
+
listener(position, origin, lastDragPosition, event) {
|
|
53
|
+
rig.move(
|
|
54
|
+
position.x - lastDragPosition.x,
|
|
55
|
+
position.y - lastDragPosition.y,
|
|
56
|
+
dom_element.clientHeight,
|
|
57
|
+
camera.fov.getValue()
|
|
58
|
+
);
|
|
93
59
|
|
|
94
60
|
event.preventDefault();
|
|
95
61
|
}
|
|
96
62
|
},
|
|
63
|
+
{
|
|
64
|
+
path: 'pointer/on/dragEnd',
|
|
65
|
+
listener() {
|
|
66
|
+
rig.end();
|
|
67
|
+
}
|
|
68
|
+
},
|
|
97
69
|
{
|
|
98
70
|
path: 'pointer/on/wheel',
|
|
99
|
-
listener(delta
|
|
100
|
-
|
|
71
|
+
listener(delta) {
|
|
72
|
+
rig.dolly(delta.y);
|
|
101
73
|
}
|
|
102
74
|
}
|
|
103
75
|
]);
|
|
104
76
|
|
|
105
77
|
const eb = new Entity();
|
|
106
78
|
eb.add(inputController);
|
|
79
|
+
eb.add(new Script(time_delta => rig.update(time_delta)));
|
|
107
80
|
|
|
108
81
|
return eb;
|
|
109
82
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The velocity of one degree of freedom under **direct drive + release momentum** — the "throw" of
|
|
3
|
+
* Google Earth / Maps / Cesium, not a spring.
|
|
4
|
+
*
|
|
5
|
+
* The axis holds no position. While a gesture is engaged the caller applies each drag to whatever it
|
|
6
|
+
* is moving and {@link record}s it here, so the drag itself has no lag. On {@link release} the
|
|
7
|
+
* average velocity over the recent window becomes the throw; averaging the velocity rather than the
|
|
8
|
+
* position rejects one jittery last frame without adding lag to the live drag. From then on
|
|
9
|
+
* {@link update} hands back how far the coast moves each frame, decaying exponentially, and the caller
|
|
10
|
+
* adds that to the value — so anyone else writing the same value keeps their write, and the coast
|
|
11
|
+
* carries on from it.
|
|
12
|
+
*
|
|
13
|
+
* Holding still before letting go fills the window with frames that did not move, so a slow,
|
|
14
|
+
* deliberate drag stops where it was left while a flick throws — no click-versus-drag gate.
|
|
15
|
+
*
|
|
16
|
+
* @author Alex Goldring
|
|
17
|
+
* @copyright Company Named Limited (c) 2026
|
|
18
|
+
*/
|
|
19
|
+
export class MomentumAxis {
|
|
20
|
+
/**
|
|
21
|
+
* units per second; non-zero while coasting
|
|
22
|
+
* @type {number}
|
|
23
|
+
*/
|
|
24
|
+
velocity: number;
|
|
25
|
+
/**
|
|
26
|
+
* true while a gesture is driving this axis
|
|
27
|
+
* @type {boolean}
|
|
28
|
+
*/
|
|
29
|
+
engaged: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Begin direct control: stop any coast and forget earlier motion.
|
|
32
|
+
*/
|
|
33
|
+
engage(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Note motion the caller has just applied directly, for the release estimate.
|
|
36
|
+
* @param {number} delta
|
|
37
|
+
*/
|
|
38
|
+
record(delta: number): void;
|
|
39
|
+
/**
|
|
40
|
+
* End the gesture, throwing with the average velocity over the most recent `window_seconds` of it.
|
|
41
|
+
* @param {number} window_seconds
|
|
42
|
+
*/
|
|
43
|
+
release(window_seconds: number): void;
|
|
44
|
+
/**
|
|
45
|
+
* No motion, no gesture, no history.
|
|
46
|
+
*/
|
|
47
|
+
stop(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Advance one frame.
|
|
50
|
+
*
|
|
51
|
+
* Engaged, this samples the frame's recorded motion and moves nothing, since the drag was applied
|
|
52
|
+
* when it happened. Coasting, it integrates the decaying velocity analytically — over `dt` the
|
|
53
|
+
* coast covers `v·τ·(1 − e^(−dt/τ))` and the velocity falls by `e^(−dt/τ)` — so the distance
|
|
54
|
+
* thrown is the same at any frame rate.
|
|
55
|
+
*
|
|
56
|
+
* @param {number} dt seconds
|
|
57
|
+
* @param {number} half_life seconds for the coast velocity to halve
|
|
58
|
+
* @param {number} stop_speed at or below this speed the coast ends
|
|
59
|
+
* @returns {number} how far the value moves this frame
|
|
60
|
+
*/
|
|
61
|
+
update(dt: number, half_life: number, stop_speed: number): number;
|
|
62
|
+
#private;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=MomentumAxis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MomentumAxis.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/camera/orbital/MomentumAxis.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;GAiBG;AACH;IACI;;;OAGG;IACH,UAFU,MAAM,CAEH;IAEb;;;OAGG;IACH,SAFU,OAAO,CAED;IA+BhB;;OAEG;IACH,eAGC;IAED;;;OAGG;IACH,cAFW,MAAM,QAIhB;IAED;;;OAGG;IACH,wBAFW,MAAM,QAehB;IAED;;OAEG;IACH,aAMC;IAED;;;;;;;;;;;;OAYG;IACH,WALW,MAAM,aACN,MAAM,cACN,MAAM,GACJ,MAAM,CAoClB;;CAuBJ"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
const LN2 = 0.6931471805599453;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Frames of drag history kept for the release estimate. The estimate reads back over a window of
|
|
5
|
+
* about a tenth of a second, so this covers it at up to 900 frames a second; beyond that the oldest
|
|
6
|
+
* part of the window is simply not seen.
|
|
7
|
+
* @type {number}
|
|
8
|
+
*/
|
|
9
|
+
const HISTORY_CAPACITY = 90;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The velocity of one degree of freedom under **direct drive + release momentum** — the "throw" of
|
|
13
|
+
* Google Earth / Maps / Cesium, not a spring.
|
|
14
|
+
*
|
|
15
|
+
* The axis holds no position. While a gesture is engaged the caller applies each drag to whatever it
|
|
16
|
+
* is moving and {@link record}s it here, so the drag itself has no lag. On {@link release} the
|
|
17
|
+
* average velocity over the recent window becomes the throw; averaging the velocity rather than the
|
|
18
|
+
* position rejects one jittery last frame without adding lag to the live drag. From then on
|
|
19
|
+
* {@link update} hands back how far the coast moves each frame, decaying exponentially, and the caller
|
|
20
|
+
* adds that to the value — so anyone else writing the same value keeps their write, and the coast
|
|
21
|
+
* carries on from it.
|
|
22
|
+
*
|
|
23
|
+
* Holding still before letting go fills the window with frames that did not move, so a slow,
|
|
24
|
+
* deliberate drag stops where it was left while a flick throws — no click-versus-drag gate.
|
|
25
|
+
*
|
|
26
|
+
* @author Alex Goldring
|
|
27
|
+
* @copyright Company Named Limited (c) 2026
|
|
28
|
+
*/
|
|
29
|
+
export class MomentumAxis {
|
|
30
|
+
/**
|
|
31
|
+
* units per second; non-zero while coasting
|
|
32
|
+
* @type {number}
|
|
33
|
+
*/
|
|
34
|
+
velocity = 0;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* true while a gesture is driving this axis
|
|
38
|
+
* @type {boolean}
|
|
39
|
+
*/
|
|
40
|
+
engaged = false;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* motion recorded since the last frame sample
|
|
44
|
+
* @type {number}
|
|
45
|
+
*/
|
|
46
|
+
#pending = 0;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* per-frame motion, a ring of {@link HISTORY_CAPACITY}
|
|
50
|
+
* @type {Float64Array}
|
|
51
|
+
*/
|
|
52
|
+
#history_motion = new Float64Array(HISTORY_CAPACITY);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* duration of each frame in {@link #history_motion}, seconds
|
|
56
|
+
* @type {Float64Array}
|
|
57
|
+
*/
|
|
58
|
+
#history_duration = new Float64Array(HISTORY_CAPACITY);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* slot the next frame is written to
|
|
62
|
+
* @type {number}
|
|
63
|
+
*/
|
|
64
|
+
#history_head = 0;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @type {number}
|
|
68
|
+
*/
|
|
69
|
+
#history_count = 0;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Begin direct control: stop any coast and forget earlier motion.
|
|
73
|
+
*/
|
|
74
|
+
engage() {
|
|
75
|
+
this.stop();
|
|
76
|
+
this.engaged = true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Note motion the caller has just applied directly, for the release estimate.
|
|
81
|
+
* @param {number} delta
|
|
82
|
+
*/
|
|
83
|
+
record(delta) {
|
|
84
|
+
this.#pending += delta;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* End the gesture, throwing with the average velocity over the most recent `window_seconds` of it.
|
|
89
|
+
* @param {number} window_seconds
|
|
90
|
+
*/
|
|
91
|
+
release(window_seconds) {
|
|
92
|
+
if (this.#pending !== 0 && this.#history_count > 0) {
|
|
93
|
+
// motion that arrived after the last frame sample belongs to the frame that just ended
|
|
94
|
+
const last = (this.#history_head + HISTORY_CAPACITY - 1) % HISTORY_CAPACITY;
|
|
95
|
+
|
|
96
|
+
this.#history_motion[last] += this.#pending;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const velocity = this.#windowed_velocity(window_seconds);
|
|
100
|
+
|
|
101
|
+
this.stop();
|
|
102
|
+
|
|
103
|
+
this.velocity = velocity;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* No motion, no gesture, no history.
|
|
108
|
+
*/
|
|
109
|
+
stop() {
|
|
110
|
+
this.velocity = 0;
|
|
111
|
+
this.engaged = false;
|
|
112
|
+
this.#pending = 0;
|
|
113
|
+
this.#history_head = 0;
|
|
114
|
+
this.#history_count = 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Advance one frame.
|
|
119
|
+
*
|
|
120
|
+
* Engaged, this samples the frame's recorded motion and moves nothing, since the drag was applied
|
|
121
|
+
* when it happened. Coasting, it integrates the decaying velocity analytically — over `dt` the
|
|
122
|
+
* coast covers `v·τ·(1 − e^(−dt/τ))` and the velocity falls by `e^(−dt/τ)` — so the distance
|
|
123
|
+
* thrown is the same at any frame rate.
|
|
124
|
+
*
|
|
125
|
+
* @param {number} dt seconds
|
|
126
|
+
* @param {number} half_life seconds for the coast velocity to halve
|
|
127
|
+
* @param {number} stop_speed at or below this speed the coast ends
|
|
128
|
+
* @returns {number} how far the value moves this frame
|
|
129
|
+
*/
|
|
130
|
+
update(dt, half_life, stop_speed) {
|
|
131
|
+
if (this.engaged) {
|
|
132
|
+
const head = this.#history_head;
|
|
133
|
+
|
|
134
|
+
this.#history_motion[head] = this.#pending;
|
|
135
|
+
this.#history_duration[head] = dt;
|
|
136
|
+
|
|
137
|
+
this.#history_head = (head + 1) % HISTORY_CAPACITY;
|
|
138
|
+
|
|
139
|
+
if (this.#history_count < HISTORY_CAPACITY) {
|
|
140
|
+
this.#history_count++;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
this.#pending = 0;
|
|
144
|
+
|
|
145
|
+
return 0;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const velocity = this.velocity;
|
|
149
|
+
|
|
150
|
+
if (velocity === 0) {
|
|
151
|
+
return 0;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const tau = half_life / LN2;
|
|
155
|
+
const decay = Math.exp(-dt / tau);
|
|
156
|
+
|
|
157
|
+
this.velocity = velocity * decay;
|
|
158
|
+
|
|
159
|
+
if (Math.abs(this.velocity) <= stop_speed) {
|
|
160
|
+
this.velocity = 0;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return velocity * tau * (1 - decay);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @param {number} window_seconds
|
|
168
|
+
* @returns {number}
|
|
169
|
+
*/
|
|
170
|
+
#windowed_velocity(window_seconds) {
|
|
171
|
+
let motion = 0;
|
|
172
|
+
let duration = 0;
|
|
173
|
+
|
|
174
|
+
for (let i = 1; i <= this.#history_count; i++) {
|
|
175
|
+
const slot = (this.#history_head + HISTORY_CAPACITY - i) % HISTORY_CAPACITY;
|
|
176
|
+
|
|
177
|
+
motion += this.#history_motion[slot];
|
|
178
|
+
duration += this.#history_duration[slot];
|
|
179
|
+
|
|
180
|
+
if (duration >= window_seconds) {
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return duration > 0 ? motion / duration : 0;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orbit, pan and zoom of a {@link TopDownCameraController}, with the feel of **direct drive + release
|
|
3
|
+
* momentum**: the "throw" of Google Earth / Cesium, not a spring chasing a goal.
|
|
4
|
+
*
|
|
5
|
+
* - **A drag moves the controller as it happens**, one to one, so the view keeps up with the hand.
|
|
6
|
+
* - **Letting go throws**: the average velocity over the last {@link VELOCITY_WINDOW} carries on and
|
|
7
|
+
* decays with a half life of {@link MOMENTUM_HALF_LIFE}, at the same distance whatever the frame
|
|
8
|
+
* rate. Holding still before letting go throws nothing. Grabbing again stops every throw.
|
|
9
|
+
* - **Zoom is instant and multiplicative**: a wheel notch is a discrete step with nothing to catch up.
|
|
10
|
+
*
|
|
11
|
+
* The rig keeps velocities, not a pose. Each frame the coast is added to the controller as it finds
|
|
12
|
+
* it, so a writer that adds to the controller composes with a throw, and one that sets its values
|
|
13
|
+
* outright wins. A teleport should {@link stop} the rig, or the remains of a throw carry on from the
|
|
14
|
+
* new pose.
|
|
15
|
+
*
|
|
16
|
+
* The rig subscribes to nothing. Its host hands it the gesture — {@link begin}, {@link move},
|
|
17
|
+
* {@link end}, {@link dolly} — from whatever input it listens to, and calls {@link update} once a frame.
|
|
18
|
+
* A drag the device abandons without an end leaves the rig engaged and still, which the next
|
|
19
|
+
* {@link begin} clears.
|
|
20
|
+
*
|
|
21
|
+
* @author Alex Goldring
|
|
22
|
+
* @copyright Company Named Limited (c) 2026
|
|
23
|
+
*/
|
|
24
|
+
export class OrbitalCameraRig {
|
|
25
|
+
/**
|
|
26
|
+
* @param {TopDownCameraController} controller moved by the rig; a host that filters the camera
|
|
27
|
+
* hands over the controller its input is meant to drive
|
|
28
|
+
* @param {Object} options
|
|
29
|
+
* @param {number} options.orbit_buttons {@link MouseEvent.buttons} bits that start an orbit, see
|
|
30
|
+
* {@link MouseEventButtons}
|
|
31
|
+
* @param {number} options.pan_buttons {@link MouseEvent.buttons} bits that start a pan; orbit wins
|
|
32
|
+
* when both are held
|
|
33
|
+
* @param {number} options.pitch_min radians; 0 looks along the horizon
|
|
34
|
+
* @param {number} options.pitch_max radians; π/2 looks straight down
|
|
35
|
+
* @param {Vector3} options.pan_axes per-axis scale on a pan's world displacement, as
|
|
36
|
+
* {@link TopDownCameraController.pan} takes it; zero Y to keep the target on the ground
|
|
37
|
+
*/
|
|
38
|
+
constructor(controller: TopDownCameraController, { orbit_buttons, pan_buttons, pitch_min, pitch_max, pan_axes }: {
|
|
39
|
+
orbit_buttons: number;
|
|
40
|
+
pan_buttons: number;
|
|
41
|
+
pitch_min: number;
|
|
42
|
+
pitch_max: number;
|
|
43
|
+
pan_axes: Vector3;
|
|
44
|
+
});
|
|
45
|
+
/**
|
|
46
|
+
* Start a drag. Stops every throw, then takes direct control of orbit or pan, chosen by the
|
|
47
|
+
* buttons held; with neither, the drag moves nothing.
|
|
48
|
+
*
|
|
49
|
+
* @param {number} buttons {@link MouseEvent.buttons} of the event that started the drag
|
|
50
|
+
*/
|
|
51
|
+
begin(buttons: number): void;
|
|
52
|
+
/**
|
|
53
|
+
* The pointer moved during a drag, applied to the controller at once.
|
|
54
|
+
*
|
|
55
|
+
* An orbit turns the view a full turn per viewport height of travel, pitch clamped to the rig's
|
|
56
|
+
* range; a pan carries the world under the pointer along with it.
|
|
57
|
+
*
|
|
58
|
+
* @param {number} delta_x pixels, the pointer's position less where it was
|
|
59
|
+
* @param {number} delta_y pixels, the pointer's position less where it was, down positive
|
|
60
|
+
* @param {number} viewport_height pixels
|
|
61
|
+
* @param {number} fov vertical field of view, in degrees
|
|
62
|
+
*/
|
|
63
|
+
move(delta_x: number, delta_y: number, viewport_height: number, fov: number): void;
|
|
64
|
+
/**
|
|
65
|
+
* End the drag, throwing with its recent velocity.
|
|
66
|
+
*/
|
|
67
|
+
end(): void;
|
|
68
|
+
/**
|
|
69
|
+
* Drop any drag and every throw, leaving the controller where it is.
|
|
70
|
+
*/
|
|
71
|
+
stop(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Zoom by wheel notches, within the controller's distance range.
|
|
74
|
+
* @param {number} notches positive away from the target, as a wheel scrolled down reports it
|
|
75
|
+
*/
|
|
76
|
+
dolly(notches: number): void;
|
|
77
|
+
/**
|
|
78
|
+
* Advance one frame: sample an engaged drag for its throw, or carry a throw on.
|
|
79
|
+
* @param {number} dt seconds
|
|
80
|
+
*/
|
|
81
|
+
update(dt: number): void;
|
|
82
|
+
#private;
|
|
83
|
+
}
|
|
84
|
+
import TopDownCameraController from "../../ecs/camera/topdown/TopDownCameraController.js";
|
|
85
|
+
import Vector3 from "../../../../core/geom/Vector3.js";
|
|
86
|
+
//# sourceMappingURL=OrbitalCameraRig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrbitalCameraRig.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/camera/orbital/OrbitalCameraRig.js"],"names":[],"mappings":"AAuCA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;IA0CI;;;;;;;;;;;;OAYG;IACH,wBAZW,uBAAuB;QAGP,aAAa,EAA7B,MAAM;QAEU,WAAW,EAA3B,MAAM;QAEU,SAAS,EAAzB,MAAM;QACU,SAAS,EAAzB,MAAM;QACW,QAAQ,EAAzB,OAAO;OAkBjB;IAED;;;;;OAKG;IACH,eAFW,MAAM,QAiBhB;IAED;;;;;;;;;;OAUG;IACH,cALW,MAAM,WACN,MAAM,mBACN,MAAM,OACN,MAAM,QAQhB;IAED;;OAEG;IACH,YAWC;IAED;;OAEG;IACH,aAQC;IAED;;;OAGG;IACH,eAFW,MAAM,QAUhB;IAED;;;OAGG;IACH,WAFW,MAAM,QAyChB;;CAwDJ;oCAzTmC,qDAAqD;oBAFrE,kCAAkC"}
|