@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
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { normalize_angle_rad } from "../../../../core/geom/normalize_angle_rad.js";
|
|
3
|
+
import Vector2 from "../../../../core/geom/Vector2.js";
|
|
4
|
+
import Vector3 from "../../../../core/geom/Vector3.js";
|
|
5
|
+
import { clamp } from "../../../../core/math/clamp.js";
|
|
6
|
+
import TopDownCameraController from "../../ecs/camera/topdown/TopDownCameraController.js";
|
|
7
|
+
import { MomentumAxis } from "./MomentumAxis.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Seconds for a throw's velocity to halve once the gesture lets go.
|
|
11
|
+
* @type {number}
|
|
12
|
+
*/
|
|
13
|
+
const MOMENTUM_HALF_LIFE = 0.1;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Seconds of the gesture's end averaged into the throw velocity.
|
|
17
|
+
* @type {number}
|
|
18
|
+
*/
|
|
19
|
+
const VELOCITY_WINDOW = 0.1;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Radians per second below which an orbit throw stops. A pan throw stops at this times the orbit
|
|
23
|
+
* distance, the same speed across the screen at any zoom.
|
|
24
|
+
* @type {number}
|
|
25
|
+
*/
|
|
26
|
+
const MOMENTUM_STOP_SPEED = 0.012;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Factor on the orbit distance per wheel notch towards the target.
|
|
30
|
+
* @type {number}
|
|
31
|
+
*/
|
|
32
|
+
const ZOOM_STEP = 0.9;
|
|
33
|
+
|
|
34
|
+
const GESTURE_NONE = 0;
|
|
35
|
+
const GESTURE_ORBIT = 1;
|
|
36
|
+
const GESTURE_PAN = 2;
|
|
37
|
+
|
|
38
|
+
const v2_pan = new Vector2();
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Orbit, pan and zoom of a {@link TopDownCameraController}, with the feel of **direct drive + release
|
|
42
|
+
* momentum**: the "throw" of Google Earth / Cesium, not a spring chasing a goal.
|
|
43
|
+
*
|
|
44
|
+
* - **A drag moves the controller as it happens**, one to one, so the view keeps up with the hand.
|
|
45
|
+
* - **Letting go throws**: the average velocity over the last {@link VELOCITY_WINDOW} carries on and
|
|
46
|
+
* decays with a half life of {@link MOMENTUM_HALF_LIFE}, at the same distance whatever the frame
|
|
47
|
+
* rate. Holding still before letting go throws nothing. Grabbing again stops every throw.
|
|
48
|
+
* - **Zoom is instant and multiplicative**: a wheel notch is a discrete step with nothing to catch up.
|
|
49
|
+
*
|
|
50
|
+
* The rig keeps velocities, not a pose. Each frame the coast is added to the controller as it finds
|
|
51
|
+
* it, so a writer that adds to the controller composes with a throw, and one that sets its values
|
|
52
|
+
* outright wins. A teleport should {@link stop} the rig, or the remains of a throw carry on from the
|
|
53
|
+
* new pose.
|
|
54
|
+
*
|
|
55
|
+
* The rig subscribes to nothing. Its host hands it the gesture — {@link begin}, {@link move},
|
|
56
|
+
* {@link end}, {@link dolly} — from whatever input it listens to, and calls {@link update} once a frame.
|
|
57
|
+
* A drag the device abandons without an end leaves the rig engaged and still, which the next
|
|
58
|
+
* {@link begin} clears.
|
|
59
|
+
*
|
|
60
|
+
* @author Alex Goldring
|
|
61
|
+
* @copyright Company Named Limited (c) 2026
|
|
62
|
+
*/
|
|
63
|
+
export class OrbitalCameraRig {
|
|
64
|
+
/**
|
|
65
|
+
* @type {TopDownCameraController}
|
|
66
|
+
*/
|
|
67
|
+
#controller;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @type {number}
|
|
71
|
+
*/
|
|
72
|
+
#orbit_buttons;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @type {number}
|
|
76
|
+
*/
|
|
77
|
+
#pan_buttons;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @type {number}
|
|
81
|
+
*/
|
|
82
|
+
#pitch_min;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @type {number}
|
|
86
|
+
*/
|
|
87
|
+
#pitch_max;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @type {Vector3}
|
|
91
|
+
*/
|
|
92
|
+
#pan_axes;
|
|
93
|
+
|
|
94
|
+
#pitch = new MomentumAxis();
|
|
95
|
+
#yaw = new MomentumAxis();
|
|
96
|
+
#target_x = new MomentumAxis();
|
|
97
|
+
#target_y = new MomentumAxis();
|
|
98
|
+
#target_z = new MomentumAxis();
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @type {number}
|
|
102
|
+
*/
|
|
103
|
+
#gesture = GESTURE_NONE;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @param {TopDownCameraController} controller moved by the rig; a host that filters the camera
|
|
107
|
+
* hands over the controller its input is meant to drive
|
|
108
|
+
* @param {Object} options
|
|
109
|
+
* @param {number} options.orbit_buttons {@link MouseEvent.buttons} bits that start an orbit, see
|
|
110
|
+
* {@link MouseEventButtons}
|
|
111
|
+
* @param {number} options.pan_buttons {@link MouseEvent.buttons} bits that start a pan; orbit wins
|
|
112
|
+
* when both are held
|
|
113
|
+
* @param {number} options.pitch_min radians; 0 looks along the horizon
|
|
114
|
+
* @param {number} options.pitch_max radians; π/2 looks straight down
|
|
115
|
+
* @param {Vector3} options.pan_axes per-axis scale on a pan's world displacement, as
|
|
116
|
+
* {@link TopDownCameraController.pan} takes it; zero Y to keep the target on the ground
|
|
117
|
+
*/
|
|
118
|
+
constructor(controller, { orbit_buttons, pan_buttons, pitch_min, pitch_max, pan_axes }) {
|
|
119
|
+
assert.defined(controller, 'controller');
|
|
120
|
+
assert.isNonNegativeInteger(orbit_buttons, 'orbit_buttons');
|
|
121
|
+
assert.isNonNegativeInteger(pan_buttons, 'pan_buttons');
|
|
122
|
+
assert.isNumber(pitch_min, 'pitch_min');
|
|
123
|
+
assert.isNumber(pitch_max, 'pitch_max');
|
|
124
|
+
assert.lessThanOrEqual(pitch_min, pitch_max, 'pitch_min must not exceed pitch_max');
|
|
125
|
+
assert.defined(pan_axes, 'pan_axes');
|
|
126
|
+
|
|
127
|
+
this.#controller = controller;
|
|
128
|
+
this.#orbit_buttons = orbit_buttons;
|
|
129
|
+
this.#pan_buttons = pan_buttons;
|
|
130
|
+
this.#pitch_min = pitch_min;
|
|
131
|
+
this.#pitch_max = pitch_max;
|
|
132
|
+
this.#pan_axes = pan_axes;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Start a drag. Stops every throw, then takes direct control of orbit or pan, chosen by the
|
|
137
|
+
* buttons held; with neither, the drag moves nothing.
|
|
138
|
+
*
|
|
139
|
+
* @param {number} buttons {@link MouseEvent.buttons} of the event that started the drag
|
|
140
|
+
*/
|
|
141
|
+
begin(buttons) {
|
|
142
|
+
this.stop();
|
|
143
|
+
|
|
144
|
+
if ((buttons & this.#orbit_buttons) !== 0) {
|
|
145
|
+
this.#gesture = GESTURE_ORBIT;
|
|
146
|
+
|
|
147
|
+
this.#pitch.engage();
|
|
148
|
+
this.#yaw.engage();
|
|
149
|
+
} else if ((buttons & this.#pan_buttons) !== 0) {
|
|
150
|
+
this.#gesture = GESTURE_PAN;
|
|
151
|
+
|
|
152
|
+
this.#target_x.engage();
|
|
153
|
+
this.#target_y.engage();
|
|
154
|
+
this.#target_z.engage();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* The pointer moved during a drag, applied to the controller at once.
|
|
160
|
+
*
|
|
161
|
+
* An orbit turns the view a full turn per viewport height of travel, pitch clamped to the rig's
|
|
162
|
+
* range; a pan carries the world under the pointer along with it.
|
|
163
|
+
*
|
|
164
|
+
* @param {number} delta_x pixels, the pointer's position less where it was
|
|
165
|
+
* @param {number} delta_y pixels, the pointer's position less where it was, down positive
|
|
166
|
+
* @param {number} viewport_height pixels
|
|
167
|
+
* @param {number} fov vertical field of view, in degrees
|
|
168
|
+
*/
|
|
169
|
+
move(delta_x, delta_y, viewport_height, fov) {
|
|
170
|
+
if (this.#gesture === GESTURE_ORBIT) {
|
|
171
|
+
this.#orbit(delta_x, delta_y, viewport_height);
|
|
172
|
+
} else if (this.#gesture === GESTURE_PAN) {
|
|
173
|
+
this.#pan(delta_x, delta_y, viewport_height, fov);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* End the drag, throwing with its recent velocity.
|
|
179
|
+
*/
|
|
180
|
+
end() {
|
|
181
|
+
if (this.#gesture === GESTURE_ORBIT) {
|
|
182
|
+
this.#pitch.release(VELOCITY_WINDOW);
|
|
183
|
+
this.#yaw.release(VELOCITY_WINDOW);
|
|
184
|
+
} else if (this.#gesture === GESTURE_PAN) {
|
|
185
|
+
this.#target_x.release(VELOCITY_WINDOW);
|
|
186
|
+
this.#target_y.release(VELOCITY_WINDOW);
|
|
187
|
+
this.#target_z.release(VELOCITY_WINDOW);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
this.#gesture = GESTURE_NONE;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Drop any drag and every throw, leaving the controller where it is.
|
|
195
|
+
*/
|
|
196
|
+
stop() {
|
|
197
|
+
this.#gesture = GESTURE_NONE;
|
|
198
|
+
|
|
199
|
+
this.#pitch.stop();
|
|
200
|
+
this.#yaw.stop();
|
|
201
|
+
this.#target_x.stop();
|
|
202
|
+
this.#target_y.stop();
|
|
203
|
+
this.#target_z.stop();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Zoom by wheel notches, within the controller's distance range.
|
|
208
|
+
* @param {number} notches positive away from the target, as a wheel scrolled down reports it
|
|
209
|
+
*/
|
|
210
|
+
dolly(notches) {
|
|
211
|
+
const controller = this.#controller;
|
|
212
|
+
|
|
213
|
+
controller.distance = clamp(
|
|
214
|
+
controller.distance * Math.pow(ZOOM_STEP, -notches),
|
|
215
|
+
controller.distanceMin,
|
|
216
|
+
controller.distanceMax
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Advance one frame: sample an engaged drag for its throw, or carry a throw on.
|
|
222
|
+
* @param {number} dt seconds
|
|
223
|
+
*/
|
|
224
|
+
update(dt) {
|
|
225
|
+
if (!(dt > 0)) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const controller = this.#controller;
|
|
230
|
+
|
|
231
|
+
const d_pitch = this.#pitch.update(dt, MOMENTUM_HALF_LIFE, MOMENTUM_STOP_SPEED);
|
|
232
|
+
|
|
233
|
+
if (d_pitch !== 0) {
|
|
234
|
+
const pitch = controller.pitch + d_pitch;
|
|
235
|
+
|
|
236
|
+
// a throw stops at the end of the range instead of pressing on into it
|
|
237
|
+
if (pitch <= this.#pitch_min) {
|
|
238
|
+
controller.pitch = this.#pitch_min;
|
|
239
|
+
this.#pitch.stop();
|
|
240
|
+
} else if (pitch >= this.#pitch_max) {
|
|
241
|
+
controller.pitch = this.#pitch_max;
|
|
242
|
+
this.#pitch.stop();
|
|
243
|
+
} else {
|
|
244
|
+
controller.pitch = pitch;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const d_yaw = this.#yaw.update(dt, MOMENTUM_HALF_LIFE, MOMENTUM_STOP_SPEED);
|
|
249
|
+
|
|
250
|
+
if (d_yaw !== 0) {
|
|
251
|
+
controller.yaw = normalize_angle_rad(controller.yaw + d_yaw);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const pan_stop_speed = MOMENTUM_STOP_SPEED * controller.distance;
|
|
255
|
+
|
|
256
|
+
const d_x = this.#target_x.update(dt, MOMENTUM_HALF_LIFE, pan_stop_speed);
|
|
257
|
+
const d_y = this.#target_y.update(dt, MOMENTUM_HALF_LIFE, pan_stop_speed);
|
|
258
|
+
const d_z = this.#target_z.update(dt, MOMENTUM_HALF_LIFE, pan_stop_speed);
|
|
259
|
+
|
|
260
|
+
if (d_x !== 0 || d_y !== 0 || d_z !== 0) {
|
|
261
|
+
controller.target._add(d_x, d_y, d_z);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* @param {number} delta_x
|
|
267
|
+
* @param {number} delta_y
|
|
268
|
+
* @param {number} viewport_height
|
|
269
|
+
*/
|
|
270
|
+
#orbit(delta_x, delta_y, viewport_height) {
|
|
271
|
+
if (!(viewport_height > 0)) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const controller = this.#controller;
|
|
276
|
+
|
|
277
|
+
const radians_per_pixel = 2 * Math.PI / viewport_height;
|
|
278
|
+
|
|
279
|
+
// a pitch found outside the range is brought into it, and the jump is no part of the gesture
|
|
280
|
+
const pitch_before = clamp(controller.pitch, this.#pitch_min, this.#pitch_max);
|
|
281
|
+
const pitch_after = clamp(pitch_before + delta_y * radians_per_pixel, this.#pitch_min, this.#pitch_max);
|
|
282
|
+
|
|
283
|
+
controller.pitch = pitch_after;
|
|
284
|
+
this.#pitch.record(pitch_after - pitch_before);
|
|
285
|
+
|
|
286
|
+
// dragging right swings the eye the other way around the target, so the world turns with the hand
|
|
287
|
+
const d_yaw = -delta_x * radians_per_pixel;
|
|
288
|
+
|
|
289
|
+
controller.yaw = normalize_angle_rad(controller.yaw + d_yaw);
|
|
290
|
+
this.#yaw.record(d_yaw);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* @param {number} delta_x
|
|
295
|
+
* @param {number} delta_y
|
|
296
|
+
* @param {number} viewport_height
|
|
297
|
+
* @param {number} fov
|
|
298
|
+
*/
|
|
299
|
+
#pan(delta_x, delta_y, viewport_height, fov) {
|
|
300
|
+
if (!(viewport_height > 0)) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const target = this.#controller.target;
|
|
305
|
+
|
|
306
|
+
const x = target.x;
|
|
307
|
+
const y = target.y;
|
|
308
|
+
const z = target.z;
|
|
309
|
+
|
|
310
|
+
// pan takes where the pointer was less where it is
|
|
311
|
+
v2_pan.set(-delta_x, -delta_y);
|
|
312
|
+
|
|
313
|
+
TopDownCameraController.pan(v2_pan, this.#controller, viewport_height, fov, this.#pan_axes);
|
|
314
|
+
|
|
315
|
+
this.#target_x.record(target.x - x);
|
|
316
|
+
this.#target_y.record(target.y - y);
|
|
317
|
+
this.#target_z.record(target.z - z);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {number} displacement_x
|
|
4
|
-
* @param {number} displacement_y
|
|
5
|
-
* @param {TopDownCameraController} input source thing being rotated
|
|
6
|
-
* @param {TopDownCameraController} output target thing where the result is written to
|
|
7
|
-
*/
|
|
8
|
-
export function rotate_from_view(displacement_x: number, displacement_y: number, input: TopDownCameraController, output: TopDownCameraController): void;
|
|
9
1
|
/**
|
|
10
2
|
* The orientation a controller looks along. The camera's transform is built from this and the
|
|
11
3
|
* distance, so anything that needs the view's own axes takes them from here rather than from
|
|
@@ -15,7 +7,41 @@ export function rotate_from_view(displacement_x: number, displacement_y: number,
|
|
|
15
7
|
* @param {TopDownCameraController} controller
|
|
16
8
|
*/
|
|
17
9
|
export function top_down_view_rotation(result: Quaternion, controller: TopDownCameraController): void;
|
|
10
|
+
/**
|
|
11
|
+
* Write a controller's pose onto a camera transform: the view rotation, and the eye its distance back
|
|
12
|
+
* from the target along it, the distance held within the controller's range.
|
|
13
|
+
*
|
|
14
|
+
* @param {TopDownCameraController} control
|
|
15
|
+
* @param {Transform64} result
|
|
16
|
+
*/
|
|
17
|
+
export function computeTopDownTransform(control: TopDownCameraController, result: Transform64): void;
|
|
18
|
+
/**
|
|
19
|
+
* Move a controller's target `distance` world units along where its view faces: `right` and
|
|
20
|
+
* `forward` pick the direction in the view's own frame, so a target can be flown up or down a slope.
|
|
21
|
+
* A diagonal travels the same distance as a straight move.
|
|
22
|
+
*
|
|
23
|
+
* The viewer's right is the negated X axis of the view rotation, as {@link pan} explains.
|
|
24
|
+
*
|
|
25
|
+
* @param {TopDownCameraController} controller its {@link TopDownCameraController#target} is moved
|
|
26
|
+
* @param {number} right −1 to 1, positive to the viewer's right
|
|
27
|
+
* @param {number} forward −1 to 1, positive into the screen
|
|
28
|
+
* @param {number} distance world units
|
|
29
|
+
*/
|
|
30
|
+
export function top_down_truck_in_view(controller: TopDownCameraController, right: number, forward: number, distance: number): void;
|
|
31
|
+
/**
|
|
32
|
+
* Move a controller's target `distance` world units across the ground, along the way its view is
|
|
33
|
+
* turned: `forward` is the view's heading with the pitch taken out, so it keeps its full speed
|
|
34
|
+
* however steeply the view looks down, straight down included, and never moves the target off the
|
|
35
|
+
* ground. A diagonal travels the same distance as a straight move.
|
|
36
|
+
*
|
|
37
|
+
* @param {TopDownCameraController} controller its {@link TopDownCameraController#target} is moved
|
|
38
|
+
* @param {number} right −1 to 1, positive to the viewer's right
|
|
39
|
+
* @param {number} forward −1 to 1, positive along the view's heading
|
|
40
|
+
* @param {number} distance world units
|
|
41
|
+
*/
|
|
42
|
+
export function top_down_truck_on_ground(controller: TopDownCameraController, right: number, forward: number, distance: number): void;
|
|
18
43
|
export default TopDownCameraController;
|
|
44
|
+
import Quaternion from "../../../../../core/geom/Quaternion.js";
|
|
19
45
|
declare class TopDownCameraController {
|
|
20
46
|
static fromJSON(j: any): TopDownCameraController;
|
|
21
47
|
constructor(options: any);
|
|
@@ -86,9 +112,7 @@ declare class TopDownCameraController {
|
|
|
86
112
|
declare namespace TopDownCameraController {
|
|
87
113
|
export let typeName: string;
|
|
88
114
|
export { pan };
|
|
89
|
-
export { rotate_from_view as rotate };
|
|
90
115
|
}
|
|
91
|
-
import Quaternion from "../../../../../core/geom/Quaternion.js";
|
|
92
116
|
import Vector3 from '../../../../../core/geom/Vector3.js';
|
|
93
117
|
/**
|
|
94
118
|
* Move a controller's target across the view plane it is looking at, by a displacement given in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TopDownCameraController.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js"],"names":[],"mappings":"AAyBA;;;;;;GAMG;AACH,
|
|
1
|
+
{"version":3,"file":"TopDownCameraController.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js"],"names":[],"mappings":"AAyBA;;;;;;;GAOG;AACH,+CAHW,UAAU,cACV,uBAAuB,QAIjC;AAiED;;;;;;GAMG;AACH,iDAHW,uBAAuB,6BA2BjC;AAED;;;;;;;;;;;GAWG;AACH,mDALW,uBAAuB,SACvB,MAAM,WACN,MAAM,YACN,MAAM,QAMhB;AAED;;;;;;;;;;GAUG;AACH,qDALW,uBAAuB,SACvB,MAAM,WACN,MAAM,YACN,MAAM,QAMhB;;uBAhKsB,wCAAwC;AAoM/D;IAyKI,iDAMC;IAtKD,0BAKC;IAbD,gBAAuB;IACvB,cAAU;IACV,YAAQ;IACR,aAAS;IACT,iBAAa;IACb,oBAAgB;IAChB,oBAAkB;IASlB;;;;;;;;;OASG;IACH,yBAJW,OAAO,UACP,OAAO,OACP,OAAO,QA0CjB;IAED;;;;OAIG;IACH,cAHW,uBAAuB,GACrB,OAAO,CAWnB;IAED;;;OAGG;IACH,YAFW,uBAAuB,QAYjC;IAED;;;OAGG;IACH,SAFa,uBAAuB,CAQnC;IAED;;;;;OAKG;IACH,QAJW,uBAAuB,KACvB,uBAAuB,KACvB,MAAM,QAahB;IAED;;;;;;;;;;;;MAYC;IAED;;;;;;;;aAsBC;CASJ;;;;;oBAnXmB,qCAAqC;AA8CzD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,iDAPW,uBAAuB,sBACvB,MAAM,OAEN,MAAM,eACN,OAAO,QA2BjB"}
|
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
import { normalize_angle_rad } from "../../../../../core/geom/normalize_angle_rad.js";
|
|
7
7
|
import Quaternion from "../../../../../core/geom/Quaternion.js";
|
|
8
8
|
import Vector3 from '../../../../../core/geom/Vector3.js';
|
|
9
|
+
import { clamp } from "../../../../../core/math/clamp.js";
|
|
9
10
|
import { lerp } from "../../../../../core/math/lerp.js";
|
|
10
11
|
import { max2 } from "../../../../../core/math/max2.js";
|
|
11
|
-
import { sign_not_zero } from "../../../../../core/math/sign_not_zero.js";
|
|
12
12
|
import { v3_distance } from "../../../../../core/geom/vec3/v3_distance.js";
|
|
13
13
|
|
|
14
14
|
const m4 = [];
|
|
@@ -21,31 +21,7 @@ const q_view = new Quaternion();
|
|
|
21
21
|
|
|
22
22
|
const v3_view_right = new Vector3();
|
|
23
23
|
const v3_view_up = new Vector3();
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
*
|
|
28
|
-
* @param {number} displacement_x
|
|
29
|
-
* @param {number} displacement_y
|
|
30
|
-
* @param {TopDownCameraController} input source thing being rotated
|
|
31
|
-
* @param {TopDownCameraController} output target thing where the result is written to
|
|
32
|
-
*/
|
|
33
|
-
export function rotate_from_view(displacement_x, displacement_y, input, output) {
|
|
34
|
-
// crop yaw and pitch to safe range of -PI to PI
|
|
35
|
-
const i_pitch = normalize_angle_rad(input.pitch);
|
|
36
|
-
const i_yaw = normalize_angle_rad(input.yaw);
|
|
37
|
-
const i_roll = normalize_angle_rad(input.roll);
|
|
38
|
-
|
|
39
|
-
const quaternion = Quaternion.fromEulerAngles(i_pitch, i_yaw, i_roll);
|
|
40
|
-
const forward = Vector3.up.clone();
|
|
41
|
-
forward.applyQuaternion(quaternion);
|
|
42
|
-
|
|
43
|
-
// flip rotation axis when pitch is over 90deg in either direction, that is UP vector is pointing down
|
|
44
|
-
const d_yaw = sign_not_zero(forward.y) * displacement_x;
|
|
45
|
-
|
|
46
|
-
output.yaw = i_yaw + d_yaw;
|
|
47
|
-
output.pitch = i_pitch - displacement_y;
|
|
48
|
-
}
|
|
24
|
+
const v3_view_forward = new Vector3();
|
|
49
25
|
|
|
50
26
|
/**
|
|
51
27
|
* The orientation a controller looks along. The camera's transform is built from this and the
|
|
@@ -122,6 +98,107 @@ function pan(delta, controller, viewport_height_px, fov, multiplier = Vector3.on
|
|
|
122
98
|
move_along(target, v3_view_up, -delta.y * m, multiplier);
|
|
123
99
|
}
|
|
124
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Write a controller's pose onto a camera transform: the view rotation, and the eye its distance back
|
|
103
|
+
* from the target along it, the distance held within the controller's range.
|
|
104
|
+
*
|
|
105
|
+
* @param {TopDownCameraController} control
|
|
106
|
+
* @param {Transform64} result
|
|
107
|
+
*/
|
|
108
|
+
export function computeTopDownTransform(control, result) {
|
|
109
|
+
|
|
110
|
+
//clamp the distance
|
|
111
|
+
const distance = clamp(control.distance, control.distanceMin, control.distanceMax);
|
|
112
|
+
const target = control.target;
|
|
113
|
+
|
|
114
|
+
// compute rotation. The transform holds its rotation as four numbers rather than a Quaternion,
|
|
115
|
+
// so the euler composition runs in a scratch and lands in the transform afterwards.
|
|
116
|
+
top_down_view_rotation(q_view, control);
|
|
117
|
+
|
|
118
|
+
result.setRotation(q_view.x, q_view.y, q_view.z, q_view.w);
|
|
119
|
+
|
|
120
|
+
// compute camera position
|
|
121
|
+
v3_view_forward.copy(Vector3.forward);
|
|
122
|
+
v3_view_forward.applyQuaternion(q_view);
|
|
123
|
+
|
|
124
|
+
v3_view_forward.multiplyScalar(-distance);
|
|
125
|
+
|
|
126
|
+
v3_view_forward.add(target);
|
|
127
|
+
|
|
128
|
+
result.setTranslation(v3_view_forward.x, v3_view_forward.y, v3_view_forward.z);
|
|
129
|
+
|
|
130
|
+
// the rotation moved, so the matrix owes an update
|
|
131
|
+
result.updateMatrix();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Move a controller's target `distance` world units along where its view faces: `right` and
|
|
136
|
+
* `forward` pick the direction in the view's own frame, so a target can be flown up or down a slope.
|
|
137
|
+
* A diagonal travels the same distance as a straight move.
|
|
138
|
+
*
|
|
139
|
+
* The viewer's right is the negated X axis of the view rotation, as {@link pan} explains.
|
|
140
|
+
*
|
|
141
|
+
* @param {TopDownCameraController} controller its {@link TopDownCameraController#target} is moved
|
|
142
|
+
* @param {number} right −1 to 1, positive to the viewer's right
|
|
143
|
+
* @param {number} forward −1 to 1, positive into the screen
|
|
144
|
+
* @param {number} distance world units
|
|
145
|
+
*/
|
|
146
|
+
export function top_down_truck_in_view(controller, right, forward, distance) {
|
|
147
|
+
top_down_view_rotation(q_view, controller);
|
|
148
|
+
|
|
149
|
+
truck_in_rotation(controller.target, q_view, right, forward, distance);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Move a controller's target `distance` world units across the ground, along the way its view is
|
|
154
|
+
* turned: `forward` is the view's heading with the pitch taken out, so it keeps its full speed
|
|
155
|
+
* however steeply the view looks down, straight down included, and never moves the target off the
|
|
156
|
+
* ground. A diagonal travels the same distance as a straight move.
|
|
157
|
+
*
|
|
158
|
+
* @param {TopDownCameraController} controller its {@link TopDownCameraController#target} is moved
|
|
159
|
+
* @param {number} right −1 to 1, positive to the viewer's right
|
|
160
|
+
* @param {number} forward −1 to 1, positive along the view's heading
|
|
161
|
+
* @param {number} distance world units
|
|
162
|
+
*/
|
|
163
|
+
export function top_down_truck_on_ground(controller, right, forward, distance) {
|
|
164
|
+
q_view.fromEulerAnglesZYX(0, controller.yaw, 0);
|
|
165
|
+
|
|
166
|
+
truck_in_rotation(controller.target, q_view, right, forward, distance);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* @param {Vector3} target
|
|
171
|
+
* @param {Quaternion} rotation
|
|
172
|
+
* @param {number} right
|
|
173
|
+
* @param {number} forward
|
|
174
|
+
* @param {number} distance
|
|
175
|
+
*/
|
|
176
|
+
function truck_in_rotation(target, rotation, right, forward, distance) {
|
|
177
|
+
const length = Math.hypot(right, forward);
|
|
178
|
+
|
|
179
|
+
if (length === 0) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const step = distance / length;
|
|
184
|
+
|
|
185
|
+
v3_view_right.copy(Vector3.right);
|
|
186
|
+
v3_view_right.applyQuaternion(rotation);
|
|
187
|
+
|
|
188
|
+
v3_view_forward.copy(Vector3.forward);
|
|
189
|
+
v3_view_forward.applyQuaternion(rotation);
|
|
190
|
+
|
|
191
|
+
// the viewer's right is the negated X axis
|
|
192
|
+
const along_right = -right * step;
|
|
193
|
+
const along_forward = forward * step;
|
|
194
|
+
|
|
195
|
+
target._add(
|
|
196
|
+
v3_view_right.x * along_right + v3_view_forward.x * along_forward,
|
|
197
|
+
v3_view_right.y * along_right + v3_view_forward.y * along_forward,
|
|
198
|
+
v3_view_right.z * along_right + v3_view_forward.z * along_forward
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
125
202
|
|
|
126
203
|
class TopDownCameraController {
|
|
127
204
|
target = new Vector3();
|
|
@@ -169,9 +246,19 @@ class TopDownCameraController {
|
|
|
169
246
|
|
|
170
247
|
m4_euler_angles(angles, m4, 2, 1, 0)
|
|
171
248
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
249
|
+
if (Math.abs(angles[2]) > Math.PI / 2) {
|
|
250
|
+
// The decomposition holds yaw within ±π/2 and, for about half of all views, answers with the
|
|
251
|
+
// view turned over — pitched past the vertical and rolled half a turn. That is the same
|
|
252
|
+
// rotation as the upright one, half a turn of yaw away, which is the pose an orbit expects:
|
|
253
|
+
// pitch within ±π/2 and, for an up of +Y, no roll.
|
|
254
|
+
this.pitch = normalize_angle_rad(angles[2] + Math.PI);
|
|
255
|
+
this.yaw = normalize_angle_rad(Math.PI - angles[1]);
|
|
256
|
+
this.roll = normalize_angle_rad(angles[0] + Math.PI);
|
|
257
|
+
} else {
|
|
258
|
+
this.pitch = angles[2];
|
|
259
|
+
this.yaw = angles[1];
|
|
260
|
+
this.roll = angles[0];
|
|
261
|
+
}
|
|
175
262
|
|
|
176
263
|
this.distance = v3_distance(eye[0], eye[1], eye[2], target[0], target[1], target[2]);
|
|
177
264
|
|
|
@@ -294,7 +381,6 @@ class TopDownCameraController {
|
|
|
294
381
|
TopDownCameraController.typeName = "TopDownCameraController";
|
|
295
382
|
|
|
296
383
|
TopDownCameraController.pan = pan;
|
|
297
|
-
TopDownCameraController.rotate = rotate_from_view;
|
|
298
384
|
|
|
299
385
|
export default TopDownCameraController;
|
|
300
386
|
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {TopDownCameraController} control
|
|
4
|
-
* @param {Transform64} result
|
|
5
|
-
*/
|
|
6
|
-
export function computeTopDownTransform(control: TopDownCameraController, result: Transform64): void;
|
|
7
1
|
/**
|
|
8
2
|
*
|
|
9
3
|
* @param {Transform64} transform
|
|
@@ -12,8 +6,8 @@ export function computeTopDownTransform(control: TopDownCameraController, result
|
|
|
12
6
|
*/
|
|
13
7
|
export function setCameraControllerFromTransform(transform: Transform64, controller: TopDownCameraController, distance?: number): void;
|
|
14
8
|
export default TopDownCameraControllerSystem;
|
|
15
|
-
import TopDownCameraController from './TopDownCameraController.js';
|
|
16
9
|
import { Transform64 } from '../../../../ecs/transform/Transform64.js';
|
|
10
|
+
import TopDownCameraController from './TopDownCameraController.js';
|
|
17
11
|
declare class TopDownCameraControllerSystem extends System<any> {
|
|
18
12
|
constructor();
|
|
19
13
|
enabled: ObservedValue<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TopDownCameraControllerSystem.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TopDownCameraControllerSystem.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js"],"names":[],"mappings":"AAgFA;;;;;GAKG;AACH,4DAJW,WAAW,cACX,uBAAuB,aACvB,MAAM,QAahB;;4BA1F2B,0CAA0C;oCAGL,8BAA8B;AAa/F;;IACI,gCAAkC;IAClC,iDAAyC;IACzC,mEAEE;IAEF;;;;;OAKG;IACH,8BA0BC;IAED,6BAaC;CACJ;uBA1EsB,2BAA2B;0BAHxB,4CAA4C;4CAE1B,0DAA0D"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import Vector3 from "../../../../../core/geom/Vector3.js";
|
|
2
|
-
import { clamp } from "../../../../../core/math/clamp.js";
|
|
3
2
|
import ObservedValue from "../../../../../core/model/ObservedValue.js";
|
|
4
3
|
import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
|
|
5
4
|
import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
|
|
@@ -9,14 +8,10 @@ import { t64_read_pose_array } from "../../../../ecs/transform/t64_read_pose_arr
|
|
|
9
8
|
import { Transform64 } from '../../../../ecs/transform/Transform64.js';
|
|
10
9
|
|
|
11
10
|
|
|
12
|
-
import TopDownCameraController, {
|
|
13
|
-
import Quaternion from "../../../../../core/geom/Quaternion.js";
|
|
11
|
+
import TopDownCameraController, { computeTopDownTransform } from './TopDownCameraController.js';
|
|
14
12
|
import { v3_quaternion_apply } from "../../../../../core/geom/vec3/v3_quaternion_apply.js";
|
|
15
13
|
|
|
16
14
|
|
|
17
|
-
const v3_scratch = new Vector3();
|
|
18
|
-
const q_scratch = new Quaternion();
|
|
19
|
-
|
|
20
15
|
/**
|
|
21
16
|
* A camera's translation and rotation before and after its controller rewrites them, to tell a move from
|
|
22
17
|
* a rewrite of the same pose.
|
|
@@ -83,37 +78,6 @@ class TopDownCameraControllerSystem extends System {
|
|
|
83
78
|
}
|
|
84
79
|
}
|
|
85
80
|
|
|
86
|
-
/**
|
|
87
|
-
*
|
|
88
|
-
* @param {TopDownCameraController} control
|
|
89
|
-
* @param {Transform64} result
|
|
90
|
-
*/
|
|
91
|
-
export function computeTopDownTransform(control, result) {
|
|
92
|
-
|
|
93
|
-
//clamp the distance
|
|
94
|
-
const distance = clamp(control.distance, control.distanceMin, control.distanceMax);
|
|
95
|
-
const target = control.target;
|
|
96
|
-
|
|
97
|
-
// compute rotation. The transform holds its rotation as four numbers rather than a Quaternion,
|
|
98
|
-
// so the euler composition runs in a scratch and lands in the transform afterwards.
|
|
99
|
-
top_down_view_rotation(q_scratch, control);
|
|
100
|
-
|
|
101
|
-
result.setRotation(q_scratch.x, q_scratch.y, q_scratch.z, q_scratch.w);
|
|
102
|
-
|
|
103
|
-
// compute camera position
|
|
104
|
-
v3_scratch.copy(Vector3.forward);
|
|
105
|
-
v3_scratch.applyQuaternion(q_scratch);
|
|
106
|
-
|
|
107
|
-
v3_scratch.multiplyScalar(-distance);
|
|
108
|
-
|
|
109
|
-
v3_scratch.add(target);
|
|
110
|
-
|
|
111
|
-
result.setTranslation(v3_scratch.x, v3_scratch.y, v3_scratch.z);
|
|
112
|
-
|
|
113
|
-
// the rotation moved, so the matrix owes an update
|
|
114
|
-
result.updateMatrix();
|
|
115
|
-
}
|
|
116
|
-
|
|
117
81
|
/**
|
|
118
82
|
*
|
|
119
83
|
* @param {Transform64} transform
|
|
@@ -3,6 +3,14 @@ export default Water;
|
|
|
3
3
|
* Optical properties of an authored water surface. MeshletGeometry supplies its shape and
|
|
4
4
|
* Transform64 supplies its placement.
|
|
5
5
|
*
|
|
6
|
+
* **The geometry is the body's area: author it with the fewest triangles that cover it.** The renderer tessellates
|
|
7
|
+
* the surface on the GPU from the view, so subdividing a flat area adds no detail to the waves, and it costs every
|
|
8
|
+
* frame. The lattice is cut against each authored triangle: every lattice cell an internal edge crosses is clipped
|
|
9
|
+
* and drawn once per triangle it touches, and no 8 × 8 patch spans an internal edge. Measured on an integrated GPU
|
|
10
|
+
* (the many-waters example at 1280 × 720), a pond and a stream authored as six-segment grids (3,012 triangles) drew
|
|
11
|
+
* 669,324 lattice vertices a pass where two triangles each drew 146,772, and cost 11.65 ms more a frame. Use more
|
|
12
|
+
* triangles only where the area needs them: its outline, a hole, a crease, a change of normal.
|
|
13
|
+
*
|
|
6
14
|
* Everything optical here is physical and in SI units (WATER_OPTICS_PLAN_2026_10_02.md §7.1): the
|
|
7
15
|
* index of refraction, the micro-roughness of the surface, and what fills the body — a
|
|
8
16
|
* {@link ParticipatingMedium}, the same description the path tracer, fog and glass read. Presets
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Water.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/water/Water.js"],"names":[],"mappings":";AAUA
|
|
1
|
+
{"version":3,"file":"Water.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/water/Water.js"],"names":[],"mappings":";AAUA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH;IA6CI,0BASC;IArDD;;;OAGG;IACH,KAFU,OAAO,CAEQ;IAEzB;;;;OAIG;IACH,WAFU,OAAO,CAEa;IAE9B;;;;;;;OAOG;IACH,oBAFU,eAAe,CAEuB;IAEhD,8CAA8C;IAC9C,kBAAyB;IAWzB,yCAAyC;IACzC,uCAMC;IAbD;;;;OAIG;IACH,kCAAqC;IAqBrC,0BAoBC;IAED;;;;;MAOC;;CACJ;;;;oBAvHmB,kCAAkC;4BAC1B,2CAA2C;mBAFpD,0CAA0C;oCAGzB,0DAA0D"}
|