@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,125 @@
1
1
  import { assert } from "../../../../core/assert.js";
2
- import { clamp } from "../../../../core/math/clamp.js";
3
2
  import Vector3 from "../../../../core/geom/Vector3.js";
3
+ import { NumericInterval } from "../../../../core/math/interval/NumericInterval.js";
4
+ import { clamp } from "../../../../core/math/clamp.js";
5
+ import { clamp01 } from "../../../../core/math/clamp01.js";
6
+ import { lerp } from "../../../../core/math/lerp.js";
7
+ import { current_time_in_seconds } from "../../../../core/time/current_time_in_seconds.js";
4
8
  import { t64_equals_components } from "../../../../engine/ecs/transform/t64_equals_components.js";
5
9
  import { Transform64 } from "../../../../engine/ecs/transform/Transform64.js";
6
- import { current_time_in_seconds } from "../../../../core/time/current_time_in_seconds.js";
10
+ import { OrbitalCameraRig } from "../../../../engine/graphics/camera/orbital/OrbitalCameraRig.js";
11
+ import TopDownCameraController, {
12
+ computeTopDownTransform,
13
+ top_down_truck_in_view
14
+ } from "../../../../engine/graphics/ecs/camera/topdown/TopDownCameraController.js";
7
15
  import KeyboardDevice from "../../../../engine/input/devices/KeyboardDevice.js";
16
+ import { MouseEventButtons } from "../../../../engine/input/devices/mouse/MouseEventButtons.js";
8
17
  import { PointerDevice } from "../../../../engine/input/devices/PointerDevice.js";
9
- import { OrbitalCameraRig } from "./OrbitalCameraRig.js";
10
- import { OrbitalCameraInput } from "./OrbitalCameraInput.js";
11
- import { createOrbitalCameraConfig } from "./OrbitalCameraConfig.js";
18
+
19
+ const RAD_TO_DEG = 180 / Math.PI;
12
20
 
13
21
  /**
14
- * Smoothed orbital camera controller — a drop-in replacement for the legacy
15
- * {@link ../OrbitalCameraController.js} that adds frame-rate-independent inertia
16
- * via meep's critically-damped springs.
17
- *
18
- * It is a thin FACADE over two decoupled, independently-testable layers:
19
- * - {@link OrbitalCameraRig} — pure control core (springs + goals, no DOM/clock)
20
- * - {@link OrbitalCameraInput} — input adapter (events → rig intents, no kinematics)
22
+ * Seconds; a frame time beyond this is a tab coming back or a hitch, not motion to integrate.
23
+ * @type {number}
24
+ */
25
+ const MAX_DT = 0.1;
26
+
27
+ /**
28
+ * Orbital camera for a Shade {@link PerspectiveCamera} outside the ECS: drag to orbit, right-drag to
29
+ * pan, wheel to zoom, W/A/S/D to fly the target along the view.
21
30
  *
22
- * The facade owns only the things that genuinely need the outside world: device
23
- * lifecycle, the frame `dt`, writing the result onto the camera's transform, and
24
- * the "camera moved outside our control" detection contract. The public surface
25
- * ({@link look}, {@link from_transform}, {@link pan}, {@link update},
26
- * `distanceLimits`, `movement_speed_scale`, `camera`) matches the legacy
27
- * controller so switching is a single import change.
31
+ * The pose is a {@link TopDownCameraController} of its own, the same one an ECS camera carries, and
32
+ * an {@link OrbitalCameraRig} moves it with the feel every orbital camera in the engine shares. Each
33
+ * {@link update} writes the pose onto the camera's transform, and a transform moved by anyone else
34
+ * since is adopted as the new pose instead.
28
35
  *
29
- * @author Alex Goldring (orbital rework)
36
+ * @author Alex Goldring
30
37
  * @copyright Company Named Limited (c) 2026
31
38
  */
32
39
  export class OrbitalCameraController {
40
+ /**
41
+ * Zoom range, world units. Mutate `.min`/`.max` or `set()`; it applies from the next
42
+ * {@link look} or {@link update}.
43
+ * @type {NumericInterval}
44
+ */
45
+ distanceLimits = new NumericInterval(0.1, 1000);
46
+
47
+ /**
48
+ * W/A/S/D speed, world units a second with the camera at the near end of {@link distanceLimits},
49
+ * rising to twice that at the far end.
50
+ * @type {number}
51
+ */
52
+ movement_speed_scale = 1;
53
+
54
+ /**
55
+ * @type {TopDownCameraController}
56
+ */
57
+ pose = new TopDownCameraController();
58
+
59
+ /**
60
+ * the camera transform as this last left it, to tell when someone else moved it
61
+ * @type {Transform64}
62
+ */
63
+ #last_recorded = new Transform64();
64
+
65
+ /**
66
+ * the pose as last written, so a pose that did not change is not written again
67
+ * @type {TopDownCameraController}
68
+ */
69
+ #last_pose = new TopDownCameraController();
70
+
71
+ /**
72
+ * @type {number}
73
+ */
74
+ #last_update_time = current_time_in_seconds();
75
+
76
+ #scratch_eye = new Vector3();
77
+ #scratch_target = new Vector3();
78
+
33
79
  /**
34
80
  * @param {import("../PerspectiveCamera.js").PerspectiveCamera} camera
35
81
  * @param {HTMLElement} domElement
36
- * @param {Partial<import("./OrbitalCameraConfig.js").ORBITAL_CAMERA_FEEL_DEFAULTS>} [configOverrides]
37
82
  */
38
- constructor(camera, domElement, configOverrides) {
83
+ constructor(camera, domElement) {
39
84
  this.camera = camera;
40
85
  this.domElement = domElement;
41
86
 
42
- this.config = createOrbitalCameraConfig(configOverrides);
87
+ this.pose.distance = 1;
88
+ this.#apply_distance_limits();
89
+
90
+ this.rig = new OrbitalCameraRig(this.pose, {
91
+ orbit_buttons: MouseEventButtons.primary,
92
+ pan_buttons: MouseEventButtons.secondary,
93
+ pitch_min: -Math.PI / 2,
94
+ pitch_max: Math.PI / 2,
95
+ pan_axes: Vector3.one
96
+ });
43
97
 
44
- // ── devices (the facade owns their lifecycle) ───────────────────────
45
98
  this.pointer = new PointerDevice(domElement);
46
- this.pointer.domElement = domElement;
99
+ this.pointer.on.dragStart.add(this.#handle_drag_start, this);
100
+ this.pointer.on.drag.add(this.#handle_drag, this);
101
+ this.pointer.on.dragEnd.add(this.#handle_drag_end, this);
102
+ this.pointer.on.wheel.add(this.#handle_wheel, this);
47
103
  this.pointer.start();
48
104
 
49
105
  this.keyboard = new KeyboardDevice(domElement);
50
- this.keyboard.domElement = domElement;
51
106
  this.keyboard.start();
52
107
 
53
- // ── layers ──────────────────────────────────────────────────────────
54
- this.rig = new OrbitalCameraRig({ config: this.config });
55
-
56
- this.input = new OrbitalCameraInput({
57
- rig: this.rig,
58
- pointer: this.pointer,
59
- keyboard: this.keyboard,
60
- viewport: domElement,
61
- lens: camera,
62
- config: this.config,
63
- });
64
- this.input.connect();
65
-
66
- // ── frame bookkeeping ───────────────────────────────────────────────
67
- this._lastRecorded = new Transform64();
68
- // seed so the first no-arg update() sees ~0 dt instead of the page lifetime
69
- this._lastUpdateTime = current_time_in_seconds();
70
- this._scratchEye = new Vector3();
71
- this._scratchTarget = new Vector3();
72
-
73
- // adopt the camera's current pose
74
108
  this.from_transform(camera.transform);
75
109
  }
76
110
 
77
- // ─────────────────────────────────────────────────────────────────────────
78
- // Public API (legacy-compatible)
79
- // ─────────────────────────────────────────────────────────────────────────
80
-
81
- /** Zoom range, in world units (NumericInterval). Mutate `.min/.max` or `.set()`. */
82
- get distanceLimits() {
83
- return this.rig.distanceLimits;
84
- }
85
-
86
- /** Scene-relative WASD/keyboard move speed. */
87
- get movement_speed_scale() {
88
- return this.rig.movementSpeedScale;
89
- }
90
-
91
- set movement_speed_scale(value) {
92
- this.rig.movementSpeedScale = value;
93
- }
94
-
95
- /** Current smoothed orbit distance (radius). */
111
+ /** Orbit distance, world units. */
96
112
  get distance() {
97
- return this.rig.distance;
113
+ return this.pose.distance;
98
114
  }
99
115
 
100
- /** Current smoothed target (shared scratch — copy if you need to retain it). */
116
+ /** Orbit target, live: copy it to keep it. */
101
117
  get target() {
102
- return this.rig.getTarget();
118
+ return this.pose.target;
103
119
  }
104
120
 
105
121
  /**
106
- * Point the camera at `to` from `from`, immediately (no animation).
122
+ * Point the camera at `to` from `from`, at once, stopping any throw.
107
123
  * @param {Vector3} from
108
124
  * @param {Vector3} to
109
125
  */
@@ -111,127 +127,161 @@ export class OrbitalCameraController {
111
127
  assert.defined(from, "from");
112
128
  assert.defined(to, "to");
113
129
 
114
- this.rig.frameTo(from, to, { animate: false });
115
- // apply immediately so a subsequent at-rest update() doesn't skip the write
116
- this.rig.composeTransform(this.camera.transform);
117
- this._lastRecorded.copy(this.camera.transform);
118
- }
130
+ const pose = this.pose;
119
131
 
120
- /**
121
- * Eased "fly to" framing: glide to the new pose over {@link config}.flyToHalfLife
122
- * instead of snapping. The normal update() loop animates it.
123
- * @param {Vector3} from
124
- * @param {Vector3} to
125
- */
126
- flyTo(from, to) {
127
- assert.defined(from, "from");
128
- assert.defined(to, "to");
132
+ this.rig.stop();
133
+
134
+ pose.setFromEyeAndTarget(from, to);
135
+
136
+ // the eye is kept within the zoom range rather than widening the range to fit it
137
+ this.#apply_distance_limits();
138
+ pose.distance = clamp(pose.distance, pose.distanceMin, pose.distanceMax);
129
139
 
130
- this.rig.frameTo(from, to, { animate: true });
131
- // camera transform is unchanged this frame; keep the snapshot in sync so
132
- // the animation isn't mistaken for an external mutation next update().
133
- this._lastRecorded.copy(this.camera.transform);
140
+ this.#write();
134
141
  }
135
142
 
136
143
  /**
137
- * Adopt an external camera transform as the new orbit pose (target is placed
138
- * `distance` ahead along its forward).
144
+ * Adopt a camera transform as the pose, the target the current orbit distance ahead of it.
139
145
  *
140
- * Read component-wise rather than through `Vector3.copy`, because a
141
- * {@link Transform64} answers `forward` and `translation` with raw
142
- * `Float64Array`s — no `.x`, and a `copy` of one silently sets three
143
- * undefineds. Those two arrays are also freshly allocated per access, so
144
- * each is read once into a scratch that outlives the call.
146
+ * Read by component, because a {@link Transform64} answers `forward` with a raw `Float64Array`,
147
+ * allocated on each access.
145
148
  *
146
149
  * @param {Transform64} transform
147
150
  */
148
151
  from_transform(transform) {
149
152
  const forward = transform.forward;
150
153
 
151
- const distance = this.rig.distance;
154
+ const distance = this.pose.distance;
152
155
 
153
- this._scratchEye.set(
156
+ this.#scratch_eye.set(
154
157
  transform.translation_x,
155
158
  transform.translation_y,
156
159
  transform.translation_z
157
160
  );
158
161
 
159
- this._scratchTarget.set(
160
- this._scratchEye.x + forward[0] * distance,
161
- this._scratchEye.y + forward[1] * distance,
162
- this._scratchEye.z + forward[2] * distance
162
+ this.#scratch_target.set(
163
+ this.#scratch_eye.x + forward[0] * distance,
164
+ this.#scratch_eye.y + forward[1] * distance,
165
+ this.#scratch_eye.z + forward[2] * distance
163
166
  );
164
167
 
165
- this.look(this._scratchEye, this._scratchTarget);
168
+ this.look(this.#scratch_eye, this.#scratch_target);
166
169
  }
167
170
 
168
171
  /**
169
- * Screen-space pan of the orbit target, in pointer pixels (legacy signature).
170
- * @param {number} delta_x
171
- * @param {number} delta_y
172
- */
173
- pan(delta_x, delta_y) {
174
- this.rig.panScreen(delta_x, delta_y, this.domElement.clientHeight, this.camera.fov);
175
- }
176
-
177
- /**
178
- * Advance one frame and write the result onto the camera transform.
172
+ * Advance one frame and write the pose onto the camera transform.
179
173
  *
180
- * @param {number} [dt] frame time in seconds. STRONGLY preferred — pass the
181
- * value `create_frame_loop` already hands the callback. Omit to fall back
182
- * to an internal clock (clamped, so no first-frame teleport).
174
+ * @param {number} [dt] frame time in seconds; `create_frame_loop` hands it to its callback. Omit
175
+ * it to measure the time since the last call instead.
183
176
  */
184
177
  update(dt) {
185
- const frameDt = this._resolveDt(dt);
178
+ const frame_dt = this.#resolve_dt(dt);
186
179
 
187
- // continuous (held-key) input → rig intents
188
- this.input.update(frameDt);
180
+ this.#apply_distance_limits();
189
181
 
190
- const camTransform = this.camera.transform;
182
+ if (!t64_equals_components(this.#last_recorded, this.camera.transform)) {
183
+ // moved outside our control: that is the pose now
184
+ this.from_transform(this.camera.transform);
191
185
 
192
- if (!t64_equals_components(this._lastRecorded, camTransform)) {
193
- // camera was moved outside our control — adopt it, skip integration
194
- this.from_transform(camTransform);
195
- } else {
196
- const moved = this.rig.update(frameDt);
197
- if (moved) {
198
- this.rig.composeTransform(camTransform);
199
- }
186
+ return;
200
187
  }
201
188
 
202
- this._lastRecorded.copy(camTransform);
189
+ this.#truck(frame_dt);
190
+
191
+ this.rig.update(frame_dt);
192
+
193
+ if (!this.pose.equals(this.#last_pose)) {
194
+ this.#write();
195
+ }
203
196
  }
204
197
 
205
- /** Detach input subscriptions and stop the devices. */
198
+ /** Detach input and stop the devices. */
206
199
  dispose() {
207
- this.input.disconnect();
208
- this.pointer.stop?.();
209
- this.keyboard.stop?.();
200
+ this.pointer.on.dragStart.remove(this.#handle_drag_start, this);
201
+ this.pointer.on.drag.remove(this.#handle_drag, this);
202
+ this.pointer.on.dragEnd.remove(this.#handle_drag_end, this);
203
+ this.pointer.on.wheel.remove(this.#handle_wheel, this);
204
+ this.pointer.stop();
205
+
206
+ this.keyboard.stop();
207
+ }
208
+
209
+ #write() {
210
+ computeTopDownTransform(this.pose, this.camera.transform);
211
+
212
+ this.#last_pose.copy(this.pose);
213
+ this.#last_recorded.copy(this.camera.transform);
214
+ }
215
+
216
+ #apply_distance_limits() {
217
+ this.pose.distanceMin = this.distanceLimits.min;
218
+ this.pose.distanceMax = this.distanceLimits.max;
219
+ }
220
+
221
+ /**
222
+ * @param {number} dt seconds
223
+ */
224
+ #truck(dt) {
225
+ const keys = this.keyboard.keys;
226
+
227
+ const right = (keys.d?.is_down ? 1 : 0) - (keys.a?.is_down ? 1 : 0);
228
+ const forward = (keys.w?.is_down ? 1 : 0) - (keys.s?.is_down ? 1 : 0);
229
+
230
+ if (right === 0 && forward === 0) {
231
+ return;
232
+ }
233
+
234
+ const zoom_scale = lerp(1, 2, clamp01(this.distanceLimits.normalizeValue(this.pose.distance)));
235
+
236
+ top_down_truck_in_view(this.pose, right, forward, this.movement_speed_scale * zoom_scale * dt);
237
+ }
238
+
239
+ /**
240
+ * @param {Vector2} origin
241
+ * @param {PointerEvent} event
242
+ */
243
+ #handle_drag_start(origin, event) {
244
+ this.rig.begin(event.buttons);
245
+ }
246
+
247
+ /**
248
+ * @param {Vector2} position
249
+ * @param {Vector2} origin
250
+ * @param {Vector2} last_position
251
+ */
252
+ #handle_drag(position, origin, last_position) {
253
+ this.rig.move(
254
+ position.x - last_position.x,
255
+ position.y - last_position.y,
256
+ this.domElement.clientHeight,
257
+ this.camera.fov * RAD_TO_DEG
258
+ );
210
259
  }
211
260
 
212
- // ─────────────────────────────────────────────────────────────────────────
213
- // Internals
214
- // ─────────────────────────────────────────────────────────────────────────
261
+ #handle_drag_end() {
262
+ this.rig.end();
263
+ }
264
+
265
+ /**
266
+ * @param {Vector3} delta signs of the wheel's motion
267
+ */
268
+ #handle_wheel(delta) {
269
+ this.#apply_distance_limits();
270
+
271
+ this.rig.dolly(delta.y);
272
+ }
215
273
 
216
274
  /**
217
- * Resolve and sanitize the frame dt. Prefers the supplied value; otherwise
218
- * derives it from an internal clock. Always clamped to [0, maxDt] so a tab
219
- * refocus / GC hitch can't make the springs jump.
220
275
  * @param {number} [dt]
221
- * @returns {number}
276
+ * @returns {number} seconds, within [0, {@link MAX_DT}]
222
277
  */
223
- _resolveDt(dt) {
278
+ #resolve_dt(dt) {
224
279
  const now = current_time_in_seconds();
225
280
 
226
- let d;
227
- if (typeof dt === "number" && Number.isFinite(dt)) {
228
- d = dt;
229
- } else {
230
- d = now - this._lastUpdateTime;
231
- }
281
+ const elapsed = (typeof dt === "number" && Number.isFinite(dt)) ? dt : now - this.#last_update_time;
232
282
 
233
- this._lastUpdateTime = now;
283
+ this.#last_update_time = now;
234
284
 
235
- return clamp(d, 0, this.config.maxDt);
285
+ return clamp(elapsed, 0, MAX_DT);
236
286
  }
237
287
  }
@@ -143,7 +143,7 @@ export class GPUFluidCascade {
143
143
  * @param {*} _resources
144
144
  * @param {{encoder: ShadeGPUCommandContext}} context
145
145
  */
146
- static "__#277@#execute_restrict"(record: object, _resources: any, context: {
146
+ static "__#279@#execute_restrict"(record: object, _resources: any, context: {
147
147
  encoder: ShadeGPUCommandContext;
148
148
  }): void;
149
149
  /**
@@ -151,7 +151,7 @@ export class GPUFluidCascade {
151
151
  * @param {*} _resources
152
152
  * @param {{encoder: ShadeGPUCommandContext}} context
153
153
  */
154
- static "__#277@#execute_fill"(record: object, _resources: any, context: {
154
+ static "__#279@#execute_fill"(record: object, _resources: any, context: {
155
155
  encoder: ShadeGPUCommandContext;
156
156
  }): void;
157
157
  /**
@@ -159,7 +159,7 @@ export class GPUFluidCascade {
159
159
  * @param {import("../../../engine/graphics/render/frame_graph/FramePassResources.js").FramePassResources} resources
160
160
  * @param {{encoder: ShadeGPUCommandContext}} context
161
161
  */
162
- static "__#277@#execute"(record: object, resources: import("../../../engine/graphics/render/frame_graph/FramePassResources.js").FramePassResources, context: {
162
+ static "__#279@#execute"(record: object, resources: import("../../../engine/graphics/render/frame_graph/FramePassResources.js").FramePassResources, context: {
163
163
  encoder: ShadeGPUCommandContext;
164
164
  }): void;
165
165
  /**
@@ -63,7 +63,7 @@ export class GPUFluidCascadeStack {
63
63
  * @param {*} _resources
64
64
  * @param {{encoder: import("../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext}} context
65
65
  */
66
- static "__#279@#execute_publish"(pass: object, _resources: any, context: {
66
+ static "__#281@#execute_publish"(pass: object, _resources: any, context: {
67
67
  encoder: import("../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext;
68
68
  }): void;
69
69
  /**
@@ -90,19 +90,19 @@ export class GPUFluidForcing {
90
90
  * @param {number} clear_size bytes cleared from 0 when the pool reuses the buffer
91
91
  * @returns {BufferResourceDescriptor}
92
92
  */
93
- static "__#280@#descriptor"(kept: BufferResourceDescriptor[], role: number, size: number, usage: number, clear_size: number): BufferResourceDescriptor;
93
+ static "__#282@#descriptor"(kept: BufferResourceDescriptor[], role: number, size: number, usage: number, clear_size: number): BufferResourceDescriptor;
94
94
  /**
95
95
  * @param {object} record
96
96
  * @param {FramePassResources} resources
97
97
  * @param {{encoder: ShadeGPUCommandContext}} context
98
98
  */
99
- static "__#280@#execute_extract"(record: object, resources: FramePassResources, context: {
99
+ static "__#282@#execute_extract"(record: object, resources: FramePassResources, context: {
100
100
  encoder: ShadeGPUCommandContext;
101
101
  }): void;
102
- static "__#280@#execute_clear"(record: any, _resources: any, context: any): void;
103
- static "__#280@#execute_query"(record: any, resources: any, context: any): void;
104
- static "__#280@#execute_command"(record: any, resources: any, context: any): void;
105
- static "__#280@#execute_apply"(record: any, resources: any, context: any): void;
102
+ static "__#282@#execute_clear"(record: any, _resources: any, context: any): void;
103
+ static "__#282@#execute_query"(record: any, resources: any, context: any): void;
104
+ static "__#282@#execute_command"(record: any, resources: any, context: any): void;
105
+ static "__#282@#execute_apply"(record: any, resources: any, context: any): void;
106
106
  /**
107
107
  * @param {object} options
108
108
  * @param {GPUDevice} options.device
@@ -41,7 +41,7 @@ export class GPUFluidPressureSolve {
41
41
  * @param {*} _resources
42
42
  * @param {{encoder: ShadeGPUCommandContext}} context
43
43
  */
44
- static "__#276@#execute"(data: {
44
+ static "__#278@#execute"(data: {
45
45
  solve: GPUFluidPressureSolve;
46
46
  arm: number;
47
47
  count: number;
@@ -49,7 +49,7 @@ export class GPUFluidQueries {
49
49
  * @param {import("../../../../engine/graphics/render/frame_graph/FramePassResources.js").FramePassResources} resources
50
50
  * @param {{encoder: import("../../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext}} context
51
51
  */
52
- static "__#281@#execute"(pass: object, resources: import("../../../../engine/graphics/render/frame_graph/FramePassResources.js").FramePassResources, context: {
52
+ static "__#283@#execute"(pass: object, resources: import("../../../../engine/graphics/render/frame_graph/FramePassResources.js").FramePassResources, context: {
53
53
  encoder: import("../../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext;
54
54
  }): void;
55
55
  /**