@woosh/meep-engine 3.60.4 → 3.60.6

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.
Files changed (419) hide show
  1. package/CHANGELOG.md +2621 -0
  2. package/CONTRIBUTING.md +7 -0
  3. package/MIGRATION_2_TO_3.md +136 -0
  4. package/SECURITY.md +4 -0
  5. package/editor/EditorCameraNavigation.d.ts +2 -1
  6. package/editor/EditorCameraNavigation.d.ts.map +1 -1
  7. package/editor/EditorCameraNavigation.js +51 -57
  8. package/package.json +6 -2
  9. package/src/engine/EngineHarness.d.ts +3 -9
  10. package/src/engine/EngineHarness.d.ts.map +1 -1
  11. package/src/engine/EngineHarness.js +6 -8
  12. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
  13. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
  14. package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
  15. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
  16. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
  17. package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
  18. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
  19. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
  20. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
  21. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
  22. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
  23. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
  24. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
  25. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  26. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
  27. package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
  28. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  29. package/src/engine/graphics/ecs/water/Water.js +8 -0
  30. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  31. package/src/engine/graphics3/WaterSystem.js +731 -734
  32. package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
  33. package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
  34. package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
  35. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
  36. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
  37. package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
  38. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
  39. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
  40. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
  41. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
  42. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
  43. package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
  44. package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
  45. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  46. package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
  47. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
  48. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
  49. package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
  50. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
  51. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
  52. package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
  53. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
  54. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
  55. package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
  56. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
  57. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
  58. package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
  59. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  60. package/src/shade/playground/water_refraction/README.md +5 -6
  61. package/src/shade/playground/water_refraction/index.html +1 -1
  62. package/src/shade/renderer/Renderer.d.ts +11 -0
  63. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  64. package/src/shade/renderer/Renderer.js +50 -6
  65. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  66. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  67. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  68. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  69. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  70. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  71. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  72. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  73. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +28 -45
  74. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  75. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +111 -119
  76. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +22 -3
  77. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  78. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +84 -3
  79. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts +19 -0
  80. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts.map +1 -0
  81. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.js +25 -0
  82. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  83. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  84. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  85. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +15 -0
  86. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -1
  87. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +38 -0
  88. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  89. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  90. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  91. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  92. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  93. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts +28 -59
  94. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts.map +1 -1
  95. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.js +84 -789
  96. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
  98. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +7 -6
  99. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  100. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +12 -11
  101. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -2
  102. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +2 -2
  103. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
  104. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  105. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
  106. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  107. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  108. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  109. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  110. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  111. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  112. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  113. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  114. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  115. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  116. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  117. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  118. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  119. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  120. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  121. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  122. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  123. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  124. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  125. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  126. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  127. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  128. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  129. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  130. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  131. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  132. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  133. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  134. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  135. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  136. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  137. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  138. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  139. package/src/shade/renderer/material/GPUMaterialManager.d.ts +11 -1
  140. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  141. package/src/shade/renderer/material/GPUMaterialManager.js +16 -8
  142. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  143. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  144. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  145. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +7 -3
  146. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  147. package/src/shade/renderer/postprocess/gtao/GTAO.js +26 -13
  148. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts +14 -0
  149. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  150. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +196 -68
  151. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  152. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +42 -28
  153. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  154. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +429 -414
  155. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts +16 -0
  156. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts.map +1 -0
  157. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.js +156 -0
  158. package/src/shade/renderer/scene/GPUSceneContext.d.ts +2 -2
  159. package/src/shade/renderer/scene/GPUSceneContext.js +5 -5
  160. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  161. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  162. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  163. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  164. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  165. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  166. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  167. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  168. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  169. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  170. package/src/shade/renderer/water/shader_water.js +22 -13
  171. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  172. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  173. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  174. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  175. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  176. package/editor/REWORK_PLAN_2026_08.md +0 -692
  177. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  178. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  179. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  180. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  181. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  182. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  183. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  184. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  185. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  186. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  187. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  188. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  189. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  190. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  191. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  192. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  193. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  194. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  195. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  196. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  197. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  198. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  199. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  200. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  201. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  202. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  203. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  204. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  205. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  206. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  207. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  208. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  209. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  210. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  211. package/src/REVIEW_2026_08_06/generation.md +0 -176
  212. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  213. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  214. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  215. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  216. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  217. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  218. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  219. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  220. package/src/REVIEW_2026_08_06/view.md +0 -667
  221. package/src/REVIEW_2026_08_06.md +0 -610
  222. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  223. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  224. package/src/core/bvh8/NOTES.md +0 -63
  225. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  226. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  227. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  228. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  229. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  230. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  231. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  232. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  233. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  234. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  235. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  236. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  237. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  238. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  239. package/src/engine/REVIEW_2026_07_03.md +0 -211
  240. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  241. package/src/engine/control/first-person/DESIGN.md +0 -658
  242. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  243. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  244. package/src/engine/control/first-person/TODO.md +0 -160
  245. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  246. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  247. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  248. package/src/engine/ecs/ik/PLAN.md +0 -179
  249. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  250. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  251. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  252. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  253. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  254. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  255. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  256. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  257. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  258. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  259. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  260. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  261. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  262. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  263. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  264. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  265. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  266. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  267. package/src/engine/physics/cloth/PLAN.md +0 -3056
  268. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  269. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  270. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  271. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  272. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  273. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  274. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  275. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  276. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  277. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  278. package/src/format/image/avif/DECISIONS.md +0 -545
  279. package/src/format/image/jpeg/NOTES.md +0 -3
  280. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  281. package/src/generation/COORDINATES.md +0 -54
  282. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  283. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  284. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  285. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  286. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  287. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  288. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  289. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  290. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  291. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  292. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  293. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  294. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  295. package/src/shade/RENDERER_CONTRACT.md +0 -697
  296. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  297. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  298. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  299. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  300. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  301. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  302. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  303. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  304. package/src/shade/renderer/NOTES.md +0 -78
  305. package/src/shade/renderer/PLAN.md +0 -8
  306. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  307. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  308. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  309. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  310. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  311. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  312. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  313. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  314. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  315. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  316. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  317. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  318. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  319. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  320. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  321. package/src/shade/renderer/camera/orbital/README.md +0 -81
  322. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  323. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  324. package/src/shade/renderer/camera/orbital/index.js +0 -9
  325. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  326. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  327. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  328. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  329. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  330. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  331. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  332. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  333. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  334. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
  335. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  336. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  337. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  338. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  339. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  340. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  341. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  342. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
  343. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts +0 -47
  344. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts.map +0 -1
  345. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.js +0 -80
  346. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts +0 -16
  347. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts.map +0 -1
  348. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.js +0 -67
  349. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts +0 -17
  350. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts.map +0 -1
  351. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.js +0 -145
  352. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts +0 -12
  353. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts.map +0 -1
  354. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.js +0 -105
  355. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  356. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
  357. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  358. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  359. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  360. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  361. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  362. package/src/shade/renderer/hiz/NOTES.md +0 -3
  363. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  364. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  365. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  366. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  367. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  368. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  369. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  370. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  371. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  372. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
  373. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  374. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  375. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  376. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  377. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  378. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
  379. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  380. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  381. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  382. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  383. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  384. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  385. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  386. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  387. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  388. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  389. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  390. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  391. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
  392. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
  393. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  394. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  395. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  396. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  397. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  398. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  399. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  400. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  401. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  402. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
  403. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  404. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  405. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  406. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  407. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  408. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  409. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  410. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  411. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  412. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  413. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
  414. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  415. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  416. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  417. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  418. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  419. package/src/shade/wgsl/NOTES.md +0 -4
@@ -1,109 +1,82 @@
1
- import { clamp } from "../../../core/math/clamp.js";
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 { decodeMouseEventButtons } from "../../input/devices/mouse/decodeMouseEventButtons.js";
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, { rotate_from_view } from "../ecs/camera/topdown/TopDownCameraController.js";
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
- * @param {number} [options.sensitivity]
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
- function zoom(delta) {
62
- const cameraController = getCameraController();
63
-
64
- const new_distance = cameraController.distance + delta;
65
- cameraController.distance = clamp(new_distance, cameraController.distanceMin, cameraController.distanceMax);
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/tap',
71
- listener(position, event) {
72
- // event.preventDefault();
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: function (position, origin, lastDragPosition, event) {
84
- const delta = lastDragPosition.clone().sub(position);
85
-
86
- const buttons = decodeMouseEventButtons(event.buttons);
87
-
88
- if (buttons[0]) {
89
- pan(delta);
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, event) {
100
- zoom(delta.y);
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"}